[英]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
集合保持為空。
修復數據模型初始化流程並在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;
}
由於所有涉及的集合都實現了INotifyCollectionChanged
您可以在新數據到達時動態更新每個集合。 您不需要一遍又一遍地初始化完整的圖表數據,如SeriesCollection
和Mapper
或標簽格式化程序(如解決方案 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.