I have been trying to build a Live Chart into my WPF application for a few days.
I want a simple diagram. Column Series, that should show int values as bars and below the timestamp.
I build it with MVVM and tried to find a solution with this tutorial. https://lvcharts.net/App/examples/v1/wpf/Basic%20Column
My XAML code:
<lvc:CartesianChart>
<lvc:CartesianChart.Series>
<lvc:ColumnSeries Values="{Binding RawDataSeries, UpdateSourceTrigger=PropertyChanged}" />
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX >
<lvc:Axis Labels="{Binding Labels}">
<lvc:Axis.Separator>
<lvc:Separator Step="1"></lvc:Separator>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
My test code in the viewmodel:
public void SetChart(int value)
{
var customerVmMapper = Mappers.Weighted<DateTimePoint>().X((x, index) => index).Y(x => x.Value);
Charting.For<DateTimePoint>(customerVmMapper);
var list = new List<DateTimePoint>()
{
new DateTimePoint() {Timestamp = DateTime.Now, Value = value},
new DateTimePoint() {Timestamp = DateTime.Now, Value = 78},
new DateTimePoint() {Timestamp = DateTime.Now, Value = 21}
};
var values = new ChartValues<DateTimePoint>();
foreach (var obj in list)
{
values.Add(obj);
}
RawDataSeries = values;
}
public ChartValues<DateTimePoint> RawDataSeries
{
get => _rawDataSeries;
set
{
_rawDataSeries = value;
OnPropertyChanged();
}
}
public class DateTimePoint
{
public DateTime Timestamp { get; set; }
public int Value { get; set; }
}
Does anyone have a tip for me?
You need to specify the correct x/y mapping of the data object, the interval of the x-axis
and a label formatter to print the timestamps:
ChartModel.cs
public class ChartModel
{
public ChartModel()
{
CartesianMapper<DateTimePoint> mapper = Mappers.Xy<DateTimePoint>()
.X((item) => (double) item.Timestamp.Ticks / TimeSpan.FromMinutes(5).Ticks) // Set interval to 5 minutes
.Y(item => item.Value)
.Fill((item) => item.Value > 99 ? Brushes.Red : Brushes.Blue);
var series = new ColumnSeries()
{
Title = "Timestamp Values",
Configuration = mapper,
Values = new ChartValues<DateTimePoint>
{
new DateTimePoint() {Timestamp = DateTime.Now, Value = 100},
new DateTimePoint() {Timestamp = DateTime.Now.AddMinutes(15), Value = 78},
new DateTimePoint() {Timestamp = DateTime.Now.AddMinutes(30), Value = 21}
}
};
this.SeriesCollection = new SeriesCollection() { series };
}
public SeriesCollection SeriesCollection { get; set; }
public Func<double, string> LabelFormatter =>
value => new DateTime((long) value * TimeSpan.FromMinutes(5).Ticks).ToString("t");
}
DateTimePoint.cs
public class DateTimePoint
{
public DateTime Timestamp { get; set; }
public int Value { get; set; }
}
MainWindow.xaml
<CartesianChart Margin="20"
Height="300"
Series="{Binding SeriesCollection}"
LegendLocation="Left">
<CartesianChart.DataContext>
<viewModels:ChartModel />
</CartesianChart.DataContext>
<CartesianChart.AxisX>
<Axis Title="Timestamp"
LabelFormatter="{Binding LabelFormatter}">
</Axis>
</CartesianChart.AxisX>
</CartesianChart>
Also read the Live Charts: Date Time example.