Начало работы с графиками¶
В этом руководстве показано, как отобразить три ряда данных в контроле CartesianChart
, используя представления панели и ряда линий.
Сначала мы определим данные для контрола диаграммы (в 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
отображает точки в виде прямоугольных панелей:
Свойство 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
).
Если вы запустите приложение сейчас, то увидите следующий результат:
Добавление дополнительной серии и оси 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
- это последовательный вид, который соединяет точки линиями:
Как и в случае с любым видом серии, вы можете использовать свойство 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>
Вы можете запустить приложение, чтобы увидеть контрол диаграммы, отображающий три ряда:
Создание пользовательского форматера меток¶
CartesianChart
форматирует метки для основных отметок на основе опций масштабирования по оси. На следующей картинке показано форматирование метки, когда единица измерения времени Month
применяется к оси X:
Свойство ScaleOptions.LabelFormatter
оси позволяет изменять формат отображения меток. Вы можете использовать класс Eremex.AvaloniaUI.Charts.FuncLabelFormatter
в качестве средства форматирования меток или создать пользовательское средство форматирования меток, реализовав интерфейс IAxisLabelFormatter
.
Мы будем использовать класс FuncLabelFormatter
для создания коротких меток для значений даты и времени оси X. В модели основного представления реализуйте свойство типа FuncLabelFormatter
, которое форматирует метки определенным образом. В XAML привяжите опцию axis ScaleOptions.LabelFormatter
к этому форматировщику.
<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, отображаемой в верхней части диаграммы.
Полный код¶
<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);
}
* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.