比较开源java图形绘制框架(JUNG和Prefuse)绘制网络拓扑

哪个开源Java图形绘制框架用于具有以下要求的网络图? 该图表将少于1000个节点。

1)具有平行边缘
2)单个图中的有向和无向边
3)由图像表示的节点
4)用户与节点和边缘的交互
5)动态添加/删除节点和边缘
6)节点和边缘上的多个标记,用户可以关闭/打开不同的标记级别。 (比如在图层中绘图并关闭/在图层上)
7)不同的布局算法,以显示星形,环形,网状拓扑

我评估了JUNG和Prefuse。 这是我为每个要求找到的。

1)当JUNG支持时,Prefuse不能显示平行边缘。 可以预操作代码来显示平行边缘吗? 由于这涉及基本的数据级别更改,我相信通常的自定义呈现更改会更加困难。

2)我没有在prefuse和JUNG中找到任何对组合图(有向和无向边)的引用。 有没有人知道呢?

3)Prefuse和JUNG都很容易

4)prefeuse和JUNG再次为用户交互提供支持。

5)prefuse和JUNG都支持它。 重绘图表时每个框架如何执行? 我在另一篇文章中看到,prefuse在动态更新方面表现不佳( Prefuse Toolkit:动态添加节点和边缘 )

6)这归结为修改图形并重新绘制它。 所以问题变得与5)相同

7)JUNG和prefuse都有多种布局算法。 但是当我尝试在JUNG和Prefuse中使用FruchtermanReingoldLayout显示相同的数据集时,我会得到不同的显示。 有什么想法吗? Prefuse中的布局算法似乎显示出比JUNG更好的布局(我认为渲染也更好),尽管Prefuse中的大多数布局算法都基于JUNG实现。 PreFuse布局(如ForceDirectedLayout / FruchtermanReingoldLayout和CircleLayout)直接映射到星形,圆形,网格拓扑。

在这些要求之外,prefuse对表达式和查询语言有很好的支持,但看起来它不像JUNG那样积极开发。 哪一个有更好的可视化? 关于哪一个适合以及如何克服缺点的任何建议?

我可以使用其他任何框架吗?

几年前(2007年?)我使用prefuse来显示呼叫数据记录。 我考虑了prefuse,jung,jgraph和其他几个并且选择了prefuse。 起初有点难以将我的脑袋包裹起来,但是一旦我熟悉它,它就很容易(扩展)和使用起来很有趣。 我想JUNG可以这么说,但我从未尝试过。

1)在prefuse中,添加自己的自定义渲染器以绘制平行边缘非常容易 – 您可以inheritance默认的EdgeRenderer并覆盖render()方法。 不需要“基本数据级别更改”。 如果您想将其视为MVC内容,那么这一切都在视图中。

2)这根本不是问题。 有多种方法可以做到这一点:1)你可以有两个渲染器 – 一个用于绘制有向边,一个用于绘制无向边,它们可以正常工作,并适当地对边进行分组。 2)放置一个标志(在prefuse speak中的后备表元组中添加一个布尔列)以指示边缘是否被定向并根据该标志在EdgeRender中相应地跳过箭头绘制部分。

3)这非常容易

4)同上

5)最后一个prefuse版本是“prefuse beta release 2007.10.21”。 我之前使用的那个,在动态添加或删除节点时可能存在竞争条件 – 我猜错了一些同步关键字。 我通过确保在添加或删除节点时停止所有动画和动作(颜色,大小,布局)来解决这个问题 – 也不要忘记更新你的lucene索引(如果你使用它内置的lucene搜索引擎)。 最新的一个应该解决这个种族问题,但我从来没有机会尝试过。

6)既然你提到了“多重标签”,我认为这不是“修改图形并重新绘制”的问题 – 只需要自定义标签/边缘渲染器以仅绘制相关标签,这不是一个大问题。 我也不认为这与5完全相关。

