Как визуализировать диаграмму перехода состояний в JUNG (Java Universal Network/Graph Framework)?

Я застрял в части визуализации, я создал DirectedSparseMultiGraph для визуализации следующей диаграммы перехода. Я хочу нарисовать его таким же образом, как показано на изображении. В данный момент я получаю это.

Я знаю, что проблема заключается в компоновке, но я новичок в фреймворке JUNG и не могу понять его правильно.

Вот мой фрагмент кода:

Классы MyVertex и MyEdge — это простые классы с полем для их идентификатора и связанной вероятности края.

package testing.jung.in.eclipse;

import java.awt.Dimension;

import javax.swing.JFrame;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;

public class BasicGraphCreation
{
public static void main(String[] args)
{
    Graph<MyVertex, MyEdge> g = new DirectedSparseMultigraph<MyVertex, MyEdge>();
    MyVertex n0 = new MyVertex(0);
    MyVertex n1 = new MyVertex(1);
    MyVertex n2 = new MyVertex(2);
    MyVertex n3 = new MyVertex(3);
    MyVertex n4 = new MyVertex(4);
    MyVertex n5 = new MyVertex(5);
    MyVertex n6 = new MyVertex(6);
    MyVertex o1 = new MyVertex(001);
    MyVertex o2 = new MyVertex(010);
    MyVertex o3 = new MyVertex(011);
    MyVertex o4 = new MyVertex(100);
    MyVertex o5 = new MyVertex(101);
    MyVertex o6 = new MyVertex(110);

    g.addEdge(new MyEdge(0.5), n0, n1, EdgeType.DIRECTED);
    g.addEdge(new MyEdge(0.5), n1, n3, EdgeType.DIRECTED);
    g.addEdge(new MyEdge(0.5), n3, n1, EdgeType.DIRECTED);
    g.addEdge(new MyEdge(0.5), n1, n4, EdgeType.DIRECTED);
    g.addEdge(new MyEdge(0.5), n3, o1);
    g.addEdge(new MyEdge(0.5), n4, o2);
    g.addEdge(new MyEdge(0.5), n4, o3);
    g.addEdge(new MyEdge(0.5), n0, n2);
    g.addEdge(new MyEdge(0.5), n2, n5);
    g.addEdge(new MyEdge(0.5), n2, n6);
    g.addEdge(new MyEdge(0.5), n6, n2);
    g.addEdge(new MyEdge(0.5), n5, o4);
    g.addEdge(new MyEdge(0.5), n5, o5);
    g.addEdge(new MyEdge(0.5), n6, o6);

    Layout<MyVertex, MyEdge> layout = new CircleLayout<MyVertex, MyEdge>(g);
    layout.setSize(new Dimension(600, 600)); // sets the initial size of the space
    // The BasicVisualizationServer<V,E> is parameterised by the edge types

    BasicVisualizationServer<MyVertex, MyEdge> vv = new BasicVisualizationServer<MyVertex, MyEdge>(layout);
    vv.setPreferredSize(new Dimension(650, 650)); //Sets the viewing area size

    vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<MyVertex>());
    vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<MyEdge>());
    vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);

    JFrame frame = new JFrame("Directed Graph ");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(vv);
    frame.pack();
    frame.setVisible(true);
}
}

person longjohnsilver    schedule 12.03.2014    source источник


Ответы (1)


Если вы знаете, где должны быть вершины, используйте StaticLayout.

Если вам нужен алгоритм макета, который будет определять, как создать такой макет автоматически, вам нужно будет предоставить его самостоятельно... и это не будет тривиально.

person Joshua O'Madadhain    schedule 14.03.2014
comment
Спасибо за ответ, Джошуа, приведенный выше пример приведен только для справки, но у меня есть информация о вершинах, ребрах и метках, которые также могут измениться, и затем мне нужно создать конечный автомат, подобный указанному выше, поэтому StaticLayout будет не делать работу, создание алгоритма самостоятельно является единственным допустимым вариантом. Можете ли вы предложить мне какой-нибудь другой вариант с открытым исходным кодом для визуализации конечных автоматов в java, я хочу использовать его в другом проекте, я нашел jautomata.sourceforge.net, но с 2006 года его развитие застопорилось. - person longjohnsilver; 15.03.2014
comment
Вы также сталкивались с этой проблемой при создании макетов JUNG2? - person longjohnsilver; 15.03.2014
comment
В случаях, когда ваш график представляет собой дерево или в основном древовидный (как в вашем примере), вы можете использовать TreeLayout. Возможно, существуют приличные алгоритмы для рендеринга FSM — я не изучал их — и если они есть, вы можете реализовать их в JUNG, не разрабатывая свой собственный алгоритм. Что бы это ни стоило, алгоритмы компоновки JUNG пытаются оптимизировать общие графики, а не пытаться выглядеть как что-то конкретное; они подчеркивают силовые макеты. CircleLayout очень редко бывает правильным ответом. Попробуйте проверить демонстрацию ShowLayouts, чтобы поиграть с различными вариантами. - person Joshua O'Madadhain; 22.03.2014
comment
Спасибо за понимание, Джошуа, вы правы в том, что граф похож на дерево, но проблема здесь в том, что графы, которые я хочу визуализировать, будут иметь как параллельные, так и самостоятельные края, а TreeLayout не поддерживает такую ​​​​структуру. Возможно ли, что я могу изменить TreeLayout для поддержки параллельных ребер и циклов. Ваше руководство о том, как действовать, было бы очень полезно. - person longjohnsilver; 16.04.2014
comment
Если вы хотите, чтобы вершины были расположены в виде дерева с «прикрепленными» дополнительными ребрами, вы можете проверить MinimiumSpanningTreeDemo. По сути, это берет древовидный подграф, вычисляет для него позиции вершин, а затем строит StaticLayout, используя эти позиции вершин. - person Joshua O'Madadhain; 23.04.2014