Search code examples
c#wpfmvvmlivecharts

Trying to build a simple Live Chart into my WPF application (ColumnSeries)


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?


Solution

  • 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.