Skip to content

Начало работы с графиками

В этом руководстве показано, как отобразить три ряда данных в контроле CartesianChart, используя представления панели и ряда линий.

charts-get-started

Сначала мы определим данные для контрола диаграммы (в View Model objects), а затем привяжем контрол диаграммы к этим данным.

Далее мы определим и настроим оси по умолчанию, а также покажем, как добавить дополнительную ось X и привязать ее к определенному ряду.

Определение модели представления для серии

Начните с создания модели представления для одной серии.

using Eremex.AvaloniaUI.Charts;

public partial class SeriesViewModel : ObservableObject
{
    [ObservableProperty] Color color;
    [ObservableProperty] ISeriesDataAdapter dataAdapter;
}

Класс SeriesViewModel предоставляет два свойства, которые определяют цвет и данные для серии.

Данные для серии диаграммного контрола предоставляются с использованием объектов Data Adapter. Диаграммы Eremex поддерживают несколько адаптеров данных для различных типов данных (числовые, дата-время и качественные). В этом руководстве мы будем использовать два адаптера данных:

  • SortedNumericDataAdapter — Содержит пары (числовые X, числовые Y), отсортированные по значениям X.
  • SortedDateTimeDataAdapter — Предоставляет пары (дата-время X, числовой Y), отсортированные по значениям X.

Эти адаптеры данных инициализируются в основной модели представления.

Информацию о других адаптерах данных смотрите в разделе Декартова диаграмма .

Определите модель основного представления

Создайте класс MainWindowViewModel, который инкапсулирует основную модель представления для окна. Экземпляр MainWindowViewModel будет установлен в качестве DataContext для окна (и контрола диаграммы).

Добавьте три свойства SeriesViewModel к классу MainWindowViewModel. Они описывают три ряда данных в контроле целевой диаграммы.

public partial class MainWindowViewModel : ViewModelBase
{
    [ObservableProperty] SeriesViewModel barSeries1; 
    [ObservableProperty] SeriesViewModel barSeries2; 
    [ObservableProperty] SeriesViewModel lineSeries;
}

Инициализируйте эти объекты в конструкторе модели представления и укажите цвета и адаптеры данных для серии.

public partial class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        //Init data
        var random = new Random(4);
        var random2 = new Random(0);

        var startDate = new DateTime(DateTime.Now.Year, 1, 1);
        SortedDateTimeDataAdapter barSeries1DataAdapter = new();
        SortedDateTimeDataAdapter barSeries2DataAdapter = new();
        SortedNumericDataAdapter lineSeriesDataAdapter = new();
        for (int i = 0; i < 12; i++)
        {
            var argument = startDate.AddMonths(i);
            barSeries1DataAdapter.Add(argument, random.NextDouble() * 100 - 30);
            barSeries2DataAdapter.Add(argument, random.NextDouble() * 100 - 30);
        }
        double startValue = 20;
        for (int i = 0; i < 365; i++)
        {
            var argument = i;
            var value = startValue + (random2.NextDouble() - 0.5) * 10;
            lineSeriesDataAdapter.Add(argument, value);
            startValue = value;
        }
        // Create data series
        BarSeries1 = new() { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = barSeries1DataAdapter };
        BarSeries2 = new() { Color = Color.FromArgb(255, 0, 170, 110), DataAdapter = barSeries2DataAdapter };
        LineSeries = new() { Color = Color.FromArgb(255, 120, 10, 12), DataAdapter = lineSeriesDataAdapter };
    }

    [ObservableProperty] SeriesViewModel barSeries1; 
    [ObservableProperty] SeriesViewModel barSeries2; 
    [ObservableProperty] SeriesViewModel lineSeries;
}

Адаптеры данных заполняются случайными данными:

  • Объекты SortedDateTimeDataAdapter заполнены 12 точками, которые соответствуют 12 месяцам года. Значения X для объектов SortedDateTimeDataAdapter являются значениями DateTime.

  • Объект SortedNumericDataAdapter содержит 365 точек, соответствующих дням года. Значения X объекта SortedNumericDataAdapter являются числовыми значениями.

Создание контрола декартовой диаграммы

Убедитесь, что для DataContext окна и контрола диаграммы установлено значение объекта MainWindowViewModel.

Откройте файл MainWindow XAML и определите контрол CartersianChart с двумя последовательностями следующим образом:

xmlns:mxc="https://schemas.eremexcontrols.net/avalonia/charts"             

