Oxyplot图表从6个用户输入文本框派生的13个点。文本框中的值保存在MainWindow.xaml.cs类的公共变量中。当用户在文本框中按Enter键时,将更新变量。如何使刷新按钮刷新图形。
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
//Refresh The Graph
}
我认为这可以使用
完成PlotModel.RefreshPlot()
方法,但我不知道如何实现它,因为Oxyplot的文档很差。
答案 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)中,您有两种选择:
Series.ItemsSource
属性从XAML绑定到viewmodel中的集合,并在需要更新时交换整个集合。这也允许使用更大的数据集进行并发异步更新。Plot.InvalidateFlag
类型的int
属性绑定到您的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++;
}
答案 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 =“ {绑定点}”
我希望这对外面的人有用