1

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

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)看起来像这样 在此处输入图像描述

我想对这张图做几件事:

  1. 我希望它们不是从上到下流动的节点,而是从左到右流动。(类似于将其旋转 90 度)
  2. 目前,布局算法确保没有重叠,从而以线性方式分布 set2 的节点。如果 set2 很大,它将超出面板的范围。我不介意重叠,并希望这些节点作为允许部分重叠的集群紧密排列在一起。

我怎样才能达到这两个要求?

4

2 回答 2

2

回答问题(1):有一个演示(L2RTreeLayoutDemo)可以做到这一点。

回答问题(2):更改布局中的 x 和/或 y 间距;这可以在构造函数中设置。

于 2012-11-30T17:16:38.087 回答
0

我扩展了 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;
    }

}
于 2012-11-27T20:40:25.703 回答