Prefuse Toolkit:动态添加节点和边

发布于 2024-07-12 06:37:40 字数 862 浏览 11 评论 0原文

有人有使用 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();

但它似乎不起作用。 有什么提示吗?

Does anyone have experience with the prefuse graph toolkit? Is it possible to change an already displayed graph, ie. add/remove nodes and/or edges, and have the display correctly adapt?

For instance, prefuse comes with an example that visualizes a network of friends:

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

What I would like to do is something along the lines of this:

// -- 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();

But it doesn't seem to work. Any hints?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝眼睛不忧郁 2024-07-19 06:37:41

您应该了解 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 文档
你可以在官方 论坛 上找到很多资源

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

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

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

这种方法效率不是很高,因为每次添加节点都会增加大量计算,但暂时没有其他有prefuse的方法。

You should be aware the several layers of prefuse:

  • Data
  • Visualization
  • Display

To be short, the three layers can be linked this way:

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

Display is a graphic component that you add to a panel as usual.

Here you only modify the data layer.

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

You need now to update the visual layer:

viz.run("repaint");

The repaint action has to be defined.

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

I really advise you to read the prefuse doc.
And you can find a lot a resources on the official forum

At least, I can say you that prefuse is for the moment not really efficient for live graph update.

But it should not be enough, as you modified the graph structure, you have to regenerate it in the visualization (ie. recalculate the node placements etc...). There are two actions already defined in your sample code. Run them at the end of your actionPerformed.

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

This method is not very efficient, because it adds a lot of computation each time you add a node, but there are not any others for the moment with prefuse.

寻找一个思念的角度 2024-07-19 06:37:41

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

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

而不是

ActionList color = new ActionList();

我们可以写

ActionList color = new ActionList(Activity.INFINITY);

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

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

因此,也许之前发布的解决方案是在图形扩展时显式运行“颜色”操作(但仅一次),可能是更好的选择......

As pointed out in my other post, the reason new nodes and edges are not visible in the original example is that the colors etc. for the nodes are not set correctly. One way to fix this is to explicitly call vis.run("color"); whenever a node or edge was added.

Alternatively, we can ensure that the color action is always running, by initializing the ActionList to which we add it (called "color" in the original example) slightly differently:

instead of

ActionList color = new ActionList();

we could write

ActionList color = new ActionList(Activity.INFINITY);

This keeps the action list running indefinitely, so that new nodes/edges will automatically be initialized for their visual appearance.

However, it is unclear to me whether this would actually be the preferred method - for things like a dynamic layout action (e.g. ForceDirectedLayout), such a declaration makes perfect sense, but for colors it seems to me that a constantly running coloring action is mostly overhead.

So, perhaps the previously posted solution of just running the "color" action explicitly (but only once) whenever the graph gets extended, might be the better choice...

半葬歌 2024-07-19 06:37:41

好吧,在深入研究了 prefuse 源代码之后,我现在对底层的工作原理有了更好的了解。 我发现实际上我用上面的代码创建的新节点不仅正确添加到图表中,可视化也注意到了它!

因此,与 Jerome 所建议的不同,没有必要显式调用 vis.run("layout")。

我认为节点未正确添加的原因是它们是在白色背景上使用白色背景、边框和文本颜色绘制的。 毫不奇怪,它们有点难以发现。

要解决这个问题,必须在插入新节点后调用颜色操作,如下所示:(

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

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

我不确定的最后一件事现在的问题是调用此操作是否会让 prefuse 再次遍历所有图形节点并设置它们的颜色 - 对于非常大的图形,当然这是不希望的。

Okay, after digging a bit through the prefuse sources, I now have a better understanding of how things work under the hood. I found out that actually the new nodes I create with the code above are not only added correctly to the graph, the visualization also takes note of it!

So, unlike Jerome suggests, it is not necessary to call vis.run("layout") explicitly.

The reason I thought the nodes were not added correctly was the fact that they are drawn with white background-, border- and text color - on white background that is. Not astonishing that they are a bit difficult to spot.

To fix that one has to call the color action after a new node is inserted, like this:

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

(Note that this action is defined further up in the code of Example.jar under //-- 4.)

One last thing I am unsure about now is whether calling this action will make prefuse go over all graph nodes again and set their color - for very large graphs that would be undesired, of course.

榆西 2024-07-19 06:37:41

您需要告诉控制容器(“d”,在 example.java 中)进行重绘。 调用 invalidate() 应该足够了(但不确定)。

无论如何,这可能对您有帮助。

You need to tell the control container ('d', in example.java) do get redrawn. Calling invalidate() should be enough (not sure, though).

Anyway, this might help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文