UNPKG

@syncfusion/ej2-diagrams

Version:

Feature-rich diagram control to create diagrams like flow charts, organizational charts, mind maps, and BPMN diagrams. Its rich feature set includes built-in shapes, editing, serializing, exporting, printing, overview, data binding, and automatic layouts.

1,205 lines 114 kB
import { Node } from '../objects/node'; import { GridPanel, RowDefinition, ColumnDefinition } from '../core/containers/grid'; import { Lane, Phase } from '../objects/node'; import { DiagramAction, NodeConstraints, DiagramConstraints, DiagramEvent, ElementAction } from '../enum/enum'; import { cloneObject, randomId } from './../utility/base-util'; import { DiagramElement } from '../core/elements/diagram-element'; import { TextElement } from '../core/elements/text-element'; import { Size } from '../primitives/size'; import { Canvas } from '../core/containers/canvas'; import { Rect } from '../primitives/rect'; import { checkParentAsContainer, findBounds, removeChildInContainer } from '../interaction/container-interaction'; import { canSelect } from './constraints-util'; /** * SwimLane modules are used to rendering and interaction. */ /** @private */ /** * initSwimLane method \ * * @returns {void} initSwimLane method .\ * @param { GridPanel} grid - provide the grid value. * @param { Diagram} diagram - provide the diagram value. * @param {NodeModel} node - provide the node value. * @private */ export function initSwimLane(grid, diagram, node) { if (!node.width && node.shape.phases.length === 0) { node.width = 100; } var row = []; var columns = []; var index = 0; var shape = node.shape; var orientation = shape.orientation === 'Horizontal' ? true : false; if (shape.header && shape.hasHeader) { createRow(row, shape.header.height); } initGridRow(row, orientation, node); initGridColumns(columns, orientation, node); grid.setDefinitions(row, columns); if (shape.header && shape.hasHeader) { headerDefine(grid, diagram, node); index++; } if (shape.phases.length > 0 && shape.phaseSize) { for (var k = 0; k < shape.phases.length; k++) { if (shape.phases[parseInt(k.toString(), 10)].id === '') { shape.phases[parseInt(k.toString(), 10)].id = randomId(); } phaseDefine(grid, diagram, node, index, orientation, k); } index++; } if (shape.lanes.length > 0) { for (var k = 0; k < shape.lanes.length; k++) { if (shape.lanes[parseInt(k.toString(), 10)].id === '') { shape.lanes[parseInt(k.toString(), 10)].id = randomId(); } laneCollection(grid, diagram, node, index, k, orientation); index++; } } } /** * addObjectToGrid method \ * * @returns {GroupableView} addObjectToGrid method .\ * @param { Diagram} diagram - provide the diagram value. * @param { GridPanel} grid - provide the grid value. * @param {NodeModel} parent - provide the parent value. * @param {NodeModel} object - provide the object value. * @param {boolean} isHeader - provide the isHeader value. * @param {boolean} isPhase - provide the isPhase value. * @param {boolean} isLane - provide the isLane value. * @param {string} canvas - provide the canvas value. * @private */ export function addObjectToGrid(diagram, grid, parent, object, isHeader, isPhase, isLane, canvas) { var node = new Node(diagram, 'nodes', object, true); node.parentId = parent.id; node.isHeader = (isHeader) ? true : false; node.isPhase = (isPhase) ? true : false; node.isLane = (isLane) ? true : false; var id = (isPhase) ? 'PhaseHeaderParent' : 'LaneHeaderParent'; if (canvas) { node["" + id] = canvas; } node.constraints &= ~(NodeConstraints.InConnect | NodeConstraints.OutConnect); node.constraints |= NodeConstraints.HideThumbs; diagram.initObject(node); diagram.nodes.push(node); if (node.wrapper.children.length > 0) { for (var i = 0; i < node.wrapper.children.length; i++) { var child = node.wrapper.children[parseInt(i.toString(), 10)]; if (child instanceof DiagramElement) { child.isCalculateDesiredSize = false; } if (child instanceof TextElement) { child.canConsiderBounds = false; if (!isHeader && (parent.shape.orientation === 'Vertical' && isPhase) || (parent.shape.orientation !== 'Vertical' && isLane)) { child.isLaneOrientation = true; child.refreshTextElement(); } } } node.wrapper.measure(new Size(undefined, undefined)); node.wrapper.arrange(node.wrapper.desiredSize); } return node.wrapper; } /** * headerDefine method \ * * @returns {void} headerDefine method .\ * @param { GridPanel} grid - provide the grid value. * @param {Diagram} diagram - provide the diagram value. * @param {NodeModel} object - provide the object value. * @private */ export function headerDefine(grid, diagram, object) { var maxWidth = 0; var columns = grid.columnDefinitions(); var shape = object.shape; for (var i = 0; i < columns.length; i++) { maxWidth += columns[parseInt(i.toString(), 10)].width; } shape.header.id = shape.header.id || randomId(); var node = { id: object.id + shape.header.id, annotations: [cloneObject(shape.header.annotation)], style: shape.header.style ? shape.header.style : undefined, offsetX: object.offsetX, offsetY: object.offsetY, rowIndex: 0, columnIndex: 0, maxWidth: maxWidth, container: { type: 'Canvas', orientation: 'Horizontal' } }; if (!canSelect(object)) { node.constraints &= ~NodeConstraints.Select; } var wrapper = addObjectToGrid(diagram, grid, object, node, true); grid.addObject(wrapper, 0, 0, 1, grid.columnDefinitions().length); } /** * phaseDefine method \ * * @returns {void} phaseDefine method .\ * @param { GridPanel} grid - provide the grid value. * @param {Diagram} diagram - provide the diagram value. * @param {NodeModel} object - provide the object value. * @param {number} indexValue - provide the indexValue value. * @param {boolean} orientation - provide the orientation value. * @param {number} phaseIndex - provide the phaseIndex value. * @private */ export function phaseDefine(grid, diagram, object, indexValue, orientation, phaseIndex) { var rowValue = 0; var colValue = 0; var maxWidth; var shape = object.shape; if (orientation) { colValue = phaseIndex; rowValue = indexValue; maxWidth = grid.columnDefinitions()[parseInt(phaseIndex.toString(), 10)].width; } else { rowValue = shape.header && shape.hasHeader ? phaseIndex + 1 : phaseIndex; } var phaseObject = { annotations: [cloneObject(shape.phases[parseInt(phaseIndex.toString(), 10)].header.annotation)], maxWidth: maxWidth, id: object.id + shape.phases[parseInt(phaseIndex.toString(), 10)].id + '_header', addInfo: shape.phases[parseInt(phaseIndex.toString(), 10)].addInfo, offsetX: object.offsetX, offsetY: object.offsetY, style: shape.phases[parseInt(phaseIndex.toString(), 10)].style, rowIndex: rowValue, columnIndex: colValue, container: { type: 'Canvas', orientation: orientation ? 'Horizontal' : 'Vertical' } }; phaseObject[shape.orientation === 'Horizontal' ? 'height' : 'width'] = shape.phaseSize; phaseObject.annotations[0].rotateAngle = orientation ? 0 : 270; if (!canSelect(object)) { phaseObject.constraints &= ~NodeConstraints.Select; } shape.phases[parseInt(phaseIndex.toString(), 10)].header.id = phaseObject.id; var wrapper = addObjectToGrid(diagram, grid, object, phaseObject, false, true, false, shape.phases[parseInt(phaseIndex.toString(), 10)].id); grid.addObject(wrapper, rowValue, colValue); } /** * laneCollection method \ * * @returns {void} laneCollection method .\ * @param { GridPanel} grid - provide the grid value. * @param {Diagram} diagram - provide the diagram value. * @param {NodeModel} object - provide the object value. * @param {number} indexValue - provide the indexValue value. * @param {number} laneIndex - provide the laneIndex value. * @param {boolean} orientation - provide the orientation value. * @private */ export function laneCollection(grid, diagram, object, indexValue, laneIndex, orientation) { var laneNode; var parentWrapper; var gridCell; var canvas; var childWrapper; var shape = object.shape; var value = shape.phases.length || 1; var isHeader = (shape.header && shape.hasHeader) ? 1 : 0; var rowValue = orientation ? indexValue : isHeader; var phaseCount = (shape.phaseSize && shape.phases.length > 0) ? 1 : 0; for (var l = 0; l < value; l++) { var colValue = orientation ? l : laneIndex + phaseCount; gridCell = grid.rows[parseInt(rowValue.toString(), 10)].cells[parseInt(colValue.toString(), 10)]; canvas = { id: object.id + shape.lanes[parseInt(laneIndex.toString(), 10)].id + l, rowIndex: rowValue, columnIndex: colValue, width: gridCell.minWidth, height: gridCell.minHeight, offsetX: object.offsetX, offsetY: object.offsetY, style: shape.lanes[parseInt(laneIndex.toString(), 10)].style, addInfo: shape.lanes[parseInt(laneIndex.toString(), 10)].addInfo, constraints: NodeConstraints.Default | NodeConstraints.ReadOnly | NodeConstraints.AllowDrop, container: { type: 'Canvas', orientation: orientation ? 'Horizontal' : 'Vertical' } }; if (!canSelect(object)) { canvas.constraints &= ~NodeConstraints.Select; } parentWrapper = addObjectToGrid(diagram, grid, object, canvas, false, false, true); if (shape.phases && shape.phases.length > 0 && shape.phases[parseInt(l.toString(), 10)]) { var phase = diagram.nameTable[shape.phases[parseInt(l.toString(), 10)].header.id]; if (phase) { phase.laneGrids.splice(laneIndex, 0, canvas.id); } } parentWrapper.children[0].isCalculateDesiredSize = false; if (l === 0) { laneNode = { id: object.id + shape.lanes[parseInt(laneIndex.toString(), 10)].id + '_' + l + '_header', style: shape.lanes[parseInt(laneIndex.toString(), 10)].header.style, annotations: [cloneObject(shape.lanes[parseInt(laneIndex.toString(), 10)].header.annotation)], offsetX: object.offsetX, offsetY: object.offsetY, rowIndex: rowValue, columnIndex: colValue, container: { type: 'Canvas', orientation: orientation ? 'Horizontal' : 'Vertical' } }; laneNode.annotations[0].rotateAngle = orientation ? 270 : 0; shape.lanes[parseInt(laneIndex.toString(), 10)].header.id = laneNode.id; // eslint-disable-next-line (orientation) ? laneNode.width = shape.lanes[laneIndex].header.width : laneNode.height = shape.lanes[parseInt(laneIndex.toString(), 10)].header.height; if (!canSelect(object)) { laneNode.constraints &= ~NodeConstraints.Select; } childWrapper = addObjectToGrid(diagram, grid, object, laneNode, false, false, true, shape.lanes[parseInt(laneIndex.toString(), 10)].id); if (orientation) { childWrapper.children[0].elementActions = childWrapper.children[0].elementActions | ElementAction.HorizontalLaneHeader; } parentWrapper.children.push(childWrapper); } grid.addObject(parentWrapper, rowValue, colValue); if (!orientation) { rowValue++; } colValue = orientation ? l : laneIndex + 1; } } /** * createRow method \ * * @returns {void} createRow method .\ * @param { RowDefinition[]} row - provide the row value. * @param {number} height - provide the height value. * @private */ export function createRow(row, height) { var rows = new RowDefinition(); rows.height = height; row.push(rows); } /** * createColumn method \ * * @returns {void} createColumn method .\ * @param {number} width - provide the width value. * @private */ export function createColumn(width) { var cols = new ColumnDefinition(); cols.width = width; return cols; } /** * initGridRow method \ * * @returns {void} initGridRow method .\ * @param {RowDefinition[]} row - provide the row value. * @param {boolean} orientation - provide the row value. * @param {NodeModel} object - provide the row value. * @private */ export function initGridRow(row, orientation, object) { var totalHeight = 0; var height; var shape = object.shape; if (row.length > 0) { for (var i = 0; i < row.length; i++) { totalHeight += row[parseInt(i.toString(), 10)].height; } } if (orientation) { if (shape.phases.length > 0 && shape.phaseSize) { totalHeight += shape.phaseSize; createRow(row, shape.phaseSize); } if (shape.lanes.length > 0) { for (var i = 0; i < shape.lanes.length; i++) { height = shape.lanes[parseInt(i.toString(), 10)].height; totalHeight += height; if (i === shape.lanes.length - 1 && totalHeight < object.height) { height += object.height - totalHeight; } createRow(row, height); } } } else { if (shape.phases.length > 0) { var phaseHeight = 0; for (var i = 0; i < shape.phases.length; i++) { var phaseOffset = shape.phases[parseInt(i.toString(), 10)].offset; if (i === 0) { phaseHeight += phaseOffset; } else { phaseOffset -= phaseHeight; phaseHeight += phaseOffset; } height = phaseOffset; totalHeight += height; if (i === shape.phases.length - 1 && totalHeight < object.height) { height += object.height - totalHeight; } createRow(row, height); } } else { createRow(row, object.height); } } } /** * initGridColumns method \ * * @returns {void} initGridRow method .\ * @param {ColumnDefinition[]} columns - provide the row value. * @param {boolean} orientation - provide the row value. * @param {NodeModel} object - provide the row value. * @private */ export function initGridColumns(columns, orientation, object) { var totalWidth = 0; var shape = object.shape; var phaseOffset; var cols; var k; var j; var value; if (shape.phases.length > 0 && shape.orientation === 'Horizontal') { for (j = 0; j < shape.phases.length; j++) { phaseOffset = shape.phases[parseInt(j.toString(), 10)].offset; if (j === 0) { totalWidth += phaseOffset; } else { phaseOffset -= totalWidth; totalWidth += phaseOffset; } cols = createColumn(phaseOffset); if (j === shape.phases.length - 1 && totalWidth < object.width) { cols.width += object.width - totalWidth; } columns.push(cols); } } else if (!orientation) { value = (shape.phaseSize && shape.phases.length > 0) ? shape.lanes.length + 1 : shape.lanes.length; if (shape.phaseSize && shape.phases.length > 0) { totalWidth += shape.phaseSize; cols = createColumn(shape.phaseSize); columns.push(cols); } for (k = 0; k < shape.lanes.length; k++) { totalWidth += shape.lanes[parseInt(k.toString(), 10)].width; cols = createColumn(shape.lanes[parseInt(k.toString(), 10)].width); if (k === shape.lanes.length - 1 && totalWidth < object.width) { cols.width += object.width - totalWidth; } columns.push(cols); } if ((shape.phases.length === 0 && shape.lanes.length === 0)) { cols = createColumn(object.width); columns.push(cols); } } else { cols = createColumn(object.width); columns.push(cols); } } /** * getConnectors method \ * * @returns {void} getConnectors method .\ * @param {Diagram} diagram - provide the row value. * @param {GridPanel} grid - provide the row value. * @param {number} rowIndex - provide the row value. * @param {boolean} isRowUpdate - provide the row value. * @private */ export function getConnectors(diagram, grid, rowIndex, isRowUpdate) { var connectors = []; var conn = 0; var childNode; var node; var k; var i; var j; var canvas; var row; var length = grid.rowDefinitions().length; var edges; for (var i_1 = 0; i_1 < length; i_1++) { row = grid.rows[parseInt(i_1.toString(), 10)]; for (j = 0; j < row.cells.length; j++) { canvas = row.cells[parseInt(j.toString(), 10)].children[0]; if (canvas && canvas.children && canvas.children.length) { for (k = 1; k < canvas.children.length; k++) { childNode = canvas.children[parseInt(k.toString(), 10)]; node = diagram.getObject(childNode.id); if (node && (node.inEdges.length > 0 || node.outEdges.length > 0)) { edges = node.inEdges.concat(node.outEdges); for (conn = 0; conn < edges.length; conn++) { if (connectors.indexOf(edges[parseInt(conn.toString(), 10)]) === -1) { connectors.push(edges[parseInt(conn.toString(), 10)]); } } } } } } } return connectors; } /** * swimLaneMeasureAndArrange method \ * * @returns {void} swimLaneMeasureAndArrange method .\ * @param {NodeModel} obj - provide the row value. * @private */ export function swimLaneMeasureAndArrange(obj) { var canvas = obj.wrapper; canvas.measure(new Size(obj.width, obj.height)); if (canvas.children[0] instanceof GridPanel) { var grid = canvas.children[0]; var isMeasure = false; if (grid.width && grid.width < grid.desiredSize.width) { isMeasure = true; grid.width = grid.desiredSize.width; } if (grid.height && grid.height < grid.desiredSize.height) { isMeasure = true; grid.height = grid.desiredSize.height; } if (isMeasure) { grid.measure(new Size(grid.width, grid.height)); } } canvas.arrange(canvas.desiredSize); } /** * ChangeLaneIndex method \ * * @returns {void} ChangeLaneIndex method .\ * @param {Diagram} diagram - provide the row value. * @param {NodeModel} obj - provide the row value. * @param {number} startRowIndex - provide the row value. * @private */ export function ChangeLaneIndex(diagram, obj, startRowIndex) { var container = obj.wrapper.children[0]; var i; var j; var k; var l; var object; var subChild; var row; var cell; var child; for (i = startRowIndex; i < container.rows.length; i++) { row = container.rows[parseInt(i.toString(), 10)]; for (j = 0; j < row.cells.length; j++) { cell = row.cells[parseInt(j.toString(), 10)]; if (cell.children && cell.children.length > 0) { for (k = 0; k < cell.children.length; k++) { child = cell.children[parseInt(k.toString(), 10)]; object = diagram.nameTable[child.id]; if (object.isLane && child.children.length > 1) { // 912905: Multi-selecting and deleting swimlane objects causes the diagram to break for (l = 1; l < child.children.length; l++) { subChild = diagram.nameTable[child.children[parseInt(l.toString(), 10)].id]; if (subChild && subChild.isLane) { subChild.rowIndex = i; subChild.columnIndex = j; } } } object.rowIndex = i; object.columnIndex = j; } } } } } /** * arrangeChildNodesInSwimLane method \ * * @returns {void} arrangeChildNodesInSwimLane method .\ * @param {Diagram} diagram - provide the row value. * @param {NodeModel} obj - provide the row value. * @private */ export function arrangeChildNodesInSwimLane(diagram, obj) { var grid = obj.wrapper.children[0]; var shape = obj.shape; var padding = shape.padding; var lanes = shape.lanes; var top = grid.bounds.y; var rowvalue; var columnValue; var phaseCount = (shape.phaseSize > 0) ? shape.phases.length : 0; var node; var canvas; var cell; var i; var j; var k; var orientation = shape.orientation === 'Horizontal' ? true : false; var col = orientation ? shape.phases.length || 1 : lanes.length + 1; var row = orientation ? ((shape.header && shape.hasHeader) ? 1 : 0) + (shape.phases.length > 0 ? 1 : 0) + (shape.lanes.length) : (shape.header && shape.hasHeader ? 1 : 0) + shape.phases.length; if (phaseCount === 0 && !orientation && shape.lanes.length) { row += 1; } if (orientation) { rowvalue = (shape.header && shape.hasHeader ? 1 : 0) + (phaseCount > 0 ? 1 : 0); columnValue = 0; } else { rowvalue = (shape.header && shape.hasHeader ? 1 : 0); columnValue = phaseCount > 0 ? 1 : 0; } if (lanes.length > 0) { top += (shape.header && shape.hasHeader) ? shape.header.height : 0; for (i = 0; i < lanes.length; i++) { for (j = 0; j < lanes[parseInt(i.toString(), 10)].children.length; j++) { node = lanes[parseInt(i.toString(), 10)].children[parseInt(j.toString(), 10)]; node.offsetX = lanes[parseInt(i.toString(), 10)].width; node.offsetY = lanes[parseInt(i.toString(), 10)].height; diagram.initObject(node); diagram.nodes.push(node); canvas = node.wrapper; if (orientation) { for (k = columnValue; k < col; k++) { cell = grid.rows[parseInt(rowvalue.toString(), 10)].cells[parseInt(k.toString(), 10)]; if (canvas.margin.left < (cell.bounds.right - grid.bounds.x)) { node.parentId = cell.children[0].id; if (k > columnValue) { canvas.margin.left = canvas.margin.left - (cell.bounds.left - grid.bounds.left); } else { if ((cell.children[0].children[1].actualSize.width + padding) >= canvas.margin.left) { canvas.margin.left = cell.children[0].children[1].actualSize.width + padding; } } if (canvas.margin.left < padding) { canvas.margin.left = padding; } if (canvas.margin.top < padding) { canvas.margin.top = padding; } addChildToLane(canvas, node, diagram); break; } } } else { for (var k_1 = rowvalue; k_1 < row; k_1++) { cell = grid.rows[parseInt(k_1.toString(), 10)].cells[parseInt(columnValue.toString(), 10)]; if (canvas.margin.top < (cell.bounds.bottom - top)) { node.parentId = cell.children[0].id; if (k_1 > rowvalue) { canvas.margin.top = canvas.margin.top - (cell.bounds.top - top); } else { if ((cell.children[0].children[1].actualSize.height + padding) >= canvas.margin.top) { canvas.margin.top = cell.children[0].children[1].actualSize.height + padding; } } if (canvas.margin.left < padding) { canvas.margin.left = padding; } if (canvas.margin.top < padding) { canvas.margin.top = padding; } addChildToLane(canvas, node, diagram); break; } } } } // eslint-disable-next-line orientation ? rowvalue++ : columnValue++; } } grid.measure(new Size(obj.width, obj.height)); grid.arrange(grid.desiredSize); updateChildOuterBounds(grid, obj); obj.width = obj.wrapper.width = grid.width; obj.height = obj.wrapper.height = grid.height; updateHeaderMaxWidth(diagram, obj); obj.wrapper.measure(new Size(obj.width, obj.height)); obj.wrapper.arrange(grid.desiredSize); checkLaneChildrenOffset(obj); checkPhaseOffset(obj, diagram); checkLaneSize(obj); } /** * addChildToLane method \ * * @returns {void} addChildToLane method .\ * @param {GroupableView} canvas - provide the row value. * @param {NodeModel} node - provide the row value. * @param {Diagram} diagram - provide the row value. * @private */ function addChildToLane(canvas, node, diagram) { canvas.measure(new Size(node.width, node.height)); canvas.arrange(canvas.desiredSize); var parent = diagram.getObject(node.parentId); diagram.addChild(parent, node.id); } /** * updateChildOuterBounds method \ * * @returns {void} updateChildOuterBounds method .\ * @param {GridPanel} grid - provide the row value. * @param {NodeModel} obj - provide the row value. * @private */ export function updateChildOuterBounds(grid, obj) { var columnDefinitions = grid.columnDefinitions(); var rowDefinitions = grid.rowDefinitions(); var i; var k; var j; var cell; var child; var row; var rowIndex = findStartLaneIndex(obj); if (obj.shape.orientation === 'Vertical') { if (rowIndex === 0) { rowIndex = (obj.shape.header && obj.shape.hasHeader) ? 1 : 0; } } var padding = obj.shape.padding; for (i = 0; i < columnDefinitions.length; i++) { grid.updateColumnWidth(i, columnDefinitions[parseInt(i.toString(), 10)].width, true, padding); } for (i = rowIndex; i < rowDefinitions.length; i++) { grid.updateRowHeight(i, rowDefinitions[parseInt(i.toString(), 10)].height, true, padding); } for (k = 0; k < rowDefinitions.length; k++) { row = grid.rows[parseInt(k.toString(), 10)]; for (i = 0; i < columnDefinitions.length; i++) { cell = row.cells[parseInt(i.toString(), 10)]; if (cell.children && cell.children.length > 0) { for (j = 0; j < cell.children.length; j++) { child = cell.children[parseInt(j.toString(), 10)]; if (child.maxWidth) { child.maxWidth = cell.actualSize.width; } if (child.maxHeight) { child.maxHeight = cell.actualSize.height; } } } } } } /** * checkLaneSize method \ * * @returns {void} checkLaneSize method .\ * @param {NodeModel} obj - provide the row value. * @private */ export function checkLaneSize(obj) { if (obj.shape.type === 'SwimLane' && !obj.shape.isLane && !obj.shape.isPhase) { // 910832 - Lane height updating to negative values wrongly during resizing var lane = void 0; var i = void 0; var j = void 0; var k = void 0; var size = void 0; //let laneCount: number = 0; var lanes = obj.shape.lanes; var laneIndex = findStartLaneIndex(obj); var rows = obj.wrapper.children[0].rowDefinitions(); var columns = obj.wrapper.children[0].columnDefinitions(); var widthSize = void 0; var heightSize = void 0; for (i = 0; i < lanes.length; i++, laneIndex++) { lane = lanes[parseInt(i.toString(), 10)]; if (obj.shape.orientation === 'Horizontal') { size = rows[parseInt(laneIndex.toString(), 10)].height; if (lane.height !== size) { lane.height = size; } for (j = 0; j < columns.length; j++) { widthSize = columns[parseInt(j.toString(), 10)].width; if (lane.width !== widthSize) { lane.width = widthSize; } } } else { size = columns[parseInt(laneIndex.toString(), 10)].width; if (lane.width !== size) { lane.width = size; } for (k = 0; k < rows.length; k++) { heightSize = rows[parseInt(k.toString(), 10)].height; if (lane.height !== heightSize) { lane.height = heightSize; } } } } } } /** * checkPhaseOffset method \ * * @returns {void} checkPhaseOffset method .\ * @param {NodeModel} obj - provide the obj value. * @param {Diagram} diagram - provide the obj value. * @private */ export function checkPhaseOffset(obj, diagram) { var shape = obj.shape; var phases = shape.phases; var i; var offset; var phaseRow; var phase; var gridRowIndex = (shape.header && shape.hasHeader) ? 1 : 0; var grid = obj.wrapper.children[0]; var top = grid.bounds.y + ((shape.header && shape.hasHeader) ? shape.header.height : 0); if (obj.shape.type === 'SwimLane') { obj = diagram.getObject(obj.id) || obj; if (phases.length > 0) { grid = obj.wrapper.children[0]; if (shape.orientation === 'Horizontal') { phaseRow = (shape.header && shape.hasHeader) ? grid.rows[1] : grid.rows[0]; for (i = 0; i < phases.length; i++) { phase = phaseRow.cells[parseInt(i.toString(), 10)].children[0]; offset = phase.bounds.right - grid.bounds.x; if (phases[parseInt(i.toString(), 10)].offset !== offset) { phases[parseInt(i.toString(), 10)].offset = offset; } diagram.nameTable[phase.id].maxWidth = phase.maxWidth; } } else { for (i = 0; i < phases.length; i++) { phase = grid.rows[gridRowIndex + i].cells[0].children[0]; offset = phase.bounds.bottom - top; if (phases[parseInt(i.toString(), 10)].offset !== offset) { phases[parseInt(i.toString(), 10)].offset = offset; } diagram.nameTable[phase.id].maxWidth = phase.maxWidth; } } } } } /** * updateConnectorsProperties method \ * * @returns {void} checkPhaseOffset method .\ * @param {string[]} connectors - provide the obj value. * @param {Diagram} diagram - provide the obj value. * @private */ export function updateConnectorsProperties(connectors, diagram) { if (connectors && connectors.length > 0) { var edges = void 0; if (diagram.lineRoutingModule && (diagram.constraints & DiagramConstraints.LineRouting)) { if (diagram.avoidLineOverlappingModule) { diagram.avoidLineOverlappingModule.removeConnectors(connectors); } diagram.lineRoutingModule.renderVirtualRegion(diagram, true); } for (var i = 0; i < connectors.length; i++) { edges = diagram.getObject(connectors[parseInt(i.toString(), 10)]); if (diagram.lineRoutingModule && (diagram.constraints & DiagramConstraints.LineRouting) && edges.type === 'Orthogonal') { diagram.lineRoutingModule.refreshConnectorSegments(diagram, edges, true); } else { diagram.connectorPropertyChange(edges, {}, { sourceID: edges.sourceID, targetID: edges.targetID }); } } } } /** * laneInterChanged method \ * * @returns {void} laneInterChanged method .\ * @param {Diagram} diagram - provide the diagram value. * @param {NodeModel} obj - provide the obj value. * @param {NodeModel} target - provide the target value. * @param {PointModel} position - provide the position value. * @private */ export function laneInterChanged(diagram, obj, target, position) { var index; var undoElement; var entry; var redoElement; var sourceIndex; var targetIndex; var temp; var sourceLaneIndex; var targetLaneIndex; var rowIndex; var swimLane = (diagram.getObject(obj.parentId)); var shape = swimLane.shape; var grid = swimLane.wrapper.children[0]; var lanes = shape.lanes; var connectors = getConnectors(diagram, grid, obj.rowIndex, true); if ((shape.orientation === 'Horizontal' && obj.rowIndex !== target.rowIndex) || (shape.orientation === 'Vertical' && obj.columnIndex !== target.columnIndex)) { if (shape.orientation === 'Horizontal') { sourceIndex = obj.rowIndex; targetIndex = target.rowIndex; index = ((shape.header && shape.hasHeader) ? 1 : 0) + (shape.phases.length && shape.phaseSize ? 1 : 0); sourceLaneIndex = obj.rowIndex - index; targetLaneIndex = target.rowIndex - index; if (lanes[parseInt(sourceLaneIndex.toString(), 10)].canMove) { if (sourceLaneIndex < targetLaneIndex) { if (position && target.wrapper.offsetY > position.y) { targetIndex += (targetLaneIndex > 0) ? -1 : 1; targetLaneIndex += (targetLaneIndex > 0) ? -1 : 1; } } else { if (position && target.wrapper.offsetY < position.y) { targetIndex += 1; targetLaneIndex += 1; } } if (sourceIndex !== targetIndex) { grid.updateRowIndex(sourceIndex, targetIndex); //To update the laneGrids arrangement after swaping lanes updatePhaseLaneGrids(sourceLaneIndex, targetLaneIndex, swimLane, diagram); } } } else { sourceIndex = obj.columnIndex; targetIndex = target.columnIndex; index = (shape.phases.length && shape.phaseSize) ? 1 : 0; sourceLaneIndex = obj.columnIndex - index; targetLaneIndex = target.columnIndex - index; rowIndex = (shape.header && shape.hasHeader) ? 1 : 0; if (lanes[parseInt(sourceLaneIndex.toString(), 10)].canMove) { if (sourceLaneIndex < targetLaneIndex) { if (position && target.wrapper.offsetX > position.x) { targetIndex += (targetLaneIndex > 0) ? -1 : 1; targetLaneIndex += (targetLaneIndex > 0) ? -1 : 1; } } else { if (position && target.wrapper.offsetX < position.x) { targetIndex += 1; targetLaneIndex += 1; } } if (sourceIndex !== targetIndex) { if ((shape.phaseSize === 0 || shape.phases.length === 0) && (targetIndex === 0 || sourceIndex === 0)) { if (shape.header && shape.hasHeader) { var changeHeaderIndex = (targetIndex === 0) ? sourceIndex : targetIndex; grid.rows[0].cells[parseInt(changeHeaderIndex.toString(), 10)].children = grid.rows[0].cells[0].children; grid.rows[0].cells[parseInt(changeHeaderIndex.toString(), 10)].columnSpan = grid.rows[0].cells[0].columnSpan; grid.rows[0].cells[0].children = []; } } grid.updateColumnIndex(0, sourceIndex, targetIndex); //To update the laneGrids arrangement after swaping lanes updatePhaseLaneGrids(sourceLaneIndex, targetLaneIndex, swimLane, diagram); } } } if (sourceIndex !== targetIndex) { temp = lanes[parseInt(sourceLaneIndex.toString(), 10)]; if (temp.canMove) { undoElement = { target: cloneObject(target), source: cloneObject(obj) }; temp = lanes[parseInt(sourceLaneIndex.toString(), 10)]; lanes.splice(sourceLaneIndex, 1); lanes.splice(targetLaneIndex, 0, temp); redoElement = { target: cloneObject(undoElement.source), source: cloneObject(undoElement.target) }; entry = { type: 'LanePositionChanged', redoObject: redoElement, undoObject: undoElement, category: 'Internal' }; if (!(diagram.diagramActions & DiagramAction.UndoRedo)) { diagram.commandHandler.addHistoryEntry(entry); } ChangeLaneIndex(diagram, swimLane, 0); updateConnectorsProperties(connectors, diagram); updateSwimLaneChildPosition(lanes, diagram); swimLane.wrapper.measure(new Size(swimLane.width, swimLane.height)); swimLane.wrapper.arrange(swimLane.wrapper.desiredSize); diagram.updateDiagramObject(swimLane); } } } diagram.updateDiagramElementQuad(); } /** * Swaps the positions of two lane grid entries within each phase of a swimlane. * * @param {number} sourceIndex - The index of the lane grid to be moved. * @param {number} targetIndex - The index where the lane grid should be moved to. * @param {NodeModel} swimlane - The swimlane node containing the phases. * @param {Diagram} diagram - The diagram instance containing the node data. * @returns {void} * @private */ export function updatePhaseLaneGrids(sourceIndex, targetIndex, swimlane, diagram) { var phases = swimlane.shape.phases; if (phases && phases.length > 0) { for (var i = 0; i < phases.length; i++) { var phaseId = swimlane.id + phases[parseInt(i.toString(), 10)].id + '_header'; var phaseObj = diagram.nameTable["" + phaseId]; if (phaseObj && phaseObj.laneGrids && sourceIndex >= 0 && targetIndex >= 0 && sourceIndex < phaseObj.laneGrids.length && targetIndex < phaseObj.laneGrids.length) { // Remove the element at sourceIndex var removed = phaseObj.laneGrids.splice(sourceIndex, 1)[0]; // Insert it at targetIndex phaseObj.laneGrids.splice(targetIndex, 0, removed); } } } } /** * updateSwimLaneObject method \ * * @returns {void} updateSwimLaneObject method .\ * @param {Diagram} diagram - provide the diagram value. * @param {Node} obj - provide the obj value. * @param {NodeModel} swimLane - provide the target value. * @param {NodeModel} helperObject - provide the position value. * @param {number} widthDiff - provide the difference in colum width. * @param {number} heightDiff - provide the difference in row height. * @private */ export function updateSwimLaneObject(diagram, obj, swimLane, helperObject, widthDiff, heightDiff) { var parentNode = diagram.getObject(swimLane.id); var shape = parentNode.shape; var index = (shape.header && shape.hasHeader) ? 1 : 0; var lanes = shape.lanes; var phases = shape.phases; var helperWidth = helperObject.wrapper.actualSize.width; var helperHeight = helperObject.wrapper.actualSize.height; var objWidth = obj.wrapper.actualSize.width; var objHeight = obj.wrapper.actualSize.height; var i; var j; var isUndoRedo = false; if (diagram.diagramActions & DiagramAction.UndoRedo) { isUndoRedo = true; } var grid = parentNode.wrapper.children[0]; // 910832 - Lane height updating to negative values wrongly during resizing if (parentNode.shape.type === 'SwimLane') { if (shape.orientation === 'Horizontal') { if (obj.isPhase) { // phases[obj.columnIndex].offset = obj.wrapper.width; for (var p = obj.columnIndex; p < phases.length; p++) { phases[parseInt(p.toString(), 10)].offset += widthDiff; //929543: To get the minWidth of phase and if the updated size less than min width then we set minWindth. var curPhase = diagram.nameTable[phases[parseInt(p.toString(), 10)].header.id]; if (curPhase) { var gridPhase = grid.rows[curPhase.rowIndex].cells[curPhase.columnIndex]; var gridPhaseMinWidth = gridPhase.minWidth; if (phases[parseInt(p.toString(), 10)].offset < gridPhaseMinWidth && !isUndoRedo) { phases[parseInt(p.toString(), 10)].offset = gridPhaseMinWidth; } } } for (i = 0; i < lanes.length; i++) { lanes[parseInt(i.toString(), 10)].width = (!isUndoRedo ? obj.wrapper.width : helperWidth); } } else { index = (shape.phaseSize && shape.phases.length > 0) ? index + 1 : index; lanes[(obj.rowIndex - index)].height = (!isUndoRedo ? obj.wrapper.height : helperHeight); } } else { if (obj.isPhase) { // phases[(obj.rowIndex - index)].offset = obj.wrapper.height; for (var p = obj.rowIndex - index; p < phases.length; p++) { phases[parseInt(p.toString(), 10)].offset += heightDiff; //929543: To get the minHeight of phase and if the updated size less than min height then we set minHeight var curPhase = diagram.nameTable[phases[parseInt(p.toString(), 10)].header.id]; if (curPhase) { var gridPhase = grid.rows[curPhase.rowIndex].cells[curPhase.columnIndex]; var gridPhaseMinHeight = gridPhase.minHeight; if (phases[parseInt(p.toString(), 10)].offset < gridPhaseMinHeight && !isUndoRedo) { phases[parseInt(p.toString(), 10)].offset = gridPhaseMinHeight; } } } for (j = 0; j < lanes.length; j++) { lanes[parseInt(j.toString(), 10)].height = obj.wrapper.height; } } else { index = (shape.phaseSize && shape.phases.length > 0) ? 1 : 0; lanes[(obj.columnIndex - index)].width = obj.wrapper.width; } } } } /** * findLaneIndex method \ * * @returns {number} findLaneIndex method .\ * @param {NodeModel} swimLane - provide the diagram value. * @param {NodeModel} laneObj - provide the obj value. * @private */ export function findLaneIndex(swimLane, laneObj) { var laneIndex; var shape = swimLane.shape; var index = (shape.header && shape.hasHeader) ? 1 : 0; if (shape.orientation === 'Horizontal') { index += shape.phases.length > 0 ? 1 : 0; laneIndex = laneObj.rowIndex - index; } else { laneIndex = laneObj.columnIndex - (shape.phaseSize && shape.phases.length > 0 ? 1 : 0); } return laneIndex; } /** * findPhaseIndex method \ * * @returns {number} findPhaseIndex method .\ * @param {NodeModel} phase - provide the diagram value. * @param {NodeModel} swimLane - provide the obj value. * @private */ export function findPhaseIndex(phase, swimLane) { var shape = swimLane.shape; var index = (shape.header && shape.hasHeader) ? 1 : 0; var phaseIndex = (shape.orientation === 'Horizontal') ? phase.columnIndex : phase.rowIndex - index; return phaseIndex; } /** * findStartLaneIndex method \ * * @returns {number} findStartLaneIndex method .\ * @param {NodeModel} swimLane - provide the obj value. * @private */ export function findStartLaneIndex(swimLane) { var index = 0; var shape = swimLane.shape; if (shape.orientation === 'Horizontal') { index = (shape.header && shape.hasHeader) ? 1 : 0; } if (shape.phases.length > 0 && shape.phaseSize) { index += 1; } return index; } /** * updatePhaseMaxWidth method \ * * @returns {void} updatePhaseMaxWidth method .\ * @param {NodeModel} parent - provide the obj value. * @param {Diagram} diagram - provide the obj value. * @param {Canvas} wrapper - provide the obj value. * @param {number} columnIndex - provide the obj value. * @private */ export function updatePhaseMaxWidth(parent, diagram, wrapper, columnIndex) { var shape = parent.shape; if (shape.phases.length > 0) { var node = diagram.nameTable[shape.phases[parseInt(columnIndex.toString(), 10)].header.id]; if (node && node.maxWidth < wrapper.outerBounds.width) { node.maxWidth = wrapper.outerBounds.width; node.wrapper.maxWidth = wrapper.outerBounds.width; } } } /** * updateHeaderMaxWidth method \ * * @returns {void} updateHeaderMaxWidth method .\ * @param {NodeModel} diagram - provide the obj value. * @param {NodeModel} swimLane - provide the obj value. * @private */ export function updateHeaderMaxWidth(diagram, swimLane) { if (swimLane.shape.header && swimLane.shape.hasHeader) { var grid = swimLane.wrapper.children[0]; var id = grid.rows[0].cells[0].children[0].id; var headerNode = diagram.nameTable["" + id]; if (headerNode && headerNode.isHeader && (headerNode.maxWidth < swimLane.width || headerNode.wrapper.maxWidth < swimLane.width)) { headerNode.maxWidth = swimLane.width; headerNode.wrapper.maxWidth = swimLane.width; } } } /** * addLane method \ * * @returns {void} addLane method .\ * @param {Diagram} diagram - provide the obj value. * @param {NodeModel} parent - provide the obj value. * @param {LaneModel} lane - provide the obj value. * @param {number} count - provide the obj value. * @private */ export function addLane(diagram, parent, lane, count) { var args; var swimLane = diagram.nameTable[parent.id]; if (swimLane.shape.type === 'SwimLane') { diagram.protectPropertyChange(true); var grid = swimLane.wrapper.children[0]; var bounds = grid.bounds; var shape = swimLane.shape; var redoObj = void 0; var orientation_1 = false; var entry = void 0; var index = void 0; var children = void 0; var j = void 0; var i = void 0; var c = void 0; var cell = void 0; var child = void 0; var point = void 0; var laneObj = new Lane(shape, 'lanes', lane, true); //To set default height and width incase of undefined height or width. lane.height = lane.height || laneObj.height; lane.width = lane.width || laneObj.width; //913805-perform undo/redo for headerless swimlane,the change won't be properly reverted. index = (shape.orientation === 'Vertical') ? 1 : (shape.header && shape.hasHeader) ? 1 : 0; if (shape.orientation === 'Horizontal') { orientation_1 = true; index = shape.phases.length > 0 ? index + 1 : index; } var connectors = getConnectors(diagram, grid, 0, true); var laneIndex = (count !== undefined) ? count : shape.lanes.length; index += laneIndex; args = { element: laneObj, cause: diagram.diagramActions, diagramAction: diagram.itemType, state: 'Changing', type: 'Addition', cancel: false, laneIndex: laneIndex }; diagram.triggerEvent(DiagramEvent.collectionChange, args); if (!args.cancel) { if (orientation_1) { var rowDef = new RowDefinition(); rowDef.height = lane.height; grid.addRow(index, rowDef, false); swimLane.height = (swimLane.height !== undefined) ? swimLane.height + lane.height : swimLane.height; swimLane.wrapper.height = grid.height = swimLane.height; } else { var colDef = new ColumnDefinition(); colDef.width = lane.width; grid.addColumn(laneIndex + 1, colDef, false); if (swimLane.width) { swimLa