【问题标题】:Prefuse Toolkit: dynamically adding nodes and edgesPrefuse Toolkit:动态添加节点和边
【发布时间】:2010-10-04 21:41:39
【问题描述】:

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

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

【问题讨论】:

    标签: java layout graph-theory prefuse


    【解决方案1】:

    你应该知道几个prefuse层:

    • 数据
    • 可视化
    • 显示

    简而言之,三层可以这样链接:

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

    Display 是您像往常一样添加到面板的图形组件。

    这里只修改数据层。

    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找到很多资源

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

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

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

    这种方法效率不是很高,因为每次添加一个节点都会增加很多计算量,但目前还没有其他的prefuse。

    【讨论】:

    • 非常感谢您的帮助。我已经阅读了文档并且知道三个不同的层,但是我没有尝试过重绘操作。不幸的是,它也不起作用。我已将动作添加到 viz 并在 actionPerformed (如上所述)结束时调用 viz.run("repaint") 但没有效果。
    • 请您再看看stackoverflow.com/questions/2273068/…的一个前置问题
    【解决方案2】:

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

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

    而不是

    ActionList color = new ActionList();
    

    我们可以写

    ActionList color = new ActionList(Activity.INFINITY);
    

    这会使动作列表无限期地运行,因此新节点/边将自动初始化以显示它们的视觉外观。

    但是,我不清楚这是否真的是首选方法 - 对于动态布局操作(例如 ForceDirectedLayout),这样的声明非常有意义,但对于颜色,在我看来,不断运行的着色行动主要是开销。

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

    【讨论】:

    【解决方案3】:

    好的,在挖掘了一些 prefuse 资源之后,我现在对引擎盖下的工作原理有了更好的了解。我发现实际上我用上面的代码创建的新节点不仅正确地添加到了图表中,可视化也注意到了它!

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

    我认为节点没有正确添加的原因是它们是用白色背景、边框和文本颜色绘制的——在白色背景上。难怪它们很难被发现。

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

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

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

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

    【讨论】:

    【解决方案4】:

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

    Anyway, this might help you.

    【讨论】:

    • 非常感谢您的提示 - 试过了,还是不行。我认为节点不是作为 AWT 或 Swing 组件实现的,prefuse 使用自己的布局机制。这可能就是为什么它不关心对 invalidate() 的调用。
    • 不,里面还是 Swing/AWT。检查 javadocs wrt 损坏管理。此外,repaint 和 revalidade 也可能有效。如有疑问,请阅读 Java 教程。
    • 请您再看看stackoverflow.com/questions/2273068/…的一个前置问题
    猜你喜欢
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多