Search code examples
c#wpfxamldata-bindinglivecharts

How to Bind a Value Property in LineSeries using LiveCharts


I am wanting to bind the Values of each Line Series in WPF to a collection of values of type SeriesCollection in C#. For now, the each lines are assigned with solid values. How can I bind it to an a Collection? An example would be binding the 1st line series to the Series Collection below. Much appreciated!

<lvc:CartesianChart>
                    <lvc:CartesianChart.Series>
                        <lvc:LineSeries Title="Pres" Values="4,7,2,9,3" Visibility="{Binding PresVisibility, Converter={StaticResource bvc}}"/>
                        <lvc:LineSeries Title="Temp" Values="6,2,6,3,8" Visibility="{Binding TempVisibility, Converter={StaticResource bvc}}"/>
                        <lvc:LineSeries Title="Flow" Values="7,2,8,3,9" Visibility="{Binding FlowVisibility, Converter={StaticResource bvc}}"/>
                        <lvc:LineSeries Title="Control" Values="6,2,6,3,8" Visibility="{Binding ControlVisibility, Converter={StaticResource bvc}}"/>
                        <lvc:LineSeries Title="Compressor" Values="7,2,8,3,9" Visibility="{Binding CompressorVisibility, Converter={StaticResource bvc}}"/>
                    </lvc:CartesianChart.Series>
                    <lvc:CartesianChart.AxisX>
                        <lvc:Axis Title="Time" Labels="{Binding CurrentLabels}"></lvc:Axis>
                    </lvc:CartesianChart.AxisX>
                    <lvc:CartesianChart.AxisY>
                        <lvc:Axis Name="yAxis" LabelFormatter="{Binding CurrentYFormatter}"></lvc:Axis>
                    </lvc:CartesianChart.AxisY>
                </lvc:CartesianChart>

In C#:

public SeriesCollection PresSeries { get; set; }

PresSeries[0].Values.Add(ScrewState.GetScrewAll().V101.p);
            PresSeries[1].Values.Add(ScrewState.GetScrewAll().V102.p);
            PresSeries[2].Values.Add(ScrewState.GetScrewAll().P1.p);
            PresSeries[3].Values.Add(ScrewState.GetScrewAll().P2.p);
            PresSeries[4].Values.Add(ScrewState.GetScrewAll().P3.p);

Solution

  • When you define the LineSeries in XAML, you don't have to define a SeriesCollection anymore (you just did it in XAML - <CartesianChart.Series> is the SeriesCollection). It's sufficient to define the actual ChartValues source collection in C# (e.g., inside your view model):

    MainWindow.xaml

    <lvc:CartesianChart x:Name="CartesianChart">
      <lvc:CartesianChart.DataContext>
        <local:LiveChartsModel />
      </lvc:CartesianChart.DataContext>
    
      <lvc:CartesianChart.Series>
        <lvc:LineSeries Title="Sine Graph"
                        Values="{Binding SineGraphValues}"
                        Configuration="{Binding DataMapper}"/>
      </lvc:CartesianChart.Series>
    </lvc:CartesianChart>
    

    LiveChartsModel.cs

    public class LiveChartsModel : INotifyPropertyChanged
    {
      public LiveChartsModel()
      {
        // Initialize the binding source
        this.SineGraphValues = new ChartValues<ObservablePoint>();
    
        // Plot a sine graph
        for (double x = 0; x <= 360; x++)
        {
          var point = new ObservablePoint() 
          { 
            X = x, 
            Y = Math.Sin(x * Math.PI / 180) 
          };
    
          this.SineGraphValues.Add(point);
        }
    
        // Setup the data mapper
        this.DataMapper = new CartesianMapper<ObservablePoint>()
          .X(point => point.X)
          .Y(point => point.Y)
          .Stroke(point => point.Y > 0.3 ? Brushes.Red : Brushes.LightGreen)
          .Fill(point => point.Y > 0.3 ? Brushes.Red : Brushes.LightGreen);
      }
    
      private object dataMapper;   
      public object DataMapper
      {
        get => this.dataMapper;
        set 
        { 
          this.dataMapper = value; 
          OnPropertyChanged();
        }
      }
    
      public ChartValues<ObservablePoint> SineGraphValues { get; }
    
      public event PropertyChangedEventHandler PropertyChanged;
      protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }