Юнг, Макет для больших вершин перекрывается, и график появляется в странном месте.

Я пытаюсь использовать Jung для проекта, и чтобы получить желаемый внешний вид/поведение, я начинаю с некоторых тестовых данных.

Идея состоит в том, чтобы иметь очень большие вершины с метками поверх форм вершин. Данные для графика будут генерироваться во время выполнения, поэтому я не могу сделать статическую компоновку.

Как мне расположить график так, чтобы Вершины не перекрывались, но все же были достаточно большими, чтобы метки помещались внутри (настоящая метка будет иметь более длинные строки 20-30 символов). Я пытался использовать SpringLayout, но узлы по-прежнему перекрываются, кроме того, макет продолжает покачиваться (что раздражает).

Я также пробовал FRLayout, увеличивая множитель Repulsion, однако после того, как число становится достаточно большим, он просто создает круг с перекрывающимися вершинами.

Если я увеличиваю масштаб с помощью жестов мыши, узлы кажутся разделенными, и я получаю вид ближе к тому, что хочу. Так что, возможно, решение включает в себя увеличение при инициализации, просто не уверен, как именно это сделать и как решить, насколько увеличить масштаб, поскольку это может зависеть от количества узлов.

Как правило, мои данные будут иметь небольшое количество узлов (менее 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 Layout Перекрытие вершин с помощью Spring Layout

Увеличение Spring Layout выглядит лучше Увеличение Spring Layout выглядит лучше


person Jim    schedule 09.07.2012    source источник
comment
Вы нашли какие-то решения самостоятельно? Меня интересует решение, сталкиваюсь с такой же проблемой.   -  person Zangdak    schedule 29.04.2014
comment
Нет, мне пришлось прекратить работу над проектом, прежде чем я смог решить эту проблему. Если вы найдете решение, пожалуйста, отправьте его здесь, так как мне любопытно!   -  person Jim    schedule 29.04.2014


Ответы (1)


Для расстояния между узлами есть setForceMultiplier и setRepulsionRange, которые помогут определить, насколько далеко друг от друга отрисовываются узлы. Чтобы избавиться от «покачивания», сделайте layout.lock(true), чтобы сохранить узлы на месте, как только они окажутся там, где вы хотите.

person user4987775    schedule 08.06.2015