InvalidatePlot中WPF中较大数据的OxyPlot性能问题 限制:

问题描述

我在wpf应用程序中使用OxyPlot作为行记录器。就像LiveDemo的例子。 在较大的可见数据集上,我遇到一些UI性能问题,并且可能整个应用程序可能冻结。似乎是PlotModel.InvalidatePlot,它经常被调用很多点,但是我没有找到更好的方法

深处:

  • 使用OxyPlot 2.0.0
  • 我在PlotModel中全部编码。 Xaml PlotView仅绑定到PlotModel。
  • 我周期性地在线程中收集数据,然后将其放入DataSource(LineList的ItemSoure的List列表)
  • 我有一个在线程中计算x和y轴表示形式的循环的类。完成所有这些操作后,它将调用PlotModel.InvalidatePlot。

如果我

  • 显示器上有超过100 k点(无论是否在多个Lineseries中)
  • 并每500毫秒为每个Lineseries添加1个DataPoint
  • 并每200毫秒调用PlotModel.InvalidatePlot

不仅PlotView出现性能问题,而且即使我调用PlotModel.InvalidatePlot(false),窗口的响应也非常慢。

我的目标

我的目标是使Windo /应用程序正常运行。它不应因线路记录器而挂断。最好的办法是没有性能问题,但我对此表示怀疑。

我发现或测试过的东西

OxyPlot具有Performance guidelines。我正在使用带DataPoints的ItemsSource。我也尝试过将它们直接添加到Lineseris.Points中,但是Plot无论如何都不会刷新(即使使用ObservableCollection也是如此),因此我必须调用PlotModel.InvalidatePlot,其结果相同。我无法绑定到Xaml中定义的Lineseries,因为我不知道会有多少行。也许我错过了直接添加积分的事情?

我还发现了一个Github问题1286,它描述了一个相关问题,但是这种解决方法在我的测试中速度较慢。

我还检查了调用PlotModel.InvalidatePlot所花费的时间,但是点数不影响它。

我已经检查了UI线程,似乎很难处理大量的点

LargepointSet

如果我放大绘图并在20 k点以下显示,那么

Zoomed

问题:

除了调用PlotModel.InvalidatePlot少得多之外,还有其他方法可以更好地处理此问题吗?

限制:

我还必须更新轴和注释。所以,我想我不会再打电话给PlotModel.InvalidatePlot。

解决方法

到目前为止,我最终计算了下次调用InvalidatePlot的时间。我使用此answer中给出的方法进行计算,返回可见点的数量。这样可以减少性能问题,但是可以在调用InvalidatePlot时修复UI线程上的块。

,

我发现使用 OxyPlot Windows 窗体实现,然后使用 WPF 中的 Windows 窗体集成显示它可以提供更好的性能。

例如

var plotView = new OxyPlot.WindowsForms.PlotView();
plotView.Model = Plot;

var host = new System.Windows.Forms.Integration.WindowsFormsHost();
host.Child = plotView;

PlotContainer = host;

其中“Plot”是您调用 InvalidatePlot() 的 PlotModel。

然后在您的 XAML 中:

<ContentControl Content="{Binding PlotContainer}"/>

或者您想以其他方式使用 WindowsFormsHost。