gojs
Version:
Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams
835 lines (834 loc) • 77.9 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", "./WallBuildingTool", "./WallReshapingTool"], function (require, exports, go, WallBuildingTool, WallReshapingTool) {
"use strict";
var Floorplan = (function (_super) {
__extends(Floorplan, _super);
function Floorplan(div) {
var _this = _super.call(this, div) || this;
_this.convertPixelsToUnits = function (num) {
var units = this.model.modelData.units;
var factor = this.model.modelData.unitsConversionFactor;
if (units === 'meters')
return (num / 100) * factor;
if (units === 'feet')
return (num / 30.48) * factor;
if (units === 'inches')
return (num / 2.54) * factor;
return num * factor;
};
_this.convertUnitsToPixels = function (num) {
var units = this.model.modelData.units;
var factor = this.model.modelData.unitsConversionFactor;
if (units === 'meters')
return (num * 100) / factor;
if (units === 'feet')
return (num * 30.48) / factor;
if (units === 'inches')
return (num * 2.54) / factor;
return num / factor;
};
_this.updateWall = function (wall) {
if (wall.data.startpoint && wall.data.endpoint) {
var shape = wall.findObject("SHAPE");
var geo = new go.Geometry(go.Geometry.Line);
var sPt = wall.data.startpoint;
var ePt = wall.data.endpoint;
var mPt = new go.Point((sPt.x + ePt.x) / 2, (sPt.y + ePt.y) / 2);
geo.startX = 0;
geo.startY = 0;
geo.endX = Math.sqrt(sPt.distanceSquaredPoint(ePt));
geo.endY = 0;
shape.geometry = geo;
wall.location = mPt;
var angle = sPt.directionPoint(ePt);
wall.rotateObject.angle = angle;
this.updateWallDimensions();
}
};
_this.getAdjustedPoint = function (point, wall, angle, wallOffset) {
var oldPoint = point.copy();
point.offset(0, -(wall.data.thickness * .5) - wallOffset);
point.offset(-oldPoint.x, -oldPoint.y).rotate(angle).offset(oldPoint.x, oldPoint.y);
return point;
};
_this.buildDimensionLink = function (wall, index, point1, point2, angle, wallOffset, soloWallFlag, floorplan) {
point1 = floorplan.getAdjustedPoint(point1, wall, angle, wallOffset);
point2 = floorplan.getAdjustedPoint(point2, wall, angle, wallOffset);
var data1 = { key: wall.data.key + "PointNode" + index, category: "PointNode", loc: go.Point.stringify(point1) };
var data2 = { key: wall.data.key + "PointNode" + (index + 1), category: "PointNode", loc: go.Point.stringify(point2) };
var data3 = { key: wall.data.key + "DimensionLink", category: 'DimensionLink', from: data1.key, to: data2.key, stroke: 'gray', angle: angle, wall: wall.data.key, soloWallFlag: soloWallFlag };
var pointNode1 = makePointNode();
var pointNode2 = makePointNode();
var link = makeDimensionLink();
floorplan.pointNodes.add(pointNode1);
floorplan.pointNodes.add(pointNode2);
floorplan.dimensionLinks.add(link);
floorplan.add(pointNode1);
floorplan.add(pointNode2);
floorplan.add(link);
pointNode1.data = data1;
pointNode2.data = data2;
link.data = data3;
link.fromNode = pointNode1;
link.toNode = pointNode2;
};
_this.updateWallDimensions = function () {
var floorplan = this;
floorplan.skipsUndoManager = true;
floorplan.startTransaction("update wall dimensions");
if (!floorplan.model.modelData.preferences.showWallLengths) {
floorplan.pointNodes.iterator.each(function (node) { floorplan.remove(node); });
floorplan.dimensionLinks.iterator.each(function (link) { floorplan.remove(link); });
floorplan.pointNodes.clear();
floorplan.dimensionLinks.clear();
floorplan.commitTransaction("update wall dimensions");
floorplan.skipsUndoManager = false;
return;
}
floorplan.dimensionLinks.iterator.each(function (link) { link.visible = true; });
var selection = floorplan.selection;
var walls = new go.Set();
selection.iterator.each(function (part) {
if ((part.category === 'WindowNode' || part.category === 'DoorNode') && part.containingGroup !== null)
walls.add(part.containingGroup);
if (part.category === 'WallGroup' && part.data && part.data.startpoint && part.data.endpoint) {
var wall_1 = part;
var soloWallLink_1 = null;
floorplan.dimensionLinks.iterator.each(function (link) { if (link.data.soloWallFlag && link.data.wall === wall_1.data.key)
soloWallLink_1 = link; });
if (soloWallLink_1 !== null) {
var linkPoint1_1 = null;
var linkPoint2_1 = null;
floorplan.pointNodes.iterator.each(function (node) {
if (node.data.key === wall_1.data.key + "PointNode1")
linkPoint1_1 = node;
if (node.data.key === wall_1.data.key + "PointNode2")
linkPoint2_1 = node;
});
var startpoint = wall_1.data.startpoint;
var endpoint = wall_1.data.endpoint;
var firstWallPt = ((startpoint.x + startpoint.y) <= (endpoint.x + endpoint.y)) ? startpoint : endpoint;
var lastWallPt = ((startpoint.x + startpoint.y) > (endpoint.x + endpoint.y)) ? startpoint : endpoint;
var newLoc1 = floorplan.getAdjustedPoint(firstWallPt.copy(), wall_1, wall_1.rotateObject.angle, 10);
var newLoc2 = floorplan.getAdjustedPoint(lastWallPt.copy(), wall_1, wall_1.rotateObject.angle, 10);
linkPoint1_1.data.loc = go.Point.stringify(newLoc1);
linkPoint2_1.data.loc = go.Point.stringify(newLoc2);
soloWallLink_1.data.angle = wall_1.rotateObject.angle;
linkPoint1_1.updateTargetBindings();
linkPoint2_1.updateTargetBindings();
soloWallLink_1.updateTargetBindings();
}
else {
var startpoint = wall_1.data.startpoint;
var endpoint = wall_1.data.endpoint;
var firstWallPt = ((startpoint.x + startpoint.y) <= (endpoint.x + endpoint.y)) ? startpoint : endpoint;
var lastWallPt = ((startpoint.x + startpoint.y) > (endpoint.x + endpoint.y)) ? startpoint : endpoint;
floorplan.buildDimensionLink(wall_1, 1, firstWallPt.copy(), lastWallPt.copy(), wall_1.rotateObject.angle, 10, true, floorplan);
}
}
});
walls.iterator.each(function (wall) {
var startpoint = wall.data.startpoint;
var endpoint = wall.data.endpoint;
var firstWallPt = ((startpoint.x + startpoint.y) <= (endpoint.x + endpoint.y)) ? startpoint : endpoint;
var lastWallPt = ((startpoint.x + startpoint.y) > (endpoint.x + endpoint.y)) ? startpoint : endpoint;
var wallPartEndpoints = [];
wall.memberParts.iterator.each(function (wallPart) {
if (wallPart.isSelected) {
var endpoints = getWallPartEndpoints(wallPart);
wallPartEndpoints.push(endpoints[0]);
wallPartEndpoints.push(endpoints[1]);
}
});
wallPartEndpoints.sort(function (a, b) {
if ((a.x + a.y) > (b.x + b.y))
return 1;
if ((a.x + a.y) < (b.x + b.y))
return -1;
else
return 0;
});
wallPartEndpoints.unshift(firstWallPt);
wallPartEndpoints.push(lastWallPt);
var angle = wall.rotateObject.angle;
var k = 1;
var _loop_1 = function (j) {
var linkPoint1 = null;
var linkPoint2 = null;
floorplan.pointNodes.iterator.each(function (node) {
if (node.data.key === wall.data.key + "PointNode" + k)
linkPoint1 = node;
if (node.data.key === wall.data.key + "PointNode" + (k + 1))
linkPoint2 = node;
});
if (linkPoint1 !== null) {
var newLoc1 = floorplan.getAdjustedPoint(wallPartEndpoints[j].copy(), wall, angle, 5);
var newLoc2 = floorplan.getAdjustedPoint(wallPartEndpoints[j + 1].copy(), wall, angle, 5);
linkPoint1.data.loc = go.Point.stringify(newLoc1);
linkPoint2.data.loc = go.Point.stringify(newLoc2);
linkPoint1.updateTargetBindings();
linkPoint2.updateTargetBindings();
}
else
floorplan.buildDimensionLink(wall, k, wallPartEndpoints[j].copy(), wallPartEndpoints[j + 1].copy(), angle, 5, false, floorplan);
k += 2;
};
for (var j = 0; j < wallPartEndpoints.length - 1; j++) {
_loop_1(j);
}
var totalWallDimensionLink = null;
floorplan.dimensionLinks.iterator.each(function (link) {
if ((link.fromNode.data.key === wall.data.key + "PointNode" + k) &&
(link.toNode.data.key === wall.data.key + "PointNode" + (k + 1)))
totalWallDimensionLink = link;
});
if (totalWallDimensionLink !== null) {
var linkPoint1_2 = null;
var linkPoint2_2 = null;
floorplan.pointNodes.iterator.each(function (node) {
if (node.data.key === wall.data.key + "PointNode" + k)
linkPoint1_2 = node;
if (node.data.key === wall.data.key + "PointNode" + (k + 1))
linkPoint2_2 = node;
});
var newLoc1 = floorplan.getAdjustedPoint(wallPartEndpoints[0].copy(), wall, angle, 25);
var newLoc2 = floorplan.getAdjustedPoint(wallPartEndpoints[wallPartEndpoints.length - 1].copy(), wall, angle, 25);
linkPoint1_2.data.loc = go.Point.stringify(newLoc1);
linkPoint2_2.data.loc = go.Point.stringify(newLoc2);
linkPoint1_2.updateTargetBindings();
linkPoint2_2.updateTargetBindings();
}
else
floorplan.buildDimensionLink(wall, k, wallPartEndpoints[0].copy(), wallPartEndpoints[wallPartEndpoints.length - 1].copy(), angle, 25, false, floorplan);
});
floorplan.dimensionLinks.iterator.each(function (link) {
var canStay = false;
floorplan.pointNodes.iterator.each(function (node) {
if (node.data.key == link.data.to)
canStay = true;
});
if (!canStay)
floorplan.remove(link);
else {
var length_1 = Math.sqrt(link.toNode.location.distanceSquaredPoint(link.fromNode.location));
if (length_1 < 1 && !link.data.soloWallFlag)
link.visible = false;
}
});
floorplan.commitTransaction("update wall dimensions");
floorplan.skipsUndoManager = false;
};
_this.getWallsIntersection = function (wall1, wall2) {
if (wall1 === null || wall2 === null)
return null;
var a1 = wall1.data.endpoint.y - wall1.data.startpoint.y;
var b1 = wall1.data.startpoint.x - wall1.data.endpoint.x;
var c1 = (a1 * wall1.data.startpoint.x) + (b1 * wall1.data.startpoint.y);
var a2 = wall2.data.endpoint.y - wall2.data.startpoint.y;
var b2 = wall2.data.startpoint.x - wall2.data.endpoint.x;
var c2 = (a2 * wall2.data.startpoint.x) + (b2 * wall2.data.startpoint.y);
var det = a1 * b2 - a2 * b1;
var x = null;
var y = null;
if (det === 0) {
if (wall1.data.startpoint.equals(wall2.data.startpoint) || wall1.data.startpoint.equals(wall2.data.endpoint))
return wall1.data.startpoint;
if (wall1.data.endpoint.equals(wall2.data.startpoint) || wall1.data.endpoint.equals(wall2.data.endpoint))
return wall1.data.endpoint;
return null;
}
else {
x = (b2 * c1 - b1 * c2) / det;
y = (a1 * c2 - a2 * c1) / det;
}
var inWall1 = ((Math.min(wall1.data.startpoint.x, wall1.data.endpoint.x) <= x) && (Math.max(wall1.data.startpoint.x, wall1.data.endpoint.x) >= x)
&& (Math.min(wall1.data.startpoint.y, wall1.data.endpoint.y) <= y) && (Math.max(wall1.data.startpoint.y, wall1.data.endpoint.y) >= y));
var inWall2 = ((Math.min(wall2.data.startpoint.x, wall2.data.endpoint.x) <= x) && (Math.max(wall2.data.startpoint.x, wall2.data.endpoint.x) >= x)
&& (Math.min(wall2.data.startpoint.y, wall2.data.endpoint.y) <= y) && (Math.max(wall2.data.startpoint.y, wall2.data.endpoint.y) >= y));
if (inWall1 && inWall2)
return new go.Point(x, y);
else
return null;
};
_this.updateWallAngles = function () {
var floorplan = this;
floorplan.skipsUndoManager = true;
floorplan.startTransaction("display angles");
if (floorplan.model.modelData.preferences.showWallAngles) {
floorplan.angleNodes.iterator.each(function (node) { node.visible = true; });
var selectedWalls_1 = [];
floorplan.selection.iterator.each(function (part) {
if (part.category === "WallGroup") {
var w = part;
selectedWalls_1.push(w);
}
});
var _loop_2 = function (i) {
var seen = new go.Set();
var wall = selectedWalls_1[i];
var possibleWalls = floorplan.findNodesByExample({ category: "WallGroup" });
possibleWalls.iterator.each(function (otherWall) {
if (otherWall.data === null || wall.data === null || seen.contains(otherWall.data.key))
return;
if ((otherWall.data.key !== wall.data.key) && (floorplan.getWallsIntersection(wall, otherWall) !== null) && (!seen.contains(otherWall.data.key))) {
seen.add(otherWall.data.key);
var intersectionPoint_1 = floorplan.getWallsIntersection(wall, otherWall);
var wallsInvolved = floorplan.findObjectsNear(intersectionPoint_1, 1, function (x) { if (x.part !== null)
return x.part; }, function (p) {
if (!(p instanceof go.Group))
return false;
else
return p.category === "WallGroup";
}, false);
var endpoints_1 = [];
wallsInvolved.iterator.each(function (w) {
var tolerance = (floorplan.model.modelData.gridSize >= 10) ? floorplan.model.modelData.gridSize : 10;
if (Math.sqrt(w.data.startpoint.distanceSquaredPoint(intersectionPoint_1)) > tolerance)
endpoints_1.push({ point: w.data.startpoint, wall: w.data.key });
if (Math.sqrt(w.data.endpoint.distanceSquaredPoint(intersectionPoint_1)) > tolerance)
endpoints_1.push({ point: w.data.endpoint, wall: w.data.key });
});
var maxRadius = 30;
for (var i_1 = 0; i_1 < endpoints_1.length; i_1++) {
var distance = Math.sqrt(endpoints_1[i_1].point.distanceSquaredPoint(intersectionPoint_1));
if (distance < maxRadius)
maxRadius = distance;
}
endpoints_1.sort(function (a, b) {
a = a.point;
b = b.point;
if (a.x - intersectionPoint_1.x >= 0 && b.x - intersectionPoint_1.x < 0)
return 1;
if (a.x - intersectionPoint_1.x < 0 && b.x - intersectionPoint_1.x >= 0)
return -1;
if (a.x - intersectionPoint_1.x == 0 && b.x - intersectionPoint_1.x == 0) {
if (a.y - intersectionPoint_1.y >= 0 || b.y - intersectionPoint_1.y >= 0)
return a.y > b.y ? 1 : -1;
return b.y > a.y ? 1 : -1;
}
var det = (a.x - intersectionPoint_1.x) * (b.y - intersectionPoint_1.y) - (b.x - intersectionPoint_1.x) * (a.y - intersectionPoint_1.y);
if (det < 0)
return 1;
if (det > 0)
return -1;
var d1 = (a.x - intersectionPoint_1.x) * (a.x - intersectionPoint_1.x) + (a.y - intersectionPoint_1.y) * (a.y - intersectionPoint_1.y);
var d2 = (b.x - intersectionPoint_1.x) * (b.x - intersectionPoint_1.x) + (b.y - intersectionPoint_1.y) * (b.y - intersectionPoint_1.y);
return d1 > d2 ? 1 : -1;
});
var _loop_3 = function (i_2) {
var p1 = endpoints_1[i_2];
var p2 = void 0;
if (endpoints_1[i_2 + 1] != null) {
p2 = endpoints_1[i_2 + 1];
}
else {
p2 = endpoints_1[0];
}
var a1 = intersectionPoint_1.directionPoint(p1.point);
var a2 = intersectionPoint_1.directionPoint(p2.point);
var sweep = Math.abs(a2 - a1 + 360) % 360;
var angle = a1;
var keyArray = [];
wallsInvolved.iterator.each(function (wall) { keyArray.push(wall); });
keyArray.sort(function (a, b) {
var aIndex = a.data.key.match(/\d+/g);
var bIndex = b.data.key.match(/\d+/g);
if (isNaN(aIndex))
return 1;
if (isNaN(bIndex))
return -1;
else
return aIndex > bIndex ? 1 : -1;
});
var key = "";
for (var j = 0; j < keyArray.length; j++)
key += keyArray[j].data.key;
key += "angle" + i_2;
var angleNode = null;
floorplan.angleNodes.iterator.each(function (aNode) { if (aNode.data.key === key)
angleNode = aNode; });
if (angleNode !== null) {
angleNode.data.angle = angle;
angleNode.data.sweep = sweep;
angleNode.data.loc = go.Point.stringify(intersectionPoint_1);
angleNode.data.maxRadius = maxRadius;
angleNode.updateTargetBindings();
}
else {
var data = { key: key, category: "AngleNode", loc: go.Point.stringify(intersectionPoint_1), stroke: "dodgerblue", angle: angle, sweep: sweep, maxRadius: maxRadius };
var newAngleNode = makeAngleNode();
newAngleNode.data = data;
floorplan.add(newAngleNode);
newAngleNode.updateTargetBindings();
floorplan.angleNodes.add(newAngleNode);
}
};
for (var i_2 = 0; i_2 < endpoints_1.length; i_2++) {
_loop_3(i_2);
}
}
});
};
for (var i = 0; i < selectedWalls_1.length; i++) {
_loop_2(i);
}
var garbage_1 = [];
floorplan.angleNodes.iterator.each(function (node) {
var keyNums = node.data.key.match(/\d+/g);
var numWalls = (node.data.key.match(/wall/g) || []).length;
var wallsInvolved = [];
for (var i = 0; i < keyNums.length - 1; i++)
wallsInvolved.push("wall" + keyNums[i]);
if (numWalls !== keyNums.length - 1)
wallsInvolved.push("wall");
for (var i = 0; i < wallsInvolved.length - 1; i++) {
var wall1 = floorplan.findPartForKey(wallsInvolved[i]);
var wall2 = floorplan.findPartForKey(wallsInvolved[i + 1]);
var intersectionPoint = floorplan.getWallsIntersection(wall1, wall2);
if (intersectionPoint === null)
garbage_1.push(node);
}
var possibleAngleNodes = new go.Set();
var allWalls = node.data.key.slice(0, node.data.key.indexOf("angle"));
floorplan.angleNodes.iterator.each(function (other) { if (other.data.key.indexOf(allWalls) !== -1)
possibleAngleNodes.add(other); });
possibleAngleNodes.iterator.each(function (pNode) {
if (pNode.data.loc !== node.data.loc) {
garbage_1.push(pNode);
}
});
if (node.data.sweep === 0)
garbage_1.push(node);
});
for (var i = 0; i < garbage_1.length; i++) {
floorplan.remove(garbage_1[i]);
floorplan.angleNodes.remove(garbage_1[i]);
}
}
if (floorplan.model.modelData.preferences.showOnlySmallWallAngles) {
floorplan.angleNodes.iterator.each(function (node) { if (node.data.sweep >= 180)
node.visible = false; });
}
if (!floorplan.model.modelData.preferences.showWallAngles) {
floorplan.angleNodes.iterator.each(function (node) { node.visible = false; });
}
floorplan.commitTransaction("display angles");
floorplan.skipsUndoManager = false;
};
_this._palettes = [];
_this._pointNodes = new go.Set();
_this._dimensionLinks = new go.Set();
_this._angleNodes = new go.Set();
var $ = go.GraphObject.make;
_this.allowLink = false;
_this.undoManager.isEnabled = true;
_this.layout.isOngoing = false;
_this.model = $(go.GraphLinksModel, {
modelData: {
"units": "centimeters",
"unitsAbbreviation": "cm",
"gridSize": 10,
"wallThickness": 5,
"preferences": {
showWallGuidelines: true,
showWallLengths: true,
showWallAngles: true,
showOnlySmallWallAngles: true,
showGrid: true,
gridSnap: true
}
}
});
_this.grid = $(go.Panel, "Grid", { gridCellSize: new go.Size(_this.model.modelData.gridSize, _this.model.modelData.gridSize), visible: true }, $(go.Shape, "LineH", { stroke: "lightgray" }), $(go.Shape, "LineV", { stroke: "lightgray" }));
_this.contextMenu = makeContextMenu();
_this.commandHandler.canGroupSelection = function () { return true; };
_this.commandHandler.canUngroupSelection = function () { return true; };
_this.commandHandler.archetypeGroupData = { isGroup: true };
_this.addDiagramListener("SelectionCopied", function (e) {
var fp = e.diagram;
fp.selection.iterator.each(function (part) {
if (part.category == "WallGroup") {
var w = part;
fp.updateWall(w);
}
});
});
_this.addDiagramListener("ExternalObjectsDropped", function (e) {
var garbage = [];
var fp = e.diagram;
fp.selection.iterator.each(function (node) {
if (node.category === "PaletteWallNode") {
var paletteWallNode = node;
var endpoints = getWallPartEndpoints(paletteWallNode);
var data = { key: "wall", category: "WallGroup", caption: "Wall", startpoint: endpoints[0], endpoint: endpoints[1], thickness: parseFloat(e.diagram.model.modelData.wallThickness), isGroup: true, notes: "" };
e.diagram.model.addNodeData(data);
var wall = e.diagram.findPartForKey(data.key);
fp.updateWall(wall);
garbage.push(paletteWallNode);
}
});
for (var i in garbage) {
e.diagram.remove(garbage[i]);
}
});
_this.addDiagramListener("ClipboardPasted", function (e) {
var fp = e.diagram;
e.diagram.selection.iterator.each(function (node) {
if (node.category === "WallGroup") {
var w = node;
fp.updateWall(w);
}
});
});
_this.nodeTemplateMap.add("", makeDefaultNode());
_this.nodeTemplateMap.add("MultiPurposeNode", makeMultiPurposeNode());
_this.nodeTemplateMap.add("WindowNode", makeWindowNode());
_this.nodeTemplateMap.add("PaletteWallNode", makePaletteWallNode());
_this.nodeTemplateMap.add("DoorNode", makeDoorNode());
_this.groupTemplateMap.add("", makeDefaultGroup());
_this.groupTemplateMap.add("WallGroup", makeWallGroup());
var wallBuildingTool = new WallBuildingTool();
_this.toolManager.mouseDownTools.insertAt(0, wallBuildingTool);
var wallReshapingTool = new WallReshapingTool();
_this.toolManager.mouseDownTools.insertAt(3, wallReshapingTool);
wallBuildingTool.isEnabled = false;
_this.toolManager.draggingTool.doMouseUp = function () {
go.DraggingTool.prototype.doMouseUp.call(this);
this.diagram.updateWallAngles();
this.isGridSnapEnabled = this.diagram.model.modelData.preferences.gridSnap;
};
_this.toolManager.draggingTool.doMouseMove = function () {
if (this.diagram.lastInput.shift) {
this.isGridSnapEnabled = false;
}
else
this.isGridSnapEnabled = this.diagram.model.modelData.preferences.gridSnap;
go.DraggingTool.prototype.doMouseMove.call(this);
};
_this.toolManager.resizingTool.doMouseMove = function () {
var floorplan = this.diagram;
var node = this.adornedObject;
this.diagram.updateWallDimensions();
go.ResizingTool.prototype.doMouseMove.call(this);
};
_this.toolManager.resizingTool.computeMaxSize = function () {
var tool = this;
var obj = tool.adornedObject.part;
var wall = this.diagram.findPartForKey(obj.data.group);
if ((obj.category === 'DoorNode' || obj.category === 'WindowNode') && wall !== null) {
var stationaryPt;
var movingPt;
var resizeAdornment = null;
obj.adornments.iterator.each(function (adorn) { if (adorn.name === "WallPartResizeAdornment")
resizeAdornment = adorn; });
resizeAdornment.elements.iterator.each(function (el) {
if (el instanceof go.Shape && el.alignment === tool.handle.alignment)
movingPt = el.getDocumentPoint(go.Spot.Center);
if (el instanceof go.Shape && el.alignment !== tool.handle.alignment)
stationaryPt = el.getDocumentPoint(go.Spot.Center);
});
var constrainingPt;
var closestDist = Number.MAX_VALUE;
wall.memberParts.iterator.each(function (part) {
if (part.data.key !== obj.data.key) {
var endpoints = getWallPartEndpoints(part);
for (var i = 0; i < endpoints.length; i++) {
var point = endpoints[i];
var distanceToMovingPt = Math.sqrt(point.distanceSquaredPoint(movingPt));
if (distanceToMovingPt < closestDist) {
var distanceToStationaryPt = Math.sqrt(point.distanceSquaredPoint(stationaryPt));
if (distanceToStationaryPt > distanceToMovingPt) {
closestDist = distanceToMovingPt;
constrainingPt = point;
}
}
}
}
});
if (constrainingPt === undefined || constrainingPt === null) {
if (wall.data.startpoint.distanceSquaredPoint(movingPt) > wall.data.startpoint.distanceSquaredPoint(stationaryPt))
constrainingPt = wall.data.endpoint;
else
constrainingPt = wall.data.startpoint;
}
var maxLength = Math.sqrt(stationaryPt.distanceSquaredPoint(constrainingPt));
return new go.Size(maxLength, wall.data.thickness);
}
return go.ResizingTool.prototype.computeMaxSize.call(tool);
};
_this.toolManager.draggingTool.isGridSnapEnabled = true;
return _this;
}
Object.defineProperty(Floorplan.prototype, "palettes", {
get: function () { return this._palettes; },
set: function (value) { this._palettes = value; },
enumerable: true,
configurable: true
});
Object.defineProperty(Floorplan.prototype, "pointNodes", {
get: function () { return this._pointNodes; },
set: function (value) { this._pointNodes = value; },
enumerable: true,
configurable: true
});
Object.defineProperty(Floorplan.prototype, "dimensionLinks", {
get: function () { return this._dimensionLinks; },
set: function (value) { this._dimensionLinks = value; },
enumerable: true,
configurable: true
});
Object.defineProperty(Floorplan.prototype, "angleNodes", {
get: function () { return this._angleNodes; },
set: function (value) { this._angleNodes = value; },
enumerable: true,
configurable: true
});
return Floorplan;
}(go.Diagram));
function makeSelectionGroup(floorplan) {
floorplan.startTransaction("group selection");
var sel = floorplan.selection;
var nodes = [];
sel.iterator.each(function (n) {
if (n instanceof go.Group)
n.memberParts.iterator.each(function (part) { nodes.push(part); });
else
nodes.push(n);
});
for (var i = 0; i < nodes.length; i++)
nodes[i].isSelected = true;
ungroupSelection(floorplan);
floorplan.commandHandler.groupSelection();
var group = floorplan.selection.first();
floorplan.model.setDataProperty(group.data, "caption", "Group");
floorplan.model.setDataProperty(group.data, "notes", "");
clearEmptyGroups(floorplan);
floorplan.clearSelection();
floorplan.select(group);
floorplan.commitTransaction("group selection");
}
function ungroupSelection(floorplan) {
floorplan.startTransaction('ungroup selection');
function ungroupNode(node) {
var group = node.containingGroup;
node.containingGroup = null;
if (group != null) {
if (group.memberParts.count === 0)
floorplan.remove(group);
else if (group.memberParts.count === 1)
group.memberParts.first().containingGroup = null;
}
}
var sel = floorplan.selection;
var groups = [];
sel.iterator.each(function (n) {
if (!(n instanceof go.Group))
ungroupNode(n);
else
groups.push(n);
});
var nodes = [];
for (var i = 0; i < groups.length; i++)
groups[i].memberParts.iterator.each(function (n) { nodes.push(n); });
for (var i = 0; i < nodes.length; i++)
ungroupNode(nodes[i]);
clearEmptyGroups(floorplan);
floorplan.commitTransaction('ungroup selection');
}
function clearEmptyGroups(floorplan) {
var nodes = floorplan.nodes;
var arr = [];
nodes.iterator.each(function (node) { if (node instanceof go.Group && node.memberParts.count === 0 && node.category !== "WallGroup") {
arr.push(node);
} });
for (var i = 0; i < arr.length; i++) {
floorplan.remove(arr[i]);
}
}
function makeGroupToolTip() {
var $ = go.GraphObject.make;
return $(go.Adornment, "Auto", $(go.Shape, { fill: "#FFFFCC" }), $(go.TextBlock, { margin: 4 }, new go.Binding("text", "", function (text, obj) {
var data = obj.part.adornedObject.data;
var name = (obj.part.adornedObject.category === "MultiPurposeNode") ? data.text : data.caption;
return "Name: " + name + "\nNotes: " + data.notes + '\nMembers: ' + obj.part.adornedObject.memberParts.count;
}).ofObject()));
}
function makeContextMenu() {
var $ = go.GraphObject.make;
return $(go.Adornment, "Vertical", $("ContextMenuButton", $(go.TextBlock, "Make Group"), { click: function (e, obj) { makeSelectionGroup(obj.part.diagram); } }, new go.Binding("visible", "visible", function (v, obj) {
var floorplan = obj.part.diagram;
if (floorplan.selection.count <= 1)
return false;
var flag = true;
floorplan.selection.iterator.each(function (node) {
if (node.category === "WallGroup" || node.category === "WindowNode" || node.category === "DoorNode")
flag = false;
});
return flag;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Ungroup"), { click: function (e, obj) { ungroupSelection(obj.part.diagram); } }, new go.Binding("visible", "", function (v, obj) {
var floorplan = obj.part.diagram;
if (floorplan !== null) {
var node = floorplan.selection.first();
return ((node instanceof go.Node && node.containingGroup != null && node.containingGroup.category != 'WallGroup') ||
(node instanceof go.Group && node.category === ''));
}
return false;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Copy"), { click: function (e, obj) { obj.part.diagram.commandHandler.copySelection(); } }, new go.Binding("visible", "", function (v, obj) {
if (obj.part.diagram !== null) {
return obj.part.diagram.selection.count > 0;
}
return false;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Cut"), { click: function (e, obj) { obj.part.diagram.commandHandler.cutSelection(); } }, new go.Binding("visible", "", function (v, obj) {
if (obj.part.diagram !== null) {
return obj.part.diagram.selection.count > 0;
}
return false;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Delete"), { click: function (e, obj) { obj.part.diagram.commandHandler.deleteSelection(); } }, new go.Binding("visible", "", function (v, obj) {
if (obj.part.diagram !== null) {
return obj.part.diagram.selection.count > 0;
}
return false;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Paste"), { click: function (e, obj) { obj.part.diagram.commandHandler.pasteSelection(obj.part.diagram.lastInput.documentPoint); } }), $("ContextMenuButton", $(go.TextBlock, "Show Selection Info"), {
click: function (e, obj) {
if (e.diagram.floorplanUI) {
var selectionInfoWindow = document.getElementById(e.diagram.floorplanUI.state.windows.selectionInfoWindow.id);
if (selectionInfoWindow.style.visibility !== 'visible')
e.diagram.floorplanUI.hideShow('selectionInfoWindow');
}
}
}, new go.Binding("visible", "", function (v, obj) {
if (obj.part.diagram !== null) {
return obj.part.diagram.selection.count > 0;
}
return false;
}).ofObject()), $("ContextMenuButton", $(go.TextBlock, "Flip Dimension Side"), {
click: function (e, obj) {
var floorplan = obj.part.diagram;
if (floorplan !== null) {
floorplan.startTransaction("flip dimension link side");
var walls = [];
floorplan.selection.iterator.each(function (part) {
if (part.category === "WallGroup")
walls.push(part);
});
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
var sPt = wall.data.startpoint.copy();
var ePt = wall.data.endpoint.copy();
floorplan.model.setDataProperty(wall.data, "startpoint", ePt);
floorplan.model.setDataProperty(wall.data, "endpoint", sPt);
floorplan.updateWall(wall);
}
floorplan.commitTransaction("flip dimension link side");
}
}
}, new go.Binding("visible", "", function (v, obj) {
if (obj.part.diagram !== null) {
var sel = obj.part.diagram.selection;
if (sel.count === 0)
return false;
var flag = false;
sel.iterator.each(function (part) {
if (part.category === "WallGroup")
flag = true;
});
return flag;
}
return false;
}).ofObject()));
}
function makeDefaultGroup() {
var $ = go.GraphObject.make;
return $(go.Group, "Vertical", {
contextMenu: makeContextMenu(),
doubleClick: function (e) {
if (e.diagram.floorplanUI)
e.diagram.floorplanUI.hideShow("selectionInfoWindow");
},
toolTip: makeGroupToolTip()
}, new go.Binding("location", "loc"), $(go.Panel, "Auto", $(go.Shape, "RoundedRectangle", { fill: "rgba(128,128,128,0.15)", stroke: 'rgba(128, 128, 128, .05)', name: 'SHAPE', strokeCap: 'square' }, new go.Binding("fill", "isSelected", function (s, obj) {
return s ? "rgba(128, 128, 128, .15)" : "rgba(128, 128, 128, 0.10)";
}).ofObject()), $(go.Placeholder, { padding: 5 })));
}
function makeArc(node) {
var ang = node.data.angle;
var sweep = node.data.sweep;
var rad = Math.min(30, node.data.maxRadius);
if (typeof sweep === "number" && sweep > 0) {
var start = new go.Point(rad, 0).rotate(ang);
return new go.Geometry()
.add(new go.PathFigure(start.x + rad, start.y + rad)
.add(new go.PathSegment(go.PathSegment.Arc, ang, sweep, rad, rad, rad, rad)))
.add(new go.PathFigure(0, 0))
.add(new go.PathFigure(2 * rad, 2 * rad));
}
else {
return new go.Geometry()
.add(new go.PathFigure(0, 0))
.add(new go.PathFigure(2 * rad, 2 * rad));
}
}
function makePointNode() {
var $ = go.GraphObject.make;
return $(go.Node, "Position", new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify));
}
function makeAngleNode() {
var $ = go.GraphObject.make;
return $(go.Node, "Spot", { locationSpot: go.Spot.Center, locationObjectName: "SHAPE", selectionAdorned: false }, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "Circle", { name: "SHAPE", height: 0, width: 0 }), $(go.Shape, { strokeWidth: 1.5, fill: null }, new go.Binding("geometry", "", makeArc).ofObject(), new go.Binding("stroke", "sweep", function (sweep) {
return (sweep % 45 < 1 || sweep % 45 > 44) ? "dodgerblue" : "lightblue";
})), $(go.Panel, "Auto", { name: "ARCLABEL" }, new go.Binding("alignment", "sweep", function (sweep, panel) {
var rad = Math.min(30, panel.part.data.maxRadius);
var angle = panel.part.data.angle;
var cntr = new go.Point(rad, 0).rotate(angle + sweep / 2);
return new go.Spot(0.5, 0.5, cntr.x, cntr.y);
}), $(go.Shape, { fill: "white" }, new go.Binding("stroke", "sweep", function (sweep) {
return (sweep % 45 < 1 || sweep % 45 > 44) ? "dodgerblue" : "lightblue";
})), $(go.TextBlock, { font: "7pt sans-serif", margin: 2 }, new go.Binding("text", "sweep", function (sweep) {
return sweep.toFixed(2) + String.fromCharCode(176);
}))));
}
function makeDimensionLink() {
var $ = go.GraphObject.make;
return $(go.Link, $(go.Shape, { stroke: "gray", strokeWidth: 2, name: 'SHAPE' }), $(go.Shape, { toArrow: "OpenTriangle", stroke: "gray", strokeWidth: 2 }), $(go.Shape, { fromArrow: "BackwardOpenTriangle", stroke: "gray", strokeWidth: 2 }), $(go.TextBlock, { text: 'sometext', segmentOffset: new go.Point(0, -10), font: "13px sans-serif" }, new go.Binding("text", "", function (link) {
var floorplan = link.diagram;
if (floorplan) {
var fromPtNode = null;
var toPtNode = null;
floorplan.pointNodes.iterator.each(function (node) {
if (node.data.key === link.data.from)
fromPtNode = node;
if (node.data.key === link.data.to)
toPtNode = node;
});
if (fromPtNode !== null) {
var fromPt = fromPtNode.location;
var toPt = toPtNode.location;
return floorplan.convertPixelsToUnits(Math.sqrt(fromPt.distanceSquaredPoint(toPt))).toFixed(2) + floorplan.model.modelData.unitsAbbreviation;
}
return null;
}
return null;
}).ofObject(), new go.Binding("angle", "angle", function (angle, link) {
if (angle > 90 && angle < 270)
return (angle + 180) % 360;
return angle;
}), new go.Binding("segmentOffset", "angle", function (angle, textblock) {
var floorplan = textblock.part.diagram;
if (floorplan) {
var wall = floorplan.findPartForKey(textblock.part.data.wall);
if (wall.rotateObject.angle > 135 && wall.rotateObject.angle < 315)
return new go.Point(0, 10);
return new go.Point(0, -10);
}
return new go.Point(0, 0);
}).ofObject(), new go.Binding("font", "", function (link) {
var floorplan = link.diagram;