7)我并不感到惊讶,因为prefuse和JUNG对FruchtermanReingoldLayout的渲染是不同的 – 有一些因素可能会影响其中一个因素,即每个实现开始计算的起始节点,所以我不会担心这个问题。 在prefuse中尝试不同的内置图形布局算法非常容易,因此您可以继续检查哪一个最接近您想要的内容。 查看RadialLayout和BalloonTreeLayout的星形布局。 ForceDirectedLayout需要相当多的迭代才能使节点的位置“稳定”。 请注意,不必显示这些迭代,因此您可以在后台运行它并呈现最终结果。

我没有使用JUNG所以我不能对此发表评论。

基于我对prefuse的经验,我强烈推荐它,因为非常好(IMHO)的深思熟虑的设计和组件之间的可靠性分离。 杰弗里·希尔(prefuse作者)在那里做得很好。

如果你使用prefuse需要注意的事项(这些是我在使用prefuse时生动地记住的两个“痛苦的拇指”):

1)有一个错误,当缩小时,节点标签没有被适当地缩小,使得它溢出节点的边界框,当节点移动时会留下字体绘制工件,因为渲染器只清除并重绘节点边界内的东西框。 IIRC这是由AWT字体指标本身的错误引起的。 解决方法是在标签和节点边界框​​之间留出足够的边距。

2)扩展内置布局时,您可能会遇到一个或两个“范围问题”,其中您希望访问的超类成员被赋予私有属性而不是受保护,因此解决方案是要么修改库本身或创建一个没有inheritance的新类(这可能有点痛苦!)。 我猜你可以对其他一些java库说同样的话。 不是每个人都有后见之明的好处吗? 🙂

自从你在一个月前(在我写这篇文章时)提出这个问题以来,我想知道你的决定是什么以及如果你继续实施它的结果。

我是JUNG的创造者和维护者之一,所以请记住下面的回答。

首先,我应该说Prefuse的作者是朋友的朋友(是的,我们见过面)并且他做得很好。 我对Prefuse没有经验,但我看到了一些用它创建的漂亮可视化。

以下是JUNG这些问题的答案。 其中几个((1),(2),(4)在PluggableRendererDemo中演示:

  1. 支持(出于性能原因,您需要正确的数据模型,并非所有支持并行边缘)
  2. 支持(再次,您需要正确的数据模型)
  3. 支持(参见ImageShaperDemo
  4. 支持(大多数演示)
  5. 支持(参见GraphEditorDemo
  6. 不直接支持,虽然您当然可以动态更改标签并使用HTML来呈现复杂标签。
  7. JUNG的布局算法更适用于一般网络(树木等少数例外)。 但是,您当然可以构建自己的布局算法,并且许多人已经这样做了。

希望这可以帮助。

我知道你指定了jung和prefuse但是……我对TomSawyer和yFiles都有很好的经验。 您提出的要求清单对于这两个要求非常基础 – 而且它们支持更多。

然。

我建议也要评估JGraph 。

我喜欢@ holygeek的回答。 对于Prefuse,这是我对2的解决方案(有向和无向边)的实现:

 public class MyRenderFactory implements RendererFactory { private NodeRenderer nodeRenderer = new NodeRenderer(); private EdgeRenderer defaultEdgeRenderer = new EdgeRenderer(); private EdgeRenderer undirectedEdgeRenderer = new EdgeRenderer(EdgeRenderer.EdgeType.LINE, EdgeRenderer.EdgeArrowType.NONE); public static String directedness = "myEdgeDirectedness"; public enum EdgeDirected { directed, undirected; public static EdgeDirected fromIsDirected(boolean isDirected) { if (isDirected) { return directed; } return undirected; } } @Override public Renderer getRenderer(VisualItem visualItem) { if (visualItem instanceof EdgeItem) { if (visualItem.get(directedness).equals(PrefuseGraphConverter.EdgeDirected.undirected)) { return undirectedEdgeRenderer; } return defaultEdgeRenderer; } return nodeRenderer; } } 

……其他地方,创建图表的地方……

 MyRenderFactory.EdgeDirected directedness = MyRenderFactory.EdgeDirected.fromIsDirected(myEdge.isDirected()); prefuseEdge.set(MyRenderFactory.directedness, directedness);