绘制/使用100万个节点

时间:2012-12-18 13:06:29

标签: java javafx-2 javafx nodes

我正忙于练习在窗格上绘制节点。我的第一个目标是使用100万个节点,然后将其增加到1500万个。

我有一个自定义对象图,我可以为此对象添加边和节点。每个节点对象都有一个我可以调用和绘制的椭圆,并与边缘对象相同。 目前我有一个为节点生成随机位置的函数。

我目前正在使用滚动窗格启用窗格周围的平移并查看所有节点。

我认为好主意是使用散列图

Map<String, ArrayList<Node>> mapX = new HashMap<String, ArrayList<Node>>();
Map<String, ArrayList<Node>> mapY = new HashMap<String, ArrayList<Node>>();

我使用以下代码将节点添加到hashmap:

int  tempXFloor = (int)Math.floor(tempX);
ArrayList<Node> tempList = mapX.get(tempXFloor+"");
if(tempList == null){
tempList = new ArrayList<>();
}
tempList.add(node); 
mapX.put(tempXFloor+"",tempList);

然后在我平移时,我得到当前位置,将其置于地板上并检查地图中是否存在条目。如果存在条目,我将ArrayList中的所有节点添加到nodesOnScreen。 nodesOnScreen是一个ArrayList类型,我将在平移时将节点添加到该列表中,同样也会从nodesOnScreen变量中删除屏幕外的节点。

我只绘制ArrayList nodesOnScreen中的节点。

我很欣赏这方面的一些指导,以及如何处理这样的大数据结构。我是朝着正确的方向前进,还是我错过了一个明显的“技巧”来做到这一点。

4 个答案:

答案 0 :(得分:3)

您想要的内容属于space partitioning structures类别。

您描述的是uniform grids or bins的特殊形式。一般版本与您的不同之处在于每个bin的大小可能超过1个单位,因此更适合不同分辨率的数据集。容器通常对于或多或少均匀分布的数据集很有用,它实现起来也非常简单。查找屏幕上的元素只需查找视口所属的所有垃圾箱。

如果你的数据集是非均匀的,即有紧密的团块和大的空白空间,你可能想尝试另一种结构,如quad trees

此外,如果您正在使用哈希表或任何其他Java容器,请使用int将其装入整数(Map<Integer, ...>),不要将其转换为字符串,这样会慢得多并消耗掉更多的记忆。

答案 1 :(得分:3)

有几点要考虑:

  1. 您的节点有多复杂?如果它们只是点,您可以考虑在WritableImage上绘制它们并节省大量内存。对于更复杂的情况,您可能希望使用Canvas。无论哪种方式,您都可以节省大量的事件处理程序,属性和其他小东西。

  2. 另一个重要问题是数据视图的相关性。如果您提供地图或类似的东西,那么用户只关心可见部分。其余的可以存储在磁盘缓存中,Pareto principle只有20%的数据会有很大用处。因此,您可以相应地进行规划,并且仅为可见部分设置真实的图形节点(并且可能为了用户体验预加载一些经过调整的部分)。

  3. “分而治之”的概念。即使您不想根据计划(2)限制用户视图,也不能始终需要1500万个节点。不是在UI库中,我担心没有足够大的显示器。因此,将数据拆分为段并一次加载一个段。如果您需要对整个集合执行任何类型的计算 - 不使用节点,请使用最简单的实现并在某些后台进程中执行计算。

  4. 在做大事之前,现有的解决方案始终是调查问题。例如,有许多缓存库,例如PojoCache,只有在将数十亿个节点拆分成组后,才能无缝地使用相关数据。

答案 2 :(得分:2)

您可以尝试使用数据虚拟化和数据提供程序“即时”构建它。不要使用RAM来保存大数据。使用数据库查询。实现List类型并在那里实现索引器,它将从数据库中返回一个项目。

答案 3 :(得分:1)

考虑细节层次。您不可能在屏幕上看到15M不同的点(没有足够的像素使单个节点前景在背景上可见)。有两种类型的详细程度方法:

  • 图形:使用非常大的画布(例如,10M x 10M),一次绘制小图块(例如,1K x 1K像素)并缩小这些图块以构成最终图像(例如,1K x 1K - > 10 x 10,两次,允许将您的10M x 10M虚拟画布缩小为1K x 1K图像。

  • 语义:将节点聚集成单个节点,并绘制clump节点而不是单个节点。您可以在多个级别执行此操作。实际上,如果你计划绘制图形,这正是图形绘制算法将在下面做的事情(没有图形绘制算法在合理的时间内处理> 50K节点而没有某种层次分解)。

在这两种情况下,您都会提供某种缩放和按需细节;主要概述仅用于平移和缩放特定细节。某种空间索引(四叉树是最常见的一种)可以让您从磁盘或二级存储中快速检索切片。在语义 - 缩放场景中,您应该向每个节点添加“父”字段,构建一个巨型(外部序列化;不要在内存中加载15M节点,除非您真的,真的必须)节点树。