package com.mxgraph.layout;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxGraph;
import java.util.ArrayList;
import java.util.List;
public class mxCircleLayout extends mxGraphLayout {
/**
* Integer specifying the size of the radius. Default is 100.
*/
protected double radius;
/**
* Boolean specifying if the circle should be moved to the top,
* left corner specified by x0 and y0. Default is false.
*/
protected boolean moveCircle = true;
/**
* Integer specifying the left coordinate of the circle.
* Default is 0.
*/
protected double x0 = 0;
/**
* Integer specifying the top coordinate of the circle.
* Default is 0.
*/
protected double y0 = 0;
/**
* Specifies if all edge points of traversed edges should be removed.
* Default is true.
*/
protected boolean resetEdges = false;
/**
* Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
* modified by the result. Default is true.
*/
protected boolean disableEdgeStyle = true;
/**
* Constructs a new stack layout layout for the specified graph,
* spacing, orientation and offset.
*/
public mxCircleLayout(mxGraph graph) {
this(graph, 100);
}
/**
* Constructs a new stack layout layout for the specified graph,
* spacing, orientation and offset.
*/
public mxCircleLayout(mxGraph graph, double radius) {
super(graph);
this.radius = radius;
}
/**
* @return the radius
*/
public double getRadius() {
return radius;
}
/**
* @param radius the radius to set
*/
public void setRadius(double radius) {
this.radius = radius;
}
/**
* @return the moveCircle
*/
public boolean isMoveCircle() {
return moveCircle;
}
/**
* @param moveCircle the moveCircle to set
*/
public void setMoveCircle(boolean moveCircle) {
this.moveCircle = moveCircle;
}
/**
* @return the x0
*/
public double getX0() {
return x0;
}
/**
* @param x0 the x0 to set
*/
public void setX0(double x0) {
this.x0 = x0;
}
/**
* @return the y0
*/
public double getY0() {
return y0;
}
/**
* @param y0 the y0 to set
*/
public void setY0(double y0) {
this.y0 = y0;
}
/**
* @return the resetEdges
*/
public boolean isResetEdges() {
return resetEdges;
}
/**
* @param resetEdges the resetEdges to set
*/
public void setResetEdges(boolean resetEdges) {
this.resetEdges = resetEdges;
}
/**
* @return the disableEdgeStyle
*/
public boolean isDisableEdgeStyle() {
return disableEdgeStyle;
}
/**
* @param disableEdgeStyle the disableEdgeStyle to set
*/
public void setDisableEdgeStyle(boolean disableEdgeStyle) {
this.disableEdgeStyle = disableEdgeStyle;
}
/*
* (non-Javadoc)
* @see com.mxgraph.layout.mxIGraphLayout#execute(java.lang.Object)
*/
public void execute(Object parent) {
mxIGraphModel model = graph.getModel();
// Moves the vertices to build a circle. Makes sure the
// radius is large enough for the vertices to not
// overlap
model.beginUpdate();
try {
// Gets all vertices inside the parent and finds
// the maximum dimension of the largest vertex
double max = 0;
Double top = null;
Double left = null;
List<Object> vertices = new ArrayList<Object>();
int childCount = model.getChildCount(parent);
for (int i = 0; i < childCount; i++) {
Object cell = model.getChildAt(parent, i);
if (!isVertexIgnored(cell)) {
vertices.add(cell);
mxRectangle bounds = getVertexBounds(cell);
if (top == null) {
top = bounds.getY();
}
else {
top = Math.min(top, bounds.getY());
}
if (left == null) {
left = bounds.getX();
}
else {
left = Math.min(left, bounds.getX());
}
max = Math.max(max, Math.max(bounds.getWidth(), bounds.getHeight()));
}
else if (!isEdgeIgnored(cell)) {
if (isResetEdges()) {
graph.resetEdge(cell);
}
if (isDisableEdgeStyle()) {
setEdgeStyleEnabled(cell, false);
}
}
}
int vertexCount = vertices.size();
double r = Math.max(vertexCount * max / Math.PI, radius);
// Moves the circle to the specified origin
if (moveCircle) {
left = x0;
top = y0;
}
circle(vertices.toArray(), r, left.doubleValue(), top.doubleValue());
}
finally {
model.endUpdate();
}
}
/**
* Executes the circular layout for the specified array
* of vertices and the given radius.
*/
public void circle(Object[] vertices, double r, double left, double top) {
int vertexCount = vertices.length;
double phi = 2 * Math.PI / vertexCount;
for (int i = 0; i < vertexCount; i++) {
if (isVertexMovable(vertices[i])) {
setVertexLocation(vertices[i], left + r + r * Math.sin(i * phi), top + r + r * Math.cos(i * phi));
}
}
}
}