Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Initialize the GraphComponent and place it in the div with CSS selector #graphComponent
- graphComponent = new yfiles.view.GraphComponent('#graphComponent')
- // conveniently store a reference to the graph that is displayed
- graph = graphComponent.graph;
- graph.edgeDefaults.style = new yfiles.styles.PolylineEdgeStyle({stroke:"2px green", smoothingLength:20, targetArrow:"green default"})
- let styles = [];
- styles.push(new yfiles.styles.PolylineEdgeStyle({stroke:"4px blue", smoothingLength:20, targetArrow:"blue default"}));
- styles.push(new yfiles.styles.PolylineEdgeStyle({stroke:"2px gold", smoothingLength:20, targetArrow:"gold default"}));
- styles.push(new yfiles.styles.PolylineEdgeStyle({stroke:"2px red", smoothingLength:20, targetArrow:"red default"}));
- styles.push(new yfiles.styles.PolylineEdgeStyle({stroke:"2px gray", smoothingLength:20, targetArrow:"gray default"}));
- graph.nodeDefaults.style = new yfiles.styles.ShapeNodeStyle({shape:"ellipse", fill:"white", stroke:"2px blue"})
- // here we define the routes...
- let routes = [
- [1,2,3,4,5],
- [1,7,8,2,3,9,10,4,5,6],
- [1,7,13,7,8,2,3,9,10,4,5,6],
- [1,7,11,12,4,5,6],
- ];
- let nodes = {};
- // let's create the graph
- routes.forEach((route,routeIndex) => {
- // assign the lane to the route index - in case we disable optimization this will be the exact lane..
- let lane = routeIndex;
- // interconnect all nodes for a route
- let previous = null;
- route.forEach(element =>{
- let newNode;
- // see whether this is a new node or an existing one
- if (!(newNode = nodes[element])){
- // choose a row for the element: 0 for start nodes, 1 for center nodes, 2 for end nodes
- let row = element === 1 ? 0 : element === 6 ? 2 : 1;
- // create a new node and assign the tag data to it
- newNode = nodes[element] = graph.createNode({labels:[String(element)], tag:{element,routeIndex,lane,row}})}
- // for all but the first node
- if (previous){
- // see if there already is a connection between the two
- if (!graph.getEdge(previous, newNode)){
- // and if there isn't create one and tag it
- graph.createEdge({source: previous, target: newNode, tag: {routeIndex, lane}, style:styles[routeIndex % styles.length]});
- }
- }
- // update chain
- previous = newNode;
- });
- });
- // configure the layout
- let layout = new yfiles.hierarchic.HierarchicLayout();
- // we want rounded corners so we start with 45 degree routing
- layout.edgeLayoutDescriptor.routingStyle = new yfiles.hierarchic.RoutingStyle(yfiles.hierarchic.EdgeRoutingStyle.OCTILINEAR);
- // lets add some more constraints
- let layoutData = new yfiles.hierarchic.HierarchicLayoutData();
- // tell it which edges to align - we align edges if they connect two nodes within a lane
- layoutData.criticalEdgePriorities.delegate = edge => edge.sourceNode.tag.lane === edge.targetNode.tag.lane ? 1 : 0;
- // optionally treat edges between lanes as undirected - yields more compact results
- //layoutData.edgeDirectedness.delegate = edge => edge.sourceNode.tag.lane !== edge.targetNode.tag.lane ? 0 : 1;
- // distribute the graph in three rows: start nodes, center nodes, end nodes
- // and each node in its lane/column
- layoutData.partitionGridData.grid = new yfiles.layout.PartitionGrid(3, 4)
- layoutData.partitionGridData.cellIds.contextDelegate = (node, grid) => {
- return grid.createCellId(node.tag.row, node.tag.lane)
- }
- // let the algorithm find a nice column ordering
- layoutData.partitionGridData.grid.optimizeColumnOrder = true;
- // configure where edges should enter/leave the nodes
- layoutData.sourcePortConstraints.delegate = edge => {
- // see if we cross a lane border
- let routeDelta = edge.sourceNode.tag.lane - edge.targetNode.tag.lane;
- if (routeDelta > 0){
- // and if so start at the west
- return yfiles.layout.PortConstraint.create("WEST", false);
- } else if (routeDelta < 0){
- // or east respectively
- return yfiles.layout.PortConstraint.create("EAST", false);
- }
- // all other edges should use default behavior
- return null;
- };
- // and the same for the target side
- layoutData.targetPortConstraints.delegate = edge => {
- let routeDelta = edge.sourceNode.tag.lane - edge.targetNode.tag.lane;
- if (routeDelta < 0){
- return yfiles.layout.PortConstraint.create("WEST", false);
- } else if (routeDelta > 0){
- return yfiles.layout.PortConstraint.create("EAST", false);
- }
- return null;
- };
- // now run the layout and morph the animation for one second
- graphComponent.morphLayout({ layout, morphDuration: '1s', layoutData }).catch(console.log);
Add Comment
Please, Sign In to add comment