3

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

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

如何布局图形以使顶点不重叠,但仍然足够大以使标签适合内部(真实标签将具有更长的字符串 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 布局重叠顶点 使用 Spring 布局重叠顶点

Spring Layout 的放大效果更好 Spring Layout 的放大效果更好

4

1 回答 1

2

对于节点间距,有一个 setForceMultiplier 和 setRepulsionRange 将有助于确定节点之间的距离。要摆脱“抖动”,请执行 layout.lock(true) 以将节点保持在您想要的位置。

于 2015-06-08T19:50:22.740 回答