Routing multiple edges between two nodes in a parallel fashion |
| Applies to: yFiles for Java 2.8, 2.7, 2.6, 2.5 |
Type: Tips & Tricks
Categories this article belongs to:
| yFiles for Java | > yFiles Layout | > Automatic Graph Layout |
This article provides a demo that shows how to use ParallelEdgeLayouter
to route multiple edges between two nodes.
The following demo code will route multiple edges between two nodes as soon as one drags the adjacent node or creates a new edge. It is meant to show the usage of ParallelEdgeLayouter
The demo source code looks like this:
package demo.view.advanced; import demo.view.DemoBase; import y.base.Edge; import y.base.EdgeCursor; import y.base.EdgeList; import y.base.NodeList; import y.base.Node; import y.layout.LayoutTool; import y.layout.ParallelEdgeLayouter; import y.util.GraphHider; import y.view.Arrow; import y.view.EditMode; import y.view.MoveSelectionMode; import y.view.CreateEdgeMode; import y.view.Graph2D; import javax.swing.JToolBar; import javax.swing.AbstractAction; import java.awt.event.ActionEvent; /** * This class creates a simple graph editor with its own MoveSelectionMode and CreateEdgeMode. Whenever nodes are moved * all adjacent edges that have the same source and target nodes are routed parallel using {@link ParallelEdgeLayouter}. * Whenever an edge is created all edges connecting from/to the same target/source node of this edge will be routed * parallel using {@link ParallelEdgeLayouter}. */ public class ParallelEdgeLayouterDemo extends DemoBase { private ParallelEdgeLayouter parallelEdeLayouter; private final int LINE_DISTANCE = 5; public ParallelEdgeLayouterDemo() { Graph2D graph = view.getGraph2D(); graph.getDefaultEdgeRealizer().setTargetArrow(Arrow.STANDARD); //create parallel edge layouter parallelEdeLayouter = new ParallelEdgeLayouter(); //set a line distance between parallel edges parallelEdeLayouter.setLineDistance(LINE_DISTANCE); // join end points of parallel edges parallelEdeLayouter.setJoinEndsEnabled(true); fillGraphInitially(graph); } private void fillGraphInitially(Graph2D graph) { //create some nodes Node node1 = graph.createNode(100, 100, "1"); Node node2 = graph.createNode(100, 200, "2"); Node node3 = graph.createNode(200, 200, "3"); //create some parallel edges for (int i = 0; i < 4; i++) { if (i % 2 == 0) { graph.createEdge(node1, node2); graph.createEdge(node2, node3); } else { graph.createEdge(node2, node1); graph.createEdge(node3, node2); } } view.fitContent(); view.updateView(); } protected JToolBar createToolBar() { JToolBar toolbar = super.createToolBar(); //add an action to reset all edge paths. toolbar.add(new AbstractAction("Reset Edge Paths") { public void actionPerformed(ActionEvent e) { LayoutTool.resetPaths(view.getGraph2D()); view.updateView(); } }); return toolbar; } protected EditMode createEditMode() { EditMode editMode = super.createEditMode(); //set our own MoveSelectionMode and CreateEdgeMode editMode.setCreateEdgeMode(new ParallelEdgeCreateEdgeMode()); editMode.setMoveSelectionMode(new ParallelEdgeMoveSelectionMode()); return editMode; } /** * Routes the edges of the given list using {@link y.layout.ParallelEdgeLayouter}. * * @param affectedEdges a list of edges that shall be routed in a parallel fashion */ private void routeParallelEdges(EdgeList affectedEdges) { Graph2D graph = view.getGraph2D(); //GraphHider is needed to hide all edges that shall not be routed by ParallelEdgeLayouter GraphHider hider = new GraphHider(graph); for (EdgeCursor edgeCursor = graph.edges(); edgeCursor.ok(); edgeCursor.next()) { Edge edge = edgeCursor.edge(); if (affectedEdges.contains(edge)) { //remove bends from affected edges LayoutTool.resetPath(graph, edge); } else { //hide unaffected edges from layouter hider.hide(edge); } } //do the layout parallelEdeLayouter.doLayout(graph); //unhide unaffected edges hider.unhideAll(); } /** * A ViewMode that handles edge creations. It will reroute all edges that have the same source and target node as the * newly created edge using {@link y.layout.ParallelEdgeLayouter} */ class ParallelEdgeCreateEdgeMode extends CreateEdgeMode { private EdgeList affectedEdges; public ParallelEdgeCreateEdgeMode() { affectedEdges = new EdgeList(); } protected void edgeCreated(Edge edge) { super.edgeCreated(edge); //collect all edges from the created edge's source to the created edge's target node, these must be rerouted for (EdgeCursor edgeCursor = edge.source().outEdges(); edgeCursor.ok(); edgeCursor.next()) { Edge outEdge = edgeCursor.edge(); if (outEdge.target() == edge.target()) { affectedEdges.add(outEdge); } } //collect all edges from the created edge's target to the created edge's source node, these must be rerouted for (EdgeCursor edgeCursor = edge.source().inEdges(); edgeCursor.ok(); edgeCursor.next()) { Edge inEdge = edgeCursor.edge(); if (inEdge.source() == edge.target()) { affectedEdges.add(inEdge); } } routeParallelEdges(affectedEdges); affectedEdges.clear(); } } /** * A ViewMode that handles selection movement. It will reroute edges between selected and unselected nodes using * {@link y.layout.ParallelEdgeLayouter} when the selected nodes are moved. */ class ParallelEdgeMoveSelectionMode extends MoveSelectionMode { private EdgeList affectedEdges; public ParallelEdgeMoveSelectionMode() { affectedEdges = new EdgeList(); } protected void selectionOnMove(double dx, double dy, double x, double y) { super.selectionOnMove(dx, dy, x, y); routeParallelEdges(affectedEdges); } protected void selectionMoveStarted(double x, double y) { super.selectionMoveStarted(x, y); //fill list with edges that shall be routed for (EdgeCursor edgeCursor = getGraph2D().edges(); edgeCursor.ok(); edgeCursor.next()) { Edge edge = edgeCursor.edge(); NodeList movedNodes = getNodesToBeMoved(); //if the source or the target of an edge is moved and the counterpart is not moved, we want to reroute the edge //if the source *and* target is moved, we do *not* want to reroute the edge if (movedNodes.contains(edge.source()) != movedNodes.contains(edge.target())) { affectedEdges.add(edge); } } } protected void selectionMovedAction(double dx, double dy, double x, double y) { super.selectionMovedAction(dx, dy, x, y); routeParallelEdges(affectedEdges); affectedEdges.clear(); } } public static void main(String[] args) { initLnF(); ParallelEdgeLayouterDemo demo = new ParallelEdgeLayouterDemo(); demo.start("ParallelEdgelayouter Demo"); } } |
| Resources: |
| Keywords: | ParallelEdgeLayouter - multiple - route - edge - router |


