如何在数据更改时刷新oxyplot图
Oxyplot图表13个点,这些点来自6个用户输入文本框。 文本框中的值保存在MainWindow.xaml.cs类的公共变量中。 当用户在文本框中按Enter键时,变量会更新。 如何使刷新按钮刷新图形。
private void RefreshButton_Click(object sender, RoutedEventArgs e) { //Refresh The Graph }
我认为这将使用
PlotModel.RefreshPlot()
方法,但我不知道如何实现它,因为Oxyplot的文档很差。
我刚刚通过NuGet更新到新版本的OxyPlot。 我正在使用OxyPlot.Wpf v20014.1.277.1,我认为你现在需要在PlotModel
而不是RefreshPlot(不再可用)上调用InvalidatePlot(bool updateData)
)。 我在我的示例代码中测试了它,它按预期工作。
如果要刷新绘图并更新数据集合,则需要将true
传递给调用:
PlotModel.InvalidatePlot(true)
将x:Name
为XAML中的OxyPlot实例:
并在按钮单击处理程序上,刷新如下:
private void RefreshButton_Click(object sender, RoutedEventArgs e) { Plot1.RefreshPlot(true); }
在对同一个问题提出同样的问题之后,似乎唯一可行的解决方案(至少在我看来)如下:
PlotView.InvalidatePlot(true)
这样做,在更新一个或多个Series
请刷新PlotView
。
刷新率取决于您的系列更新的频率或速率。
这是一个代码片段(在Xamarin Android上,但无论如何都应该工作):
PlotView resultsChart = FindViewById(Resource.Id.resultsChart); PlotModel plotModel = new PlotModel { // set here main properties such as the legend, the title, etc. example : Title = "My Awesome Real-Time Updated Chart", TitleHorizontalAlignment = TitleHorizontalAlignment.CenteredWithinPlotArea, LegendTitle = "I am a Legend", LegendOrientation = LegendOrientation.Horizontal, LegendPlacement = LegendPlacement.Inside, LegendPosition = LegendPosition.TopRight // there are many other properties you can set here } // now let's define X and Y axis for the plot model LinearAxis xAxis = new LinearAxis(); xAxis.Position = AxisPosition.Bottom; xAxis.Title = "Time (hours)"; LinearAxis yAxis = new LinearAxis(); yAxis.Position = AxisPosition.Left; yAxis.Title = "Values"; plotModel.Axes.Add(xAxis); plotModel.Axes.Add(yAxis); // Finally let's define a LineSerie LineSeries lineSerie = new LineSeries { StrokeThickness = 2, CanTrackerInterpolatePoints = false, Title = "Value", Smooth = false }; plotModel.Series.Add(lineSerie); resultsChart.Model = plotModel;
现在,每当您需要将DataPoints
添加到LineSerie
并相应地自动更新PlotView
,只需执行以下操作:
resultsChart.InvalidatePlot(true);
这样做会自动刷新PlotView
。
另外,当事件发生时, PlotView
也会更新,例如触摸,缩放或任何类型的UI相关事件。
我希望我能提供帮助。 很长一段时间我都遇到了麻烦。
在当前的OxyPlot.Wpf(1.0.0-unstable1983)中,您有两个选择:
- 将
Series.ItemsSource
属性从XAML绑定到viewmodel中的集合,并在需要更新时交换整个集合。 这还允许使用更大的数据集进行并发异步更新。 - 将类型为
int
的Plot.InvalidateFlag
属性绑定到viewmodel,并在需要更新时递增。 不过,我还没有测试过这种方法。
以下代码说明了这两个选项(选择一个)。 XAML:
ViewModel上的更新:
private async Task UpdateAsync() { // TODO do some heavy computation here List data = await ... // option 1: Trigger INotifyPropertyChanged on the ItemsSource. // Concurrent access is ok here. this.DataSeries = data; // switch data sets // option 2: Update the data in place and trigger via flag // Only one update at a time. this.DataSeries.Clear(); data.ForEach(this.DataSeries.Add); this.InvalidateFlag++; }
我发现获得“某种”自动更新的最简洁方法是对LineSeries的ItemsSource集合上的CollectionChanged做出反应。
在ViewModel中:
ObservableCollection Data { get; set; } = new ObservableCollection (); public PlotModel PlotModel { get { return _plot_model; } set { _plot_model = value; RaisePropertyChanged(() => PlotModel); } } PlotModel _plot_model; // Inside constructor: Data.CollectionChanged += (a, b) => PlotModel.InvalidatePlot(true);
存在三个替代方案如何刷新绘图(来自OxyPlot文档 ):
- 更改
PlotView
控件的Model
属性 - 在
PlotView
控件上调用Invalidate
- 在
PlotModel
上调用Invalidate