簡體   English   中英

WPF MVVM LiveCharts 如何顯示 X 軸標簽?

[英]WPF MVVM LiveCharts how to show X axis Label?

我很難在我的笛卡爾條形圖中顯示一些簡單的標簽,我讀了很多書,但似乎沒有什么對我有用。 我在我的項目中使用了 MVVM 模式,所以這是我迄今為止的代碼。

看法

<lvc:CartesianChart Grid.Row="2" Series="{Binding ChartDataSets}">
    <lvc:CartesianChart.AxisX>
        <lvc:Axis LabelsRotation="20" Labels="{Binding ColumnLabels}" Position="RightTop" >
            <lvc:Axis.Separator >
                <lvc:Separator Step="1"></lvc:Separator>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        <lvc:Axis LabelFormatter="{Binding Formatter}" Position="RightTop"></lvc:Axis>
    </lvc:CartesianChart.AxisY>
</lvc:CartesianChart>

數據模型

類數據模型:INotifyPropertyChanged { 私有雙值; public double Value { get => this.value; 設置 { this.value = 值; OnPropertyChanged(); } }

private string label;
public string Label
{
    get => this.label;
    set
    {
        this.label = value;
        OnPropertyChanged("Label");
    }
}

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

}

視圖模型

class BackupStatsViewModel : INotifyPropertyChanged
{
    ChartValues<DataModel> values = new ChartValues<DataModel>();
    public SeriesCollection ChartDataSets { get; set; }
    public ObservableCollection<string> ColumnLabels { get; set; }
    public class ErrorPrt
    {
        public ErrorPrt(){
            prtName = string.Empty;
            Count = -1;
        }
        public string prtName { get; set; }
        public int Count { get; set; }
    }
    public BackupStatsViewModel()
    {
        InitializeBarChartData();
    }
    private void InitializeBarChartData()
    {

        this.ColumnLabels = new ObservableCollection<string>(values.Select(dataModel => dataModel.Label));
        var dataMapper = new CartesianMapper<DataModel>()
          .Y(dataModel => dataModel.Value)
          .Fill(dataModel => dataModel.Value > 15.0 ? Brushes.Red : Brushes.Green);

        this.ChartDataSets = new SeriesCollection
        {
          new ColumnSeries
          {
            Values = values,
            Configuration = dataMapper,
            DataLabels = true
          }
          
        };
    }
    public ErrorPrt[] PrtCount(List<DataRow> rows)
    {
        IEnumerable<IGrouping<string, DataRow>> grouped = rows.GroupBy(s => s.Field<string>(2));
        ErrorPrt[] err = new ErrorPrt[grouped.Count()];
        //Omitted code for sake of brevity
        
        ErrorPrt[] arr = err.Where(c => c != null).ToArray();
        
        for (int i = 0; i < arr.Count(); i++)
            values.Add(new DataModel() { Label = $"PRT {arr[i].prtName}", Value = arr[i].Count });

        return arr;
    }
 }

但是正如您所看到的,X 軸上沒有顯示任何標簽.. 真的不知道如何繞過這個問題才能繼續我的工作..請有人告訴我正確的方法嗎? 在此處輸入圖片說明

你的流程看起來很糟糕:
您首先通過調用InitializeBarChartData()從構造函數初始化圖表數據,這也會初始化ColumnLabels集合。 然后創建底層ErrorPtr項,它們是列標簽數據的提供者。
結果是ColumnLabels屬性為空 => 不會顯示任何標簽。

因為您將新的ErrorPtr項添加到values字段,並且該字段的類型為ChartValues並且該集合實現INotifyCollectionChanged ,所以圖表將反映這些更改。 你在這里很幸運。

但是,因為在創建ErrorPtr項后永遠不會更新ColumnLabels屬性,所以最初(從構造函數調用InitializeBarChartData之后)空的ColumnLabels集合保持為空。

解決方案1

修復數據模型初始化流程並PrtCount之后調用InitializeBarChartData

public ErrorPrt[] PrtCount(List<DataRow> rows)
{
    IEnumerable<IGrouping<string, DataRow>> grouped = rows.GroupBy(s => s.Field<string>(2));
    ErrorPrt[] err = new ErrorPrt[grouped.Count()];
    //Omitted code for sake of brevity
    
    ErrorPrt[] arr = err.Where(c => c != null).ToArray();
    
    for (int i = 0; i < arr.Count(); i++)
        this.values.Add(new DataModel() { Label = $"PRT {arr[i].prtName}", Value = arr[i].Count });

    // Initialize the chat models.
    // NOW the label data (the ErrorPrt.prtName) is generated 
    // and ready to be extracted from the ErrorPrt instances
    InitializeBarChartData();

    return arr;
}

解決方案2(推薦)

由於所有涉及的集合都實現了INotifyCollectionChanged您可以在新數據到達時動態更新每個集合。 您不需要一遍又一遍地初始化完整的圖表數據,如SeriesCollectionMapper或標簽格式化程序(如解決方案 1 - 如果PrtCount將被多次調用)。
您可以繼續從構造函數調用InitializeBarChartData一次,就像您目前正在這樣做一樣。

不僅要更新values字段,還要更新ColumnLabels屬性:

public ErrorPrt[] PrtCount(List<DataRow> rows)
{
    IEnumerable<IGrouping<string, DataRow>> grouped = rows.GroupBy(s => s.Field<string>(2));
    ErrorPrt[] err = new ErrorPrt[grouped.Count()];
    //Omitted code for sake of brevity
    
    ErrorPrt[] arr = err.Where(c => c != null).ToArray();        

    for (int i = 0; i < arr.Count(); i++)
    {    
        var newDataModel = new DataModel() { Label = $"PRT {arr[i].prtName}", Value = arr[i].Count };

        // Here you update the column values
        // and add the new items to the existing items of previous calls
        this.values.Add(newDataModel);

        // Also update the labels whenever new column data has arrived
        this.ColumnLabels.Add(newDataModel.Label);
    }

    return arr;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM