UNPKG

gojs

Version:

Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams

535 lines (534 loc) 26.5 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); define(["require", "exports", "../../../release/go"], function (require, exports, go) { "use strict"; var WallReshapingTool = (function (_super) { __extends(WallReshapingTool, _super); function WallReshapingTool() { var _this = _super.call(this) || this; _this.makeAdornment = function (selelt) { var adornment = new go.Adornment; adornment.type = go.Panel.Spot; adornment.locationObjectName = "BODY"; adornment.locationSpot = go.Spot.Center; var h = new go.Shape(); h.name = "BODY"; h.fill = null; h.stroke = null; h.strokeWidth = 0; adornment.add(h); h = this.makeHandle(); h.name = 'sPt'; adornment.add(h); h = this.makeHandle(); h.name = 'ePt'; adornment.add(h); adornment.category = this.name; adornment.adornedObject = selelt; return adornment; }; _this.makeHandle = function () { var h = this.handleArchetype; return h.copy(); }; _this.calcAngleAndLengthFromHandle = function (mousePt) { var tool = this; var diagram = this.diagram; var h = this.handle; var otherH; var node = this.adornedShape.part; var adornments = node.adornments.iterator; var adornment; adornments.each(function (a) { if (a.category === tool.name) adornment = a; }); adornment.elements.each(function (e) { if (e.name != undefined && e.name != h.name) { otherH = e; } }); var otherHandlePt = otherH.getDocumentPoint(go.Spot.Center); var deltaY = mousePt.y - otherHandlePt.y; var deltaX = mousePt.x - otherHandlePt.x; var angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI); if (angle < 0) angle += 360; tool.angle = angle; var distanceBetween = Math.sqrt(mousePt.distanceSquared(otherHandlePt.x, otherHandlePt.y)); tool.length = distanceBetween; }; _this.snapPointToGrid = function (point) { var diagram = this.diagram; var newx = diagram.model.modelData.gridSize * Math.round(point.x / diagram.model.modelData.gridSize); var newy = diagram.model.modelData.gridSize * Math.round(point.y / diagram.model.modelData.gridSize); var newPt = new go.Point(newx, newy); return newPt; }; _this.reshape = function (newPoint) { var diagram = this.diagram; var tool = this; var shape = this.adornedShape; var node = shape.part; if (this.diagram.lastInput.shift) { var sPt = void 0; if (tool.handle.name === 'sPt') sPt = node.data.endpoint; else sPt = node.data.startpoint; var oldGridSize = diagram.model.modelData.gridSize; var gridSize = diagram.model.modelData.gridSize; if (!(this.diagram.toolManager.draggingTool.isGridSnapEnabled)) gridSize = 1; var angle = tool.angle; var length_1 = tool.length; if (angle > 67.5 && angle < 112.5) { var newy = sPt.y + length_1; newy = gridSize * Math.round(newy / gridSize); newPoint = new go.Point(sPt.x, newy); } if (angle > 112.5 && angle < 202.5) { var newx = sPt.x - length_1; newx = gridSize * Math.round(newx / gridSize); newPoint = new go.Point(newx, sPt.y); } if (angle > 247.5 && angle < 292.5) { var newy = sPt.y - length_1; newy = gridSize * Math.round(newy / gridSize); newPoint = new go.Point(sPt.x, newy); } if (angle > 337.5 || angle < 22.5) { var newx = sPt.x + length_1; newx = gridSize * Math.round(newx / gridSize); newPoint = new go.Point(newx, sPt.y); } if (angle > 22.5 && angle < 67.5) { var newx = (Math.sin(.785) * length_1); newx = gridSize * Math.round(newx / gridSize) + sPt.x; var newy = (Math.cos(.785) * length_1); newy = gridSize * Math.round(newy / gridSize) + sPt.y; newPoint = new go.Point(newx, newy); } if (angle > 112.5 && angle < 157.5) { var newx = (Math.sin(.785) * length_1); newx = sPt.x - (gridSize * Math.round(newx / gridSize)); var newy = (Math.cos(.785) * length_1); newy = gridSize * Math.round(newy / gridSize) + sPt.y; newPoint = new go.Point(newx, newy); } if (angle > 202.5 && angle < 247.5) { var newx = (Math.sin(.785) * length_1); newx = sPt.x - (gridSize * Math.round(newx / gridSize)); var newy = (Math.cos(.785) * length_1); newy = sPt.y - (gridSize * Math.round(newy / gridSize)); newPoint = new go.Point(newx, newy); } if (angle > 292.5 && angle < 337.5) { var newx = (Math.sin(.785) * length_1); newx = sPt.x + (gridSize * Math.round(newx / gridSize)); var newy = (Math.cos(.785) * length_1); newy = sPt.y - (gridSize * Math.round(newy / gridSize)); newPoint = new go.Point(newx, newy); } gridSize = oldGridSize; } if (this.diagram.toolManager.draggingTool.isGridSnapEnabled) newPoint = this.snapPointToGrid(newPoint); else newPoint = new go.Point(newPoint.x, newPoint.y); var type = this.handle.name; if (type === undefined) return; switch (type) { case 'sPt': reshapeWall(node, node.data.endpoint, node.data.startpoint, newPoint, diagram, tool); break; case 'ePt': reshapeWall(node, node.data.startpoint, node.data.endpoint, newPoint, diagram, tool); break; } this.updateAdornments(shape.part); this.showMatches(); var fp = diagram; fp.updateWallDimensions(); }; _this.showMatches = function () { var diagram = this.diagram; if (!diagram.model.modelData.preferences.showWallGuidelines) return; var tool = this; var wall = this.adornedShape.part; var comparePt; if (this.handle.name === 'sPt') comparePt = wall.data.startpoint; else comparePt = wall.data.endpoint; var hWall = this.adornedShape.part; var glPoints = diagram.findNodesByExample({ category: 'GLPointNode' }); diagram.removeParts(glPoints, true); var walls = this.diagram.findNodesByExample({ category: 'WallGroup' }); walls.iterator.each(function (w) { if (w.data.key != hWall.data.key) { var shape = w.findObject('SHAPE'); var geo = shape.geometry; var pt1 = w.data.startpoint; var pt2 = w.data.endpoint; tool.checkPtLinedUp(pt1, comparePt.x, pt1.x, comparePt); tool.checkPtLinedUp(pt1, comparePt.y, pt1.y, comparePt); tool.checkPtLinedUp(pt2, comparePt.x, pt2.x, comparePt); tool.checkPtLinedUp(pt2, comparePt.y, pt2.y, comparePt); } }); }; _this.checkPtLinedUp = function (pt, comparePtCoord, ptCoord, comparePt) { function makeGuideLinePoint() { var $ = go.GraphObject.make; return $(go.Node, "Spot", { locationSpot: go.Spot.TopLeft, locationObjectName: "SHAPE", desiredSize: new go.Size(1, 1), }, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, { stroke: null, strokeWidth: 1, name: "SHAPE", fill: "black", })); } function makeGuideLineLink() { var $ = go.GraphObject.make; return $(go.Link, $(go.Shape, { stroke: "black", strokeWidth: 2, name: 'SHAPE', }, new go.Binding("strokeWidth", "width"), new go.Binding('stroke', 'stroke'))); } var diagram = this.diagram; var errorMargin = Math.abs(comparePtCoord - ptCoord); if (errorMargin < 2) { var data = { category: "GLPointNode", loc: go.Point.stringify(pt), key: "glpt" }; var data2 = { key: 'movingPt', category: "GLPointNode", loc: go.Point.stringify(comparePt) }; var data3 = { key: 'guideline', category: 'guideLine', from: 'movingPt', to: data.key, stroke: 'blue' }; var GLPoint1 = makeGuideLinePoint(); var GLPoint2 = makeGuideLinePoint(); var GLLink = makeGuideLineLink(); diagram.add(GLPoint1); diagram.add(GLPoint2); diagram.add(GLLink); GLPoint1.data = data; GLPoint2.data = data2; GLLink.data = data3; GLLink.fromNode = GLPoint1; GLLink.toNode = GLPoint2; } }; var h = new go.Shape(); h.figure = "Diamond"; h.desiredSize = new go.Size(7, 7); h.fill = "lightblue"; h.stroke = "dodgerblue"; h.cursor = "move"; _this._handleArchetype = h; _this._handle = null; _this._adornedShape = null; _this._reshapeObjectName = 'SHAPE'; _this._angle = 0; _this._length; _this._isBuilding = false; _this._returnPoint = null; _this._returnData = null; return _this; } Object.defineProperty(WallReshapingTool.prototype, "handleArchetype", { get: function () { return this._handleArchetype; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "handle", { get: function () { return this._handle; }, set: function (value) { this._handle = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "adornedShape", { get: function () { return this._adornedShape; }, set: function (value) { this._adornedShape = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "angle", { get: function () { return this._angle; }, set: function (value) { this._angle = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "length", { get: function () { return this._length; }, set: function (value) { this._length = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "reshapeObjectName", { get: function () { return this._reshapeObjectName; }, set: function (value) { this._reshapeObjectName = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "isBuilding", { get: function () { return this._isBuilding; }, set: function (value) { this._isBuilding = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "returnData", { get: function () { return this._returnData; }, set: function (value) { this._returnData = value; }, enumerable: true, configurable: true }); Object.defineProperty(WallReshapingTool.prototype, "returnPoint", { get: function () { return this._returnPoint; }, set: function (value) { this._returnPoint = value; }, enumerable: true, configurable: true }); WallReshapingTool.prototype.updateAdornments = function (part) { if (part === null || part instanceof go.Link) return; if (part.isSelected && !this.diagram.isReadOnly) { var selelt_go = part.findObject(this.reshapeObjectName); if (selelt_go.part.data.category === "WallGroup") { var selelt = selelt_go; var adornment = part.findAdornment(this.name); if (adornment === null) { adornment = this.makeAdornment(selelt); } if (adornment !== null && selelt.geometry != null) { var geo_1 = selelt.geometry; var b_1 = geo_1.bounds; adornment.findObject("BODY").desiredSize = b_1.size; adornment.elements.each(function (h) { if (h.name === undefined) return; var x = 0; var y = 0; switch (h.name) { case 'sPt': x = geo_1.startX; y = geo_1.startY; break; case 'ePt': x = geo_1.endX; y = geo_1.endY; break; } var xCheck = Math.min((x - b_1.x) / b_1.width, 1); var yCheck = Math.min((y - b_1.y) / b_1.height, 1); if (xCheck < 0) xCheck = 0; if (yCheck < 0) yCheck = 0; if (xCheck > 1) xCheck = 1; if (yCheck > 1) yCheck = 1; if (isNaN(xCheck)) xCheck = 0; if (isNaN(yCheck)) yCheck = 0; h.alignment = new go.Spot(Math.max(0, xCheck), Math.max(0, yCheck)); }); part.addAdornment(this.name, adornment); adornment.location = selelt.getDocumentPoint(go.Spot.Center); adornment.angle = selelt.getDocumentAngle(); return; } } } part.removeAdornment(this.name); }; WallReshapingTool.prototype.canStart = function () { if (!this.isEnabled) return false; var diagram = this.diagram; if (diagram === null || diagram.isReadOnly) return false; if (!diagram.allowReshape) return false; if (!diagram.lastInput.left) return false; var h = this.findToolHandleAt(diagram.firstInput.documentPoint, this.name); return (h !== null || this.isBuilding); }; WallReshapingTool.prototype.doActivate = function () { var diagram = this.diagram; if (diagram === null) return; if (this.isBuilding) { var wall = this.adornedShape.part; this.handle = this.findToolHandleAt(wall.data.endpoint, this.name); } else { this.handle = this.findToolHandleAt(diagram.firstInput.documentPoint, this.name); if (this.handle === null) return; var adorn = this.handle.part; var shape = adorn.adornedObject; var wall = shape.part; if (!shape) return; this.adornedShape = shape; this.returnPoint = this.snapPointToGrid(diagram.firstInput.documentPoint); var wallParts = wall.memberParts; if (wallParts.count != 0) { var locationsMap_1 = new go.Map(); wallParts.iterator.each(function (wallPart) { locationsMap_1.add(wallPart.data.key, wallPart.location); }); this.returnData = locationsMap_1; } } diagram.isMouseCaptured = true; this.startTransaction(this.name); this.isActive = true; }; WallReshapingTool.prototype.doMouseMove = function () { var diagram = this.diagram; var tool = this; var adorn = tool.handle.part; var wall = adorn.adornedPart; if (tool.isActive && diagram !== null) { var mousePt = diagram.lastInput.documentPoint; tool.calcAngleAndLengthFromHandle(mousePt); var newpt = diagram.lastInput.documentPoint; tool.reshape(newpt); } var fp = diagram; fp.updateWallAngles(); }; WallReshapingTool.prototype.doMouseUp = function () { var diagram = this.diagram; if (this.isActive && diagram !== null) { var newpt = diagram.lastInput.documentPoint; this.reshape(newpt); this.transactionResult = this.name; } this.stopTool(); }; WallReshapingTool.prototype.doDeactivate = function () { var diagram = this.diagram; var fp = diagram; var returnData = this.returnData; var adorn = this.handle.part; var wall = adorn.adornedPart; var sPt = wall.data.startpoint; var ePt = wall.data.endpoint; var length = Math.sqrt(sPt.distanceSquared(ePt.x, ePt.y)); if (length < 1) { diagram.remove(wall); wall.memberParts.iterator.each(function (member) { diagram.remove(member); }); var wallDimensionLinkPointNodes_1 = []; fp.pointNodes.iterator.each(function (node) { if (node.data.key.indexOf(wall.data.key) !== -1) wallDimensionLinkPointNodes_1.push(node); }); diagram.remove(wallDimensionLinkPointNodes_1[0]); diagram.remove(wallDimensionLinkPointNodes_1[1]); } if (diagram.lastInput.key === "Esc" && !this.isBuilding) { diagram.skipsUndoManager = true; diagram.startTransaction("reset to old data"); if (this.handle.name === "sPt") wall.data.startpoint = this.returnPoint; else wall.data.endpoint = this.returnPoint; fp.updateWall(wall); if (this.returnData) { this.returnData.iterator.each(function (kvp) { var key = kvp.key; var loc = kvp.value; var wallPart = diagram.findPartForKey(key); wallPart.location = loc; wallPart.rotateObject.angle = wall.rotateObject.angle; }); } diagram.commitTransaction("reset to old data"); diagram.skipsUndoManager = false; } var glPoints = this.diagram.findNodesByExample({ category: 'GLPointNode' }); diagram.removeParts(glPoints, true); fp.updateWallDimensions(); diagram.commitTransaction(this.name); this.isActive = false; }; return WallReshapingTool; }(go.Tool)); function reshapeWall(wall, stationaryPoint, movingPoint, newPoint, diagram, tool) { var wallParts = wall.memberParts; var arr = []; var oldAngle = wall.rotateObject.angle; wallParts.iterator.each(function (part) { arr.push(part); }); var distancesMap = new go.Map(); var closestPart = null; var closestDistance = Number.MAX_VALUE; for (var i = 0; i < arr.length; i++) { var part = arr[i]; var distanceToStationaryPt = Math.sqrt(part.location.distanceSquaredPoint(stationaryPoint)); distancesMap.add(part.data.key, distanceToStationaryPt); var endpoints = getWallPartEndpoints(part); var distanceToMovingPt = Math.min(Math.sqrt(endpoints[0].distanceSquaredPoint(movingPoint)), Math.sqrt(endpoints[1].distanceSquaredPoint(movingPoint))); if (distanceToMovingPt < closestDistance) { closestDistance = distanceToMovingPt; closestPart = part; } } if (closestPart !== null) { var loc = closestPart.location; var partLength = closestPart.data.length; var angle = oldAngle; var point1 = new go.Point((loc.x + (partLength / 2)), loc.y); var point2 = new go.Point((loc.x - (partLength / 2)), loc.y); point1.offset(-loc.x, -loc.y).rotate(angle).offset(loc.x, loc.y); point2.offset(-loc.x, -loc.y).rotate(angle).offset(loc.x, loc.y); var distance1 = Math.sqrt(stationaryPoint.distanceSquaredPoint(point1)); var distance2 = Math.sqrt(stationaryPoint.distanceSquaredPoint(point2)); var minLength = void 0; var newLoc = void 0; if (distance1 > distance2) { minLength = distance1; newLoc = point1; } else { minLength = distance2; newLoc = point2; } var testDistance = Math.sqrt(stationaryPoint.distanceSquaredPoint(newPoint)); if (testDistance < minLength) newPoint = newLoc; } if (movingPoint === wall.data.endpoint) diagram.model.setDataProperty(wall.data, "endpoint", newPoint); else diagram.model.setDataProperty(wall.data, "startpoint", newPoint); var fp = diagram; fp.updateWall(wall); var newAngle = wall.rotateObject.angle; var angleOffset = newAngle - oldAngle; distancesMap.iterator.each(function (kvp) { var wallPart = diagram.findPartForKey(kvp.key); var distance = kvp.value; var wallLength = Math.sqrt(stationaryPoint.distanceSquaredPoint(movingPoint)); var newLoc = new go.Point(stationaryPoint.x + ((distance / wallLength) * (movingPoint.x - stationaryPoint.x)), stationaryPoint.y + ((distance / wallLength) * (movingPoint.y - stationaryPoint.y))); wallPart.location = newLoc; wallPart.angle = (wallPart.angle + angleOffset) % 360; }); } function getWallPartEndpoints(wallPart) { var loc = wallPart.location; var partLength = wallPart.data.length; var angle = 0; if (wallPart.containingGroup !== null) angle = wallPart.containingGroup.rotateObject.angle; else angle = 180; var point1 = new go.Point((loc.x + (partLength / 2)), loc.y); var point2 = new go.Point((loc.x - (partLength / 2)), loc.y); point1.offset(-loc.x, -loc.y).rotate(angle).offset(loc.x, loc.y); point2.offset(-loc.x, -loc.y).rotate(angle).offset(loc.x, loc.y); var arr = []; arr.push(point1); arr.push(point2); return arr; } return WallReshapingTool; });