2010-03-25 346 views
9

我一直在试图找出什么是适当的方式来呈现实时数据作为WPF中的线图。实际上,我实际上是指从USB设备收集的数据,该数据以大约40Hz的速率生成数据。我正在以40Hz的频率以异步方式读取多个(最多7个)数据流。WPF图表/实时数据的可视化

我试过使用两种现成的解决方案(WPF工具包图表和Swordfish图表),几乎查看了动态数据可视化组件,但在阅读其论坛上的一些评论后放弃了它。看起来,现成的图表解决方案适用于静态图表,而且我实际上需要类似于Windows任务管理器的东西 - 只需要更快,更多的数据点。

目前,我已经推出了我自己的解决方案,目前看起来工作效果最好,但我有一种感觉,我错过了一些东西,因为看起来我应该能够从中获得更好的性能。

要求是,它应该能够在滑动窗口中处理大约10000点的恒定范围 - 随着新数据进入(以40Hz),旧数据get被推到可见范围之外的左侧。它需要维持这个速度至少20-30分钟(每个数据流总共约75-100万点)。

我当前的自定义实现是基于从Shape继承的组件,并使用DefinigGeometry的StreamingGeometry。来自设备的数据通过队列传递给组件以提高性能,这是由于固有的“突发效应”,并且在出队操作之后,组件会失效。

所以,我的问题是,我在正确的道路上,还是我完全错了?在WPF中完成这种数据可视化的最有效方法是什么?任何帮助或提示将不胜感激。

+0

DirectX interop是方向。有些人会使用slimDX,但这是一个巨大的依赖性和抽象的学习曲线。我建议直接使用DX9或(通过DXGI的DX11),因为它与WPF D3DImage界面握手。仍然是一个学习曲线,但与slimdx相同,更易于创建DX设备,上下文,缓冲区,着色器并使用Direct3D获取应用程序。文档很糟糕,但足够好,完成后,您已经完成了一些很酷的事情,而不依赖于其他人。使用WPF WinForm MFC EXE查看我们的真实世界[18M制图演示](http://www.gigasoft.com),它主要是音频WAV和GIS数据。 – Robert 2014-06-14 13:58:11

+0

@罗伯特,感谢您的意见。理想情况下,我希望将DX9与w XP兼容,但是我无法弄清楚是否可以用D3D绘制任意粗线,这与我用WPF实现的别名路径质量相当。任何指针?你是否必须编写自己的tesselation程序?如果我能得到我想要的性能/质量明智的话,我甚至会对DX10感到满意。 – 2014-06-14 16:00:36

+0

粗线是D3D最大的缺点。虽然它不是什么大不了的。如果您可以围绕已知的图表大小设计,那么顶点缓冲区逻辑将知道大小及其将线绘制为四边形(双三角形)的简单问题。b)如果您不想基于图形重建顶点缓冲区大小事件,那么着色器应该被设计为在恒定缓冲区中保存长宽比和物理大小设置,然后在顶点着色器中使用这些数据来动态调整行四边形。 dx9/11就是这种情况。或者,您可以使用D2D和数据缩减逻辑来绘制大量数据。 – Robert 2014-06-14 16:23:38

回答

1

WPF的保留模式渲染使得绘制/重绘自定义图表和图像变得棘手,从而使得高性能,特别是当这些绘图包含大量对象时。

我已经能够在WPF中做的最快的绘图是通过使用一个WritableBitmap并用一个WritePixels的调用填充它,这可能是一个选项。它大大超出了我使用PathGeometries编写并绘制到Canvas的图表的绘制速度。

我很想看看有没有更快的中间立场。

+0

一个可能的“中间地带”是将其绘制到OnRender覆盖中的RenderContext上。如果没有其他的东西给人一种巨大的精神上的宽慰,因为它更像传统的GDI/WinForms绘画......(更严重的是,它应该能够访问体面的渲染原语,而不需要构建保留模式树的开销往往只是一个冗余重复的自己的对象图) – 2010-07-16 08:24:47

