[LiveCharts2] 資料對應 -- IChartEntity interface

除了使用 Mapping property,LiveChart 提供了另一種資料對應的方式 – 透過實作 IChartEntity interface。

實作 IChartEntity

承上篇文章的 PersonViewModel,加入對於 IChartEntity interface 的實作,這邊為了方便說明,多加了一個 Index property:

 public class PersonViewModel : NotifyPropertyBase, IChartEntity
 {

     private string _name;
     public string Name
     {
         get => _name;
         set => SetProperty(ref _name, value);
     }

     private int _score;
     public int Score
     {
         get => _score;
         set => SetProperty(ref _score, value);
     }

     private int _index;
     public int Index
     {
         get => _index;
         set => SetProperty(ref _index, value);  
     }
     public ChartEntityMetaData MetaData
     {
         get; set;
     }
     public Coordinate Coordinate
     {
         get; set;
     }

     protected override void OnPropertyChanged(string propertyName)
     {
         Coordinate = new Coordinate(Index, Score);
         base.OnPropertyChanged(propertyName);
     }
 }

以下兩個屬性來自於 IChartEntity interface,你會發現沒做甚麼特別的事情 (因為有了 Index 屬性可以當作 X 軸的座標定義):

 public ChartEntityMetaData MetaData
 {
     get; set;
 }
 public Coordinate Coordinate
 {
     get; set;
 }

接著 override NotifyPropertyBase.OnPropertyChanged 方法,當屬性值變更的時候重新產生 Coordinate,如果要寫得更精確一些就加上屬性名稱的判斷,也就是只有當 Index 和 Score 這兩個決定 X/Y 軸資訊的屬性變更時才重新定義 Coordinate。

 protected override void OnPropertyChanged(string propertyName)
 {
     Coordinate = new Coordinate(Index, Score);
     base.OnPropertyChanged(propertyName);
 }
回到 MainViewModel

當資料來源實作了 IChartEntity interface,就不需要設定 Series 裡的 Mapping property:

 public class MainViewModel : NotifyPropertyBase
 {
     private ObservableCollection<PersonViewModel> _people;
     public ObservableCollection<PersonViewModel> People
     {
         get => _people;
         set => SetProperty(ref _people, value);
     }

     public MainViewModel()
        {
            InitialData();
            Chart = new ChartCommonViewModel();
            AddSeries();
            AddXAxes();
            AddYAxes();
            CreateTextPaint();
        }
     private void InitialData()
        {
            People = new ObservableCollection<PersonViewModel>()
            {
                new PersonViewModel { Name = "魯夫" , Score = 98, Index=0},
                new PersonViewModel { Name = "索隆" , Score = 79, Index=1},
                new PersonViewModel { Name = "香吉士" , Score = 58, Index=2},
                new PersonViewModel { Name = "娜美" , Score = 82, Index=3},
                new PersonViewModel { Name = "羅賓" , Score = 100, Index=4},
                new PersonViewModel { Name = "喬巴" , Score = 43, Index=5},
            };
        }
     private void CreateTextPaint()
        {
            Chart.ToolTipTextPaint = new SolidColorPaint
            {
                Color = SKColors.Black,
                SKTypeface = SKFontManager.Default.MatchFamily("新細明體"),
            };
        }

     private void AddSeries()
        {
            Chart.Series.Add(
                  new ColumnSeries<PersonViewModel>
                  {                     
                      Values = People,
                  });
        }

     private void AddXAxes()
        {
            Chart.XAxes.Add(
                new Axis
                {
                    Labels = new ObservableCollection<string>(People.Select(x => x.Name)),
                    LabelsPaint = new SolidColorPaint
                    {
                        Color = SKColors.Black,
                        SKTypeface = SKFontManager.Default.MatchFamily("新細明體"),
                    },
                });
        }

     private void AddYAxes()
        {
            Chart.YAxes.Add(
                 new Axis
                 {
                     Labeler = value => $"{value} 分",
                     LabelsPaint = new SolidColorPaint
                     {
                         Color = SKColors.Black,
                         SKTypeface = SKFontManager.Default.MatchFamily("新細明體"),
                     },
                 });
        }

     private ChartCommonViewModel _chart;
     public ChartCommonViewModel Chart
        {
            get => _chart;
            set => SetProperty(ref _chart, value);
        }
 }

其餘的部分就和前一篇一樣了,完整範例可以參考我的github