Подтвердить что ты не робот

Как обновить график оксиплотов при изменении данных

GUI for the program

Графики Oxyplot 13 точек, которые получены из 6 текстовых полей ввода пользователя. Значения в текстовых полях хранятся в общедоступных переменных в классе MainWindow.xaml.cs. Переменные обновляются, когда пользователь нажимает кнопку ввода в текстовое поле. Как сделать кнопку обновления обновить график.

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

Я думаю, что это будет сделано с помощью

PlotModel.RefreshPlot() 

но я не уверен, как его реализовать из-за плохой документации Oxyplot.

4b9b3361

Ответ 1

Я только что обновил новую версию OxyPlot через NuGet. Я использую OxyPlot.Wpf v20014.1.277.1, и я думаю, теперь вам нужно вызвать InvalidatePlot(bool updateData) в PlotModel вместо RefreshPlot (который больше не доступен). Я тестировал это в своем примере кода, и он работал, как ожидалось.

Если вы хотите обновить график и обновить коллекции данных, вам необходимо передать true на вызов:

PlotModel.InvalidatePlot(true)

Ответ 2

Дайте x:Name экземпляру OxyPlot в XAML:

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

и в обработчике щелчка на кнопке, выполните следующие действия:

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

Ответ 3

После того же вопроса с той же проблемой, казалось бы, единственное рабочее решение (по крайней мере, с моей точки зрения):

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 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 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 также будет обновляться, когда произойдет событие, такое как касание, щепотка для увеличения или любые связанные с пользовательским интерфейсом события.

Я надеюсь, что смогу помочь. У меня были проблемы с этим в течение очень долгого времени.

Ответ 4

В текущем OxyPlot.Wpf(1.0.0-unstable1983) у вас есть две возможности:

  • Привязать свойство Series.ItemsSource из XAML к коллекции в вашей модели viewmodel и обмениваться всей коллекцией, когда вам нужно обновление. Это также позволяет одновременные обновления асинхронизации с большими наборами данных.
  • Привязать свойство Plot.InvalidateFlag типа int к вашей модели просмотра и приращению всякий раз, когда вам нужно обновление. Однако я не тестировал этот подход.

Следующий код иллюстрирует обе опции (выберите один). 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++;
}

Ответ 5

Самый чистый способ, которым я нашел автоматическое обновление "своего рода", реагирует на CollectionChanged в коллекции, которая является элементом ItemsSeries LineSeries.

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

Ответ 6

Существует три альтернативы: как обновить график (из Документация OxyPlot):

  • Измените свойство Model элемента управления PlotView
  • Вызов Invalidate в элементе управления PlotView
  • Вызовите Invalidate на PlotModel