我想在我的应用程序中使用实时绘图制作简单的线条图。我知道有很多各种各样的库,但是它们太大了,或者没有正确的功能或许可证。
我的想法是制作自定义视图并仅扩展View
类。使用OpenGL
在这种情况下会像拍摄到鸭用佳能。我已经有视图在绘制静态数据-首先,我将所有数据放入对象float
数组中Plot
,然后使用循环在类onDraw()
方法中绘制所有内容PlotView
。
我也有一个线程可以为绘图提供新数据。但是现在的问题是在添加新数据时如何绘制它。首先想到的是简单地添加新的点并绘制。再次添加另一个。但是我不确定100点或1000点会发生什么。我要添加新点,要求视图使其自身无效,但仍未绘制一些点。在这种情况下,甚至使用一些队列也可能会很困难,因为onDraw()
它将再次从头开始,因此队列元素的数量只会增加。
您会建议如何实现这一目标?
让我尝试进一步说明问题。
第一个问题是-您的情况缓慢吗?您知道延误来自何处吗?首先,请确保您要解决的问题;其次,请确保您知道问题的根源。
假设您的问题在于您暗示的数据大小。如何解决这个问题是一个复杂的问题。这取决于所绘制数据的属性-您可以假设哪些不变性,依此类推。您已经讨论过将数据存储在中float[]
,所以我将假设您拥有固定数量的数据点,这些数据点的值会发生变化。我还要假设“ 100或1000”是“很多”,因为坦率地说1000个浮点数并不是很多数据。
当您要绘制一个非常大的数组时,性能极限最终将来自遍历数组。这样,您的性能增强将减少正在循环的阵列的数量。这就是数据属性起作用的地方。
减少重绘操作量的一种方法是保留一个类似于的“脏列表” Queue<Int>
。每次数组中的一个单元格更改时,您都会将该数组索引放入队列,并将其标记为“脏”。每次您的绘图方法回来时,请从脏列表中取出固定数量的条目,并仅更新与这些条目相对应的渲染图像块-您可能必须做一些缩放和/或抗锯齿或之所以如此,是因为有了这么多的数据点,您获得的数据可能多于屏幕像素。您在任何给定帧更新中重新绘制的条目数应以所需的帧速率为限-您可以根据以前的绘制操作花费了多长时间以及脏列表得到的深度来进行自适应调整,
如果您想一次在屏幕上绘制所有数据,则这特别适合。如果您仅查看数据块(例如在可滚动视图中),并且数组位置和窗口大小之间存在某种对应关系,则可以“显示”数据-在每个绘制调用中,仅考虑屏幕上实际存在的数据子集。如果还进行了“缩放”操作,则可以将两种方法混合使用-这可能会变得很复杂。
如果将数据放在窗口中,以便确定每个数组元素中的值是确定数据点在屏幕上还是屏幕外的值,请考虑使用对的排序列表,其中排序键为值。在这种情况下,这将使您执行上面概述的窗口优化。如果在两个维度上都进行窗口化,则很可能只需要执行一个或另一个优化,但是也可以使用二维范围查询结构来实现这一目的。
假设我对固定数据大小的假设是错误的;而是将数据添加到列表的末尾,但现有数据点不会更改。在这种情况下,最好使用链接的类似Queue的结构,该结构会丢弃旧数据点而不是数组,因为增大数组会不必要地在应用程序中造成混乱。
在这种情况下,您的优化是预先绘制到队列之后的缓冲区中-当新元素进入队列时,将整个缓冲区向左移动并仅绘制包含新元素的区域。
如果问题是数据的/ rate /,则使用排队结构并跳过元素-在将它们添加到队列中时将其折叠,存储/绘制每个n
th元素或类似的方法。
相反,如果渲染过程占用了您的所有时间,请考虑在后台线程上进行渲染并存储渲染的图像。这将让您花费尽可能多的时间进行重绘-图表本身的帧率会下降,但不会降低应用程序的整体响应速度。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句