manual js syntax updates
parent
249e8bea6e
commit
c5e7813b34
|
@ -0,0 +1,77 @@
|
|||
class WeightedCellSorter {
|
||||
/**
|
||||
* Variable: weightedValue
|
||||
*
|
||||
* The weighted value of the cell stored.
|
||||
*/
|
||||
weightedValue = 0;
|
||||
|
||||
/**
|
||||
* Variable: nudge
|
||||
*
|
||||
* Whether or not to flip equal weight values.
|
||||
*/
|
||||
nudge = false;
|
||||
|
||||
/**
|
||||
* Variable: visited
|
||||
*
|
||||
* Whether or not this cell has been visited in the current assignment.
|
||||
*/
|
||||
visited = false;
|
||||
|
||||
/**
|
||||
* Variable: rankIndex
|
||||
*
|
||||
* The index this cell is in the model rank.
|
||||
*/
|
||||
rankIndex = null;
|
||||
|
||||
/**
|
||||
* Variable: cell
|
||||
*
|
||||
* The cell whose median value is being calculated.
|
||||
*/
|
||||
cell = null;
|
||||
|
||||
/**
|
||||
* Class: WeightedCellSorter
|
||||
*
|
||||
* A utility class used to track cells whilst sorting occurs on the weighted
|
||||
* sum of their connected edges. Does not violate (x.compareTo(y)==0) ==
|
||||
* (x.equals(y))
|
||||
*
|
||||
* Constructor: WeightedCellSorter
|
||||
*
|
||||
* Constructs a new weighted cell sorted for the given cell and weight.
|
||||
*/
|
||||
constructor(cell, weightedValue) {
|
||||
this.cell = cell;
|
||||
this.weightedValue = weightedValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function: compare
|
||||
*
|
||||
* Compares two WeightedCellSorters.
|
||||
*/
|
||||
compare = (a, b) => {
|
||||
if (a != null && b != null) {
|
||||
if (b.weightedValue > a.weightedValue) {
|
||||
return -1;
|
||||
} else if (b.weightedValue < a.weightedValue) {
|
||||
return 1;
|
||||
} else {
|
||||
if (b.nudge) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default WeightedCellSorter;
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,24 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
class mxCompositeLayout extends mxGraphLayout{
|
||||
/**
|
||||
* Variable: layouts
|
||||
*
|
||||
* Holds the array of <mxGraphLayouts> that this layout contains.
|
||||
*/
|
||||
layouts = null;
|
||||
|
||||
/**
|
||||
* Variable: master
|
||||
*
|
||||
* Reference to the <mxGraphLayouts> that handles moves. If this is null
|
||||
* then the first layout in <layouts> is used.
|
||||
*/
|
||||
master = null;
|
||||
|
||||
/**
|
||||
* Class: mxCompositeLayout
|
||||
*
|
||||
* Allows to compose multiple layouts into a single layout. The master layout
|
||||
|
@ -30,72 +47,44 @@
|
|||
* master - Optional layout that handles moves. If no layout is given then
|
||||
* the first layout of the above array is used to handle moves.
|
||||
*/
|
||||
function mxCompositeLayout(graph, layouts, master)
|
||||
{
|
||||
mxGraphLayout.call(this, graph);
|
||||
constructor(graph, layouts, master) {
|
||||
super(graph);
|
||||
this.layouts = layouts;
|
||||
this.master = master;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends mxGraphLayout.
|
||||
*/
|
||||
mxCompositeLayout.prototype = new mxGraphLayout();
|
||||
constructor = mxCompositeLayout;
|
||||
|
||||
/**
|
||||
* Variable: layouts
|
||||
*
|
||||
* Holds the array of <mxGraphLayouts> that this layout contains.
|
||||
*/
|
||||
layouts = null;
|
||||
|
||||
/**
|
||||
* Variable: master
|
||||
*
|
||||
* Reference to the <mxGraphLayouts> that handles moves. If this is null
|
||||
* then the first layout in <layouts> is used.
|
||||
*/
|
||||
master = null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: moveCell
|
||||
*
|
||||
* Implements <mxGraphLayout.moveCell> by calling move on <master> or the first
|
||||
* layout in <layouts>.
|
||||
*/
|
||||
moveCell = (cell, x, y)=>
|
||||
{
|
||||
if (this.master != null)
|
||||
{
|
||||
moveCell=(cell, x, y)=>{
|
||||
if (this.master != null) {
|
||||
this.master.moveCell.apply(this.master, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this.layouts[0].moveCell.apply(this.layouts[0], arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Implements <mxGraphLayout.execute> by executing all <layouts> in a
|
||||
* single transaction.
|
||||
*/
|
||||
execute = (parent)=>
|
||||
{
|
||||
execute=(parent)=>{
|
||||
var model = this.graph.getModel();
|
||||
|
||||
model.beginUpdate();
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < this.layouts.length; i++)
|
||||
{
|
||||
try {
|
||||
for (var i = 0; i < this.layouts.length; i++) {
|
||||
this.layouts[i].execute.apply(this.layouts[i], arguments);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default mxCompositeLayout;
|
||||
|
|
|
@ -2,7 +2,11 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
import mxPoint from "FIXME";
|
||||
|
||||
class mxEdgeLabelLayout extends mxGraphLayout {
|
||||
/**
|
||||
* Class: mxEdgeLabelLayout
|
||||
*
|
||||
* Extends <mxGraphLayout> to implement an edge label layout. This layout
|
||||
|
@ -25,24 +29,16 @@
|
|||
*
|
||||
* graph - <mxGraph> that contains the cells.
|
||||
*/
|
||||
function mxEdgeLabelLayout(graph, radius)
|
||||
{
|
||||
mxGraphLayout.call(this, graph);
|
||||
};
|
||||
constructor(graph, radius) {
|
||||
super(graph);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxGraphLayout.
|
||||
*/
|
||||
mxEdgeLabelLayout.prototype = new mxGraphLayout();
|
||||
constructor = mxEdgeLabelLayout;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Implements <mxGraphLayout.execute>.
|
||||
*/
|
||||
execute = (parent)=>
|
||||
{
|
||||
execute = (parent) => {
|
||||
var view = this.graph.view;
|
||||
var model = this.graph.getModel();
|
||||
|
||||
|
@ -51,79 +47,64 @@ execute = (parent)=>
|
|||
var vertices = [];
|
||||
var childCount = model.getChildCount(parent);
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
var cell = model.getChildAt(parent, i);
|
||||
var state = view.getState(cell);
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
if (!this.isVertexIgnored(cell))
|
||||
{
|
||||
if (state != null) {
|
||||
if (!this.isVertexIgnored(cell)) {
|
||||
vertices.push(state);
|
||||
}
|
||||
else if (!this.isEdgeIgnored(cell))
|
||||
{
|
||||
} else if (!this.isEdgeIgnored(cell)) {
|
||||
edges.push(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.placeLabels(vertices, edges);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: placeLabels
|
||||
*
|
||||
* Places the labels of the given edges.
|
||||
*/
|
||||
placeLabels = (v, e)=>
|
||||
{
|
||||
placeLabels = (v, e) => {
|
||||
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
|
||||
{
|
||||
for (var i = 0; i < e.length; i++)
|
||||
{
|
||||
try {
|
||||
for (var i = 0; i < e.length; i++) {
|
||||
var edge = e[i];
|
||||
|
||||
if (edge != null && edge.text != null &&
|
||||
edge.text.boundingBox != null)
|
||||
{
|
||||
for (var j = 0; j < v.length; j++)
|
||||
{
|
||||
edge.text.boundingBox != null) {
|
||||
for (var j = 0; j < v.length; j++) {
|
||||
var vertex = v[j];
|
||||
|
||||
if (vertex != null)
|
||||
{
|
||||
if (vertex != null) {
|
||||
this.avoid(edge, vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: avoid
|
||||
*
|
||||
* Places the labels of the given edges.
|
||||
*/
|
||||
avoid = (edge, vertex)=>
|
||||
{
|
||||
avoid = (edge, vertex) => {
|
||||
var model = this.graph.getModel();
|
||||
var labRect = edge.text.boundingBox;
|
||||
|
||||
if (mxUtils.intersects(labRect, vertex))
|
||||
{
|
||||
if (mxUtils.intersects(labRect, vertex)) {
|
||||
var dy1 = -labRect.y - labRect.height + vertex.y;
|
||||
var dy2 = -labRect.y + vertex.y + vertex.height;
|
||||
|
||||
|
@ -134,32 +115,28 @@ avoid = (edge, vertex)=>
|
|||
|
||||
var dx = (Math.abs(dx1) < Math.abs(dx2)) ? dx1 : dx2;
|
||||
|
||||
if (Math.abs(dx) < Math.abs(dy))
|
||||
{
|
||||
if (Math.abs(dx) < Math.abs(dy)) {
|
||||
dy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
var g = model.getGeometry(edge.cell);
|
||||
|
||||
if (g != null)
|
||||
{
|
||||
if (g != null) {
|
||||
g = g.clone();
|
||||
|
||||
if (g.offset != null)
|
||||
{
|
||||
if (g.offset != null) {
|
||||
g.offset.x += dx;
|
||||
g.offset.y += dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
g.offset = new mxPoint(dx, dy);
|
||||
}
|
||||
|
||||
model.setGeometry(edge.cell, g);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default mxEdgeLabelLayout;
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
class mxFastOrganicLayout extends mxGraphLayout {
|
||||
/**
|
||||
* Class: mxFastOrganicLayout
|
||||
*
|
||||
* Extends <mxGraphLayout> to implement a fast organic layout algorithm.
|
||||
|
@ -20,180 +22,173 @@
|
|||
*
|
||||
* Constructs a new fast organic layout for the specified graph.
|
||||
*/
|
||||
function mxFastOrganicLayout(graph)
|
||||
{
|
||||
mxGraphLayout.call(this, graph);
|
||||
};
|
||||
constructor(graph) {
|
||||
super(graph);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxGraphLayout.
|
||||
*/
|
||||
mxFastOrganicLayout.prototype = new mxGraphLayout();
|
||||
constructor = mxFastOrganicLayout;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: useInputOrigin
|
||||
*
|
||||
* Specifies if the top left corner of the input cells should be the origin
|
||||
* of the layout result. Default is true.
|
||||
*/
|
||||
useInputOrigin = true;
|
||||
useInputOrigin = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: resetEdges
|
||||
*
|
||||
* Specifies if all edge points of traversed edges should be removed.
|
||||
* Default is true.
|
||||
*/
|
||||
resetEdges = true;
|
||||
resetEdges = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: disableEdgeStyle
|
||||
*
|
||||
* Specifies if the STYLE_NOEDGESTYLE flag should be set on edges that are
|
||||
* modified by the result. Default is true.
|
||||
*/
|
||||
disableEdgeStyle = true;
|
||||
disableEdgeStyle = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: forceConstant
|
||||
*
|
||||
* The force constant by which the attractive forces are divided and the
|
||||
* replusive forces are multiple by the square of. The value equates to the
|
||||
* average radius there is of free space around each node. Default is 50.
|
||||
*/
|
||||
forceConstant = 50;
|
||||
forceConstant = 50;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: forceConstantSquared
|
||||
*
|
||||
* Cache of <forceConstant>^2 for performance.
|
||||
*/
|
||||
forceConstantSquared = 0;
|
||||
forceConstantSquared = 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: minDistanceLimit
|
||||
*
|
||||
* Minimal distance limit. Default is 2. Prevents of
|
||||
* dividing by zero.
|
||||
*/
|
||||
minDistanceLimit = 2;
|
||||
minDistanceLimit = 2;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: maxDistanceLimit
|
||||
*
|
||||
* Maximal distance limit. Default is 500. Prevents of
|
||||
* dividing by zero.
|
||||
*/
|
||||
maxDistanceLimit = 500;
|
||||
maxDistanceLimit = 500;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: minDistanceLimitSquared
|
||||
*
|
||||
* Cached version of <minDistanceLimit> squared.
|
||||
*/
|
||||
minDistanceLimitSquared = 4;
|
||||
minDistanceLimitSquared = 4;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: initialTemp
|
||||
*
|
||||
* Start value of temperature. Default is 200.
|
||||
*/
|
||||
initialTemp = 200;
|
||||
initialTemp = 200;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: temperature
|
||||
*
|
||||
* Temperature to limit displacement at later stages of layout.
|
||||
*/
|
||||
temperature = 0;
|
||||
temperature = 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: maxIterations
|
||||
*
|
||||
* Total number of iterations to run the layout though.
|
||||
*/
|
||||
maxIterations = 0;
|
||||
maxIterations = 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: iteration
|
||||
*
|
||||
* Current iteration count.
|
||||
*/
|
||||
iteration = 0;
|
||||
iteration = 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: vertexArray
|
||||
*
|
||||
* An array of all vertices to be laid out.
|
||||
*/
|
||||
vertexArray;
|
||||
vertexArray;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: dispX
|
||||
*
|
||||
* An array of locally stored X co-ordinate displacements for the vertices.
|
||||
*/
|
||||
dispX;
|
||||
dispX;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: dispY
|
||||
*
|
||||
* An array of locally stored Y co-ordinate displacements for the vertices.
|
||||
*/
|
||||
dispY;
|
||||
dispY;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: cellLocation
|
||||
*
|
||||
* An array of locally stored co-ordinate positions for the vertices.
|
||||
*/
|
||||
cellLocation;
|
||||
cellLocation;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: radius
|
||||
*
|
||||
* The approximate radius of each cell, nodes only.
|
||||
*/
|
||||
radius;
|
||||
radius;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: radiusSquared
|
||||
*
|
||||
* The approximate radius squared of each cell, nodes only.
|
||||
*/
|
||||
radiusSquared;
|
||||
radiusSquared;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: isMoveable
|
||||
*
|
||||
* Array of booleans representing the movable states of the vertices.
|
||||
*/
|
||||
isMoveable;
|
||||
isMoveable;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: neighbours
|
||||
*
|
||||
* Local copy of cell neighbours.
|
||||
*/
|
||||
neighbours;
|
||||
neighbours;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: indices
|
||||
*
|
||||
* Hashtable from cells to local indices.
|
||||
*/
|
||||
indices;
|
||||
indices;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: allowedToRun
|
||||
*
|
||||
* Boolean flag that specifies if the layout is allowed to run. If this is
|
||||
* set to false, then the layout exits in the following iteration.
|
||||
*/
|
||||
allowedToRun = true;
|
||||
allowedToRun = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isVertexIgnored
|
||||
*
|
||||
* Returns a boolean indicating if the given <mxCell> should be ignored as a
|
||||
|
@ -203,28 +198,24 @@ allowedToRun = true;
|
|||
*
|
||||
* vertex - <mxCell> whose ignored state should be returned.
|
||||
*/
|
||||
isVertexIgnored = (vertex)=>
|
||||
{
|
||||
isVertexIgnored = (vertex) => {
|
||||
return isVertexIgnored.apply(this, arguments) ||
|
||||
this.graph.getConnections(vertex).length == 0;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Implements <mxGraphLayout.execute>. This operates on all children of the
|
||||
* given parent where <isVertexIgnored> returns false.
|
||||
*/
|
||||
execute = (parent)=>
|
||||
{
|
||||
execute = (parent) => {
|
||||
var model = this.graph.getModel();
|
||||
this.vertexArray = [];
|
||||
var cells = this.graph.getChildVertices(parent);
|
||||
|
||||
for (var i = 0; i < cells.length; i++)
|
||||
{
|
||||
if (!this.isVertexIgnored(cells[i]))
|
||||
{
|
||||
for (var i = 0; i < cells.length; i++) {
|
||||
if (!this.isVertexIgnored(cells[i])) {
|
||||
this.vertexArray.push(cells[i]);
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +234,7 @@ execute = (parent)=>
|
|||
this.radius = [];
|
||||
this.radiusSquared = [];
|
||||
|
||||
if (this.forceConstant < 0.001)
|
||||
{
|
||||
if (this.forceConstant < 0.001) {
|
||||
this.forceConstant = 0.001;
|
||||
}
|
||||
|
||||
|
@ -254,8 +244,7 @@ execute = (parent)=>
|
|||
// arrays called neighbours which holds, for each vertex, a list of
|
||||
// ints which represents the neighbours cells to that vertex as
|
||||
// the indices into vertexArray
|
||||
for (var i = 0; i < this.vertexArray.length; i++)
|
||||
{
|
||||
for (var i = 0; i < this.vertexArray.length; i++) {
|
||||
var vertex = this.vertexArray[i];
|
||||
this.cellLocation[i] = [];
|
||||
|
||||
|
@ -282,10 +271,8 @@ execute = (parent)=>
|
|||
// Moves cell location back to top-left from center locations used in
|
||||
// algorithm, resetting the edge points is part of the transaction
|
||||
model.beginUpdate();
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
try {
|
||||
for (var i = 0; i < n; i++) {
|
||||
this.dispX[i] = 0;
|
||||
this.dispY[i] = 0;
|
||||
this.isMoveable[i] = this.isVertexMovable(this.vertexArray[i]);
|
||||
|
@ -297,16 +284,13 @@ execute = (parent)=>
|
|||
var cells = this.graph.getOpposites(edges, this.vertexArray[i]);
|
||||
this.neighbours[i] = [];
|
||||
|
||||
for (var j = 0; j < cells.length; j++)
|
||||
{
|
||||
for (var j = 0; j < cells.length; j++) {
|
||||
// Resets the points on the traversed edge
|
||||
if (this.resetEdges)
|
||||
{
|
||||
if (this.resetEdges) {
|
||||
this.graph.resetEdge(edges[j]);
|
||||
}
|
||||
|
||||
if (this.disableEdgeStyle)
|
||||
{
|
||||
if (this.disableEdgeStyle) {
|
||||
this.setEdgeStyleEnabled(edges[j], false);
|
||||
}
|
||||
|
||||
|
@ -316,8 +300,7 @@ execute = (parent)=>
|
|||
|
||||
// Check the connected cell in part of the vertex list to be
|
||||
// acted on by this layout
|
||||
if (index != null)
|
||||
{
|
||||
if (index != null) {
|
||||
this.neighbours[i][j] = index;
|
||||
}
|
||||
|
||||
|
@ -325,8 +308,7 @@ execute = (parent)=>
|
|||
// any cell listed to be acted upon in this layout. Set
|
||||
// the index to the value of this vertex (a dummy self-loop)
|
||||
// so the attraction force of the edge is not calculated
|
||||
else
|
||||
{
|
||||
else {
|
||||
this.neighbours[i][j] = i;
|
||||
}
|
||||
}
|
||||
|
@ -334,16 +316,13 @@ execute = (parent)=>
|
|||
this.temperature = this.initialTemp;
|
||||
|
||||
// If max number of iterations has not been set, guess it
|
||||
if (this.maxIterations == 0)
|
||||
{
|
||||
if (this.maxIterations == 0) {
|
||||
this.maxIterations = 20 * Math.sqrt(n);
|
||||
}
|
||||
|
||||
// Main iteration loop
|
||||
for (this.iteration = 0; this.iteration < this.maxIterations; this.iteration++)
|
||||
{
|
||||
if (!this.allowedToRun)
|
||||
{
|
||||
for (this.iteration = 0; this.iteration < this.maxIterations; this.iteration++) {
|
||||
if (!this.allowedToRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -360,16 +339,13 @@ execute = (parent)=>
|
|||
var minx = null;
|
||||
var miny = null;
|
||||
|
||||
for (var i = 0; i < this.vertexArray.length; i++)
|
||||
{
|
||||
for (var i = 0; i < this.vertexArray.length; i++) {
|
||||
var vertex = this.vertexArray[i];
|
||||
|
||||
if (this.isVertexMovable(vertex))
|
||||
{
|
||||
if (this.isVertexMovable(vertex)) {
|
||||
var bounds = this.getVertexBounds(vertex);
|
||||
|
||||
if (bounds != null)
|
||||
{
|
||||
if (bounds != null) {
|
||||
this.cellLocation[i][0] -= bounds.width / 2.0;
|
||||
this.cellLocation[i][1] -= bounds.height / 2.0;
|
||||
|
||||
|
@ -378,21 +354,15 @@ execute = (parent)=>
|
|||
|
||||
this.setVertexLocation(vertex, x, y);
|
||||
|
||||
if (minx == null)
|
||||
{
|
||||
if (minx == null) {
|
||||
minx = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
minx = Math.min(minx, x);
|
||||
}
|
||||
|
||||
if (miny == null)
|
||||
{
|
||||
if (miny == null) {
|
||||
miny = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
miny = Math.min(miny, y);
|
||||
}
|
||||
}
|
||||
|
@ -405,40 +375,33 @@ execute = (parent)=>
|
|||
var dx = -(minx || 0) + 1;
|
||||
var dy = -(miny || 0) + 1;
|
||||
|
||||
if (initialBounds != null)
|
||||
{
|
||||
if (initialBounds != null) {
|
||||
dx += initialBounds.x;
|
||||
dy += initialBounds.y;
|
||||
}
|
||||
|
||||
this.graph.moveCells(this.vertexArray, dx, dy);
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: calcPositions
|
||||
*
|
||||
* Takes the displacements calculated for each cell and applies them to the
|
||||
* local cache of cell positions. Limits the displacement to the current
|
||||
* temperature.
|
||||
*/
|
||||
calcPositions = ()=>
|
||||
{
|
||||
for (var index = 0; index < this.vertexArray.length; index++)
|
||||
{
|
||||
if (this.isMoveable[index])
|
||||
{
|
||||
calcPositions = () => {
|
||||
for (var index = 0; index < this.vertexArray.length; index++) {
|
||||
if (this.isMoveable[index]) {
|
||||
// Get the distance of displacement for this node for this
|
||||
// iteration
|
||||
var deltaLength = Math.sqrt(this.dispX[index] * this.dispX[index] +
|
||||
this.dispY[index] * this.dispY[index]);
|
||||
|
||||
if (deltaLength < 0.001)
|
||||
{
|
||||
if (deltaLength < 0.001) {
|
||||
deltaLength = 0.001;
|
||||
}
|
||||
|
||||
|
@ -459,30 +422,26 @@ calcPositions = ()=>
|
|||
this.cellLocation[index][1] += newYDisp;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: calcAttraction
|
||||
*
|
||||
* Calculates the attractive forces between all laid out nodes linked by
|
||||
* edges
|
||||
*/
|
||||
calcAttraction = ()=>
|
||||
{
|
||||
calcAttraction = () => {
|
||||
// Check the neighbours of each vertex and calculate the attractive
|
||||
// force of the edge connecting them
|
||||
for (var i = 0; i < this.vertexArray.length; i++)
|
||||
{
|
||||
for (var k = 0; k < this.neighbours[i].length; k++)
|
||||
{
|
||||
for (var i = 0; i < this.vertexArray.length; i++) {
|
||||
for (var k = 0; k < this.neighbours[i].length; k++) {
|
||||
// Get the index of the othe cell in the vertex array
|
||||
var j = this.neighbours[i][k];
|
||||
|
||||
// Do not proceed self-loops
|
||||
if (i != j &&
|
||||
this.isMoveable[i] &&
|
||||
this.isMoveable[j])
|
||||
{
|
||||
this.isMoveable[j]) {
|
||||
var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
|
||||
var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];
|
||||
|
||||
|
@ -490,8 +449,7 @@ calcAttraction = ()=>
|
|||
var deltaLengthSquared = xDelta * xDelta + yDelta
|
||||
* yDelta - this.radiusSquared[i] - this.radiusSquared[j];
|
||||
|
||||
if (deltaLengthSquared < this.minDistanceLimitSquared)
|
||||
{
|
||||
if (deltaLengthSquared < this.minDistanceLimitSquared) {
|
||||
deltaLengthSquared = this.minDistanceLimitSquared;
|
||||
}
|
||||
|
||||
|
@ -509,41 +467,34 @@ calcAttraction = ()=>
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: calcRepulsion
|
||||
*
|
||||
* Calculates the repulsive forces between all laid out nodes
|
||||
*/
|
||||
calcRepulsion = ()=>
|
||||
{
|
||||
calcRepulsion = () => {
|
||||
var vertexCount = this.vertexArray.length;
|
||||
|
||||
for (var i = 0; i < vertexCount; i++)
|
||||
{
|
||||
for (var j = i; j < vertexCount; j++)
|
||||
{
|
||||
for (var i = 0; i < vertexCount; i++) {
|
||||
for (var j = i; j < vertexCount; j++) {
|
||||
// Exits if the layout is no longer allowed to run
|
||||
if (!this.allowedToRun)
|
||||
{
|
||||
if (!this.allowedToRun) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (j != i &&
|
||||
this.isMoveable[i] &&
|
||||
this.isMoveable[j])
|
||||
{
|
||||
this.isMoveable[j]) {
|
||||
var xDelta = this.cellLocation[i][0] - this.cellLocation[j][0];
|
||||
var yDelta = this.cellLocation[i][1] - this.cellLocation[j][1];
|
||||
|
||||
if (xDelta == 0)
|
||||
{
|
||||
if (xDelta == 0) {
|
||||
xDelta = 0.01 + Math.random();
|
||||
}
|
||||
|
||||
if (yDelta == 0)
|
||||
{
|
||||
if (yDelta == 0) {
|
||||
yDelta = 0.01 + Math.random();
|
||||
}
|
||||
|
||||
|
@ -553,14 +504,12 @@ calcRepulsion = ()=>
|
|||
var deltaLengthWithRadius = deltaLength - this.radius[i]
|
||||
- this.radius[j];
|
||||
|
||||
if (deltaLengthWithRadius > this.maxDistanceLimit)
|
||||
{
|
||||
if (deltaLengthWithRadius > this.maxDistanceLimit) {
|
||||
// Ignore vertices too far apart
|
||||
continue;
|
||||
}
|
||||
|
||||
if (deltaLengthWithRadius < this.minDistanceLimit)
|
||||
{
|
||||
if (deltaLengthWithRadius < this.minDistanceLimit) {
|
||||
deltaLengthWithRadius = this.minDistanceLimit;
|
||||
}
|
||||
|
||||
|
@ -577,15 +526,17 @@ calcRepulsion = ()=>
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: reduceTemperature
|
||||
*
|
||||
* Reduces the temperature of the layout from an initial setting in a linear
|
||||
* fashion to zero.
|
||||
*/
|
||||
reduceTemperature = ()=>
|
||||
{
|
||||
reduceTemperature = () => {
|
||||
this.temperature = this.initialTemp * (1.0 - this.iteration / this.maxIterations);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default mxFastOrganicLayout;
|
||||
|
|
|
@ -2,7 +2,12 @@
|
|||
* Copyright (c) 2006-2018, JGraph Ltd
|
||||
* Copyright (c) 2006-2018, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
import mxDictionary from "FIXME";
|
||||
|
||||
class mxGraphLayout {
|
||||
/**
|
||||
* Class: mxGraphLayout
|
||||
*
|
||||
* Base class for all layout algorithms in mxGraph. Main public functions are
|
||||
|
@ -23,34 +28,33 @@
|
|||
*
|
||||
* graph - Enclosing
|
||||
*/
|
||||
function mxGraphLayout(graph)
|
||||
{
|
||||
constructor(graph) {
|
||||
this.graph = graph;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: graph
|
||||
*
|
||||
* Reference to the enclosing <mxGraph>.
|
||||
*/
|
||||
graph = null;
|
||||
graph = null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: useBoundingBox
|
||||
*
|
||||
* Boolean indicating if the bounding box of the label should be used if
|
||||
* its available. Default is true.
|
||||
*/
|
||||
useBoundingBox = true;
|
||||
useBoundingBox = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable: parent
|
||||
*
|
||||
* The parent cell of the layout, if any
|
||||
*/
|
||||
parent = null;
|
||||
parent = null;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: moveCell
|
||||
*
|
||||
* Notified when a cell is being moved in a parent that has automatic
|
||||
|
@ -66,9 +70,10 @@ parent = null;
|
|||
* x - X-coordinate of the new cell location.
|
||||
* y - Y-coordinate of the new cell location.
|
||||
*/
|
||||
moveCell = (cell, x, y)=> { };
|
||||
moveCell = (cell, x, y) => {
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: resizeCell
|
||||
*
|
||||
* Notified when a cell is being resized in a parent that has automatic
|
||||
|
@ -81,9 +86,10 @@ moveCell = (cell, x, y)=> { };
|
|||
* cell - <mxCell> which has been moved.
|
||||
* bounds - <mxRectangle> that represents the new cell bounds.
|
||||
*/
|
||||
resizeCell = (cell, bounds)=> { };
|
||||
resizeCell = (cell, bounds) => {
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Executes the layout algorithm for the children of the given parent.
|
||||
|
@ -92,19 +98,19 @@ resizeCell = (cell, bounds)=> { };
|
|||
*
|
||||
* parent - <mxCell> whose children should be layed out.
|
||||
*/
|
||||
execute = (parent)=> { };
|
||||
execute = (parent) => {
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: getGraph
|
||||
*
|
||||
* Returns the graph that this layout operates on.
|
||||
*/
|
||||
getGraph = ()=>
|
||||
{
|
||||
getGraph = () => {
|
||||
return this.graph;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: getConstraint
|
||||
*
|
||||
* Returns the constraint for the given key and cell. The optional edge and
|
||||
|
@ -121,12 +127,11 @@ getGraph = ()=>
|
|||
* source - Optional boolean that specifies if the connection is incoming
|
||||
* or outgoing. Default is null.
|
||||
*/
|
||||
getConstraint = (key, cell, edge, source)=>
|
||||
{
|
||||
getConstraint = (key, cell, edge, source) => {
|
||||
return this.graph.getCurrentCellStyle(cell)[key]
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: traverse
|
||||
*
|
||||
* Traverses the (directed) graph invoking the given function for each
|
||||
|
@ -157,31 +162,24 @@ getConstraint = (key, cell, edge, source)=>
|
|||
* null for the first step of the traversal.
|
||||
* visited - Optional <mxDictionary> of cell paths for the visited cells.
|
||||
*/
|
||||
mxGraphLayout.traverse = (vertex, directed, func, edge, visited)=>
|
||||
{
|
||||
if (func != null && vertex != null)
|
||||
{
|
||||
traverse = (vertex, directed, func, edge, visited) => {
|
||||
if (func != null && vertex != null) {
|
||||
directed = (directed != null) ? directed : true;
|
||||
visited = visited || new mxDictionary();
|
||||
|
||||
if (!visited.get(vertex))
|
||||
{
|
||||
if (!visited.get(vertex)) {
|
||||
visited.put(vertex, true);
|
||||
var result = func(vertex, edge);
|
||||
|
||||
if (result == null || result)
|
||||
{
|
||||
if (result == null || result) {
|
||||
var edgeCount = this.graph.model.getEdgeCount(vertex);
|
||||
|
||||
if (edgeCount > 0)
|
||||
{
|
||||
for (var i = 0; i < edgeCount; i++)
|
||||
{
|
||||
if (edgeCount > 0) {
|
||||
for (var i = 0; i < edgeCount; i++) {
|
||||
var e = this.graph.model.getEdgeAt(vertex, i);
|
||||
var isSource = this.graph.model.getTerminal(e, true) == vertex;
|
||||
|
||||
if (!directed || isSource)
|
||||
{
|
||||
if (!directed || isSource) {
|
||||
var next = this.graph.view.getVisibleTerminal(e, !isSource);
|
||||
this.traverse(next, directed, func, e, visited);
|
||||
}
|
||||
|
@ -190,9 +188,9 @@ mxGraphLayout.traverse = (vertex, directed, func, edge, visited)=>
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isAncestor
|
||||
*
|
||||
* Returns true if the given parent is an ancestor of the given child.
|
||||
|
@ -203,27 +201,23 @@ mxGraphLayout.traverse = (vertex, directed, func, edge, visited)=>
|
|||
* child - <mxCell> that specifies the child.
|
||||
* traverseAncestors - boolean whether to
|
||||
*/
|
||||
isAncestor = (parent, child, traverseAncestors)=>
|
||||
{
|
||||
if (!traverseAncestors)
|
||||
{
|
||||
isAncestor = (parent, child, traverseAncestors) => {
|
||||
if (!traverseAncestors) {
|
||||
return (this.graph.model.getParent(child) == parent);
|
||||
}
|
||||
|
||||
if (child == parent)
|
||||
{
|
||||
if (child == parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (child != null && child != parent)
|
||||
{
|
||||
while (child != null && child != parent) {
|
||||
child = this.graph.model.getParent(child);
|
||||
}
|
||||
|
||||
return child == parent;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isVertexMovable
|
||||
*
|
||||
* Returns a boolean indicating if the given <mxCell> is movable or
|
||||
|
@ -234,12 +228,11 @@ isAncestor = (parent, child, traverseAncestors)=>
|
|||
*
|
||||
* cell - <mxCell> whose movable state should be returned.
|
||||
*/
|
||||
isVertexMovable = (cell)=>
|
||||
{
|
||||
isVertexMovable = (cell) => {
|
||||
return this.graph.isCellMovable(cell);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isVertexIgnored
|
||||
*
|
||||
* Returns a boolean indicating if the given <mxCell> should be ignored by
|
||||
|
@ -249,13 +242,12 @@ isVertexMovable = (cell)=>
|
|||
*
|
||||
* vertex - <mxCell> whose ignored state should be returned.
|
||||
*/
|
||||
isVertexIgnored = (vertex)=>
|
||||
{
|
||||
isVertexIgnored = (vertex) => {
|
||||
return !this.graph.getModel().isVertex(vertex) ||
|
||||
!this.graph.isCellVisible(vertex);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isEdgeIgnored
|
||||
*
|
||||
* Returns a boolean indicating if the given <mxCell> should be ignored by
|
||||
|
@ -265,101 +257,88 @@ isVertexIgnored = (vertex)=>
|
|||
*
|
||||
* cell - <mxCell> whose ignored state should be returned.
|
||||
*/
|
||||
isEdgeIgnored = (edge)=>
|
||||
{
|
||||
isEdgeIgnored = (edge) => {
|
||||
var model = this.graph.getModel();
|
||||
|
||||
return !model.isEdge(edge) ||
|
||||
!this.graph.isCellVisible(edge) ||
|
||||
model.getTerminal(edge, true) == null ||
|
||||
model.getTerminal(edge, false) == null;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: setEdgeStyleEnabled
|
||||
*
|
||||
* Disables or enables the edge style of the given edge.
|
||||
*/
|
||||
setEdgeStyleEnabled = (edge, value)=>
|
||||
{
|
||||
setEdgeStyleEnabled = (edge, value) => {
|
||||
this.graph.setCellStyles(mxConstants.STYLE_NOEDGESTYLE,
|
||||
(value) ? '0' : '1', [edge]);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: setOrthogonalEdge
|
||||
*
|
||||
* Disables or enables orthogonal end segments of the given edge.
|
||||
*/
|
||||
setOrthogonalEdge = (edge, value)=>
|
||||
{
|
||||
setOrthogonalEdge = (edge, value) => {
|
||||
this.graph.setCellStyles(mxConstants.STYLE_ORTHOGONAL,
|
||||
(value) ? '1' : '0', [edge]);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: getParentOffset
|
||||
*
|
||||
* Determines the offset of the given parent to the parent
|
||||
* of the layout
|
||||
*/
|
||||
getParentOffset = (parent)=>
|
||||
{
|
||||
getParentOffset = (parent) => {
|
||||
var result = new mxPoint();
|
||||
|
||||
if (parent != null && parent != this.parent)
|
||||
{
|
||||
if (parent != null && parent != this.parent) {
|
||||
var model = this.graph.getModel();
|
||||
|
||||
if (model.isAncestor(this.parent, parent))
|
||||
{
|
||||
if (model.isAncestor(this.parent, parent)) {
|
||||
var parentGeo = model.getGeometry(parent);
|
||||
|
||||
while (parent != this.parent)
|
||||
{
|
||||
while (parent != this.parent) {
|
||||
result.x = result.x + parentGeo.x;
|
||||
result.y = result.y + parentGeo.y;
|
||||
|
||||
parent = model.getParent(parent);;
|
||||
parent = model.getParent(parent);
|
||||
;
|
||||
parentGeo = model.getGeometry(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: setEdgePoints
|
||||
*
|
||||
* Replaces the array of mxPoints in the geometry of the given edge
|
||||
* with the given array of mxPoints.
|
||||
*/
|
||||
setEdgePoints = (edge, points)=>
|
||||
{
|
||||
if (edge != null)
|
||||
{
|
||||
setEdgePoints = (edge, points) => {
|
||||
if (edge != null) {
|
||||
var model = this.graph.model;
|
||||
var geometry = model.getGeometry(edge);
|
||||
|
||||
if (geometry == null)
|
||||
{
|
||||
if (geometry == null) {
|
||||
geometry = new mxGeometry();
|
||||
geometry.setRelative(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
geometry = geometry.clone();
|
||||
}
|
||||
|
||||
if (this.parent != null && points != null)
|
||||
{
|
||||
if (this.parent != null && points != null) {
|
||||
var parent = model.getParent(edge);
|
||||
|
||||
var parentOffset = this.getParentOffset(parent);
|
||||
|
||||
for (var i = 0; i < points.length; i++)
|
||||
{
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
points[i].x = points[i].x - parentOffset.x;
|
||||
points[i].y = points[i].y - parentOffset.y;
|
||||
}
|
||||
|
@ -368,9 +347,9 @@ setEdgePoints = (edge, points)=>
|
|||
geometry.points = points;
|
||||
model.setGeometry(edge, geometry);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: setVertexLocation
|
||||
*
|
||||
* Sets the new position of the given cell taking into account the size of
|
||||
|
@ -385,47 +364,39 @@ setEdgePoints = (edge, points)=>
|
|||
* x - Integer that defines the x-coordinate of the new location.
|
||||
* y - Integer that defines the y-coordinate of the new location.
|
||||
*/
|
||||
setVertexLocation = (cell, x, y)=>
|
||||
{
|
||||
setVertexLocation = (cell, x, y) => {
|
||||
var model = this.graph.getModel();
|
||||
var geometry = model.getGeometry(cell);
|
||||
var result = null;
|
||||
|
||||
if (geometry != null)
|
||||
{
|
||||
if (geometry != null) {
|
||||
result = new mxRectangle(x, y, geometry.width, geometry.height);
|
||||
|
||||
// Checks for oversize labels and shifts the result
|
||||
// TODO: Use mxUtils.getStringSize for label bounds
|
||||
if (this.useBoundingBox)
|
||||
{
|
||||
if (this.useBoundingBox) {
|
||||
var state = this.graph.getView().getState(cell);
|
||||
|
||||
if (state != null && state.text != null && state.text.boundingBox != null)
|
||||
{
|
||||
if (state != null && state.text != null && state.text.boundingBox != null) {
|
||||
var scale = this.graph.getView().scale;
|
||||
var box = state.text.boundingBox;
|
||||
|
||||
if (state.text.boundingBox.x < state.x)
|
||||
{
|
||||
if (state.text.boundingBox.x < state.x) {
|
||||
x += (state.x - box.x) / scale;
|
||||
result.width = box.width;
|
||||
}
|
||||
|
||||
if (state.text.boundingBox.y < state.y)
|
||||
{
|
||||
if (state.text.boundingBox.y < state.y) {
|
||||
y += (state.y - box.y) / scale;
|
||||
result.height = box.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.parent != null)
|
||||
{
|
||||
if (this.parent != null) {
|
||||
var parent = model.getParent(cell);
|
||||
|
||||
if (parent != null && parent != this.parent)
|
||||
{
|
||||
if (parent != null && parent != this.parent) {
|
||||
var parentOffset = this.getParentOffset(parent);
|
||||
|
||||
x = x - parentOffset.x;
|
||||
|
@ -433,8 +404,7 @@ setVertexLocation = (cell, x, y)=>
|
|||
}
|
||||
}
|
||||
|
||||
if (geometry.x != x || geometry.y != y)
|
||||
{
|
||||
if (geometry.x != x || geometry.y != y) {
|
||||
geometry = geometry.clone();
|
||||
geometry.x = x;
|
||||
geometry.y = y;
|
||||
|
@ -444,27 +414,24 @@ setVertexLocation = (cell, x, y)=>
|
|||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: getVertexBounds
|
||||
*
|
||||
* Returns an <mxRectangle> that defines the bounds of the given cell or
|
||||
* the bounding box if <useBoundingBox> is true.
|
||||
*/
|
||||
getVertexBounds = (cell)=>
|
||||
{
|
||||
getVertexBounds = (cell) => {
|
||||
var geo = this.graph.getModel().getGeometry(cell);
|
||||
|
||||
// Checks for oversize label bounding box and corrects
|
||||
// the return value accordingly
|
||||
// TODO: Use mxUtils.getStringSize for label bounds
|
||||
if (this.useBoundingBox)
|
||||
{
|
||||
if (this.useBoundingBox) {
|
||||
var state = this.graph.getView().getState(cell);
|
||||
|
||||
if (state != null && state.text != null && state.text.boundingBox != null)
|
||||
{
|
||||
if (state != null && state.text != null && state.text.boundingBox != null) {
|
||||
var scale = this.graph.getView().scale;
|
||||
var tmp = state.text.boundingBox;
|
||||
|
||||
|
@ -477,13 +444,11 @@ getVertexBounds = (cell)=>
|
|||
}
|
||||
}
|
||||
|
||||
if (this.parent != null)
|
||||
{
|
||||
if (this.parent != null) {
|
||||
var parent = this.graph.getModel().getParent(cell);
|
||||
geo = geo.clone();
|
||||
|
||||
if (parent != null && parent != this.parent)
|
||||
{
|
||||
if (parent != null && parent != this.parent) {
|
||||
var parentOffset = this.getParentOffset(parent);
|
||||
geo.x = geo.x + parentOffset.x;
|
||||
geo.y = geo.y + parentOffset.y;
|
||||
|
@ -491,101 +456,16 @@ getVertexBounds = (cell)=>
|
|||
}
|
||||
|
||||
return new mxRectangle(geo.x, geo.y, geo.width, geo.height);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: arrangeGroups
|
||||
*
|
||||
* Shortcut to <mxGraph.updateGroupBounds> with moveGroup set to true.
|
||||
*/
|
||||
arrangeGroups = (cells, border, topBorder, rightBorder, bottomBorder, leftBorder)=>
|
||||
{
|
||||
arrangeGroups = (cells, border, topBorder, rightBorder, bottomBorder, leftBorder) => {
|
||||
return this.graph.updateGroupBounds(cells, border, true, topBorder, rightBorder, bottomBorder, leftBorder);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Class: WeightedCellSorter
|
||||
*
|
||||
* A utility class used to track cells whilst sorting occurs on the weighted
|
||||
* sum of their connected edges. Does not violate (x.compareTo(y)==0) ==
|
||||
* (x.equals(y))
|
||||
*
|
||||
* Constructor: WeightedCellSorter
|
||||
*
|
||||
* Constructs a new weighted cell sorted for the given cell and weight.
|
||||
*/
|
||||
function WeightedCellSorter(cell, weightedValue)
|
||||
{
|
||||
this.cell = cell;
|
||||
this.weightedValue = weightedValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable: weightedValue
|
||||
*
|
||||
* The weighted value of the cell stored.
|
||||
*/
|
||||
weightedValue = 0;
|
||||
|
||||
/**
|
||||
* Variable: nudge
|
||||
*
|
||||
* Whether or not to flip equal weight values.
|
||||
*/
|
||||
nudge = false;
|
||||
|
||||
/**
|
||||
* Variable: visited
|
||||
*
|
||||
* Whether or not this cell has been visited in the current assignment.
|
||||
*/
|
||||
visited = false;
|
||||
|
||||
/**
|
||||
* Variable: rankIndex
|
||||
*
|
||||
* The index this cell is in the model rank.
|
||||
*/
|
||||
rankIndex = null;
|
||||
|
||||
/**
|
||||
* Variable: cell
|
||||
*
|
||||
* The cell whose median value is being calculated.
|
||||
*/
|
||||
cell = null;
|
||||
|
||||
/**
|
||||
* Function: compare
|
||||
*
|
||||
* Compares two WeightedCellSorters.
|
||||
*/
|
||||
compare = (a, b)=>
|
||||
{
|
||||
if (a != null && b != null)
|
||||
{
|
||||
if (b.weightedValue > a.weightedValue)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (b.weightedValue < a.weightedValue)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b.nudge)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
export default mxGraphLayout;
|
||||
|
|
|
@ -2,7 +2,26 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
import mxPoint from "FIXME";
|
||||
|
||||
class mxParallelEdgeLayout extends mxGraphLayout {
|
||||
/**
|
||||
* Variable: spacing
|
||||
*
|
||||
* Defines the spacing between the parallels. Default is 20.
|
||||
*/
|
||||
spacing = 20;
|
||||
|
||||
/**
|
||||
* Variable: checkOverlap
|
||||
*
|
||||
* Specifies if only overlapping edges should be considered
|
||||
* parallel. Default is false.
|
||||
*/
|
||||
checkOverlap = false;
|
||||
|
||||
/**
|
||||
* Class: mxParallelEdgeLayout
|
||||
*
|
||||
* Extends <mxGraphLayout> for arranging parallel edges. This layout works
|
||||
|
@ -45,79 +64,46 @@
|
|||
*
|
||||
* Constructs a new parallel edge layout for the specified graph.
|
||||
*/
|
||||
function mxParallelEdgeLayout(graph)
|
||||
{
|
||||
mxGraphLayout.call(this, graph);
|
||||
};
|
||||
constructor(graph) {
|
||||
super(graph);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxGraphLayout.
|
||||
*/
|
||||
mxParallelEdgeLayout.prototype = new mxGraphLayout();
|
||||
constructor = mxParallelEdgeLayout;
|
||||
|
||||
/**
|
||||
* Variable: spacing
|
||||
*
|
||||
* Defines the spacing between the parallels. Default is 20.
|
||||
*/
|
||||
spacing = 20;
|
||||
|
||||
/**
|
||||
* Variable: checkOverlap
|
||||
*
|
||||
* Specifies if only overlapping edges should be considered
|
||||
* parallel. Default is false.
|
||||
*/
|
||||
checkOverlap = false;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Implements <mxGraphLayout.execute>.
|
||||
*/
|
||||
execute = (parent, cells)=>
|
||||
{
|
||||
execute = (parent, cells) => {
|
||||
var lookup = this.findParallels(parent, cells);
|
||||
|
||||
this.graph.model.beginUpdate();
|
||||
try
|
||||
{
|
||||
for (var i in lookup)
|
||||
{
|
||||
try {
|
||||
for (var i in lookup) {
|
||||
var parallels = lookup[i];
|
||||
|
||||
if (parallels.length > 1)
|
||||
{
|
||||
if (parallels.length > 1) {
|
||||
this.layout(parallels);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
this.graph.model.endUpdate();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: findParallels
|
||||
*
|
||||
* Finds the parallel edges in the given parent.
|
||||
*/
|
||||
findParallels = (parent, cells)=>
|
||||
{
|
||||
findParallels = (parent, cells) => {
|
||||
var lookup = [];
|
||||
|
||||
var addCell = mxUtils.bind(this, (cell)=>
|
||||
{
|
||||
if (!this.isEdgeIgnored(cell))
|
||||
{
|
||||
var addCell = mxUtils.bind(this, (cell) => {
|
||||
if (!this.isEdgeIgnored(cell)) {
|
||||
var id = this.getEdgeId(cell);
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
if (lookup[id] == null)
|
||||
{
|
||||
if (id != null) {
|
||||
if (lookup[id] == null) {
|
||||
lookup[id] = [];
|
||||
}
|
||||
|
||||
|
@ -126,36 +112,30 @@ findParallels = (parent, cells)=>
|
|||
}
|
||||
});
|
||||
|
||||
if (cells != null)
|
||||
{
|
||||
for (var i = 0; i < cells.length; i++)
|
||||
{
|
||||
if (cells != null) {
|
||||
for (var i = 0; i < cells.length; i++) {
|
||||
addCell(cells[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
var model = this.graph.getModel();
|
||||
var childCount = model.getChildCount(parent);
|
||||
|
||||
for (var i = 0; i < childCount; i++)
|
||||
{
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
addCell(model.getChildAt(parent, i));
|
||||
}
|
||||
}
|
||||
|
||||
return lookup;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: getEdgeId
|
||||
*
|
||||
* Returns a unique ID for the given edge. The id is independent of the
|
||||
* edge direction and is built using the visible terminal of the given
|
||||
* edge.
|
||||
*/
|
||||
getEdgeId = (edge)=>
|
||||
{
|
||||
getEdgeId = (edge) => {
|
||||
var view = this.graph.getView();
|
||||
|
||||
// Cannot used cached visible terminal because this could be triggered in BEFORE_UNDO
|
||||
|
@ -163,46 +143,41 @@ getEdgeId = (edge)=>
|
|||
var trg = view.getVisibleTerminal(edge, false);
|
||||
var pts = '';
|
||||
|
||||
if (src != null && trg != null)
|
||||
{
|
||||
if (src != null && trg != null) {
|
||||
src = mxObjectIdentity.get(src);
|
||||
trg = mxObjectIdentity.get(trg);
|
||||
|
||||
if (this.checkOverlap)
|
||||
{
|
||||
if (this.checkOverlap) {
|
||||
var state = this.graph.view.getState(edge);
|
||||
|
||||
if (state != null && state.absolutePoints != null)
|
||||
{
|
||||
if (state != null && state.absolutePoints != null) {
|
||||
var tmp = [];
|
||||
|
||||
for (var i = 0; i < state.absolutePoints.length; i++)
|
||||
{
|
||||
for (var i = 0; i < state.absolutePoints.length; i++) {
|
||||
var pt = state.absolutePoints[i];
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
if (pt != null) {
|
||||
tmp.push(pt.x, pt.y);
|
||||
}
|
||||
}
|
||||
|
||||
pts = tmp.join(',');
|
||||
}
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
return ((src > trg) ? trg + '-' + src : src + '-' + trg) + pts;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: layout
|
||||
*
|
||||
* Lays out the parallel edges in the given array.
|
||||
*/
|
||||
layout = (parallels)=>
|
||||
{
|
||||
layout = (parallels) => {
|
||||
var edge = parallels[0];
|
||||
var view = this.graph.getView();
|
||||
var model = this.graph.getModel();
|
||||
|
@ -210,19 +185,15 @@ layout = (parallels)=>
|
|||
var trg = model.getGeometry(view.getVisibleTerminal(edge, false));
|
||||
|
||||
// Routes multiple loops
|
||||
if (src == trg)
|
||||
{
|
||||
if (src == trg) {
|
||||
var x0 = src.x + src.width + this.spacing;
|
||||
var y0 = src.y + src.height / 2;
|
||||
|
||||
for (var i = 0; i < parallels.length; i++)
|
||||
{
|
||||
for (var i = 0; i < parallels.length; i++) {
|
||||
this.route(parallels[i], x0, y0);
|
||||
x0 += this.spacing;
|
||||
}
|
||||
}
|
||||
else if (src != null && trg != null)
|
||||
{
|
||||
} else if (src != null && trg != null) {
|
||||
// Routes parallel edges
|
||||
var scx = src.x + src.width / 2;
|
||||
var scy = src.y + src.height / 2;
|
||||
|
@ -235,8 +206,7 @@ layout = (parallels)=>
|
|||
|
||||
var len = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (len > 0) {
|
||||
var x0 = scx + dx / 2;
|
||||
var y0 = scy + dy / 2;
|
||||
|
||||
|
@ -246,25 +216,25 @@ layout = (parallels)=>
|
|||
x0 += nx * (parallels.length - 1) / 2;
|
||||
y0 -= ny * (parallels.length - 1) / 2;
|
||||
|
||||
for (var i = 0; i < parallels.length; i++)
|
||||
{
|
||||
for (var i = 0; i < parallels.length; i++) {
|
||||
this.route(parallels[i], x0, y0);
|
||||
x0 -= nx;
|
||||
y0 += ny;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: route
|
||||
*
|
||||
* Routes the given edge via the given point.
|
||||
*/
|
||||
route = (edge, x, y)=>
|
||||
{
|
||||
if (this.graph.isCellMovable(edge))
|
||||
{
|
||||
route = (edge, x, y) => {
|
||||
if (this.graph.isCellMovable(edge)) {
|
||||
this.setEdgePoints(edge, [new mxPoint(x, y)]);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default mxParallelEdgeLayout;
|
||||
|
|
|
@ -2,7 +2,42 @@
|
|||
* Copyright (c) 2006-2015, JGraph Ltd
|
||||
* Copyright (c) 2006-2015, Gaudenz Alder
|
||||
*/
|
||||
/**
|
||||
|
||||
import mxRectangle from "FIXME";
|
||||
|
||||
class mxPartitionLayout extends mxGraphLayout {
|
||||
/**
|
||||
* Variable: horizontal
|
||||
*
|
||||
* Boolean indicating the direction in which the space is partitioned.
|
||||
* Default is true.
|
||||
*/
|
||||
horizontal = null;
|
||||
|
||||
/**
|
||||
* Variable: spacing
|
||||
*
|
||||
* Integer that specifies the absolute spacing in pixels between the
|
||||
* children. Default is 0.
|
||||
*/
|
||||
spacing = null;
|
||||
|
||||
/**
|
||||
* Variable: border
|
||||
*
|
||||
* Integer that specifies the absolute inset in pixels for the parent that
|
||||
* contains the children. Default is 0.
|
||||
*/
|
||||
border = null;
|
||||
|
||||
/**
|
||||
* Variable: resizeVertices
|
||||
*
|
||||
* Boolean that specifies if vertices should be resized. Default is true.
|
||||
*/
|
||||
resizeVertices = true;
|
||||
|
||||
/**
|
||||
* Class: mxPartitionLayout
|
||||
*
|
||||
* Extends <mxGraphLayout> for partitioning the parent cell vertically or
|
||||
|
@ -24,74 +59,33 @@
|
|||
* Constructs a new stack layout layout for the specified graph,
|
||||
* spacing, orientation and offset.
|
||||
*/
|
||||
function mxPartitionLayout(graph, horizontal, spacing, border)
|
||||
{
|
||||
mxGraphLayout.call(this, graph);
|
||||
constructor(graph, horizontal, spacing, border) {
|
||||
super(graph);
|
||||
this.horizontal = (horizontal != null) ? horizontal : true;
|
||||
this.spacing = spacing || 0;
|
||||
this.border = border || 0;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends mxGraphLayout.
|
||||
*/
|
||||
mxPartitionLayout.prototype = new mxGraphLayout();
|
||||
constructor = mxPartitionLayout;
|
||||
|
||||
/**
|
||||
* Variable: horizontal
|
||||
*
|
||||
* Boolean indicating the direction in which the space is partitioned.
|
||||
* Default is true.
|
||||
*/
|
||||
horizontal = null;
|
||||
|
||||
/**
|
||||
* Variable: spacing
|
||||
*
|
||||
* Integer that specifies the absolute spacing in pixels between the
|
||||
* children. Default is 0.
|
||||
*/
|
||||
spacing = null;
|
||||
|
||||
/**
|
||||
* Variable: border
|
||||
*
|
||||
* Integer that specifies the absolute inset in pixels for the parent that
|
||||
* contains the children. Default is 0.
|
||||
*/
|
||||
border = null;
|
||||
|
||||
/**
|
||||
* Variable: resizeVertices
|
||||
*
|
||||
* Boolean that specifies if vertices should be resized. Default is true.
|
||||
*/
|
||||
resizeVertices = true;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: isHorizontal
|
||||
*
|
||||
* Returns <horizontal>.
|
||||
*/
|
||||
isHorizontal = ()=>
|
||||
{
|
||||
isHorizontal=()=>{
|
||||
return this.horizontal;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: moveCell
|
||||
*
|
||||
* Implements <mxGraphLayout.moveCell>.
|
||||
*/
|
||||
moveCell = (cell, x, y)=>
|
||||
{
|
||||
moveCell = (cell, x, y)=>{
|
||||
var model = this.graph.getModel();
|
||||
var parent = model.getParent(cell);
|
||||
|
||||
if (cell != null &&
|
||||
parent != null)
|
||||
{
|
||||
parent != null) {
|
||||
var i = 0;
|
||||
var last = 0;
|
||||
var childCount = model.getChildCount(parent);
|
||||
|
@ -122,16 +116,16 @@ moveCell = (cell, x, y)=>
|
|||
|
||||
model.add(parent, cell, idx);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function: execute
|
||||
*
|
||||
* Implements <mxGraphLayout.execute>. All children where <isVertexIgnored>
|
||||
* returns false and <isVertexMovable> returns true are modified.
|
||||
*/
|
||||
execute = (parent)=>
|
||||
{
|
||||
execute = (parent)=>
|
||||
{
|
||||
var horizontal = this.isHorizontal();
|
||||
var model = this.graph.getModel();
|
||||
var pgeo = model.getGeometry(parent);
|
||||
|
@ -229,12 +223,13 @@ execute = (parent)=>
|
|||
model.setGeometry(child, geo);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
} finally {
|
||||
model.endUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default mxPartitionLayout;
|
||||
|
|
Loading…
Reference in New Issue