2011-04-14 42 views
0

我一直在研究JUNG2一段时间,试图可视化一组对象的相当复杂的层次结构。不幸的是,这个层次结构实际上并不像树:JUNG2布局问题:结果图最终变得太宽

  1. 某些节点将有多个父母。此外,这些父母可能在树的不同分支。
  2. 一些节点可能有重复(这是已被允许,我不能不理会他们)

截至目前我使用的是SparseGraph;将所有节点放在图中,用有向图绘制子/超关系,并在节点之间复制为无向边。然后,在MinimumSpanningTreeDemo源代码之后,我创建一个MinimumSpanningTreeForest2对象,并将Forest发送到TreeLayout。长话短说,我得到的布局,但他们是约15000像素宽!由于我不是以交互方式使用这些图形,而是以静态图像的形式使用这些图形,因此在报告中使用这些操作根本不可行。

我意识到如果节点标签太多,并排太多,我认为节点标签需要相当多的空间,所以我想我可以旋转标签并使它们垂直。这已经失败了,我设法旋转标签使用自定义类扩展DefaultVertexLabelRenderer,但是当我将旋转设置为Math.PI/2时,我只是看到没有标签!所以这里是我的问题:

  1. 是否有可能强制布局更苗条?我想制作一个树状图,即claimed to be possible using JUNG2。这真的有可能吗?在那种情况下如何?
  2. 在我的想法中是否存在一个错误,即应该可以垂直渲染节点标签?我试图改变VertexLabelAsShapeRenderer班的定位点,但仍然没有快乐。说到问题; Renderer s RendererContext与实际渲染对象之间的连接真的很模糊。有很多类,我很难找出哪些实际用于渲染。例如,BasicVertexLabelRenderer看起来好像根本没有被默认使用。因此标签的整体定位就是神秘...

我知道JUNG开发商已经把艰苦的工作时间到图书馆,我不想出言刻薄或忘恩负义,但我真的觉得有一个很长的差距介于this tutorial之间,并确定如何编写演示以及渲染如何工作。

在任何情况下;这里的地方创建图表的我的代码位:

public void visualizeGraph(File saveFolder){ 

    MinimumSpanningForest2<PHGNode, PHGEdge> prim = new MinimumSpanningForest2<PHGNode, PHGEdge>(
      g, new DelegateForest<PHGNode, PHGEdge>(), DelegateTree.<PHGNode, PHGEdge>getFactory(), 
       new ConstantTransformer(1.0)); 

    Forest<PHGNode, PHGEdge> tree = prim.getForest(); 

    Layout<PHGNode, PHGEdge> layout = new TreeLayout<PHGNode, PHGEdge>(tree); 
    // custom visualization viewer that allows writing to disk 
    final WritingVisualizationViewer<PHGNode, PHGEdge> vv = new WritingVisualizationViewer<PHGNode, PHGEdge>(layout,layout.getSize()); 

    // this class extends VertexLabelAsShapeRenderer and supplies means of fiddling with label coordinates 
    VerticalVertexLabelAsShapeRenderer<PHGNode,PHGEdge> vlasr = 
      new VerticalVertexLabelAsShapeRenderer<PHGNode,PHGEdge>(vv.getRenderContext()); 

    vv.getRenderContext().setVertexLabelTransformer(
      new ChainedTransformer<PHGNode,String>(new Transformer[]{ 
        new ToStringLabeller<PHGEdge>(),new Transformer<String,String>() { 
          public String transform(String input) { return input;  }}})); 

    // Change the background of node labels so that they appear transparent 
    Transformer<PHGNode,Paint> vertexPaint = new Transformer<PHGNode,Paint>() { 
     public Paint transform(PHGNode n) { return vv.getBackground(); } 
    }; 

     // extends DefaultVertexLabelRendeder to provide rotation of labels 
    VerticalVertexLabelRenderer vvlr = new VerticalVertexLabelRenderer(); 
    vv.getRenderContext().setVertexLabelRenderer(vvlr); 

    vv.getRenderContext().setVertexFontTransformer(new VertexFontTransformer<PathwayHierarchyGraph.PHGNode>()); 
    vv.getRenderContext().setVertexShapeTransformer(vlasr); 
    vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint); 
    vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.BentLine<PHGNode, PHGEdge>()); 
    vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR); 


    //printGraphStats(tree); 
    vv.writeToDisk(saveFolder,"hierarchyTree.png"); 


} 
+0

自'Prefuse'以来,我是'JUNG2'的粉丝。我看到很多人都开始对'JUNG2'问很多问题。和你一样,我也必须修改它以获得与示例,演示和教程不同的内容。这样好的网络图库还没有被其社区的更高级的教程更新...太糟糕了......也许,你可以查看'JUNG2 Sourceforge forum'获取更多答案 – eee 2011-04-15 03:33:06

+0

你是什么意思? Prefuse“?他们是完全独立的项目。 – 2011-04-16 23:52:40

回答

1

回答您的问题:

(1)JUNG没有一个树状布局。我也会对看到链接问题的评论者使用JUNG生成树状图表示感兴趣。但是,您可以指定兄弟姐妹之间的x分隔是什么(以及父母和孩子之间的y分隔是什​​么)。 (2)我没有编写大部分的JUNG可视化代码,所以我不得不深入研究它。 Offhand我会说AFAIK可能没有对旋转顶点标签的直接支持(我记得没人会问这个问题),但是你的尝试听起来似乎是合理的,我不知道为什么将角度设置为pi/2应该导致它失败。不过,我会看看控制台的踪迹。发生这种情况时几乎肯定会抛出一些异常。

作为一种实用的解决方案,您可以尝试渲染顶点标签的一部分,并使用悬停文本显示其余部分。

作为JUNG的创造者和主要维护者之一,我想有更多的时间来致力于开发和文档。任何想要帮助的人都应该对我有所帮助,我很乐意谈谈你能做些什么。 :)

+0

谢谢你的回复约书亚。关于树状图问题,我想我必须自己尝试编写一个布局实现。本质上,树状图并不是我所需要的,因为我需要可视化多个父层次结构(请参阅:http://stats.stackexchange.com/questions/9266/a-smart-way-of-clustering-a-基于集合的固有层次结构)说到层次结构,如果一个孩子有多个父亲,那么没有办法使用树形布局,是吗? – posdef 2011-04-18 07:03:54

+0

不客气。 – 2011-04-19 16:50:19

+0

(在我完成之前,先前的注释变得不可编辑。)是的,如果您第一次提取跨越子树(请参阅最小生成树演示),那么您可以使用树布局(如果孩子有多个父亲)。也有DAGLayout,但这是一个设计不太好的贡献;然而,另一个用户最近正在改进它,并可能将捐赠的结果返回。 – 2011-04-19 17:14:34