Jung,大顶点的布局重叠,图形出现在奇怪的位置

时间:2012-07-09 19:08:24

标签: java graph jung

我正在尝试将Jung用于项目并获得我想要的外观/行为我从一些测试数据开始。

我们的想法是在Verticies形状的顶部放置带有标签的非常大的顶点。图表的数据将在运行时生成,因此我无法进行静态布局。

如何布置图形以使顶点不重叠,但仍然足够大以使标签适合内部(真实标签将具有更长的字符串20-30个字符)。我已经尝试过使用SpringLayout,但节点仍然重叠,另外布局保持抖动(这很烦人)。

我还尝试了FRLayout,同时增加了排斥乘数,但是在数字变得足够大之后,它只会创建一个圆顶重叠的圆圈。

如果我使用鼠标手势放大,节点似乎分开,我得到的视图更接近我想要的。因此,解决方案可能涉及放大初始化,只是不确定如何做到这一点,以及如何决定放大多少,因为它可能取决于节点的数量。

一般来说,我的数据将包含少量节点(少于50个节点,通常少于10个节点)。然而,它是数据驱动的,因此我无法完全控制这些尺寸。

最后,当图表显示时,它也部分离开了屏幕。理想情况下,它将朝向可视区域的左上部分呈现。有没有办法控制它?

以下是我正在使用的示例类,以更好地显示我的意思(修剪后发布)。

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.TestGraphs;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.algorithms.layout.AbstractLayout;
import edu.uci.ics.jung.algorithms.layout.SpringLayout;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.AbstractVertexShapeTransformer;
import edu.uci.ics.jung.visualization.decorators.EdgeShape;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import java.awt.BorderLayout;
import java.awt.Color;
import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.functors.ConstantTransformer;
import edu.uci.ics.jung.visualization.picking.PickedState;
import edu.uci.ics.jung.visualization.renderers.DefaultVertexLabelRenderer;
import edu.uci.ics.jung.visualization.renderers.GradientVertexRenderer;
import edu.uci.ics.jung.visualization.renderers.VertexLabelAsShapeRenderer;
import java.awt.*;

    public class IDRelationshipGraphPanel extends javax.swing.JPanel
{
    private final VisualizationViewer<Integer,Number> vv;
    protected Transformer<Integer,String> vs;
    protected DefaultModalGraphMouse<Integer, Number> gm;
    protected AbstractLayout layout;
    protected VertexShapeSizeAspect<Integer,Number> vssa;

    public IDRelationshipGraphPanel()
    {

    Graph<? extends Object, ? extends Object> g = TestGraphs.getOneComponentGraph(); 

    layout = new SpringLayout( g) ;       
    vv= new VisualizationViewer<Integer,Number>(layout);
    GraphZoomScrollPane scrollPane = new GraphZoomScrollPane(vv);

    gm = new DefaultModalGraphMouse<Integer, Number>();
    vv.setGraphMouse(gm);                
    add(scrollPane, BorderLayout.CENTER);

    PickedState<Integer> picked_state = vv.getPickedVertexState();

    VertexLabelAsShapeRenderer<Integer, Number> vlasr = new VertexLabelAsShapeRenderer<Integer, Number>(vv.getRenderContext());

    vv.getRenderContext().setVertexShapeTransformer(vlasr);
    vv.getRenderContext().setVertexLabelRenderer(new DefaultVertexLabelRenderer(Color.red));
    vv.getRenderContext().setEdgeStrokeTransformer(new ConstantTransformer(new BasicStroke(2.5f)));

    // customize the renderer
    vv.getRenderer().setVertexRenderer(new GradientVertexRenderer<Integer, Number>( new Color(175,224,228), new Color(133,170,173), true));
    vv.getRenderer().setVertexLabelRenderer(vlasr);

    vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Integer>());
    vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line<Integer, Number>());                            

    vssa = new VertexShapeSizeAspect<Integer,Number>();
    vv.getRenderContext().setVertexShapeTransformer(vssa);

    vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
    vv.getRenderContext().setArrowDrawPaintTransformer(new ConstantTransformer(Color.black));        
    }

    private final static class VertexShapeSizeAspect<V,E>
    extends AbstractVertexShapeTransformer <V>
    implements Transformer<V,Shape>  {

    public VertexShapeSizeAspect()
    {
        setSizeTransformer(new Transformer<V,Integer>()
                {
                    public Integer transform(V v) 
                    {
                    return 150;
                    }
                });
        setAspectRatioTransformer(new Transformer<V,Float>() 
                {
                    public Float transform(V v) 
                    {
                    return 1.0f;
                    }
                });                                                                
    }

    public Shape transform(V v){return factory.getEllipse(v);}
    } 
}

使用Spring布局重叠Verticies Overlapping Verticies with Spring Layout

放大弹簧布局看起来更好 Zoom in of Spring Layout appears better

1 个答案:

答案 0 :(得分:2)

对于节点间距,有一个setForceMultiplier和setRepulsionRange,它将有助于确定绘制节点的距离。要摆脱&#34; jiggle&#34;,请执行layout.lock(true),以便在节点到达所需位置时将节点保持在原位。