package graph; import java.awt.Color; import java.util.ArrayList; import org.eclipse.elk.graph.ElkConnectableShape; import org.eclipse.elk.graph.ElkEdge; import org.eclipse.elk.graph.ElkNode; import org.eclipse.emf.common.util.EList; import bk.LayoutType; import view.NodeView; /** * Die Implementation eines Knotens in einem Layered Graph. Implementiert {@link LayeredGraphNode}. * * @author kolja * */ public class LayeredNode implements LayeredGraphNode { private ElkNode original; private LayeredGraphNode parent; private boolean dummy; private class LayoutInfo { private double x; private double y; private double w; private double h; private Color color; private boolean selected; private boolean xUndef; // Block Calculation private LayeredGraphNode align; private LayeredGraphNode root; // HorizontalCompaction private LayeredGraphNode sink; private double shift; private NodeView view; } private class CombinedLayoutInfo { private double x; private double y; private double w; private double h; private boolean selected; private NodeView view; } private LayoutInfo[] layouts; private CombinedLayoutInfo combined; private String name; private boolean mouseOver; // for subgraph in this node private ArrayList edges; private ArrayList nodes; private ArrayList> layers; /** * Konvertiert einen Graph aus dem Elk format in einen Graph, der mehr Informationen enth�lt * * @param n * Der Graph, welcher konvertiert werden soll * @return Ein layered Graph, welcher im wesentlichen ein Wrapper f�r den urspr�nglichen Graphen ist */ public static LayeredGraphNode convertToLayeredGraph(ElkNode n) { LayeredNode ln = new LayeredNode(n, null); for (ElkNode node : n.getChildren()) ln.addNode(convertToLayeredGraph(node)); for (ElkEdge edge : n.getContainedEdges()) { // TODO n.getProperty(Properties.LAYERPOS) reads position of node n in his layer ArrayList sources = new ArrayList<>(); ArrayList targets = new ArrayList<>(); EList s = edge.getSources(); EList t = edge.getTargets(); for (ElkConnectableShape shape : s) sources.add(ln.findNodeFromOriginal(shape)); for (ElkConnectableShape shape : t) targets.add(ln.findNodeFromOriginal(shape)); ln.createEdge(edge, sources, targets); } return ln; } /** * creates a {@link LayeredNode} from an {@link ElkNode}. * @param original the original {@link ElkNode}. * @param parent the graph containing the edge. */ public LayeredNode(ElkNode original, LayeredGraphNode parent) { this.original = original; this.parent = parent; edges = new ArrayList<>(); nodes = new ArrayList<>(); layers = new ArrayList<>(); layouts = new LayoutInfo[ 4 ]; for( int i = 0; i < 4; i++ ) layouts[ i ] = new LayoutInfo(); int index = 0; for( LayoutInfo l : layouts ) { if( original != null ) { l.x = original.getX(); l.y = original.getX(); l.w = original.getWidth(); l.h = original.getHeight(); } l.align = this; l.root = this; l.sink = this; if( index == 0 || index == 2 ) l.shift = Double.POSITIVE_INFINITY; else l.shift = Double.NEGATIVE_INFINITY; l.xUndef = true; index++; } dummy = false; combined = new CombinedLayoutInfo(); if (original != null) { combined.x = original.getX(); combined.y = original.getX(); combined.w = original.getWidth(); combined.h = original.getHeight(); } combined.selected = false; setMouseOver(false); } public void setMouseOver( boolean over ) { mouseOver = over; } public boolean isMouseOver() { return mouseOver; } /** * associates the node with an {@link NodeView} in order to display it in the given layout. * @param view the view * @param layout the layout */ public void setView(NodeView view, LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].view = view; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].view = view; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].view = view; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].view = view; if (layout == LayoutType.COMBINED) this.combined.view = view; } /** * returns the {@link NodeView} of this node in the given layout. * @param layout the layout * @return the view */ public NodeView getView(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return layouts[0].view; if (layout == LayoutType.RIGHTMOST_UPPER) return layouts[1].view; if (layout == LayoutType.LEFTMOST_LOWER) return layouts[2].view; if (layout == LayoutType.RIGHTMOST_LOWER) return layouts[3].view; if (layout == LayoutType.COMBINED) return combined.view; return null; } @Override public void setDummyNode(boolean dummy) { this.dummy = dummy; } @Override public boolean isDummyNode() { return dummy; } @Override public void setShift(double shift, LayoutType layout) { if (layout == null) { this.layouts[0].shift = shift; this.layouts[1].shift = shift; this.layouts[2].shift = shift; this.layouts[3].shift = shift; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].shift = shift; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].shift = shift; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].shift = shift; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].shift = shift; } @Override public double getShift(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].shift; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].shift; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].shift; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].shift; return 0; } @Override public void setSink(LayeredGraphNode sink, LayoutType layout) { if (layout == null) { this.layouts[0].sink = sink; this.layouts[1].sink = sink; this.layouts[2].sink = sink; this.layouts[3].sink = sink; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].sink = sink; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].sink = sink; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].sink = sink; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].sink = sink; } @Override public LayeredGraphNode getSink(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].sink; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].sink; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].sink; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].sink; return null; } @Override public boolean isXUndefined(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].xUndef; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].xUndef; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].xUndef; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].xUndef; return true; } @Override public void setAlign(LayeredGraphNode align, LayoutType layout) { if (layout == null) { this.layouts[0].align = align; this.layouts[1].align = align; this.layouts[2].align = align; this.layouts[3].align = align; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].align = align; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].align = align; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].align = align; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].align = align; } @Override public LayeredGraphNode getAlign(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].align; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].align; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].align; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].align; return null; } @Override public void setRoot(LayeredGraphNode root, LayoutType layout) { if (layout == null) { this.layouts[0].root = root; this.layouts[1].root = root; this.layouts[2].root = root; this.layouts[3].root = root; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].root = root; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].root = root; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].root = root; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].root = root; } @Override public LayeredGraphNode getRoot(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].root; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].root; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].root; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].root; return null; } @Override public void setSelected(LayoutType layout) { if (layout == null) { this.layouts[0].selected = true; this.layouts[1].selected = true; this.layouts[2].selected = true; this.layouts[3].selected = true; combined.selected = true; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].selected = true; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].selected = true; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].selected = true; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].selected = true; if (layout == LayoutType.COMBINED) combined.selected = true; } @Override public void unselectGraph() { for (LayeredGraphNode n : nodes) { n.unselectGraph(); } this.layouts[0].selected = false; this.layouts[1].selected = false; this.layouts[2].selected = false; this.layouts[3].selected = false; combined.selected = false; } @Override public boolean isSelected(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) { return layouts[0].selected; } if (layout == LayoutType.RIGHTMOST_UPPER) { return layouts[1].selected; } if (layout == LayoutType.LEFTMOST_LOWER) { return layouts[2].selected; } if (layout == LayoutType.RIGHTMOST_LOWER) { return layouts[3].selected; } if (layout == LayoutType.COMBINED) { return combined.selected; } return false; } @Override public void setColor( Color c, LayoutType layout ) { if( layout == null ) { this.layouts[ 0 ].color = c; this.layouts[ 1 ].color = c; this.layouts[ 2 ].color = c; this.layouts[ 3 ].color = c; } if( layout == LayoutType.LEFTMOST_UPPER ) this.layouts[ 0 ].color = c; if( layout == LayoutType.RIGHTMOST_UPPER ) this.layouts[ 1 ].color = c; if( layout == LayoutType.LEFTMOST_LOWER ) this.layouts[ 2 ].color = c; if( layout == LayoutType.RIGHTMOST_LOWER ) this.layouts[ 3 ].color = c; } private int calcClassSize(LayeredGraphNode sink, LayoutType layout) { if (parent == null) return 1; int ret = 0; for (LayeredGraphNode n : parent.getContainedNodes()) { if (n.getRoot(layout).getSink(layout) == sink) ret++; } return ret; } @Override public Color getClassColor(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].sink == this && calcClassSize(this, layout) == 1) return Color.LIGHT_GRAY; if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].sink == this) return this.layouts[0].color; else if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].sink.getClassColor(layout); if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].sink == this && calcClassSize(this, layout) == 1) return Color.LIGHT_GRAY; if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].sink == this) return this.layouts[1].color; else if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].sink.getClassColor(layout); if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].sink == this && calcClassSize(this, layout) == 1) return Color.LIGHT_GRAY; if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].sink == this) return this.layouts[2].color; else if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].sink.getClassColor(layout); if (layout == LayoutType.RIGHTMOST_LOWER && this.layouts[3].sink == this && calcClassSize(this, layout) == 1) return Color.LIGHT_GRAY; if( layout == LayoutType.RIGHTMOST_LOWER && this.layouts[ 3 ].sink == this ) return this.layouts[ 3 ].color; else if( layout == LayoutType.RIGHTMOST_LOWER ) return this.layouts[ 3 ].sink.getClassColor( layout ); if( layout == LayoutType.COMBINED ) return Color.LIGHT_GRAY; return null; } @Override public Color getColor( LayoutType layout ) { if( layout == null ) return this.layouts[ 0 ].color; if( layout == LayoutType.LEFTMOST_UPPER && this.layouts[ 0 ].root == this && this.layouts[ 0 ].align == this ) return Color.LIGHT_GRAY; if (layout == LayoutType.LEFTMOST_UPPER && this.layouts[0].root != this) return this.layouts[0].root.getColor(layout); if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].color; if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].root == this && this.layouts[1].align == this) return Color.LIGHT_GRAY; if (layout == LayoutType.RIGHTMOST_UPPER && this.layouts[1].root != this) return this.layouts[1].root.getColor(layout); if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].color; if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].root == this && this.layouts[2].align == this) return Color.LIGHT_GRAY; if (layout == LayoutType.LEFTMOST_LOWER && this.layouts[2].root != this) return this.layouts[2].root.getColor(layout); if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].color; if (layout == LayoutType.RIGHTMOST_LOWER && this.layouts[3].root == this && this.layouts[3].align == this) return Color.LIGHT_GRAY; if( layout == LayoutType.RIGHTMOST_LOWER && this.layouts[ 3 ].root != this ) return this.layouts[ 3 ].root.getColor( layout ); if( layout == LayoutType.RIGHTMOST_LOWER ) return this.layouts[ 3 ].color; if( layout == LayoutType.COMBINED ) return Color.LIGHT_GRAY; return null; } @Override public void setName(String n) { name = n; } @Override public ElkNode getOriginalNode() { return original; } @Override public void remove() { parent.removeNode(this); } @Override public LayeredGraphNode parent() { return parent; } @Override public void setLayer(int index) { parent.setNodeLayer(this, index); } @Override public int getLayer() { return parent.getNodeLayer(this); } @Override public void setX(double x, boolean def, LayoutType layout) { if (layout == null) { layouts[0].x = x; layouts[1].x = x; layouts[2].x = x; layouts[3].x = x; combined.x = x; } if (layout == LayoutType.LEFTMOST_UPPER) { layouts[0].xUndef = !def; layouts[0].x = x; } if (layout == LayoutType.RIGHTMOST_UPPER) { layouts[1].xUndef = !def; layouts[1].x = x; } if (layout == LayoutType.LEFTMOST_LOWER) { layouts[2].xUndef = !def; layouts[2].x = x; } if (layout == LayoutType.RIGHTMOST_LOWER) { layouts[3].xUndef = !def; layouts[3].x = x; } if (layout == LayoutType.COMBINED) combined.x = x; } @Override public void setY(double y, LayoutType layout) { if (layout == null) { layouts[0].y = y; layouts[1].y = y; layouts[2].y = y; layouts[3].y = y; combined.y = y; } if (layout == LayoutType.LEFTMOST_UPPER) layouts[0].y = y; if (layout == LayoutType.RIGHTMOST_UPPER) layouts[1].y = y; if (layout == LayoutType.LEFTMOST_LOWER) layouts[2].y = y; if (layout == LayoutType.RIGHTMOST_LOWER) layouts[3].y = y; if (layout == LayoutType.COMBINED) combined.y = y; } @Override public double getX(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].x; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].x; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].x; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].x; if (layout == LayoutType.COMBINED) return combined.x; return 0; } @Override public double getY(LayoutType layout) { if (layout == LayoutType.LEFTMOST_UPPER) return this.layouts[0].y; if (layout == LayoutType.RIGHTMOST_UPPER) return this.layouts[1].y; if (layout == LayoutType.LEFTMOST_LOWER) return this.layouts[2].y; if (layout == LayoutType.RIGHTMOST_LOWER) return this.layouts[3].y; if (layout == LayoutType.COMBINED) return combined.y; return 0; } @Override public double getWidth(LayoutType layout) { if (nodes.size() > 0) { double max = 0; double min = Double.POSITIVE_INFINITY; for( LayeredGraphNode n : nodes ) { if( max < n.getX(layout) + n.getWidth(layout) ) max = n.getX(layout) + n.getWidth(layout); min = Math.min( n.getX(layout), min); } if (layout == LayoutType.LEFTMOST_UPPER) return Math.max(max - min, layouts[0].w); if (layout == LayoutType.RIGHTMOST_UPPER) return Math.max(max - min, layouts[1].w); if (layout == LayoutType.LEFTMOST_LOWER) return Math.max(max - min, layouts[2].w); if (layout == LayoutType.RIGHTMOST_LOWER) return Math.max(max - min, layouts[3].w); if (layout == LayoutType.COMBINED) return Math.max(max - min, combined.w); } if (layout == LayoutType.LEFTMOST_UPPER) return layouts[0].w; if (layout == LayoutType.RIGHTMOST_UPPER) return layouts[1].w; if (layout == LayoutType.LEFTMOST_LOWER) return layouts[2].w; if (layout == LayoutType.RIGHTMOST_LOWER) return layouts[3].w; if (layout == LayoutType.COMBINED) return combined.w; return 0; } @Override public double getHeight( LayoutType layout ) { if( nodes.size() > 0 ) { double max = 0; for( LayeredGraphNode n : nodes ) { if( max < n.getY(layout) + n.getHeight(layout) ) max = n.getY(layout) + n.getHeight(layout); } if( layout == LayoutType.LEFTMOST_UPPER ) return Math.max( max, layouts[ 0 ].h ); if( layout == LayoutType.RIGHTMOST_UPPER ) return Math.max( max, layouts[ 1 ].h ); if( layout == LayoutType.LEFTMOST_LOWER ) return Math.max( max, layouts[ 2 ].h ); if( layout == LayoutType.RIGHTMOST_LOWER ) return Math.max( max, layouts[ 3 ].h ); if( layout == LayoutType.COMBINED ) return Math.max( max, combined.h ); } if (layout == LayoutType.LEFTMOST_UPPER) return layouts[0].h; if (layout == LayoutType.RIGHTMOST_UPPER) return layouts[1].h; if (layout == LayoutType.LEFTMOST_LOWER) return layouts[2].h; if (layout == LayoutType.RIGHTMOST_LOWER) return layouts[3].h; if (layout == LayoutType.COMBINED) return combined.h; return 0; } @Override public void setWidth(double w, LayoutType layout) { if (layout == null) { this.layouts[0].w = w; this.layouts[1].w = w; this.layouts[2].w = w; this.layouts[3].w = w; combined.w = w; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].w = w; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].w = w; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].w = w; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].w = w; if (layout == LayoutType.COMBINED) combined.w = w; } @Override public void setHeight(double h, LayoutType layout) { if (layout == null) { this.layouts[0].h = h; this.layouts[1].h = h; this.layouts[2].h = h; this.layouts[3].h = h; combined.h = h; } if (layout == LayoutType.LEFTMOST_UPPER) this.layouts[0].h = h; if (layout == LayoutType.RIGHTMOST_UPPER) this.layouts[1].h = h; if (layout == LayoutType.LEFTMOST_LOWER) this.layouts[2].h = h; if (layout == LayoutType.RIGHTMOST_LOWER) this.layouts[3].h = h; if (layout == LayoutType.COMBINED) combined.h = h; } @Override public void removeEdge(LayeredGraphEdge e) { edges.remove(e); } @Override public void removeNode(LayeredGraphNode n) { for (LayeredGraphEdge e : n.getIncomingEdges()) e.remove(); for (LayeredGraphEdge e : n.getOutgoingEdges()) e.remove(); nodes.remove(n); for (ArrayList l : layers) { l.remove(n); } } @Override public void setNodeLayer(LayeredGraphNode n, int index) { while (index >= layers.size()) layers.add(new ArrayList<>()); int old = n.getLayer(); if (old >= 0) layers.get(old).remove(n); layers.get(index).add(n); } @Override public void setOrderedLayer(ArrayList indizes, int layerIndex) { ArrayList l2 = layers.get(layerIndex); ArrayList result = new ArrayList(); while (indizes.size() > 0) { int mIndex = 0; double min = indizes.get(0); for (int i = 1; i < indizes.size(); i++) { if (min > indizes.get(i)) { mIndex = i; min = indizes.get(i); } } result.add(l2.get(mIndex)); l2.remove(mIndex); indizes.remove(mIndex); } layers.set(layerIndex, result); } @Override public ArrayList getOutgoingEdges() { return parent.getOutgoingEdges(this); } @Override public ArrayList getSortedOutgoingEdges() { return parent.getSortedOutgoingEdges(this); } @Override public ArrayList getIncomingEdges() { return parent.getIncomingEdges(this); } @Override public ArrayList getSortedIncomingEdges() { return parent.getSortedIncomingEdges(this); } @Override public ArrayList getContainedEdges() { return edges; } @Override public ArrayList getContainedNodes() { return nodes; } @Override public ArrayList getSortedContainedNodes() { ArrayList result = new ArrayList<>(); for (ArrayList l : layers) { result.addAll(l); } return result; } @Override public ArrayList> getContainedLayers() { return layers; } @Override public int getNodeLayer(LayeredGraphNode n) { for (int i = 0; i < layers.size(); i++) { if (layers.get(i).contains(n)) return i; } return -1; } @Override public ArrayList getOutgoingEdges(LayeredGraphNode n) { ArrayList result = new ArrayList<>(); for( LayeredGraphEdge e : edges ) { if( e.getSources().contains( n ) && !result.contains( e ) ) result.add( e ); } return result; } @Override public ArrayList getIncomingEdges(LayeredGraphNode n) { ArrayList result = new ArrayList<>(); for( LayeredGraphEdge e : edges ) { if( e.getTargets().contains( n ) && !result.contains( e ) ) result.add( e ); } return result; } @Override public ArrayList getSortedOutgoingEdges(LayeredGraphNode n) { ArrayList result = new ArrayList<>(); if( n.getLayer() + 1 >= layers.size() ) return result; ArrayList< LayeredGraphEdge > unsorted = getOutgoingEdges( n ); for( LayeredGraphNode node : layers.get( n.getLayer() + 1 ) ) { for( LayeredGraphEdge e : unsorted ) { if( e.getTargets().contains( node ) && !result.contains( e ) ) result.add( e ); } } return result; } @Override public ArrayList getSortedIncomingEdges(LayeredGraphNode n) { ArrayList result = new ArrayList<>(); if( n.getLayer() - 1 < 0 ) return result; ArrayList< LayeredGraphEdge > unsorted = getIncomingEdges( n ); for( LayeredGraphNode node : layers.get( n.getLayer() - 1 ) ) { for( LayeredGraphEdge e : unsorted ) { if( e.getSources().contains( node ) && !result.contains( e ) ) result.add( e ); } } return result; } @Override public LayeredGraphEdge findEdgeBetween( LayeredGraphNode source, LayeredGraphNode target ) { for( LayeredGraphEdge e : edges ) { if( e.getSources().contains( source ) && e.getTargets().contains( target ) ) return e; } return null; } @Override public LayeredGraphNode createNode(ElkNode original) { LayeredGraphNode n = new LayeredNode(original, this); nodes.add(n); return n; } @Override public LayeredGraphEdge createEdge(ElkEdge original, ArrayList sources, ArrayList targets) { LayeredGraphEdge e = new LayeredEdge(original, sources, targets, this); edges.add(e); return e; } @Override public LayeredGraphEdge createSimpleEdge(ElkEdge original, LayeredGraphNode source, LayeredGraphNode target) { ArrayList sources = new ArrayList<>(); ArrayList targets = new ArrayList<>(); sources.add(source); targets.add(target); LayeredGraphEdge e = new LayeredEdge(original, sources, targets, this); edges.add(e); return e; } @Override public LayeredGraphEdge findEdgeFromOriginal(Object original) { for (LayeredGraphEdge e : edges) { if (e.getOriginalEdge() == original) return e; } return null; } @Override public LayeredGraphNode findNodeFromOriginal(Object original) { for (LayeredGraphNode n : nodes) { if (n.getOriginalNode() == original) return n; } return null; } @Override public LayeredGraphNode findNodeByName(String name) { for (LayeredGraphNode n : nodes) { if (name != null && n.toString().equals(name)) return n; } return null; } @Override public void addNode(LayeredGraphNode n) { nodes.add(n); n.setParent(this); } @Override public void addEdge(LayeredGraphEdge e) { edges.add(e); e.setGraph(this); } @Override public void setParent(LayeredGraphNode parent) { this.parent = parent; } @Override public String toString() { if( name != null ) return name; return "unnamed node"; } }