Created
November 28, 2014 12:52
-
-
Save davidjgraph/cf3b0fec8c32ddf38558 to your computer and use it in GitHub Desktop.
mxCircleLayout.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2006-2013, JGraph Ltd | |
*/ | |
/** | |
* 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], | |
left + r + r * Math.sin(i*phi), | |
top + r + r * Math.cos(i*phi)); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment