[英]How to refresh oxyplot plot when data changes
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)中,您有兩個選擇:
Series.ItemsSource
屬性從XAML綁定到viewmodel中的集合,並在需要更新時交換整個集合。 這還允許使用更大的數據集進行並發異步更新。 int
的Plot.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.