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 { public double x; public double y; public double w; public double h; public Color color; public boolean selected; public boolean xUndef; // Block Calculation public LayeredGraphNode align; public LayeredGraphNode root; // Compaction public LayeredGraphNode sink; public double shift; private NodeView view; } private class CombinedLayoutInfo { public double x; public double y; public double w; public double h; public Color color; public boolean selected; private NodeView view; } private LayoutInfo[] layouts; private CombinedLayoutInfo combined; private String name; // for subgraph in this node private ArrayList< LayeredGraphEdge > edges; private ArrayList< LayeredGraphNode > nodes; private ArrayList< ArrayList< LayeredGraphNode > > 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< LayeredGraphNode > sources = new ArrayList<>(); ArrayList< LayeredGraphNode > 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; } 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.color = null; combined.selected = false; } public void setView( NodeView view, LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].view = view; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].view = view; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].view = view; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].view = view; if( layout == LayoutType.COMBINED ) this.combined.view = view; } public NodeView getView( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return layouts[ 0 ].view; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return layouts[ 1 ].view; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return layouts[ 2 ].view; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].shift = shift; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].shift = shift; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].shift = shift; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].shift = shift; } @Override public double getShift( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].shift; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].shift; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].shift; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].sink = sink; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].sink = sink; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].sink = sink; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].sink = sink; } @Override public LayeredGraphNode getSink( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].sink; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].sink; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].sink; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return this.layouts[ 3 ].sink; return null; } @Override public boolean isXUndefined( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].xUndef; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].xUndef; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].xUndef; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].align = align; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].align = align; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].align = align; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].align = align; } @Override public LayeredGraphNode getAlign( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].align; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].align; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].align; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].root = root; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].root = root; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].root = root; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].root = root; } @Override public LayeredGraphNode getRoot( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].root; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].root; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].root; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].selected = true; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].selected = true; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].selected = true; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) { boolean tmp = layouts[ 0 ].selected; layouts[ 0 ].selected = false; return tmp; } if( layout == LayoutType.TOP_BOTTOM_RIGHT ) { boolean tmp = layouts[ 1 ].selected; layouts[ 1 ].selected = false; return tmp; } if( layout == LayoutType.BOTTOM_TOP_LEFT ) { boolean tmp = layouts[ 2 ].selected; layouts[ 2 ].selected = false; return tmp; } if( layout == LayoutType.BOTTOM_TOP_RIGHT ) { boolean tmp = layouts[ 3 ].selected; layouts[ 3 ].selected = false; return tmp; } if( layout == LayoutType.COMBINED ) { boolean tmp = combined.selected; combined.selected = false; return tmp; } 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; combined.color = c; } if( layout == LayoutType.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].color = c; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].color = c; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].color = c; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) this.layouts[ 3 ].color = c; if( layout == LayoutType.COMBINED ) combined.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.TOP_BOTTOM_LEFT && this.layouts[ 0 ].sink == this && calcClassSize( this, layout ) == 1 ) return Color.LIGHT_GRAY; if( layout == LayoutType.TOP_BOTTOM_LEFT && this.layouts[ 0 ].sink == this ) return this.layouts[ 0 ].color; else if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].sink.getClassColor( layout ); if( layout == LayoutType.TOP_BOTTOM_RIGHT && this.layouts[ 1 ].sink == this && calcClassSize( this, layout ) == 1 ) return Color.LIGHT_GRAY; if( layout == LayoutType.TOP_BOTTOM_RIGHT && this.layouts[ 1 ].sink == this ) return this.layouts[ 1 ].color; else if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].sink.getClassColor( layout ); if( layout == LayoutType.BOTTOM_TOP_LEFT && this.layouts[ 2 ].sink == this && calcClassSize( this, layout ) == 1 ) return Color.LIGHT_GRAY; if( layout == LayoutType.BOTTOM_TOP_LEFT && this.layouts[ 2 ].sink == this ) return this.layouts[ 2 ].color; else if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].sink.getClassColor( layout ); if( layout == LayoutType.BOTTOM_TOP_RIGHT && this.layouts[ 3 ].sink == this && calcClassSize( this, layout ) == 1 ) return Color.LIGHT_GRAY; if( layout == LayoutType.BOTTOM_TOP_RIGHT && this.layouts[ 3 ].sink == this ) return this.layouts[ 3 ].color; else if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return this.layouts[ 3 ].sink.getClassColor( layout ); if( layout == LayoutType.COMBINED ) return combined.color; return null; } @Override public Color getColor( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT && this.layouts[ 0 ].root == this && this.layouts[ 0 ].align == this ) return Color.LIGHT_GRAY; if( layout == LayoutType.TOP_BOTTOM_LEFT && this.layouts[ 0 ].root != this ) return this.layouts[ 0 ].root.getColor( layout ); if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].color; if( layout == LayoutType.TOP_BOTTOM_RIGHT && this.layouts[ 1 ].root == this && this.layouts[ 1 ].align == this ) return Color.LIGHT_GRAY; if( layout == LayoutType.TOP_BOTTOM_RIGHT && this.layouts[ 1 ].root != this ) return this.layouts[ 1 ].root.getColor( layout ); if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].color; if( layout == LayoutType.BOTTOM_TOP_LEFT && this.layouts[ 2 ].root == this && this.layouts[ 2 ].align == this ) return Color.LIGHT_GRAY; if( layout == LayoutType.BOTTOM_TOP_LEFT && this.layouts[ 2 ].root != this ) return this.layouts[ 2 ].root.getColor( layout ); if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].color; if( layout == LayoutType.BOTTOM_TOP_RIGHT && this.layouts[ 3 ].root == this && this.layouts[ 3 ].align == this ) return Color.LIGHT_GRAY; if( layout == LayoutType.BOTTOM_TOP_RIGHT && this.layouts[ 3 ].root != this ) return this.layouts[ 3 ].root.getColor( layout ); if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return this.layouts[ 3 ].color; if( layout == LayoutType.COMBINED ) return combined.color; return null; } @Override public void setName( String n ) { name = n; } @Override public String getName() { return name; } @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.TOP_BOTTOM_LEFT ) { layouts[ 0 ].xUndef = !def; layouts[ 0 ].x = x; } if( layout == LayoutType.TOP_BOTTOM_RIGHT ) { layouts[ 1 ].xUndef = !def; layouts[ 1 ].x = x; } if( layout == LayoutType.BOTTOM_TOP_LEFT ) { layouts[ 2 ].xUndef = !def; layouts[ 2 ].x = x; } if( layout == LayoutType.BOTTOM_TOP_RIGHT ) { 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.TOP_BOTTOM_LEFT ) layouts[ 0 ].y = y; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) layouts[ 1 ].y = y; if( layout == LayoutType.BOTTOM_TOP_LEFT ) layouts[ 2 ].y = y; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) layouts[ 3 ].y = y; if( layout == LayoutType.COMBINED ) combined.y = y; } @Override public double getX( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].x; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].x; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].x; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return this.layouts[ 3 ].x; if( layout == LayoutType.COMBINED ) return combined.x; return 0; } @Override public double getY( LayoutType layout ) { if( layout == LayoutType.TOP_BOTTOM_LEFT ) return this.layouts[ 0 ].y; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return this.layouts[ 1 ].y; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return this.layouts[ 2 ].y; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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) + 50 ) max = n.getX(layout) + n.getWidth(layout) + 50; min = Math.min( n.getX(layout), min); } if( layout == LayoutType.TOP_BOTTOM_LEFT ) return Math.max( max - min, layouts[ 0 ].w ); if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return Math.max( max - min, layouts[ 1 ].w ); if( layout == LayoutType.BOTTOM_TOP_LEFT ) return Math.max( max - min, layouts[ 2 ].w ); if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return Math.max( max - min, layouts[ 3 ].w ); if( layout == LayoutType.COMBINED ) return Math.max( max - min, combined.w ); } if( layout == LayoutType.TOP_BOTTOM_LEFT ) return layouts[ 0 ].w; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return layouts[ 1 ].w; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return layouts[ 2 ].w; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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) + 50 ) max = n.getY(layout) + n.getHeight(layout) + 50; } if( layout == LayoutType.TOP_BOTTOM_LEFT ) return Math.max( max, layouts[ 0 ].h ); if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return Math.max( max, layouts[ 1 ].h ); if( layout == LayoutType.BOTTOM_TOP_LEFT ) return Math.max( max, layouts[ 2 ].h ); if( layout == LayoutType.BOTTOM_TOP_RIGHT ) return Math.max( max, layouts[ 3 ].h ); if( layout == LayoutType.COMBINED ) return Math.max( max, combined.h ); } if( layout == LayoutType.TOP_BOTTOM_LEFT ) return layouts[ 0 ].h; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) return layouts[ 1 ].h; if( layout == LayoutType.BOTTOM_TOP_LEFT ) return layouts[ 2 ].h; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].w = w; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].w = w; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].w = w; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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.TOP_BOTTOM_LEFT ) this.layouts[ 0 ].h = h; if( layout == LayoutType.TOP_BOTTOM_RIGHT ) this.layouts[ 1 ].h = h; if( layout == LayoutType.BOTTOM_TOP_LEFT ) this.layouts[ 2 ].h = h; if( layout == LayoutType.BOTTOM_TOP_RIGHT ) 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< LayeredGraphNode > getSortedContainedNodes() { ArrayList< LayeredGraphNode > 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( n.getName() != null && name != null && n.getName().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"; } }