<mxc:CartesianChart>
    <mxc:CartesianChart.Series>
        <mxc:CartesianSeries Name="barSeries1" DataAdapter="{Binding BarSeries1.DataAdapter}" >
        </mxc:CartesianSeries>

        <mxc:CartesianSeries Name="barSeries2" DataAdapter="{Binding BarSeries2.DataAdapter}" >
        </mxc:CartesianSeries>
    </mxc:CartesianChart.Series>
</mxc:CartesianChart>

Этот код добавляет две серии (объекты CartesianSeries) в коллекцию CartesianChart.Series и привязывает их к соответствующим адаптерам данных в модели основного представления.

Укажите вид серии

series view определяет внешний вид и свойства настроек серии. Декартова диаграмма поддерживает несколько видов рядов: линия, линия рассеяния, область диапазона, Панель, панель диапазона и т.д. Смотрите следующий раздел для получения дополнительной информации: Декартова диаграмма .

Давайте применим к серии вид серии на панели. Для этой цели определите объект CartesianSideBySideBarSeriesView как содержимое объекта CartesianSeries.

<mxc:CartesianChart>
    <mxc:CartesianChart.Series>
        <mxc:CartesianSeries Name="barSeries1" DataAdapter="{Binding BarSeries1.DataAdapter}" >
            <mxc:CartesianSideBySideBarSeriesView Color="{Binding BarSeries1.Color}" />
        </mxc:CartesianSeries>
        <mxc:CartesianSeries Name="barSeries2" DataAdapter="{Binding BarSeries2.DataAdapter}" >
            <mxc:CartesianSideBySideBarSeriesView Color="{Binding BarSeries2.Color}" />
        </mxc:CartesianSeries>
    </mxc:CartesianChart.Series>
</mxc:CartesianChart>

CartesianSideBySideBarSeriesView отображает точки в виде прямоугольных панелей:

chart-CartesianSideBySideBarSeriesView-oneseries

Свойство Color для представления серии позволяет вам указать цвет для отображения связанной серии.

Создание и настройка осей по умолчанию

Декартова диаграмма может автоматически создавать оси для нижележащих данных. Возможно, вам потребуется вручную определить оси X и Y, если вы хотите настроить свойства осей (например, указать опции заголовка и масштаба).

Чтобы определить оси, добавьте объекты AxisX и/или AxisY в коллекции CartesianChart.AxesX/CartesianChart.AxesY:

<mxc:CartesianChart>
    <!-- ... -->
    <mxc:CartesianChart.AxesX>
        <mxc:AxisX Name="salesAxis" Title="Sales">
            <mxc:AxisX.ScaleOptions>
                <mxc:DateTimeScaleOptions MeasureUnit="Month" />
            </mxc:AxisX.ScaleOptions>
        </mxc:AxisX>
    </mxc:CartesianChart.AxesX>

    <mxc:CartesianChart.AxesY>
        <mxc:AxisY Title="Currency"/>
    </mxc:CartesianChart.AxesY>
</mxc:CartesianChart>

Приведенный выше код создает оси X и Y и определяет названия для них.

Поскольку нижележащие точки данных представляют значения для отдельных месяцев, единица измерения времени Month применяется к горизонтальной оси дата-время (с использованием свойства AxisX.ScaleOptions).

Если вы запустите приложение сейчас, то увидите следующий результат:

charts-get-started-two-series

Добавление дополнительной серии и оси X

Вы можете добавить в контрол диаграммы столько рядов, сколько захотите. Эти серии могут использовать либо оси по умолчанию, либо свои собственные оси.

Давайте добавим на диаграмму ряд линий и ось для него.

Сначала создайте новый объект CartesianSeries в коллекции CartesianChart.Series и привяжите его к объекту LineSeries.DataAdapter, определенному в модели представления.

<mxc:CartesianChart>
    <mxc:CartesianChart.Series>
        <!-- ... -->
        <mxc:CartesianSeries Name="lineSeries" DataAdapter="{Binding LineSeries.DataAdapter}" >
        </mxc:CartesianSeries> 
    </mxc:CartesianChart.Series>
</mxc:CartesianChart>

Укажите вид серии линий

Чтобы применить представление серии линий к этой серии, определите объект CartesianLineSeriesView в качестве содержимого серии:

<mxc:CartesianSeries Name="lineSeries" DataAdapter="{Binding LineSeries.DataAdapter}" >
    <mxc:CartesianLineSeriesView Color="{Binding LineSeries.Color}" />