+0

恐怕OnRender仍然使用保留模式管道。你正在做的就是使用这个将保留的模式对象发布到图形管道。为了测试它,在内部放置一个断点并最小化/最大化窗口。如果这是一种即时模式方法(例如Winforms中的OnPaint),则您将强制重绘。我不是100%确定,但我认为调整大小也不会导致OnRender触发,除非您明确将其设置为标志。 – 2011-12-21 12:22:08

1

披露:我自己ABT软件和开发SciChart,加上已对WriteableBitmapEx开源库

不幸的是你不会错过任何贡献。 WPF/Silverlight中的保留模式渲染引擎为这类工作提供了糟糕的性能。我曾参与过许多从Windows Forms升级到WPF的系统,其中客户非常失望于这种“GPU加速”框架的渲染性能!

无论如何,有一种方法。使用即时模式呈现。查看WriteableBitmap或InteropBitmap类。有一个很好的开源库,在那里我称之为WriteableBitmapExRene Schulte。 WriteableBitmapEx提供了一些直接绘制到位图的低级绘图函数(GDI样式)。这提供了出色的性能和低内存占用(是MS的花哨框架被一些经过优化的for循环和指向字节数组的指针击败)。

如果它是您正在寻找的特定第三方图表组件,请尝试SciChart。 SciChart是我自己开发的一个组件,旨在填补超高性能WPF或Silverlight科学/股票图表的空白。它使用专有的重采样算法在绘制之前减少数据集,即时模式渲染以及其他一系列优化(如对象池和资源重用),从而为超大型数据集和低内存占用带来平滑刷新率。

点击上面链接的性能演示(需要Silverlight 4)。目前SciChart能够以大约5FPS渲染1,000,000个数据点(取决于目标硬件),相当于每秒5,000,000个数据点。商业许可证将于2012年第一季度上市。

+0

@DrABT - 出于好奇,WritableBitmapEx支持任意反锯齿厚度,还是你必须在SciChart组件中单独实现? – 2014-05-14 17:31:25

+0

Hi Miky,据我所知,WBEX不支持这一点。我们使用几种不同的算法自行实现,以在质量和速度之间取得良好的折衷。在WBEX论坛上讨论一个简单的算法,在该论坛中,您预先缓存大小为N的椭圆,然后在bresenham线的每个点上对其进行处理。令人惊讶的是,这可以起作用,但会导致锯齿边缘,因为WBEX具有整数坐标。要获得真正平滑的宽线,您需要浮点 - 在CPU方面也很昂贵! SciChart高质量渲染器可以做到这一点,就像实验D3D渲染器一样。 – 2014-05-14 21:58:15

+0

@DrABT感谢您的快速响应。我目前没有积极地开展这项工作,但也许我会在某个时候重新审视我们的实施。 – 2014-05-15 00:55:31

1

最佳结果可以通过低级DirectX编程和利用HLSL着色器来实现。当最大性能和实时需求很重要时,基于System.Windows.Media命名空间的渲染应该立即被忽略。我们能够开发可以绘制超过1000万个数据点的例程,例如, 8个数据输入x 125 M个数据点,使用宽线,无下采样。例程是LightningChart,WPF图表(和WinForms图表)的一部分。我们花了7年的时间才达到这一点...我们制作了一个billion points example,包括VS项目和Youtube视频。

[我是LightningChart的技术主管]

+0

嗨帕西 - 感谢您的回答; LightningChart是开源的吗?如果没有,你会介意分享一些关于你正在使用什么类型的低级DirectX原语和着色器的细节吗?你在使用Direct2D还是Direct3D?你在用什么着色器? – 2016-08-31 00:29:35

+0

嗨迈克,LightningChart不是开源的。我们也使用Direct3D来处理2D图形。 Direct2D是一些缓慢而有限的技术。道歉我无法公开所有的细节。我们的表现是多年工作的结果,尝试不同方法和客户的实际需求。 – 2016-09-04 08:33:21