问题:
在下面描述的场景中,我可以通过哪些方式改善渲染时间?
说明
我面临的任务是在JavaFX中的散点图上绘制相当多的点。我从Oracle DB获取数据。
我认为我目前的瓶颈是scatterChart.getData().add(series);
series
包含图表中所需的所有数据点。
执行此操作,并在屏幕上呈现图表可能需要几秒到几分钟。在此期间,GUI冻结。
我们正在运行一些带有4核心4线程,Intel HD4000图形的联想智能手机。
完成图表的一些示例如下。后者是目前最糟糕的情况,但随着收集的数据越来越多,将会显示更多的数据。
(由于图像不切实际,只有链接)
Chart with ~5.5K points
Chart with ~75K points
更多信息
我关注了this tutorial因为我是JavaFX的新手,所以我不确定渲染的确切方式。
代码示例
这不是我使用的实际代码,只是为了说明我是如何做事的。
//Reference to the chart in the fxml file.
@FXML
private ScatterChart<Date, Number> scatterChart
= new ScatterChart<>(new DateAxis(), new NumberAxis());
private void handleSelectionUpdate(PerfResultSet newValue){
//newValue is an object containing all the data from the database
XYChart.Series<Date, Number> series = new XYChart.Series<>();
/**
* adding all the data from newValue to series as
* XYChart.Data<Date, Number>
*
* this is handled by multiple threads and does not take long
*/
series.setName("myName");
//this statement is where the gui freezes
//can I optimize this in any way?
scatterChart.getData().add(series);
}
答案 0 :(得分:3)
我遇到了类似的问题 - 我正在使用Javascript绘制包含许多点到google地图的路线。我取消了考虑当前规模的积分。我看到你的png文件,似乎你真的需要~30-50点来表达以下信息 - 嘿,这个垂直/水平段包含这么多点你可以假设它实线!
下一个问题是最大规模 - 我认为,75K图表中的每条实线实际上都不稳固。我的意思是,在小范围内,我看到很多点像实线____
,但在最大尺度上我看到它们为. . . ... . ..
但通常,最大比例仅需要小块图表和你可能不是按比例而是按边界消除。再次参考谷歌地图 - 当你缩放地图时,你没有看到整个地球的酷分辨率,但一些小地图。其他边框自动消除。
在这里发布您的代码,有关缩放,缩放的一些信息(您有这样的功能吗?)。如果你没有,并且你的图表总是像链接中的png文件一样,你应该遍历每条垂直或水平线,寻找后续点,并将100个序数点替换为100点的中间点。而不是100实验上找到这样的X,将序列 X点替换为一个中间值点不会影响结果图表。
我重复主要思想 - 存在一些X,这样绘制X 序列点等于在某个固定尺度上绘制1点 - 许多点不能提供精度但只是简单地“覆盖”彼此由于规模和人眼限制。
如果您的比例是常数,则找到X的一些伪代码;
int MAGIC = 50; //change it on each run of your program! You have to find the best value
int counter=1; // points[0] taken as included in accumulating solid segment
int startIndex=0,endIndex;
ArrayList<Integer> compressedDatesArray = new ArrayList<Integer>();
for(int i=1;i<datesArray.length;i++){
if(deltaBetweenDates(datesArray[i]-datesArray[i-1])==1){
counter++;
endIndex=i;
if(counter==MAGIC){
counter=0;
compressedDatesArray.add(datesArray[{endIndex-startIndex)/2]);
startIndex=endIndex+1;
}
}
}
渲染compressedArray,请参阅png。如果结果不好 - chnage MAGIC并重复
<强>更新强>
你可以二元搜索 MAGIC - 尝试5000,如果在压缩5000点后仍然稳定,如果没有尝试更大的值,请尝试2500等等......人类也可以二元搜索某事= )))
另外,不要忘记记住代表大段的点的Y值。我的意思是,也声明compressedY
并添加datesArray[(endIndex-startIndex/2)]