如何在数据更改时刷新oxyplot图

Jka*_*lus 21 c# wpf graph oxyplot

该程序的GUI

Oxyplot图表13个点,这些点来自6个用户输入文本框.文本框中的值保存在MainWindow.xaml.cs类的公共变量中.当用户在文本框中按Enter键时,将更新变量.如何使刷新按钮刷新图形.

private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            //Refresh The Graph
        }
Run Code Online (Sandbox Code Playgroud)

我认为这将使用

PlotModel.RefreshPlot() 
Run Code Online (Sandbox Code Playgroud)

方法,但我不知道如何实现它,因为Oxyplot的文档很差.

rut*_*pia 34

我刚刚通过NuGet更新到新版本的OxyPlot.我使用OxyPlot.Wpf v20014.1.277.1,我想你现在需要调用InvalidatePlot(bool updateData)PlotModel,而不是RefreshPlot(这是不再可用).我在我的示例代码中对此进行了测试,并且按预期工作.

如果要刷新绘图更新数据集合,则需要传递true给调用:

PlotModel.InvalidatePlot(true)
Run Code Online (Sandbox Code Playgroud)


Roh*_*ats 6

x:Name在XAML中给OxyPlot实例:

<oxy:Plot x:Name="Plot1"/>
Run Code Online (Sandbox Code Playgroud)

并在按钮单击处理程序上,刷新如下:

private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
   Plot1.RefreshPlot(true);
}
Run Code Online (Sandbox Code Playgroud)


hel*_*ker 6

我发现获得“某种”自动更新的最干净的方法是对LineSeries的ItemsSource集合上的CollectionChanged做出反应。

在ViewModel中:

ObservableCollection<DataPoint> Data { get; set; } 
    = new ObservableCollection<DataPoint>();

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);
Run Code Online (Sandbox Code Playgroud)


Pat*_*lph 5

在当前的 OxyPlot.Wpf (1.0.0-unstable1983) 中,您有两个选择:

  1. Series.ItemsSourceXAML 中的属性绑定到视图模型中的集合,并在需要更新时交换整个集合。这也允许对更大的数据集进行并发异步更新。
  2. Plot.InvalidateFlagtype 属性绑定int到您的视图模型,并在需要更新时增加。不过,我还没有测试过这种方法。

以下代码说明了这两个选项(选择一个)。XAML:

<oxy:Plot InvalidateFlag="{Binding InvalidateFlag}">
    <oxy:Plot.Series>
        <oxy:LineSeries ItemsSource="{Binding DataSeries}" />
      </oxy:Plot.Series>
 </oxy:Plot>
Run Code Online (Sandbox Code Playgroud)

ViewModel 的更新:

private async Task UpdateAsync()
{
    // TODO do some heavy computation here
    List<DataPoint> 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++;
}
Run Code Online (Sandbox Code Playgroud)