204 lines
4.2 KiB
JavaScript
204 lines
4.2 KiB
JavaScript
/**
|
|
* Copyright (c) 2006-2015, JGraph Ltd
|
|
* Copyright (c) 2006-2015, Gaudenz Alder
|
|
*/
|
|
/**
|
|
* Class: mxCircleLayout
|
|
*
|
|
* Extends <mxGraphLayout> to implement a circluar layout for a given radius.
|
|
* The vertices do not need to be connected for this layout to work and all
|
|
* connections between vertices are not taken into account.
|
|
*
|
|
* Example:
|
|
*
|
|
* (code)
|
|
* var layout = new mxCircleLayout(graph);
|
|
* layout.execute(graph.getDefaultParent());
|
|
* (end)
|
|
*
|
|
* Constructor: mxCircleLayout
|
|
*
|
|
* Constructs a new circular layout for the specified radius.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* graph - <mxGraph> that contains the cells.
|
|
* radius - Optional radius as an int. Default is 100.
|
|
*/
|
|
function mxCircleLayout(graph, radius)
|
|
{
|
|
mxGraphLayout.call(this, graph);
|
|
this.radius = (radius != null) ? radius : 100;
|
|
};
|
|
|
|
/**
|
|
* Extends mxGraphLayout.
|
|
*/
|
|
mxCircleLayout.prototype = new mxGraphLayout();
|
|
mxCircleLayout.prototype.constructor = mxCircleLayout;
|
|
|
|
/**
|
|
* Variable: radius
|
|
*
|
|
* Integer specifying the size of the radius. Default is 100.
|
|
*/
|
|
mxCircleLayout.prototype.radius = null;
|
|
|
|
/**
|
|
* Variable: moveCircle
|
|
*
|
|
* Boolean specifying if the circle should be moved to the top,
|
|
* left corner specified by <x0> and <y0>. Default is false.
|
|
*/
|
|
mxCircleLayout.prototype.moveCircle = false;
|
|
|
|
/**
|
|
* Variable: x0
|
|
*
|
|
* Integer specifying the left coordinate of the circle.
|
|
* Default is 0.
|
|
*/
|
|
mxCircleLayout.prototype.x0 = 0;
|
|
|
|
/**
|
|
* Variable: y0
|
|
*
|
|
* Integer specifying the top coordinate of the circle.
|
|
* Default is 0.
|
|
*/
|
|
mxCircleLayout.prototype.y0 = 0;
|
|
|
|
/**
|
|
* Variable: resetEdges
|
|
*
|
|
* Specifies if all edge points of traversed edges should be removed.
|
|
* Default is true.
|
|
*/
|
|
mxCircleLayout.prototype.resetEdges = true;
|
|
|
|
/**
|
|
* Variable: disableEdgeStyle
|
|
*
|
|
* Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
|
|
* modified by the result. Default is true.
|
|
*/
|
|
mxCircleLayout.prototype.disableEdgeStyle = true;
|
|
|
|
/**
|
|
* Function: execute
|
|
*
|
|
* Implements <mxGraphLayout.execute>.
|
|
*/
|
|
mxCircleLayout.prototype.execute = function(parent)
|
|
{
|
|
var model = this.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
|
|
var max = 0;
|
|
var top = null;
|
|
var left = null;
|
|
var vertices = [];
|
|
var childCount = model.getChildCount(parent);
|
|
|
|
for (var i = 0; i < childCount; i++)
|
|
{
|
|
var cell = model.getChildAt(parent, i);
|
|
|
|
if (!this.isVertexIgnored(cell))
|
|
{
|
|
vertices.push(cell);
|
|
var bounds = this.getVertexBounds(cell);
|
|
|
|
if (top == null)
|
|
{
|
|
top = bounds.y;
|
|
}
|
|
else
|
|
{
|
|
top = Math.min(top, bounds.y);
|
|
}
|
|
|
|
if (left == null)
|
|
{
|
|
left = bounds.x;
|
|
}
|
|
else
|
|
{
|
|
left = Math.min(left, bounds.x);
|
|
}
|
|
|
|
max = Math.max(max, Math.max(bounds.width, bounds.height));
|
|
}
|
|
else if (!this.isEdgeIgnored(cell))
|
|
{
|
|
// Resets the points on the traversed edge
|
|
if (this.resetEdges)
|
|
{
|
|
this.graph.resetEdge(cell);
|
|
}
|
|
|
|
if (this.disableEdgeStyle)
|
|
{
|
|
this.setEdgeStyleEnabled(cell, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
var r = this.getRadius(vertices.length, max);
|
|
|
|
// Moves the circle to the specified origin
|
|
if (this.moveCircle)
|
|
{
|
|
left = this.x0;
|
|
top = this.y0;
|
|
}
|
|
|
|
this.circle(vertices, r, left, top);
|
|
}
|
|
finally
|
|
{
|
|
model.endUpdate();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Function: getRadius
|
|
*
|
|
* Returns the radius to be used for the given vertex count. Max is the maximum
|
|
* width or height of all vertices in the layout.
|
|
*/
|
|
mxCircleLayout.prototype.getRadius = function(count, max)
|
|
{
|
|
return Math.max(count * max / Math.PI, this.radius);
|
|
};
|
|
|
|
/**
|
|
* Function: circle
|
|
*
|
|
* Executes the circular layout for the specified array
|
|
* of vertices and the given radius. This is called from
|
|
* <execute>.
|
|
*/
|
|
mxCircleLayout.prototype.circle = function(vertices, r, left, top)
|
|
{
|
|
var vertexCount = vertices.length;
|
|
var phi = 2 * Math.PI / vertexCount;
|
|
|
|
for (var i = 0; i < vertexCount; i++)
|
|
{
|
|
if (this.isVertexMovable(vertices[i]))
|
|
{
|
|
this.setVertexLocation(vertices[i],
|
|
Math.round(left + r + r * Math.sin(i * phi)),
|
|
Math.round(top + r + r * Math.cos(i * phi)));
|
|
}
|
|
}
|
|
};
|