gojs
Version:
Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams
535 lines (534 loc) • 26.5 kB
JavaScript
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;
});