Make SingleCycleLayouter use bent edges instead of straight edges
Tips & TricksSummary
This article explains how to customize SingleCycleLayouter so that it uses bent edges instead of straight edges.
Description
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.EventQueue;
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) {
EventQueue.invokeLater(new Runnable() {
public void run() {
initLnF();
new SingleCycleDemo().start("Single Cycle Demo");
}
});
}
}
Resources
Categories this article belongs to:
yFiles for Java > yFiles Layout > Automatic Graph Layout > Circular Layout
yFiles for Java > yFiles Viewer > Displaying and Editing Graphs > Bringing Graph Elements to Life: The Realizer Concept
Applies to:
yFiles for Java 2: 2.7, 2.8, 2.9, 2.10, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18
Keywords:
SingleCycleLayouter - ArcEdgeRealizer - edges - bent edges - straight edges - circular - arc