diff --git a/javascript/src/js/layout/mxCompactTreeLayout.js b/javascript/src/js/layout/mxCompactTreeLayout.js index 7d392ad3e..2cd1d354c 100644 --- a/javascript/src/js/layout/mxCompactTreeLayout.js +++ b/javascript/src/js/layout/mxCompactTreeLayout.js @@ -4,33 +4,9 @@ */ import mxDictionary from "FIXME"; +import mxPoint from "FIXME"; class mxCompactTreeLayout extends mxGraphLayout { - /** - * Class: mxCompactTreeLayout - * - * Extends to implement a compact tree (Moen) algorithm. This - * layout is suitable for graphs that have no cycles (trees). Vertices that are - * not connected to the tree will be ignored by this layout. - * - * Example: - * - * (code) - * var layout = new mxCompactTreeLayout(graph); - * layout.execute(graph.getDefaultParent()); - * (end) - * - * Constructor: mxCompactTreeLayout - * - * Constructs a new compact tree layout for the specified graph - * and orientation. - */ - constructor(graph, horizontal, invert) { - super(graph); - this.horizontal = (horizontal != null) ? horizontal : true; - this.invert = (invert != null) ? invert : false; - }; - /** * Variable: horizontal * @@ -218,6 +194,31 @@ class mxCompactTreeLayout extends mxGraphLayout { */ node = null; + /** + * Class: mxCompactTreeLayout + * + * Extends to implement a compact tree (Moen) algorithm. This + * layout is suitable for graphs that have no cycles (trees). Vertices that are + * not connected to the tree will be ignored by this layout. + * + * Example: + * + * (code) + * var layout = new mxCompactTreeLayout(graph); + * layout.execute(graph.getDefaultParent()); + * (end) + * + * Constructor: mxCompactTreeLayout + * + * Constructs a new compact tree layout for the specified graph + * and orientation. + */ + constructor(graph, horizontal, invert) { + super(graph); + this.horizontal = (horizontal != null) ? horizontal : true; + this.invert = (invert != null) ? invert : false; + }; + /** * Function: isVertexIgnored * diff --git a/javascript/src/js/layout/mxRadialTreeLayout.js b/javascript/src/js/layout/mxRadialTreeLayout.js index 847c71622..acb73f059 100644 --- a/javascript/src/js/layout/mxRadialTreeLayout.js +++ b/javascript/src/js/layout/mxRadialTreeLayout.js @@ -2,317 +2,295 @@ * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ -/** - * Class: mxRadialTreeLayout - * - * Extends to implement a radial tree algorithm. This - * layout is suitable for graphs that have no cycles (trees). Vertices that are - * not connected to the tree will be ignored by this layout. - * - * Example: - * - * (code) - * var layout = new mxRadialTreeLayout(graph); - * layout.execute(graph.getDefaultParent()); - * (end) - * - * Constructor: mxRadialTreeLayout - * - * Constructs a new radial tree layout for the specified graph - */ -function mxRadialTreeLayout(graph) -{ - mxCompactTreeLayout.call(this, graph , false); -}; -/** - * Extends mxGraphLayout. - */ -mxUtils.extend(mxRadialTreeLayout, mxCompactTreeLayout); +class mxRadialTreeLayout extends mxCompactTreeLayout { + /** + * Variable: angleOffset + * + * The initial offset to compute the angle position. + */ + angleOffset = 0.5; -/** - * Variable: angleOffset - * - * The initial offset to compute the angle position. - */ -angleOffset = 0.5; + /** + * Variable: rootx + * + * The X co-ordinate of the root cell + */ + rootx = 0; -/** - * Variable: rootx - * - * The X co-ordinate of the root cell - */ -rootx = 0; + /** + * Variable: rooty + * + * The Y co-ordinate of the root cell + */ + rooty = 0; -/** - * Variable: rooty - * - * The Y co-ordinate of the root cell - */ -rooty = 0; + /** + * Variable: levelDistance + * + * Holds the levelDistance. Default is 120. + */ + levelDistance = 120; -/** - * Variable: levelDistance - * - * Holds the levelDistance. Default is 120. - */ -levelDistance = 120; + /** + * Variable: nodeDistance + * + * Holds the nodeDistance. Default is 10. + */ + nodeDistance = 10; -/** - * Variable: nodeDistance - * - * Holds the nodeDistance. Default is 10. - */ -nodeDistance = 10; + /** + * Variable: autoRadius + * + * Specifies if the radios should be computed automatically + */ + autoRadius = false; -/** - * Variable: autoRadius - * - * Specifies if the radios should be computed automatically - */ -autoRadius = false; + /** + * Variable: sortEdges + * + * Specifies if edges should be sorted according to the order of their + * opposite terminal cell in the model. + */ + sortEdges = false; -/** - * Variable: sortEdges - * - * Specifies if edges should be sorted according to the order of their - * opposite terminal cell in the model. - */ -sortEdges = false; + /** + * Variable: rowMinX + * + * Array of leftmost x coordinate of each row + */ + rowMinX = []; -/** - * Variable: rowMinX - * - * Array of leftmost x coordinate of each row - */ -rowMinX = []; + /** + * Variable: rowMaxX + * + * Array of rightmost x coordinate of each row + */ + rowMaxX = []; -/** - * Variable: rowMaxX - * - * Array of rightmost x coordinate of each row - */ -rowMaxX = []; + /** + * Variable: rowMinCenX + * + * Array of x coordinate of leftmost vertex of each row + */ + rowMinCenX = []; -/** - * Variable: rowMinCenX - * - * Array of x coordinate of leftmost vertex of each row - */ -rowMinCenX = []; + /** + * Variable: rowMaxCenX + * + * Array of x coordinate of rightmost vertex of each row + */ + rowMaxCenX = []; -/** - * Variable: rowMaxCenX - * - * Array of x coordinate of rightmost vertex of each row - */ -rowMaxCenX = []; + /** + * Variable: rowRadi + * + * Array of y deltas of each row behind root vertex, also the radius in the tree + */ + rowRadi = []; -/** - * Variable: rowRadi - * - * Array of y deltas of each row behind root vertex, also the radius in the tree - */ -rowRadi = []; + /** + * Variable: row + * + * Array of vertices on each row + */ + row = []; -/** - * Variable: row - * - * Array of vertices on each row - */ -row = []; + /** + * Class: mxRadialTreeLayout + * + * Extends to implement a radial tree algorithm. This + * layout is suitable for graphs that have no cycles (trees). Vertices that are + * not connected to the tree will be ignored by this layout. + * + * Example: + * + * (code) + * var layout = new mxRadialTreeLayout(graph); + * layout.execute(graph.getDefaultParent()); + * (end) + * + * Constructor: mxRadialTreeLayout + * + * Constructs a new radial tree layout for the specified graph + */ + constructor(graph) { + super(graph, false); + }; -/** - * Function: isVertexIgnored - * - * Returns a boolean indicating if the given should be ignored as a - * vertex. This returns true if the cell has no connections. - * - * Parameters: - * - * vertex - whose ignored state should be returned. - */ -isVertexIgnored = (vertex)=> -{ - return isVertexIgnored.apply(this, arguments) || - this.graph.getConnections(vertex).length == 0; -}; + /** + * Function: isVertexIgnored + * + * Returns a boolean indicating if the given should be ignored as a + * vertex. This returns true if the cell has no connections. + * + * Parameters: + * + * vertex - whose ignored state should be returned. + */ + isVertexIgnored = (vertex) => { + return super.isVertexIgnored(vertex) || + this.graph.getConnections(vertex).length === 0; + }; -/** - * Function: execute - * - * Implements . - * - * If the parent has any connected edges, then it is used as the root of - * the tree. Else, will be used to find a suitable - * root node within the set of children of the given parent. - * - * Parameters: - * - * parent - whose children should be laid out. - * root - Optional that will be used as the root of the tree. - */ -execute = (parent, root)=> -{ - this.parent = parent; - - this.useBoundingBox = false; - this.edgeRouting = false; - //this.horizontal = false; + /** + * Function: execute + * + * Implements . + * + * If the parent has any connected edges, then it is used as the root of + * the tree. Else, will be used to find a suitable + * root node within the set of children of the given parent. + * + * Parameters: + * + * parent - whose children should be laid out. + * root - Optional that will be used as the root of the tree. + */ + execute = (parent, root) => { + this.parent = parent; - execute.apply(this, arguments); - - var bounds = null; - var rootBounds = this.getVertexBounds(this.root); - this.centerX = rootBounds.x + rootBounds.width / 2; - this.centerY = rootBounds.y + rootBounds.height / 2; + this.useBoundingBox = false; + this.edgeRouting = false; + //this.horizontal = false; - // Calculate the bounds of the involved vertices directly from the values set in the compact tree - for (var vertex in this.visited) - { - var vertexBounds = this.getVertexBounds(this.visited[vertex]); - bounds = (bounds != null) ? bounds : vertexBounds.clone(); - bounds.add(vertexBounds); - } - - this.calcRowDims([this.node], 0); - - var maxLeftGrad = 0; - var maxRightGrad = 0; + execute.apply(this, arguments); - // Find the steepest left and right gradients - for (var i = 0; i < this.row.length; i++) - { - var leftGrad = (this.centerX - this.rowMinX[i] - this.nodeDistance) / this.rowRadi[i]; - var rightGrad = (this.rowMaxX[i] - this.centerX - this.nodeDistance) / this.rowRadi[i]; - - maxLeftGrad = Math.max (maxLeftGrad, leftGrad); - maxRightGrad = Math.max (maxRightGrad, rightGrad); - } - - // Extend out row so they meet the maximum gradient and convert to polar co-ords - for (var i = 0; i < this.row.length; i++) - { - var xLeftLimit = this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i]; - var xRightLimit = this.centerX + this.nodeDistance + maxRightGrad * this.rowRadi[i]; - var fullWidth = xRightLimit - xLeftLimit; - - for (var j = 0; j < this.row[i].length; j ++) - { - var row = this.row[i]; - var node = row[j]; - var vertexBounds = this.getVertexBounds(node.cell); - var xProportion = (vertexBounds.x + vertexBounds.width / 2 - xLeftLimit) / (fullWidth); - var theta = 2 * Math.PI * xProportion; - node.theta = theta; + var bounds = null; + var rootBounds = this.getVertexBounds(this.root); + this.centerX = rootBounds.x + rootBounds.width / 2; + this.centerY = rootBounds.y + rootBounds.height / 2; + + // Calculate the bounds of the involved vertices directly from the values set in the compact tree + for (var vertex in this.visited) { + var vertexBounds = this.getVertexBounds(this.visited[vertex]); + bounds = (bounds != null) ? bounds : vertexBounds.clone(); + bounds.add(vertexBounds); } - } - // Post-process from outside inwards to try to align parents with children - for (var i = this.row.length - 2; i >= 0; i--) - { - var row = this.row[i]; - - for (var j = 0; j < row.length; j++) - { - var node = row[j]; - var child = node.child; - var counter = 0; - var totalTheta = 0; - - while (child != null) - { - totalTheta += child.theta; - counter++; + this.calcRowDims([this.node], 0); + + var maxLeftGrad = 0; + var maxRightGrad = 0; + + // Find the steepest left and right gradients + for (var i = 0; i < this.row.length; i++) { + var leftGrad = (this.centerX - this.rowMinX[i] - this.nodeDistance) / this.rowRadi[i]; + var rightGrad = (this.rowMaxX[i] - this.centerX - this.nodeDistance) / this.rowRadi[i]; + + maxLeftGrad = Math.max(maxLeftGrad, leftGrad); + maxRightGrad = Math.max(maxRightGrad, rightGrad); + } + + // Extend out row so they meet the maximum gradient and convert to polar co-ords + for (var i = 0; i < this.row.length; i++) { + var xLeftLimit = this.centerX - this.nodeDistance - maxLeftGrad * this.rowRadi[i]; + var xRightLimit = this.centerX + this.nodeDistance + maxRightGrad * this.rowRadi[i]; + var fullWidth = xRightLimit - xLeftLimit; + + for (var j = 0; j < this.row[i].length; j++) { + var row = this.row[i]; + var node = row[j]; + var vertexBounds = this.getVertexBounds(node.cell); + var xProportion = (vertexBounds.x + vertexBounds.width / 2 - xLeftLimit) / (fullWidth); + var theta = 2 * Math.PI * xProportion; + node.theta = theta; + } + } + + // Post-process from outside inwards to try to align parents with children + for (var i = this.row.length - 2; i >= 0; i--) { + var row = this.row[i]; + + for (var j = 0; j < row.length; j++) { + var node = row[j]; + var child = node.child; + var counter = 0; + var totalTheta = 0; + + while (child != null) { + totalTheta += child.theta; + counter++; + child = child.next; + } + + if (counter > 0) { + var averTheta = totalTheta / counter; + + if (averTheta > node.theta && j < row.length - 1) { + var nextTheta = row[j + 1].theta; + node.theta = Math.min(averTheta, nextTheta - Math.PI / 10); + } else if (averTheta < node.theta && j > 0) { + var lastTheta = row[j - 1].theta; + node.theta = Math.max(averTheta, lastTheta + Math.PI / 10); + } + } + } + } + + // Set locations + for (var i = 0; i < this.row.length; i++) { + for (var j = 0; j < this.row[i].length; j++) { + var row = this.row[i]; + var node = row[j]; + var vertexBounds = this.getVertexBounds(node.cell); + this.setVertexLocation(node.cell, + this.centerX - vertexBounds.width / 2 + this.rowRadi[i] * Math.cos(node.theta), + this.centerY - vertexBounds.height / 2 + this.rowRadi[i] * Math.sin(node.theta)); + } + } + }; + + /** + * Function: calcRowDims + * + * Recursive function to calculate the dimensions of each row + * + * Parameters: + * + * row - Array of internal nodes, the children of which are to be processed. + * rowNum - Integer indicating which row is being processed. + */ + calcRowDims = (row, rowNum) => { + if (row == null || row.length == 0) { + return; + } + + // Place root's children proportionally around the first level + this.rowMinX[rowNum] = this.centerX; + this.rowMaxX[rowNum] = this.centerX; + this.rowMinCenX[rowNum] = this.centerX; + this.rowMaxCenX[rowNum] = this.centerX; + this.row[rowNum] = []; + + var rowHasChildren = false; + + for (var i = 0; i < row.length; i++) { + var child = row[i] != null ? row[i].child : null; + + while (child != null) { + var cell = child.cell; + var vertexBounds = this.getVertexBounds(cell); + + this.rowMinX[rowNum] = Math.min(vertexBounds.x, this.rowMinX[rowNum]); + this.rowMaxX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width, this.rowMaxX[rowNum]); + this.rowMinCenX[rowNum] = Math.min(vertexBounds.x + vertexBounds.width / 2, this.rowMinCenX[rowNum]); + this.rowMaxCenX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width / 2, this.rowMaxCenX[rowNum]); + this.rowRadi[rowNum] = vertexBounds.y - this.getVertexBounds(this.root).y; + + if (child.child != null) { + rowHasChildren = true; + } + + this.row[rowNum].push(child); child = child.next; } - - if (counter > 0) - { - var averTheta = totalTheta / counter; - - if (averTheta > node.theta && j < row.length - 1) - { - var nextTheta = row[j+1].theta; - node.theta = Math.min (averTheta, nextTheta - Math.PI/10); - } - else if (averTheta < node.theta && j > 0 ) - { - var lastTheta = row[j-1].theta; - node.theta = Math.max (averTheta, lastTheta + Math.PI/10); - } - } } - } - - // Set locations - for (var i = 0; i < this.row.length; i++) - { - for (var j = 0; j < this.row[i].length; j ++) - { - var row = this.row[i]; - var node = row[j]; - var vertexBounds = this.getVertexBounds(node.cell); - this.setVertexLocation(node.cell, - this.centerX - vertexBounds.width / 2 + this.rowRadi[i] * Math.cos(node.theta), - this.centerY - vertexBounds.height / 2 + this.rowRadi[i] * Math.sin(node.theta)); + + if (rowHasChildren) { + this.calcRowDims(this.row[rowNum], rowNum + 1); } - } -}; + }; +} -/** - * Function: calcRowDims - * - * Recursive function to calculate the dimensions of each row - * - * Parameters: - * - * row - Array of internal nodes, the children of which are to be processed. - * rowNum - Integer indicating which row is being processed. - */ -calcRowDims = (row, rowNum)=> -{ - if (row == null || row.length == 0) - { - return; - } - - // Place root's children proportionally around the first level - this.rowMinX[rowNum] = this.centerX; - this.rowMaxX[rowNum] = this.centerX; - this.rowMinCenX[rowNum] = this.centerX; - this.rowMaxCenX[rowNum] = this.centerX; - this.row[rowNum] = []; - - var rowHasChildren = false; - - for (var i = 0; i < row.length; i++) - { - var child = row[i] != null ? row[i].child : null; - - while (child != null) - { - var cell = child.cell; - var vertexBounds = this.getVertexBounds(cell); - - this.rowMinX[rowNum] = Math.min(vertexBounds.x, this.rowMinX[rowNum]); - this.rowMaxX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width, this.rowMaxX[rowNum]); - this.rowMinCenX[rowNum] = Math.min(vertexBounds.x + vertexBounds.width / 2, this.rowMinCenX[rowNum]); - this.rowMaxCenX[rowNum] = Math.max(vertexBounds.x + vertexBounds.width / 2, this.rowMaxCenX[rowNum]); - this.rowRadi[rowNum] = vertexBounds.y - this.getVertexBounds(this.root).y; - - if (child.child != null) - { - rowHasChildren = true; - } - - this.row[rowNum].push(child); - child = child.next; - } - } - - if (rowHasChildren) - { - this.calcRowDims(this.row[rowNum], rowNum + 1); - } -}; +export default mxRadialTreeLayout; diff --git a/javascript/src/js/layout/mxStackLayout.js b/javascript/src/js/layout/mxStackLayout.js index 8209041d9..bd85a894b 100644 --- a/javascript/src/js/layout/mxStackLayout.js +++ b/javascript/src/js/layout/mxStackLayout.js @@ -2,602 +2,518 @@ * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ -/** - * Class: mxStackLayout - * - * Extends to create a horizontal or vertical stack of the - * child vertices. The children do not need to be connected for this layout - * to work. - * - * Example: - * - * (code) - * var layout = new mxStackLayout(graph, true); - * layout.execute(graph.getDefaultParent()); - * (end) - * - * Constructor: mxStackLayout - * - * Constructs a new stack layout layout for the specified graph, - * spacing, orientation and offset. - */ -function mxStackLayout(graph, horizontal, spacing, x0, y0, border) -{ - mxGraphLayout.call(this, graph); - this.horizontal = (horizontal != null) ? horizontal : true; - this.spacing = (spacing != null) ? spacing : 0; - this.x0 = (x0 != null) ? x0 : 0; - this.y0 = (y0 != null) ? y0 : 0; - this.border = (border != null) ? border : 0; -}; -/** - * Extends mxGraphLayout. - */ -mxStackLayout.prototype = new mxGraphLayout(); -constructor = mxStackLayout; +class mxStackLayout extends mxGraphLayout { + /** + * Variable: horizontal + * + * Specifies the orientation of the layout. Default is true. + */ + horizontal = null; -/** - * Variable: horizontal - * - * Specifies the orientation of the layout. Default is true. - */ -horizontal = null; + /** + * Variable: spacing + * + * Specifies the spacing between the cells. Default is 0. + */ + spacing = null; -/** - * Variable: spacing - * - * Specifies the spacing between the cells. Default is 0. - */ -spacing = null; + /** + * Variable: x0 + * + * Specifies the horizontal origin of the layout. Default is 0. + */ + x0 = null; -/** - * Variable: x0 - * - * Specifies the horizontal origin of the layout. Default is 0. - */ -x0 = null; + /** + * Variable: y0 + * + * Specifies the vertical origin of the layout. Default is 0. + */ + y0 = null; -/** - * Variable: y0 - * - * Specifies the vertical origin of the layout. Default is 0. - */ -y0 = null; + /** + * Variable: border + * + * Border to be added if fill is true. Default is 0. + */ + border = 0; -/** - * Variable: border - * - * Border to be added if fill is true. Default is 0. - */ -border = 0; + /** + * Variable: marginTop + * + * Top margin for the child area. Default is 0. + */ + marginTop = 0; -/** - * Variable: marginTop - * - * Top margin for the child area. Default is 0. - */ -marginTop = 0; + /** + * Variable: marginLeft + * + * Top margin for the child area. Default is 0. + */ + marginLeft = 0; -/** - * Variable: marginLeft - * - * Top margin for the child area. Default is 0. - */ -marginLeft = 0; + /** + * Variable: marginRight + * + * Top margin for the child area. Default is 0. + */ + marginRight = 0; -/** - * Variable: marginRight - * - * Top margin for the child area. Default is 0. - */ -marginRight = 0; + /** + * Variable: marginBottom + * + * Top margin for the child area. Default is 0. + */ + marginBottom = 0; -/** - * Variable: marginBottom - * - * Top margin for the child area. Default is 0. - */ -marginBottom = 0; + /** + * Variable: keepFirstLocation + * + * Boolean indicating if the location of the first cell should be + * kept, that is, it will not be moved to x0 or y0. Default is false. + */ + keepFirstLocation = false; -/** - * Variable: keepFirstLocation - * - * Boolean indicating if the location of the first cell should be - * kept, that is, it will not be moved to x0 or y0. Default is false. - */ -keepFirstLocation = false; + /** + * Variable: fill + * + * Boolean indicating if dimension should be changed to fill out the parent + * cell. Default is false. + */ + fill = false; -/** - * Variable: fill - * - * Boolean indicating if dimension should be changed to fill out the parent - * cell. Default is false. - */ -fill = false; - -/** - * Variable: resizeParent - * - * If the parent should be resized to match the width/height of the - * stack. Default is false. - */ -resizeParent = false; + /** + * Variable: resizeParent + * + * If the parent should be resized to match the width/height of the + * stack. Default is false. + */ + resizeParent = false; -/** - * Variable: resizeParentMax - * - * Use maximum of existing value and new value for resize of parent. - * Default is false. - */ -resizeParentMax = false; + /** + * Variable: resizeParentMax + * + * Use maximum of existing value and new value for resize of parent. + * Default is false. + */ + resizeParentMax = false; -/** - * Variable: resizeLast - * - * If the last element should be resized to fill out the parent. Default is - * false. If is true then this is ignored. - */ -resizeLast = false; + /** + * Variable: resizeLast + * + * If the last element should be resized to fill out the parent. Default is + * false. If is true then this is ignored. + */ + resizeLast = false; -/** - * Variable: wrap - * - * Value at which a new column or row should be created. Default is null. - */ -wrap = null; + /** + * Variable: wrap + * + * Value at which a new column or row should be created. Default is null. + */ + wrap = null; -/** - * Variable: borderCollapse - * - * If the strokeWidth should be ignored. Default is true. - */ -borderCollapse = true; + /** + * Variable: borderCollapse + * + * If the strokeWidth should be ignored. Default is true. + */ + borderCollapse = true; -/** - * Variable: allowGaps - * - * If gaps should be allowed in the stack. Default is false. - */ -allowGaps = false; + /** + * Variable: allowGaps + * + * If gaps should be allowed in the stack. Default is false. + */ + allowGaps = false; -/** - * Variable: gridSize - * - * Grid size for alignment of position and size. Default is 0. - */ -gridSize = 0; + /** + * Variable: gridSize + * + * Grid size for alignment of position and size. Default is 0. + */ + gridSize = 0; -/** - * Function: isHorizontal - * - * Returns . - */ -isHorizontal = ()=> -{ - return this.horizontal; -}; + /** + * Class: mxStackLayout + * + * Extends to create a horizontal or vertical stack of the + * child vertices. The children do not need to be connected for this layout + * to work. + * + * Example: + * + * (code) + * var layout = new mxStackLayout(graph, true); + * layout.execute(graph.getDefaultParent()); + * (end) + * + * Constructor: mxStackLayout + * + * Constructs a new stack layout layout for the specified graph, + * spacing, orientation and offset. + */ + constructor(graph, horizontal, spacing, x0, y0, border) { + super(graph); + this.horizontal = (horizontal != null) ? horizontal : true; + this.spacing = (spacing != null) ? spacing : 0; + this.x0 = (x0 != null) ? x0 : 0; + this.y0 = (y0 != null) ? y0 : 0; + this.border = (border != null) ? border : 0; + }; -/** - * Function: moveCell - * - * Implements . - */ -moveCell = (cell, x, y)=> -{ - var model = this.graph.getModel(); - var parent = model.getParent(cell); - var horizontal = this.isHorizontal(); - - if (cell != null && parent != null) - { - var i = 0; - var last = 0; - var childCount = model.getChildCount(parent); - var value = (horizontal) ? x : y; - var pstate = this.graph.getView().getState(parent); + /** + * Function: isHorizontal + * + * Returns . + */ + isHorizontal = () => { + return this.horizontal; + }; - if (pstate != null) - { - value -= (horizontal) ? pstate.x : pstate.y; - } - - value /= this.graph.view.scale; - - for (i = 0; i < childCount; i++) - { - var child = model.getChildAt(parent, i); - - if (child != cell) - { - var bounds = model.getGeometry(child); - - if (bounds != null) - { - var tmp = (horizontal) ? - bounds.x + bounds.width / 2 : - bounds.y + bounds.height / 2; - - if (last <= value && tmp > value) - { - break; - } - - last = tmp; - } - } - } - - // Changes child order in parent - var idx = parent.getIndex(cell); - idx = Math.max(0, i - ((i > idx) ? 1 : 0)); - - model.add(parent, cell, idx); - } -}; - -/** - * Function: getParentSize - * - * Returns the size for the parent container or the size of the graph - * container if the parent is a layer or the root of the model. - */ -getParentSize = (parent)=> -{ - var model = this.graph.getModel(); - var pgeo = model.getGeometry(parent); - - // Handles special case where the parent is either a layer with no - // geometry or the current root of the view in which case the size - // of the graph's container will be used. - if (this.graph.container != null && ((pgeo == null && - model.isLayer(parent)) || parent == this.graph.getView().currentRoot)) - { - var width = this.graph.container.offsetWidth - 1; - var height = this.graph.container.offsetHeight - 1; - pgeo = new mxRectangle(0, 0, width, height); - } - - return pgeo; -}; - -/** - * Function: getLayoutCells - * - * Returns the cells to be layouted. - */ -getLayoutCells = (parent)=> -{ - var model = this.graph.getModel(); - var childCount = model.getChildCount(parent); - var cells = []; - - for (var i = 0; i < childCount; i++) - { - var child = model.getChildAt(parent, i); - - if (!this.isVertexIgnored(child) && this.isVertexMovable(child)) - { - cells.push(child); - } - } - - if (this.allowGaps) - { - cells.sort(mxUtils.bind(this, (c1, c2)=> - { - var geo1 = this.graph.getCellGeometry(c1); - var geo2 = this.graph.getCellGeometry(c2); - - return (this.horizontal) ? - ((geo1.x == geo2.x) ? 0 : ((geo1.x > geo2.x > 0) ? 1 : -1)) : - ((geo1.y == geo2.y) ? 0 : ((geo1.y > geo2.y > 0) ? 1 : -1)); - })); - } - - return cells; -}; - -/** - * Function: snap - * - * Snaps the given value to the grid size. - */ -snap = (value)=> -{ - if (this.gridSize != null && this.gridSize > 0) - { - value = Math.max(value, this.gridSize); - - if (value / this.gridSize > 1) - { - var mod = value % this.gridSize; - value += mod > this.gridSize / 2 ? (this.gridSize - mod) : -mod; - } - } - - return value; -}; - -/** - * Function: execute - * - * Implements . - * - * Only children where returns false are taken into - * account. - */ -execute = (parent)=> -{ - if (parent != null) - { - var pgeo = this.getParentSize(parent); + /** + * Function: moveCell + * + * Implements . + */ + moveCell = (cell, x, y) => { + var model = this.graph.getModel(); + var parent = model.getParent(cell); var horizontal = this.isHorizontal(); - var model = this.graph.getModel(); - var fillValue = null; - - if (pgeo != null) - { - fillValue = (horizontal) ? pgeo.height - this.marginTop - this.marginBottom : - pgeo.width - this.marginLeft - this.marginRight; + + if (cell != null && parent != null) { + var i = 0; + var last = 0; + var childCount = model.getChildCount(parent); + var value = (horizontal) ? x : y; + var pstate = this.graph.getView().getState(parent); + + if (pstate != null) { + value -= (horizontal) ? pstate.x : pstate.y; + } + + value /= this.graph.view.scale; + + for (i = 0; i < childCount; i++) { + var child = model.getChildAt(parent, i); + + if (child != cell) { + var bounds = model.getGeometry(child); + + if (bounds != null) { + var tmp = (horizontal) ? + bounds.x + bounds.width / 2 : + bounds.y + bounds.height / 2; + + if (last <= value && tmp > value) { + break; + } + + last = tmp; + } + } + } + + // Changes child order in parent + var idx = parent.getIndex(cell); + idx = Math.max(0, i - ((i > idx) ? 1 : 0)); + + model.add(parent, cell, idx); } - - fillValue -= 2 * this.border; - var x0 = this.x0 + this.border + this.marginLeft; - var y0 = this.y0 + this.border + this.marginTop; - - // Handles swimlane start size - if (this.graph.isSwimlane(parent)) - { - // Uses computed style to get latest - var style = this.graph.getCellStyle(parent); - var start = mxUtils.getNumber(style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE); - var horz = mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true) == 1; + }; - if (pgeo != null) - { - if (horz) - { - start = Math.min(start, pgeo.height); - } - else - { - start = Math.min(start, pgeo.width); - } - } - - if (horizontal == horz) - { - fillValue -= start; - } + /** + * Function: getParentSize + * + * Returns the size for the parent container or the size of the graph + * container if the parent is a layer or the root of the model. + */ + getParentSize = (parent) => { + var model = this.graph.getModel(); + var pgeo = model.getGeometry(parent); - if (horz) - { - y0 += start; - } - else - { - x0 += start; + // Handles special case where the parent is either a layer with no + // geometry or the current root of the view in which case the size + // of the graph's container will be used. + if (this.graph.container != null && ((pgeo == null && + model.isLayer(parent)) || parent == this.graph.getView().currentRoot)) { + var width = this.graph.container.offsetWidth - 1; + var height = this.graph.container.offsetHeight - 1; + pgeo = new mxRectangle(0, 0, width, height); + } + + return pgeo; + }; + + /** + * Function: getLayoutCells + * + * Returns the cells to be layouted. + */ + getLayoutCells = (parent) => { + var model = this.graph.getModel(); + var childCount = model.getChildCount(parent); + var cells = []; + + for (var i = 0; i < childCount; i++) { + var child = model.getChildAt(parent, i); + + if (!this.isVertexIgnored(child) && this.isVertexMovable(child)) { + cells.push(child); } } - model.beginUpdate(); - try - { - var tmp = 0; - var last = null; - var lastValue = 0; - var lastChild = null; - var cells = this.getLayoutCells(parent); - - for (var i = 0; i < cells.length; i++) - { - var child = cells[i]; - var geo = model.getGeometry(child); - - if (geo != null) - { - geo = geo.clone(); - - if (this.wrap != null && last != null) - { - if ((horizontal && last.x + last.width + - geo.width + 2 * this.spacing > this.wrap) || - (!horizontal && last.y + last.height + - geo.height + 2 * this.spacing > this.wrap)) - { - last = null; - - if (horizontal) - { - y0 += tmp + this.spacing; + if (this.allowGaps) { + cells.sort(mxUtils.bind(this, (c1, c2) => { + var geo1 = this.graph.getCellGeometry(c1); + var geo2 = this.graph.getCellGeometry(c2); + + return (this.horizontal) ? + ((geo1.x == geo2.x) ? 0 : ((geo1.x > geo2.x > 0) ? 1 : -1)) : + ((geo1.y == geo2.y) ? 0 : ((geo1.y > geo2.y > 0) ? 1 : -1)); + })); + } + + return cells; + }; + + /** + * Function: snap + * + * Snaps the given value to the grid size. + */ + snap = (value) => { + if (this.gridSize != null && this.gridSize > 0) { + value = Math.max(value, this.gridSize); + + if (value / this.gridSize > 1) { + var mod = value % this.gridSize; + value += mod > this.gridSize / 2 ? (this.gridSize - mod) : -mod; + } + } + + return value; + }; + + /** + * Function: execute + * + * Implements . + * + * Only children where returns false are taken into + * account. + */ + execute = (parent) => { + if (parent != null) { + var pgeo = this.getParentSize(parent); + var horizontal = this.isHorizontal(); + var model = this.graph.getModel(); + var fillValue = null; + + if (pgeo != null) { + fillValue = (horizontal) ? pgeo.height - this.marginTop - this.marginBottom : + pgeo.width - this.marginLeft - this.marginRight; + } + + fillValue -= 2 * this.border; + var x0 = this.x0 + this.border + this.marginLeft; + var y0 = this.y0 + this.border + this.marginTop; + + // Handles swimlane start size + if (this.graph.isSwimlane(parent)) { + // Uses computed style to get latest + var style = this.graph.getCellStyle(parent); + var start = mxUtils.getNumber(style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE); + var horz = mxUtils.getValue(style, mxConstants.STYLE_HORIZONTAL, true) == 1; + + if (pgeo != null) { + if (horz) { + start = Math.min(start, pgeo.height); + } else { + start = Math.min(start, pgeo.width); + } + } + + if (horizontal == horz) { + fillValue -= start; + } + + if (horz) { + y0 += start; + } else { + x0 += start; + } + } + + model.beginUpdate(); + try { + var tmp = 0; + var last = null; + var lastValue = 0; + var lastChild = null; + var cells = this.getLayoutCells(parent); + + for (var i = 0; i < cells.length; i++) { + var child = cells[i]; + var geo = model.getGeometry(child); + + if (geo != null) { + geo = geo.clone(); + + if (this.wrap != null && last != null) { + if ((horizontal && last.x + last.width + + geo.width + 2 * this.spacing > this.wrap) || + (!horizontal && last.y + last.height + + geo.height + 2 * this.spacing > this.wrap)) { + last = null; + + if (horizontal) { + y0 += tmp + this.spacing; + } else { + x0 += tmp + this.spacing; + } + + tmp = 0; } - else - { - x0 += tmp + this.spacing; + } + + tmp = Math.max(tmp, (horizontal) ? geo.height : geo.width); + var sw = 0; + + if (!this.borderCollapse) { + var childStyle = this.graph.getCellStyle(child); + sw = mxUtils.getNumber(childStyle, mxConstants.STYLE_STROKEWIDTH, 1); + } + + if (last != null) { + var temp = lastValue + this.spacing + Math.floor(sw / 2); + + if (horizontal) { + geo.x = this.snap(((this.allowGaps) ? Math.max(temp, geo.x) : + temp) - this.marginLeft) + this.marginLeft; + } else { + geo.y = this.snap(((this.allowGaps) ? Math.max(temp, geo.y) : + temp) - this.marginTop) + this.marginTop; + } + } else if (!this.keepFirstLocation) { + if (horizontal) { + geo.x = (this.allowGaps && geo.x > x0) ? Math.max(this.snap(geo.x - + this.marginLeft) + this.marginLeft, x0) : x0; + } else { + geo.y = (this.allowGaps && geo.y > y0) ? Math.max(this.snap(geo.y - + this.marginTop) + this.marginTop, y0) : y0; } - - tmp = 0; - } - } - - tmp = Math.max(tmp, (horizontal) ? geo.height : geo.width); - var sw = 0; - - if (!this.borderCollapse) - { - var childStyle = this.graph.getCellStyle(child); - sw = mxUtils.getNumber(childStyle, mxConstants.STYLE_STROKEWIDTH, 1); - } - - if (last != null) - { - var temp = lastValue + this.spacing + Math.floor(sw / 2); - - if (horizontal) - { - geo.x = this.snap(((this.allowGaps) ? Math.max(temp, geo.x) : - temp) - this.marginLeft) + this.marginLeft; } - else - { - geo.y = this.snap(((this.allowGaps) ? Math.max(temp, geo.y) : - temp) - this.marginTop) + this.marginTop; + + if (horizontal) { + geo.y = y0; + } else { + geo.x = x0; } - } - else if (!this.keepFirstLocation) - { - if (horizontal) - { - geo.x = (this.allowGaps && geo.x > x0) ? Math.max(this.snap(geo.x - - this.marginLeft) + this.marginLeft, x0) : x0; + + if (this.fill && fillValue != null) { + if (horizontal) { + geo.height = fillValue; + } else { + geo.width = fillValue; + } } - else - { - geo.y = (this.allowGaps && geo.y > y0) ? Math.max(this.snap(geo.y - - this.marginTop) + this.marginTop, y0) : y0; + + if (horizontal) { + geo.width = this.snap(geo.width); + } else { + geo.height = this.snap(geo.height); } - } - - if (horizontal) - { - geo.y = y0; - } - else - { - geo.x = x0; - } - - if (this.fill && fillValue != null) - { - if (horizontal) - { - geo.height = fillValue; + + this.setChildGeometry(child, geo); + lastChild = child; + last = geo; + + if (horizontal) { + lastValue = last.x + last.width + Math.floor(sw / 2); + } else { + lastValue = last.y + last.height + Math.floor(sw / 2); } - else - { - geo.width = fillValue; - } - } - - if (horizontal) - { - geo.width = this.snap(geo.width); - } - else - { - geo.height = this.snap(geo.height); - } - - this.setChildGeometry(child, geo); - lastChild = child; - last = geo; - - if (horizontal) - { - lastValue = last.x + last.width + Math.floor(sw / 2); - } - else - { - lastValue = last.y + last.height + Math.floor(sw / 2); } } - } - if (this.resizeParent && pgeo != null && last != null && !this.graph.isCellCollapsed(parent)) - { - this.updateParentGeometry(parent, pgeo, last); - } - else if (this.resizeLast && pgeo != null && last != null && lastChild != null) - { - if (horizontal) - { - last.width = pgeo.width - last.x - this.spacing - this.marginRight - this.marginLeft; + if (this.resizeParent && pgeo != null && last != null && !this.graph.isCellCollapsed(parent)) { + this.updateParentGeometry(parent, pgeo, last); + } else if (this.resizeLast && pgeo != null && last != null && lastChild != null) { + if (horizontal) { + last.width = pgeo.width - last.x - this.spacing - this.marginRight - this.marginLeft; + } else { + last.height = pgeo.height - last.y - this.spacing - this.marginBottom; + } + + this.setChildGeometry(lastChild, last); } - else - { - last.height = pgeo.height - last.y - this.spacing - this.marginBottom; - } - - this.setChildGeometry(lastChild, last); + } finally { + model.endUpdate(); } } - finally - { - model.endUpdate(); - } - } -}; + }; -/** - * Function: setChildGeometry - * - * Sets the specific geometry to the given child cell. - * - * Parameters: - * - * child - The given child of . - * geo - The specific geometry of . - */ -setChildGeometry = (child, geo)=> -{ - var geo2 = this.graph.getCellGeometry(child); - - if (geo2 == null || geo.x != geo2.x || geo.y != geo2.y || - geo.width != geo2.width || geo.height != geo2.height) - { - this.graph.getModel().setGeometry(child, geo); - } -}; + /** + * Function: setChildGeometry + * + * Sets the specific geometry to the given child cell. + * + * Parameters: + * + * child - The given child of . + * geo - The specific geometry of . + */ + setChildGeometry = (child, geo) => { + var geo2 = this.graph.getCellGeometry(child); -/** - * Function: updateParentGeometry - * - * Updates the geometry of the given parent cell. - * - * Parameters: - * - * parent - The given parent of . - * pgeo - The new for parent. - * last - The last . - */ -updateParentGeometry = (parent, pgeo, last)=> -{ - var horizontal = this.isHorizontal(); - var model = this.graph.getModel(); + if (geo2 == null || geo.x != geo2.x || geo.y != geo2.y || + geo.width != geo2.width || geo.height != geo2.height) { + this.graph.getModel().setGeometry(child, geo); + } + }; - var pgeo2 = pgeo.clone(); - - if (horizontal) - { - var tmp = last.x + last.width + this.marginRight + this.border; - - if (this.resizeParentMax) - { - pgeo2.width = Math.max(pgeo2.width, tmp); + /** + * Function: updateParentGeometry + * + * Updates the geometry of the given parent cell. + * + * Parameters: + * + * parent - The given parent of . + * pgeo - The new for parent. + * last - The last . + */ + updateParentGeometry = (parent, pgeo, last) => { + var horizontal = this.isHorizontal(); + var model = this.graph.getModel(); + + var pgeo2 = pgeo.clone(); + + if (horizontal) { + var tmp = last.x + last.width + this.marginRight + this.border; + + if (this.resizeParentMax) { + pgeo2.width = Math.max(pgeo2.width, tmp); + } else { + pgeo2.width = tmp; + } + } else { + var tmp = last.y + last.height + this.marginBottom + this.border; + + if (this.resizeParentMax) { + pgeo2.height = Math.max(pgeo2.height, tmp); + } else { + pgeo2.height = tmp; + } } - else - { - pgeo2.width = tmp; + + if (pgeo.x != pgeo2.x || pgeo.y != pgeo2.y || + pgeo.width != pgeo2.width || pgeo.height != pgeo2.height) { + model.setGeometry(parent, pgeo2); } - } - else - { - var tmp = last.y + last.height + this.marginBottom + this.border; - - if (this.resizeParentMax) - { - pgeo2.height = Math.max(pgeo2.height, tmp); - } - else - { - pgeo2.height = tmp; - } - } - - if (pgeo.x != pgeo2.x || pgeo.y != pgeo2.y || - pgeo.width != pgeo2.width || pgeo.height != pgeo2.height) - { - model.setGeometry(parent, pgeo2); - } -}; + }; +} + +export default mxStackLayout;