</mxc:CartesianSeries> 

CartesianLineSeriesView - это последовательный вид, который соединяет точки линиями:

chart-CartesianLineSeriesView-one-series

Как и в случае с любым видом серии, вы можете использовать свойство CartesianLineSeriesView.Color, чтобы указать цвет отрисовки серии.

Укажите собственную ось для серии линий

Значения X серии Линий имеют числовой тип, в то время как на существующей горизонтальной оси отображаются значения DateTime. Таким образом, для ряда линий требуется дополнительная числовая ось.

Определите новую числовую ось X в коллекции CartesianChart.AxesX.

<mxc:CartesianChart.AxesX>
    <!-- ... -->
    <mxc:AxisX Position="Far" Title="Expenses">
        <mxc:AxisX.ScaleOptions>
            <mxc:NumericScaleOptions />
        </mxc:AxisX.ScaleOptions>
    </mxc:AxisX>
</mxc:CartesianChart.AxesX>

Свойству оси Position присвоено значение Far, чтобы отображать ось на краю, противоположном позиции по умолчанию. Для горизонтальной оси опция Far соответствует верхнему краю диаграммы. Для вертикальной оси опция Far размещает ось у правого края диаграммы.

Теперь нам нужно привязать ряд линий к его оси. Это достигается путем указания идентификатора оси (уникального строкового значения). Задайте один и тот же идентификатор свойству Key оси и свойству CartesianSeries.AxisXKey/CartesianSeries.AxisYKey серии.

В этом руководстве укажите идентификатор "lineSeriesAxis" для серии и оси следующим образом:

<mxc:CartesianSeries Name="lineSeries" DataAdapter="{Binding LineSeries.DataAdapter}"  
  AxisXKey="lineSeriesAxis">
    <mxc:CartesianLineSeriesView Color="{Binding LineSeries.Color}" />
</mxc:CartesianSeries>

<mxc:CartesianChart.AxesX>
    <!-- ... -->
    <mxc:AxisX Position="Far" Title="Expenses"
       Key="lineSeriesAxis">
        <mxc:AxisX.ScaleOptions>
            <mxc:NumericScaleOptions />
        </mxc:AxisX.ScaleOptions>
    </mxc:AxisX>
</mxc:CartesianChart.AxesX>

Вы можете запустить приложение, чтобы увидеть контрол диаграммы, отображающий три ряда:

charts-get-started-three-series

Создание пользовательского форматера меток

CartesianChart форматирует метки для основных отметок на основе опций масштабирования по оси. На следующей картинке показано форматирование метки, когда единица измерения времени Month применяется к оси X:

chart-get-started-label-formatting-month-default

Свойство ScaleOptions.LabelFormatter оси позволяет изменять формат отображения меток. Вы можете использовать класс Eremex.AvaloniaUI.Charts.FuncLabelFormatter в качестве средства форматирования меток или создать пользовательское средство форматирования меток, реализовав интерфейс IAxisLabelFormatter.

Мы будем использовать класс FuncLabelFormatter для создания коротких меток для значений даты и времени оси X. В модели основного представления реализуйте свойство типа FuncLabelFormatter, которое форматирует метки определенным образом. В XAML привяжите опцию axis ScaleOptions.LabelFormatter к этому форматировщику.

chart-get-started-label-formatting-month-custom

<mxc:AxisX Name="salesAxis" Title="Sales">
    <mxc:AxisX.ScaleOptions>
        <mxc:DateTimeScaleOptions MeasureUnit="Month" LabelFormatter="{Binding MonthFormatter}" />
    </mxc:AxisX.ScaleOptions>
</mxc:AxisX>
public partial class MainWindowViewModel : ViewModelBase
{
    // ...
    [ObservableProperty] FuncLabelFormatter monthFormatter = new(o => String.Format("{0:MMM} {0:yy}", o));
}

Результат

Теперь вы можете запустить приложение, чтобы увидеть результат выполнения этого руководства. Контрол CartesianChart отображает три ряда данных, используя представления панели и линии. Ряд линий связан со своей собственной осью X, отображаемой в верхней части диаграммы.

charts-get-started

Полный код

