我正在尝试将 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 Layout 的放大效果更好