我有以下三组整数,如下所示:

set0 = {1} //this will always be a singleton set.
set1 = {2, 3, 4, 5}
set2 = {6, 7}


我有一个图,它的边缘从set1到set2或set2到set3,从而形成清晰的树状顶点层次。

 Set0 -- Set1  -- Set2


为了显示此树状图,我创建了DelegateForestTreeLayout

package Test;

import java.util.HashSet;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JPanel;

import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.layout.TreeLayout;
import edu.uci.ics.jung.graph.DelegateForest;
import edu.uci.ics.jung.graph.Forest;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;

class Main{
    public static void main(String[] args){

    Set<Integer> set0 = new HashSet<Integer>();
    Set<Integer> set1 = new HashSet<Integer>();
    Set<Integer> set2 = new HashSet<Integer>();

    set0.add(1);

    set1.add(2);
    set1.add(3);
    set1.add(4);
    set1.add(5);

    set2.add(6);
    set2.add(7);

    JFrame frame = new JFrame();
    frame.add(createGraphPanel(set0, set1, set2));
    frame.pack();
    frame.setVisible(true);


    }

    private static JPanel createGraphPanel( Set<Integer> setZero, Set<Integer> firstSet, Set<Integer> secondSet) {
            // create a graph
            Graph<Integer, String> graph = new DelegateForest<Integer, String>();

                Integer vertex1 = setZero.iterator().next();
            for (Integer i : firstSet) {
                graph.addEdge(vertex1+"-"+i, vertex1, i);
            }

            Layout<Integer, String> layout = new TreeLayout<Integer, String>((Forest<Integer, String>) graph);
            VisualizationViewer<Integer, String> vv = new  VisualizationViewer<Integer,String>(layout);

            vv.getRenderContext().setVertexLabelTransformer(
                    new ToStringLabeller<Integer>());

            return vv;
        }
    }


但是,我得到的图(当前仅包含set1和set2)看起来像这样


我想对这张图做几件事:


我希望节点从上到下流动,而不是从上到下流动。 (有点像旋转90度)
当前,布局算法确保不存在重叠,该重叠以线性方式扩展set2的节点。如果set2很大,它将超出面板的范围。我不介意重叠,并且希望这些节点以允许部分重叠的群集的形式出现在一起。


如何达到两个要求?

最佳答案

我扩展了TreeLayout类并交换了所有x / y变量。这应该水平显示树。但是,您必须添加自己的代码以防止将顶点放置在一行中(也许使用边界框,并在越过顶点时从顶部开始)。

public class HorizontalOverlappingTreeLayout<V, E> extends TreeLayout<V, E> {

    public static void main(String[] args) {
        Set<Integer> set0 = new HashSet<Integer>();
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();
        set0.add(1);
        set1.add(2);
        set1.add(3);
        set1.add(4);
        set1.add(5);
        set2.add(6);
        set2.add(7);

        JPanel panel = new JPanel();
        Graph<Integer, String> graph = new DelegateForest<Integer, String>();
        Integer vertex1 = set0.iterator().next();
        for (Integer i : set1) {
            graph.addEdge(vertex1 + "-" + i, vertex1, i);
        }

        Layout<Integer, String> layout = new HorizontalOverlappingTreeLayout<Integer, String>(
                (Forest<Integer, String>) graph);
        VisualizationViewer<Integer, String> vv = new VisualizationViewer<Integer, String>(layout);
        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<Integer>());
        panel.add(vv);

        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public HorizontalOverlappingTreeLayout(Forest<V, E> g) {
        super(g);
    }

    @Override
    protected void buildTree() {
        this.m_currentPoint = new Point(0, 20);
        Collection<V> roots = TreeUtils.getRoots(graph);
        if (roots.size() > 0 && graph != null) {
            calculateDimensionY(roots);
            for (V v : roots) {
                calculateDimensionY(v);
                m_currentPoint.y += this.basePositions.get(v) / 2 + this.distY;
                buildTree(v, this.m_currentPoint.y);
            }
        }
        // TODO: removed code here
    }

    @Override
    protected void buildTree(V v, int y) {
        if (!alreadyDone.contains(v)) {
            alreadyDone.add(v);

            // go one level further down
            this.m_currentPoint.x += this.distX;
            this.m_currentPoint.y = y;

            this.setCurrentPositionFor(v);

            int sizeYofCurrent = basePositions.get(v);

            int lastY = y - sizeYofCurrent / 2;

            int sizeYofChild;
            int startYofChild;

            for (V element : graph.getSuccessors(v)) {
                sizeYofChild = this.basePositions.get(element);
                startYofChild = lastY + sizeYofChild / 2;
                buildTree(element, startYofChild);
                lastY = lastY + sizeYofChild + distY;
            }
            this.m_currentPoint.x -= this.distX;
        }
    }

    private int calculateDimensionY(V v) {
        int size = 0;
        int childrenNum = graph.getSuccessors(v).size();

        if (childrenNum != 0) {
            for (V element : graph.getSuccessors(v)) {
                size += calculateDimensionY(element) + distY;
            }
        }
        size = Math.max(0, size - distY);
        basePositions.put(v, size);

        return size;
    }

    private int calculateDimensionY(Collection<V> roots) {
        int size = 0;
        for (V v : roots) {
            int childrenNum = graph.getSuccessors(v).size();

            if (childrenNum != 0) {
                for (V element : graph.getSuccessors(v)) {
                    size += calculateDimensionY(element) + distY;
                }
            }
            size = Math.max(0, size - distY);
            basePositions.put(v, size);
        }

        return size;
    }

}

关于java - 如何在JUNG图中强制执行自定义布局?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13408980/

10-11 22:37