Make SingleCycleLayouter use bent edges instead of straight edges
Applies to: yFiles 2.4, yFiles 2.3, yFiles 2.2, yFiles 2.1, yFiles 2.0 print article email article

Type: Tips & Tricks

This article explains how to customize SingleCycleLayouter so that it uses bent edges instead of straight edges.

By default SingleCycleLayouter uses straight edges. If your result should look more circular, you can use the following trick:
Insert a path with length 2 for every edge before layouting. The connection node of this path provides the reference coordinate for the according bend.
The bend itself can be produced with ArcEdgeRealizer.

For an example have a look at the following samplecode:
package demo.view;

import java.awt.geom.Line2D;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import y.base.Edge;
import y.base.Node;
import y.layout.circular.SingleCycleLayouter;
import y.view.ArcEdgeRealizer;
import y.view.Graph2D;

/**
 * Demonstrates how to layout a circular graph with
 * SingleCycleLayouter. The edges of the graph
 * will be represented as arcs.
 */
public class SingleCycleDemo extends ViewActionDemo {
  
  public SingleCycleDemo() {
    Graph2D graph = view.getGraph2D();
    
    //create circular graph
    Node first = graph.createNode();
    Node last = first;
    for(int i = 0; i < 5; i++) {
      Node v = graph.createNode();
      graph.createEdge(last,v);
      last = v;
    }
    graph.createEdge(last, first);
    
    //splitNode construction
    Map splitMap = new HashMap();
    Edge[] edges = graph.getEdgeArray();
    for(int i = 0; i < edges.length; i++) {
      Edge e = edges[i];
      Node splitNode = graph.createNode();
      graph.createEdge(e.source(), splitNode);
      graph.createEdge(splitNode, e.target());
      graph.setSize(splitNode, 1, 1);
      splitMap.put(splitNode, e);
    }
    
    //layout extended graph
    SingleCycleLayouter layouter = new SingleCycleLayouter();
    layouter.doLayout(graph);
    
    
    for(Iterator iter = splitMap.keySet().iterator(); iter.hasNext();) {
      Node splitNode = (Node)iter.next();
      Edge e = (Edge)splitMap.get(splitNode);
      
      //set up an arc edge realizer that uses the splitNode
      //coordinate as its reference point for height calculation
      ArcEdgeRealizer arc = new ArcEdgeRealizer();
      graph.setRealizer(e, arc);
      arc.setArcType(ArcEdgeRealizer.FIXED_HEIGHT);
      Line2D line = new Line2D.Double(
      graph.getCenterX(e.source()),
      graph.getCenterY(e.source()),
      graph.getCenterX(e.target()),
      graph.getCenterY(e.target()));
      float dist = (float)line.ptLineDist(
      graph.getCenterX(splitNode),
      graph.getCenterY(splitNode));
      
      arc.setHeight(-dist);
      //note: use "dist" if cycle orientation is the other way around
      
      //remove temporary splitNodes again
      graph.removeNode(splitNode);
    }
    
    view.fitContent();
    graph.updateViews();
  }
  
  public static void main(String args[]) {
    SingleCycleDemo demo = new SingleCycleDemo();
    demo.startInFrame(demo.getClass().getName());
  }
  
}
Note
To test and compile this samplecode, just download the attached file "SingleCycleDemo" and copy it to <yFilesDir>/demo/view.

Keywords: SingleCycleLayouter - ArcEdgeRealizer - edges - bent edges - straight edges - circular

Provide feedback:
How useful was this article?    less 1 2 3 4 5 more
Email address (optional):
COPYRIGHT © 2008 yWorks · ALL RIGHTS RESERVED imprint | top | home