Prefuse Toolkit:动态添加节点和边缘

有没有人有prefuse图形工具包的经验? 是否可以更改已显示的图形,即。 添加/删除节点和/或边缘,并使显示正确适应?

例如,prefuse附带了一个可视化朋友网络的示例:

http://prefuse.org/doc/manual/introduction/example/Example.java

我想做的是这样的事情:

// -- 7. add new nodes on the fly ------------------------------------- new Timer(2000, new ActionListener() { private Node oldNode = graph.nodes().next(); // init with random node public void actionPerformed(ActionEvent e) { // insert new node // Node newNode = graph.addNode(); // insert new edge // graph.addEdge(oldNode, newNode); // remember node for next call // oldNode = newNode; } }).start(); 

但它似乎没有用。 任何提示?

你应该知道几层prefuse:

  • 数据
  • 可视化
  • 显示

简而言之,这三层可以通过这种方式链接:

 Graph graph = new Graph(eg. yourXML_file); Visualization viz = new Visualization(); viz.add(GRAPH, graph); Display disp = new Display(); disp.setVisualization(viz); 

显示是您照常添加到面板的图形组件。

在这里,您只需修改数据层。

 Node newNode = graph.addNode(); graph.addEdge(oldNode, newNode); 

您现在需要更新可视图层:

 viz.run("repaint"); 

必须定义重绘动作。

 ActionList repaint = new ActionList(); repaint.add(new RepaintAction()); viz.putAction("repaint", repaint); 

我真的建议你阅读prefuse doc 。 你可以在官方论坛上找到很多资源

至少,我可以说,prefuse目前对于实时图形更新并不是非常有效。

但这还不够,因为您修改了图形结构,您必须在可视化中重新生成它(即重新计算节点放置等…)。 您的示例代码中已经定义了两个操作。 在actionPerformed结束时运行它们。

 viz.run("color"); viz.run("layout"); 

这种方法效率不高,因为每次添加节点时都会增加大量的计算,但目前还没有任何其他的预加入。

正如我在另一篇文章中指出的那样,原始示例中新节点和边缘不可见的原因是节点的颜色等未正确设置。 解决这个问题的一种方法是明确调用vis.run(“color”); 每当添加节点或边缘时。

或者,我们可以通过初始化我们添加它的ActionList(在原始示例中称为“color”)稍微不同来确保颜色操作始终在运行:

代替

 ActionList color = new ActionList(); 

我们可以写

 ActionList color = new ActionList(Activity.INFINITY); 

这使动作列表无限期地运行,以便新的节点/边缘将自动初始化为其视觉外观。

然而,我不清楚这是否真的是首选的方法 – 对于像动态布局动作(例如ForceDirectedLayout)这样的事情,这样的声明非常有意义,但对于颜色,在我看来,持续运行的着色操作主要是高架。

因此,也许之前发布的只是在图表扩展时明确地(但仅一次)运行“颜色”动作的解决方案可能是更好的选择……

好的,在通过预熔源挖掘了一下之后,我现在可以更好地了解工作原理。 我发现实际上我用上面的代码创建的新节点不仅正确地添加到图形中,可视化也注意到它!

因此,与杰罗姆建议的不同,没有必要明确地调用vis.run(“布局”)。

我认为节点没有正确添加的原因是它们在白色背景上绘制的是白色背景,边框和文本颜色 。 并不惊讶他们有点难以发现。

要修复,必须在插入新节点后调用颜色操作,如下所示:

 // insert new edge // graph.addEdge(oldNode, newNode); vis.run("color"); // <- this is new 

(请注意,此操作在// 4.下的Example.jar代码中进一步定义。)

我现在最不确定的一件事是,调用此动作是否会使prefuse再次遍历所有图形节点并设置其颜色 - 当然,对于非常大的图形来说,这是不希望的。

你需要告诉控件容器(’d’,在example.java中)重绘。 调用invalidate()应该足够了(但不确定)。

无论如何,这可能会对你有所帮助。