簡體   English   中英

如何在數據更改時刷新oxyplot圖

[英]How to refresh oxyplot plot when data changes

該程序的GUI

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實例:

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

並在按鈕單擊處理程序上,刷新如下:

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

我發現獲得“某種”自動更新的最簡潔方法是對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);

在對同一問題提出同樣的問題之后,似乎唯一可行的解​​決方案(至少在我看來)如下:

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相關事件。

我希望我能幫忙。 很長一段時間我都遇到了麻煩。

在當前的OxyPlot.Wpf(1.0.0-unstable1983)中,您有兩個選擇:

  1. Series.ItemsSource屬性從XAML綁定到viewmodel中的集合,並在需要更新時交換整個集合。 這還允許使用更大的數據集進行並發異步更新。
  2. 將類型為intPlot.InvalidateFlag屬性綁定到viewmodel,並在需要更新時遞增。 不過,我還沒有測試過這種方法。

以下代碼說明了這兩個選項(選擇一個)。 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++;
}

存在三個替代方案如何刷新繪圖(來自OxyPlot文檔 ):

  • 更改PlotView控件的Model屬性
  • PlotView控件上調用Invalidate
  • PlotModel上調用Invalidate

再過兩年......這個解決方案對我有用,因為我沒有氧模型,我錯過了上面提到的一些命名函數。

代碼背后:

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

要更新數據,請不要交換整個IList,而是添加一些新的DataPoints並刪除位置0的舊DataPoints。

XAML:

<UserControl x:Class="UxHMI.LineChart"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:UxHMI"
         xmlns:oxy="http://oxyplot.org/wpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="Container" Background="White">
    <oxy:Plot x:Name="myChart" Title="{Binding Title}" FontFamily="Bosch Sans Medium" Foreground="#FF0C6596" FontSize="19" Canvas.Left="298" Canvas.Top="32" Background="AliceBlue" Margin="0,0,10,0">
        <oxy:Plot.Series>
            <oxy:LineSeries x:Name="ls" Background="White" ItemsSource="{Binding Points}" LineStyle="Solid" Color="ForestGreen" MarkerType="None" MarkerSize="5" MarkerFill="Black">

            </oxy:LineSeries>
        </oxy:Plot.Series>
    </oxy:Plot>
    <Button x:Name="button" Content="Random" HorizontalAlignment="Left" Margin="0,278,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
</Grid>

重要的是x:Name =“myChart”ItemsSource =“{Binding Points}”

我希望這對那里的人有用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM