UNPKG

gojs

Version:

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

835 lines (834 loc) 77.9 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", "./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;