<mx:MxWindow xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:EremexChartsSample.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mx="https://schemas.eremexcontrols.net/avalonia"
        xmlns:mxc="https://schemas.eremexcontrols.net/avalonia/charts"             
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="EremexChartsSample.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"

        Title="EremexChartsSample">

    <Design.DataContext>
        <!-- This only sets the DataContext for the previewer in an IDE,
             to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
        <vm:MainWindowViewModel/>
    </Design.DataContext>

    <mxc:CartesianChart Name="chart1">
        <mxc:CartesianChart.Series>
            <mxc:CartesianSeries Name="barSeries1" DataAdapter="{Binding BarSeries1.DataAdapter}" >
                <mxc:CartesianSideBySideBarSeriesView Color="{Binding BarSeries1.Color}" BarWidth="1" />
            </mxc:CartesianSeries>
            <mxc:CartesianSeries Name="barSeries2" DataAdapter="{Binding BarSeries2.DataAdapter}" >
                <mxc:CartesianSideBySideBarSeriesView Color="{Binding BarSeries2.Color}" />
            </mxc:CartesianSeries>
            <mxc:CartesianSeries Name="lineSeries" DataAdapter="{Binding LineSeries.DataAdapter}"  AxisXKey="lineSeriesAxis" >
                <mxc:CartesianLineSeriesView Color="{Binding LineSeries.Color}" />
            </mxc:CartesianSeries>
        </mxc:CartesianChart.Series>

        <mxc:CartesianChart.AxesX>
            <mxc:AxisX Name="salesAxis" Title="Sales">
                <mxc:AxisX.ScaleOptions>
                    <mxc:DateTimeScaleOptions MeasureUnit="Month" LabelFormatter="{Binding MonthFormatter}" />
                </mxc:AxisX.ScaleOptions>
            </mxc:AxisX>
            <mxc:AxisX Key="lineSeriesAxis" Position="Far" Title="Expenses">
                <mxc:AxisX.ScaleOptions>
                    <mxc:NumericScaleOptions />
                </mxc:AxisX.ScaleOptions>
            </mxc:AxisX>
        </mxc:CartesianChart.AxesX>

        <mxc:CartesianChart.AxesY>
            <mxc:AxisY Title="Currency"/>
        </mxc:CartesianChart.AxesY>

    </mxc:CartesianChart>
</mx:MxWindow>
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using Eremex.AvaloniaUI.Charts;
using System;

namespace EremexChartsSample.ViewModels;

public partial class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        //Init data
        var random = new Random(4);
        var random2 = new Random(0);

        var startDate = new DateTime(DateTime.Now.Year, 1, 1);
        SortedDateTimeDataAdapter barSeries1DataAdapter = new();
        SortedDateTimeDataAdapter barSeries2DataAdapter = new();
        SortedNumericDataAdapter lineSeriesDataAdapter = new();
        for (int i = 0; i < 12; i++)
        {
            var argument = startDate.AddMonths(i);
            barSeries1DataAdapter.Add(argument, random.NextDouble() * 100 - 30);
            barSeries2DataAdapter.Add(argument, random.NextDouble() * 100 - 30);

        }

        double startValue = 20;
        for (int i = 0; i < 365; i++)
        {
            var argument = i;
            var value = startValue + (random2.NextDouble() - 0.5) * 10;
            lineSeriesDataAdapter.Add(argument, value);
            startValue = value;
        }

        // Create data series
        BarSeries1 = new() { Color = Color.FromArgb(255, 0, 120, 122), DataAdapter = barSeries1DataAdapter };
        BarSeries2 = new() { Color = Color.FromArgb(255, 0, 170, 110), DataAdapter = barSeries2DataAdapter };
        LineSeries = new() { Color = Color.FromArgb(255, 120, 10, 12), DataAdapter = lineSeriesDataAdapter };
    }

    [ObservableProperty] SeriesViewModel barSeries1; 
    [ObservableProperty] SeriesViewModel barSeries2; 
    [ObservableProperty] SeriesViewModel lineSeries;

    [ObservableProperty] CustomLabelFormatter monthFormatter = new(o => String.Format("{0:MMM} {0:yy}", o));
}

public partial class SeriesViewModel : ObservableObject
{
    [ObservableProperty] Color color;
    [ObservableProperty] ISeriesDataAdapter dataAdapter;
}

public class CustomLabelFormatter : IAxisLabelFormatter
{
    readonly Func<object, string> formatFunc;

    public CustomLabelFormatter(Func<object, string> formatFunc)
    {
        this.formatFunc = formatFunc;
    }
    public string Format(object value) => 
        formatFunc(value);
}



* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.