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

时间:2014-01-04 22:44:31

标签: c# wpf graph oxyplot

GUI for the program

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

private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            //Refresh The Graph
        }

我认为这可以使用

完成
PlotModel.RefreshPlot() 

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

7 个答案:

答案 0 :(得分:31)

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

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

PlotModel.InvalidatePlot(true)

答案 1 :(得分:5)

x:Name提供给XAML中的OxyPlot实例:

<oxy:Plot x:Name="Plot1"/>

并在按钮点击处理程序上,像这样刷新:

private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
   Plot1.RefreshPlot(true);
}

答案 2 :(得分:5)

我发现的最干净的方式是&#34;有点&#34;自动更新是对LineSeries&#39;集合上的CollectionChanged做出反应。的ItemsSource。

在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);

答案 3 :(得分:4)

在对同一问题提出同样的问题之后,似乎唯一有效的解决方案(至少在我看来)如下:

PlotView.InvalidatePlot(true)

这样做,在更新一个或多个Series后,请刷新PlotView

刷新率取决于您的系列更新的频率或速率。

这是一段代码片段(在Xamarin Android上,但无论如何都应该有效):

PlotView resultsChart = FindViewById<PlotView>(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相关事件。

我希望我能提供帮助。我很长时间没遇到这个问题了。

答案 4 :(得分:3)

存在三种替代方案,如何刷新情节(来自OxyPlot documentation):

  • 更改Model控件的PlotView属性
  • 致电Invalidate控件
  • 上的PlotView
  • 致电Invalidate
  • 上的PlotModel

答案 5 :(得分:2)

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

  1. Series.ItemsSource属性从XAML绑定到viewmodel中的集合,并在需要更新时交换整个集合。这也允许使用更大的数据集进行并发异步更新。
  2. Plot.InvalidateFlag类型的int属性绑定到您的viewmodel,并在需要更新时递增。不过,我还没有测试过这种方法。
  3. 以下代码说明了这两个选项(选择一个)。 XAML:

    <oxy:Plot InvalidateFlag="{Binding InvalidateFlag}">
        <oxy:Plot.Series>
            <oxy:LineSeries ItemsSource="{Binding DataSeries}" />
          </oxy:Plot.Series>
     </oxy:Plot>
    

    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++;
    }
    

答案 6 :(得分:1)

再过两年,...这个解决方案对我有用,因为我没有oxyplot模型,而且上面缺少一些命名函数。

背后的代码:

jdbc:oracle:thin

要更新数据,请不要交换整个IList,而要向其中添加一些新的DataPoint并删除位置0处的旧数据点。

XAML:

public partial class LineChart : UserControl
{
    public LineChart()
    {
        InitializeComponent();

        DataContext = this;
        myChart.Title = "hier könnte Ihr Text stehen!";

        this.Points = new List<DataPoint>();
        randomPoints();
    }


    public IList<DataPoint> Points { get; private set; }

    public void randomPoints()
    {
        Random rd = new Random();
        String myText = "";

        int anz = rd.Next(30, 60);

        for (int i = 0; i < anz; i++)
            myText += i + "," + rd.Next(0, 99) + ";";

        myText = myText.Substring(0, myText.Length - 1);
        String[] splitText = myText.Split(';');

        for (int i = 0; i < splitText.Length; i++)
        {
            String[] tmp = splitText[i].Split(',');
            Points.Add(new DataPoint(Double.Parse(tmp[0].Trim()), Double.Parse(tmp[1].Trim())));
        }

        while (Points.Count > anz)
            Points.RemoveAt(0);

        myChart.InvalidatePlot(true);
    }
}

重要的是 x:Name =“ myChart” ItemsSource =“ {绑定点}”

我希望这对外面的人有用