// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea // Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ package graphtea.plugins.visualization.hierarchical; import graphtea.graph.atributeset.GraphAttrSet; import graphtea.graph.graph.Edge; import graphtea.graph.graph.GPoint; import graphtea.graph.graph.GraphModel; import graphtea.graph.graph.Vertex; import graphtea.platform.core.AbstractAction; import graphtea.platform.core.BlackBoard; import graphtea.plugins.visualization.corebasics.animator.GeneralAnimator; import graphtea.ui.UIUtils; import java.util.HashMap; import java.util.Iterator; import java.util.Vector; /** * @author Rouzbeh Ebrahimi */ public class BendedTrees extends AbstractAction { String event = UIUtils.getUIEventKey("BendedTrees"); public Vector<Vertex> visitedVertices = new Vector<>(); public HashMap<Vertex, GPoint> vertexPlaces = new HashMap<>(); public HashMap<Edge, Vector<GPoint>> edgeBendPoints = new HashMap<>(); public Vector<Vertex> children = new Vector<>(); public GraphModel graph; /** * constructor * * @param bb the blackboard of the action */ public BendedTrees(BlackBoard bb) { super(bb); listen4Event(event); } private Vertex findAppropriateRoot(GraphModel g) { Vertex root = g.getAVertex(); Iterator<Vertex> ei = g.iterator(); for (; ei.hasNext();) { Vertex e = ei.next(); root = findHigherVertex(e, root); } return root; } private Vertex findHigherVertex(Vertex v1, Vertex v2) { Vector<Vertex> t1 = new Vector<>(); Vector<Vertex> t2 = new Vector<>(); t1.add(v1); t2.add(v2); if (BFS(new Vector<>(), t1, 0) > BFS(new Vector<>(), t2, 0)) { return v1; } else { return v2; } } private int BFS(Vector<Vertex> marked, Vector<Vertex> currentLevel, int maxLevel) { marked.addAll(currentLevel); Vector<Vertex> nextLevel = new Vector<>(); for (Vertex v : currentLevel) { v.setMark(true); Iterator<Edge> em = g.edgeIterator(v); for (; em.hasNext();) { Edge e = em.next(); Vertex v2 = e.source; if (!marked.contains(v2)) { nextLevel.add(v2); } } } maxLevel++; if (nextLevel.size() != 0) { return BFS(marked, nextLevel, maxLevel); } else { return maxLevel; } } static GraphModel g; public void performAction(String eventName, Object value) { visitedVertices = new Vector<>(); vertexPlaces = new HashMap<>(); children = new Vector<>(); edgeBendPoints = new HashMap<>(); g = blackboard.getData(GraphAttrSet.name); try { this.graph = g; Vertex root = findAppropriateRoot(g); visitedVertices.add(root); locateAllVertices(visitedVertices, 800, 50); reshapeAllEdges(); GeneralAnimator t = new GeneralAnimator(vertexPlaces, edgeBendPoints, g, blackboard); t.start(); } catch (NullPointerException e) { System.out.println("Graph is Empty"); // ExceptionHandler.catchException(e); } } public Vector<Vertex> findNextLevelChildren(Vector<Vertex> currentLevelVertices) { Vector<Vertex> newChildren = new Vector<>(); for (Vertex v : currentLevelVertices) { Iterator<Edge> e = g.edgeIterator(v); for (; e.hasNext();) { Edge ed = e.next(); Vertex dest = ed.source; if (!visitedVertices.contains(dest)) { newChildren.add(dest); } } } return newChildren; } public void reshapeAllEdges() { Iterator<Edge> ei = graph.edgeIterator(); for (; ei.hasNext();) { Edge e = ei.next(); GPoint d1 = vertexPlaces.get(e.target); GPoint d2 = vertexPlaces.get(e.source); Vector<GPoint> bendPoints = new Vector<>(); bendPoints.add(new GPoint(d1.getX(), d1.getY() - 15)); bendPoints.add(new GPoint(d2.getX(), d2.getY() + 15)); edgeBendPoints.put(e, bendPoints); } } public void locateAllVertices(Vector<Vertex> currentLevelVertices, int width, int currentLevelHeight) { int currentLevelCount = currentLevelVertices.size(); int i = 0; Vector<Vertex> nextLevel = findNextLevelChildren(currentLevelVertices); int nextLevelCount = nextLevel.size(); int horizontalDist = width / (currentLevelCount + nextLevelCount); for (Vertex v : currentLevelVertices) { if (nextLevelCount != 0) { GPoint newPoint = new GPoint(horizontalDist * (i + 1) + width / (nextLevelCount + currentLevelCount), currentLevelHeight); vertexPlaces.put(v, newPoint); i += g.getInDegree(v); } else { GPoint newPoint = new GPoint(horizontalDist * (i) + width / (currentLevelCount), currentLevelHeight); vertexPlaces.put(v, newPoint); i++; } } if (!nextLevel.isEmpty()) { visitedVertices.addAll(nextLevel); locateAllVertices(nextLevel, width, currentLevelHeight + 30); } else { return; } } }