有没有人有使用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();
但它似乎不起作用。任何提示?
答案 0 :(得分:7)
你应该知道几层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。 你可以在官方forum
上找到很多资源至少,我可以说你的前提是暂时不能真正有效地进行实时图表更新。
但是它不够,因为你修改了图形结构,你必须在可视化中重新生成它(即重新计算节点位置等...)。您的示例代码中已经定义了两个操作。在actionPerformed结束时运行它们。
viz.run("color");
viz.run("layout");
这种方法效率不高,因为每次添加节点时都会增加大量的计算,但目前还没有任何其他的预处理。
答案 1 :(得分:6)
正如我在另一篇文章中指出的那样,原始示例中新节点和边缘不可见的原因是节点的颜色等未正确设置。解决这个问题的一种方法是明确调用vis.run(“color”);无论何时添加节点或边缘。
或者,我们可以通过初始化我们添加它的ActionList(在原始示例中称为“color”)稍微不同来确保颜色操作始终在运行:
而不是
ActionList color = new ActionList();
我们可以写
ActionList color = new ActionList(Activity.INFINITY);
这会使动作列表无限期地运行,以便新的节点/边缘将自动初始化为其视觉外观。
然而,我不清楚这是否真的是首选的方法 - 对于像动态布局动作(例如ForceDirectedLayout)这样的事情,这样的声明很有意义,但对于颜色来说,在我看来,一个不断运行的着色行动主要是开销。
所以,也许以前发布的解决方案只是在图表扩展时明确地(但只有一次)运行“颜色”动作,可能是更好的选择......
答案 2 :(得分:2)
好的,在通过预熔源挖掘了一下之后,我现在可以更好地了解它是如何工作的。我发现实际上我用上面的代码创建的新节点不仅正确地添加到图形中,可视化也注意到了它!
因此,与杰罗姆建议的不同,没有必要明确地调用vis.run(“布局”)。
我认为节点没有正确添加的原因是它们是在白色背景上用白色背景,边框和文本颜色绘制的。并不惊讶他们有点难以发现。
要修复,必须在插入新节点后调用颜色操作,如下所示:
// insert new edge //
graph.addEdge(oldNode, newNode);
vis.run("color"); // <- this is new
(请注意,此操作在//. 4下的Example.jar代码中进一步定义。)
现在我不确定的最后一件事是,调用此动作是否会使prefuse再次遍历所有图形节点并设置其颜色 - 当然,对于非常大的图形来说是不希望的。
答案 3 :(得分:0)
你需要告诉控件容器('d',在example.java中)重新绘制。调用invalidate()应该足够了(但不确定)。