You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1328 lines
52 KiB
1328 lines
52 KiB
"use strict";
|
|
(self["webpackChunk"] = self["webpackChunk"] || []).push([[14058],{
|
|
|
|
/***/ 79113:
|
|
/*!**********************************************!*\
|
|
!*** ./src/pages/Demo/index.tsx + 1 modules ***!
|
|
\**********************************************/
|
|
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
|
|
// ESM COMPAT FLAG
|
|
__webpack_require__.r(__webpack_exports__);
|
|
|
|
// EXPORTS
|
|
__webpack_require__.d(__webpack_exports__, {
|
|
"default": function() { return /* binding */ Demo; }
|
|
});
|
|
|
|
// EXTERNAL MODULE: ./node_modules/_react@17.0.2@react/index.js
|
|
var _react_17_0_2_react = __webpack_require__(59301);
|
|
// EXTERNAL MODULE: ./node_modules/_gojs3@2.3.10@gojs3/release/go-module.js
|
|
var go_module = __webpack_require__(12378);
|
|
;// CONCATENATED MODULE: ./src/pages/Demo/js/DrawCommandHandler.js
|
|
|
|
|
|
/*
|
|
* Copyright (C) 1998-2023 by Northwoods Software Corporation. All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* This is an extension and not part of the main GoJS library.
|
|
* Note that the API for this class may change with any version, even point releases.
|
|
* If you intend to use an extension in production, you should copy the code to your own source directory.
|
|
* Extensions can be found in the GoJS kit under the extensions or extensionsJSM folders.
|
|
* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
|
|
*/
|
|
|
|
/**
|
|
* @constructor
|
|
* @extends CommandHandler
|
|
* @class
|
|
* This CommandHandler class allows the user to position selected Parts in a diagram
|
|
* relative to the first part selected, in addition to overriding the doKeyDown method
|
|
* of the CommandHandler for handling the arrow keys in additional manners.
|
|
* <p>
|
|
* Typical usage:
|
|
* <pre>
|
|
* new go.Diagram("myDiagramDiv",
|
|
* {
|
|
* commandHandler: $(DrawCommandHandler),
|
|
* . . .
|
|
* }
|
|
* )
|
|
* </pre>
|
|
* or:
|
|
* <pre>
|
|
* myDiagram.commandHandler = new DrawCommandHandler();
|
|
* </pre>
|
|
*/
|
|
function DrawCommandHandler() {
|
|
go.CommandHandler.call(this);
|
|
this._arrowKeyBehavior = "move";
|
|
this._pasteOffset = new go.Point(10, 10);
|
|
this._lastPasteOffset = new go.Point(0, 0);
|
|
}
|
|
go.Diagram.inherit(DrawCommandHandler, go.CommandHandler);
|
|
|
|
/**
|
|
* This controls whether or not the user can invoke the {@link #alignLeft}, {@link #alignRight},
|
|
* {@link #alignTop}, {@link #alignBottom}, {@link #alignCenterX}, {@link #alignCenterY} commands.
|
|
* @this {DrawCommandHandler}
|
|
* @return {boolean}
|
|
* This returns true:
|
|
* if the diagram is not {@link Diagram#isReadOnly},
|
|
* if the model is not {@link Model#isReadOnly}, and
|
|
* if there are at least two selected {@link Part}s.
|
|
*/
|
|
DrawCommandHandler.prototype.canAlignSelection = function () {
|
|
var diagram = this.diagram;
|
|
if (diagram === null || diagram.isReadOnly || diagram.isModelReadOnly) return false;
|
|
if (diagram.selection.count < 2) return false;
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts along the left-most edge of the left-most part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignLeft = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("aligning left");
|
|
var minPosition = Infinity;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
minPosition = Math.min(current.position.x, minPosition);
|
|
});
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(minPosition, current.position.y));
|
|
});
|
|
diagram.commitTransaction("aligning left");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts at the right-most edge of the right-most part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignRight = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("aligning right");
|
|
var maxPosition = -Infinity;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
var rightSideLoc = current.actualBounds.x + current.actualBounds.width;
|
|
maxPosition = Math.max(rightSideLoc, maxPosition);
|
|
});
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(maxPosition - current.actualBounds.width, current.position.y));
|
|
});
|
|
diagram.commitTransaction("aligning right");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts at the top-most edge of the top-most part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignTop = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("alignTop");
|
|
var minPosition = Infinity;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
minPosition = Math.min(current.position.y, minPosition);
|
|
});
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(current.position.x, minPosition));
|
|
});
|
|
diagram.commitTransaction("alignTop");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts at the bottom-most edge of the bottom-most part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignBottom = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("aligning bottom");
|
|
var maxPosition = -Infinity;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
var bottomSideLoc = current.actualBounds.y + current.actualBounds.height;
|
|
maxPosition = Math.max(bottomSideLoc, maxPosition);
|
|
});
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(current.actualBounds.x, maxPosition - current.actualBounds.height));
|
|
});
|
|
diagram.commitTransaction("aligning bottom");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts at the x-value of the center point of the first selected part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignCenterX = function () {
|
|
var diagram = this.diagram;
|
|
var firstSelection = diagram.selection.first();
|
|
if (!firstSelection) return;
|
|
diagram.startTransaction("aligning Center X");
|
|
var centerX = firstSelection.actualBounds.x + firstSelection.actualBounds.width / 2;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(centerX - current.actualBounds.width / 2, current.actualBounds.y));
|
|
});
|
|
diagram.commitTransaction("aligning Center X");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts at the y-value of the center point of the first selected part.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.alignCenterY = function () {
|
|
var diagram = this.diagram;
|
|
var firstSelection = diagram.selection.first();
|
|
if (!firstSelection) return;
|
|
diagram.startTransaction("aligning Center Y");
|
|
var centerY = firstSelection.actualBounds.y + firstSelection.actualBounds.height / 2;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
current.move(new go.Point(current.actualBounds.x, centerY - current.actualBounds.height / 2));
|
|
});
|
|
diagram.commitTransaction("aligning Center Y");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts top-to-bottom in order of the order selected.
|
|
* Distance between parts can be specified. Default distance is 0.
|
|
* @this {DrawCommandHandler}
|
|
* @param {number} distance
|
|
*/
|
|
DrawCommandHandler.prototype.alignColumn = function (distance) {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("align Column");
|
|
if (distance === undefined) distance = 0; // for aligning edge to edge
|
|
distance = parseFloat(distance);
|
|
var selectedParts = new Array();
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
selectedParts.push(current);
|
|
});
|
|
for (var i = 0; i < selectedParts.length - 1; i++) {
|
|
var current = selectedParts[i];
|
|
// adds distance specified between parts
|
|
var curBottomSideLoc = current.actualBounds.y + current.actualBounds.height + distance;
|
|
var next = selectedParts[i + 1];
|
|
next.move(new go.Point(current.actualBounds.x, curBottomSideLoc));
|
|
}
|
|
diagram.commitTransaction("align Column");
|
|
};
|
|
|
|
/**
|
|
* Aligns selected parts left-to-right in order of the order selected.
|
|
* Distance between parts can be specified. Default distance is 0.
|
|
* @this {DrawCommandHandler}
|
|
* @param {number} distance
|
|
*/
|
|
DrawCommandHandler.prototype.alignRow = function (distance) {
|
|
if (distance === undefined) distance = 0; // for aligning edge to edge
|
|
distance = parseFloat(distance);
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("align Row");
|
|
var selectedParts = new Array();
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link) return; // skips over go.Link
|
|
selectedParts.push(current);
|
|
});
|
|
for (var i = 0; i < selectedParts.length - 1; i++) {
|
|
var current = selectedParts[i];
|
|
// adds distance specified between parts
|
|
var curRightSideLoc = current.actualBounds.x + current.actualBounds.width + distance;
|
|
var next = selectedParts[i + 1];
|
|
next.move(new go.Point(curRightSideLoc, current.actualBounds.y));
|
|
}
|
|
diagram.commitTransaction("align Row");
|
|
};
|
|
|
|
/**
|
|
* This controls whether or not the user can invoke the {@link #rotate} command.
|
|
* @this {DrawCommandHandler}
|
|
* @param {number=} angle the positive (clockwise) or negative (counter-clockwise) change in the rotation angle of each Part, in degrees.
|
|
* @return {boolean}
|
|
* This returns true:
|
|
* if the diagram is not {@link Diagram#isReadOnly},
|
|
* if the model is not {@link Model#isReadOnly}, and
|
|
* if there is at least one selected {@link Part}.
|
|
*/
|
|
DrawCommandHandler.prototype.canRotate = function (number) {
|
|
var diagram = this.diagram;
|
|
if (diagram === null || diagram.isReadOnly || diagram.isModelReadOnly) return false;
|
|
if (diagram.selection.count < 1) return false;
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Change the angle of the parts connected with the given part. This is in the command handler
|
|
* so it can be easily accessed for the purpose of creating commands that change the rotation of a part.
|
|
* @this {DrawCommandHandler}
|
|
* @param {number=} angle the positive (clockwise) or negative (counter-clockwise) change in the rotation angle of each Part, in degrees.
|
|
*/
|
|
DrawCommandHandler.prototype.rotate = function (angle) {
|
|
if (angle === undefined) angle = 90;
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("rotate " + angle.toString());
|
|
var diagram = this.diagram;
|
|
diagram.selection.each(function (current) {
|
|
if (current instanceof go.Link || current instanceof go.Group) return; // skips over Links and Groups
|
|
current.angle += angle;
|
|
});
|
|
diagram.commitTransaction("rotate " + angle.toString());
|
|
};
|
|
|
|
/**
|
|
* Change the z-ordering of selected parts to pull them forward, in front of all other parts
|
|
* in their respective layers.
|
|
* All unselected parts in each layer with a selected Part with a non-numeric {@link Part#zOrder} will get a zOrder of zero.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.pullToFront = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("pullToFront");
|
|
// find the affected Layers
|
|
var layers = new go.Map();
|
|
diagram.selection.each(function (part) {
|
|
layers.set(part.layer, 0);
|
|
});
|
|
// find the maximum zOrder in each Layer
|
|
layers.iteratorKeys.each(function (layer) {
|
|
var max = 0;
|
|
layer.parts.each(function (part) {
|
|
if (part.isSelected) return;
|
|
var z = part.zOrder;
|
|
if (isNaN(z)) {
|
|
part.zOrder = 0;
|
|
} else {
|
|
max = Math.max(max, z);
|
|
}
|
|
});
|
|
layers.set(layer, max);
|
|
});
|
|
// assign each selected Part.zOrder to the computed value for each Layer
|
|
diagram.selection.each(function (part) {
|
|
DrawCommandHandler._assignZOrder(part, layers.get(part.layer) + 1);
|
|
});
|
|
diagram.commitTransaction("pullToFront");
|
|
};
|
|
|
|
/**
|
|
* Change the z-ordering of selected parts to push them backward, behind of all other parts
|
|
* in their respective layers.
|
|
* All unselected parts in each layer with a selected Part with a non-numeric {@link Part#zOrder} will get a zOrder of zero.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype.pushToBack = function () {
|
|
var diagram = this.diagram;
|
|
diagram.startTransaction("pushToBack");
|
|
// find the affected Layers
|
|
var layers = new go.Map();
|
|
diagram.selection.each(function (part) {
|
|
layers.set(part.layer, 0);
|
|
});
|
|
// find the minimum zOrder in each Layer
|
|
layers.iteratorKeys.each(function (layer) {
|
|
var min = 0;
|
|
layer.parts.each(function (part) {
|
|
if (part.isSelected) return;
|
|
var z = part.zOrder;
|
|
if (isNaN(z)) {
|
|
part.zOrder = 0;
|
|
} else {
|
|
min = Math.min(min, z);
|
|
}
|
|
});
|
|
layers.set(layer, min);
|
|
});
|
|
// assign each selected Part.zOrder to the computed value for each Layer
|
|
diagram.selection.each(function (part) {
|
|
DrawCommandHandler._assignZOrder(part,
|
|
// make sure a group's nested nodes are also behind everything else
|
|
layers.get(part.layer) - 1 - DrawCommandHandler._findGroupDepth(part));
|
|
});
|
|
diagram.commitTransaction("pushToBack");
|
|
};
|
|
DrawCommandHandler._assignZOrder = function (part, z, root) {
|
|
if (root === undefined) root = part;
|
|
if (part.layer === root.layer) part.zOrder = z;
|
|
if (part instanceof go.Group) {
|
|
part.memberParts.each(function (m) {
|
|
DrawCommandHandler._assignZOrder(m, z + 1, root);
|
|
});
|
|
}
|
|
};
|
|
DrawCommandHandler._findGroupDepth = function (part) {
|
|
if (part instanceof go.Group) {
|
|
var d = 0;
|
|
part.memberParts.each(function (m) {
|
|
d = Math.max(d, DrawCommandHandler._findGroupDepth(m));
|
|
});
|
|
return d + 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* This implements custom behaviors for arrow key keyboard events.
|
|
* Set {@link #arrowKeyBehavior} to "select", "move" (the default), "scroll" (the standard behavior), or "none"
|
|
* to affect the behavior when the user types an arrow key.
|
|
* @this {DrawCommandHandler}*/
|
|
DrawCommandHandler.prototype.doKeyDown = function () {
|
|
var diagram = this.diagram;
|
|
if (diagram === null) return;
|
|
var e = diagram.lastInput;
|
|
|
|
// determines the function of the arrow keys
|
|
if (e.key === "Up" || e.key === "Down" || e.key === "Left" || e.key === "Right") {
|
|
var behavior = this.arrowKeyBehavior;
|
|
if (behavior === "none") {
|
|
// no-op
|
|
return;
|
|
} else if (behavior === "select") {
|
|
this._arrowKeySelect();
|
|
return;
|
|
} else if (behavior === "move") {
|
|
this._arrowKeyMove();
|
|
return;
|
|
} else if (behavior === "tree") {
|
|
this._arrowKeyTree();
|
|
return;
|
|
}
|
|
// otherwise drop through to get the default scrolling behavior
|
|
}
|
|
|
|
// otherwise still does all standard commands
|
|
go.CommandHandler.prototype.doKeyDown.call(this);
|
|
};
|
|
|
|
/**
|
|
* Collects in an Array all of the non-Link Parts currently in the Diagram.
|
|
* @this {DrawCommandHandler}
|
|
* @return {Array}
|
|
*/
|
|
DrawCommandHandler.prototype._getAllParts = function () {
|
|
var allParts = new Array();
|
|
this.diagram.nodes.each(function (node) {
|
|
allParts.push(node);
|
|
});
|
|
this.diagram.parts.each(function (part) {
|
|
allParts.push(part);
|
|
});
|
|
// note that this ignores Links
|
|
return allParts;
|
|
};
|
|
|
|
/**
|
|
* To be called when arrow keys should move the Diagram.selection.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype._arrowKeyMove = function () {
|
|
var diagram = this.diagram;
|
|
var e = diagram.lastInput;
|
|
// moves all selected parts in the specified direction
|
|
var vdistance = 0;
|
|
var hdistance = 0;
|
|
// if control is being held down, move pixel by pixel. Else, moves by grid cell size
|
|
if (e.control || e.meta) {
|
|
vdistance = 1;
|
|
hdistance = 1;
|
|
} else if (diagram.grid !== null) {
|
|
var cellsize = diagram.grid.gridCellSize;
|
|
hdistance = cellsize.width;
|
|
vdistance = cellsize.height;
|
|
}
|
|
diagram.startTransaction("arrowKeyMove");
|
|
diagram.selection.each(function (part) {
|
|
if (e.key === "Up") {
|
|
part.move(new go.Point(part.actualBounds.x, part.actualBounds.y - vdistance));
|
|
} else if (e.key === "Down") {
|
|
part.move(new go.Point(part.actualBounds.x, part.actualBounds.y + vdistance));
|
|
} else if (e.key === "Left") {
|
|
part.move(new go.Point(part.actualBounds.x - hdistance, part.actualBounds.y));
|
|
} else if (e.key === "Right") {
|
|
part.move(new go.Point(part.actualBounds.x + hdistance, part.actualBounds.y));
|
|
}
|
|
});
|
|
diagram.commitTransaction("arrowKeyMove");
|
|
};
|
|
|
|
/**
|
|
* To be called when arrow keys should change selection.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype._arrowKeySelect = function () {
|
|
var diagram = this.diagram;
|
|
var e = diagram.lastInput;
|
|
// with a part selected, arrow keys change the selection
|
|
// arrow keys + shift selects the additional part in the specified direction
|
|
// arrow keys + control toggles the selection of the additional part
|
|
var nextPart = null;
|
|
if (e.key === "Up") {
|
|
nextPart = this._findNearestPartTowards(270);
|
|
} else if (e.key === "Down") {
|
|
nextPart = this._findNearestPartTowards(90);
|
|
} else if (e.key === "Left") {
|
|
nextPart = this._findNearestPartTowards(180);
|
|
} else if (e.key === "Right") {
|
|
nextPart = this._findNearestPartTowards(0);
|
|
}
|
|
if (nextPart !== null) {
|
|
if (e.shift) {
|
|
nextPart.isSelected = true;
|
|
} else if (e.control || e.meta) {
|
|
nextPart.isSelected = !nextPart.isSelected;
|
|
} else {
|
|
diagram.select(nextPart);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Finds the nearest selectable Part in the specified direction, based on their center points.
|
|
* if it doesn't find anything, it just returns the current Part.
|
|
* @this {DrawCommandHandler}
|
|
* @param {number} dir the direction, in degrees
|
|
* @return {Part} the closest Part found in the given direction
|
|
*/
|
|
DrawCommandHandler.prototype._findNearestPartTowards = function (dir) {
|
|
var originalPart = this.diagram.selection.first();
|
|
if (originalPart === null) return null;
|
|
var originalPoint = originalPart.actualBounds.center;
|
|
var allParts = this._getAllParts();
|
|
var closestDistance = Infinity;
|
|
var closest = originalPart; // if no parts meet the criteria, the same part remains selected
|
|
|
|
for (var i = 0; i < allParts.length; i++) {
|
|
var nextPart = allParts[i];
|
|
if (nextPart === originalPart) continue; // skips over currently selected part
|
|
if (!nextPart.canSelect()) continue;
|
|
var nextPoint = nextPart.actualBounds.center;
|
|
var angle = originalPoint.directionPoint(nextPoint);
|
|
var anglediff = this._angleCloseness(angle, dir);
|
|
if (anglediff <= 45) {
|
|
// if this part's center is within the desired direction's sector,
|
|
var distance = originalPoint.distanceSquaredPoint(nextPoint);
|
|
distance *= 1 + Math.sin(anglediff * Math.PI / 180); // the more different from the intended angle, the further it is
|
|
if (distance < closestDistance) {
|
|
// and if it's closer than any other part,
|
|
closestDistance = distance; // remember it as a better choice
|
|
closest = nextPart;
|
|
}
|
|
}
|
|
}
|
|
return closest;
|
|
};
|
|
|
|
/**
|
|
* @this {DrawCommandHandler}
|
|
* @param {number} a
|
|
* @param {number} dir
|
|
* @return {number}
|
|
*/
|
|
DrawCommandHandler.prototype._angleCloseness = function (a, dir) {
|
|
return Math.min(Math.abs(dir - a), Math.min(Math.abs(dir + 360 - a), Math.abs(dir - 360 - a)));
|
|
};
|
|
|
|
/**
|
|
* To be called when arrow keys should change the selected node in a tree and expand or collapse subtrees.
|
|
* @this {DrawCommandHandler}
|
|
*/
|
|
DrawCommandHandler.prototype._arrowKeyTree = function () {
|
|
var diagram = this.diagram;
|
|
var selected = diagram.selection.first();
|
|
if (!(selected instanceof go.Node)) return;
|
|
var e = diagram.lastInput;
|
|
if (e.key === "Right") {
|
|
if (selected.isTreeLeaf) {
|
|
// no-op
|
|
} else if (!selected.isTreeExpanded) {
|
|
if (diagram.commandHandler.canExpandTree(selected)) {
|
|
diagram.commandHandler.expandTree(selected); // expands the tree
|
|
}
|
|
} else {
|
|
// already expanded -- select the first child node
|
|
var first = this._sortTreeChildrenByY(selected).first();
|
|
if (first !== null) diagram.select(first);
|
|
}
|
|
} else if (e.key === "Left") {
|
|
if (!selected.isTreeLeaf && selected.isTreeExpanded) {
|
|
if (diagram.commandHandler.canCollapseTree(selected)) {
|
|
diagram.commandHandler.collapseTree(selected); // collapses the tree
|
|
}
|
|
} else {
|
|
// either a leaf or is already collapsed -- select the parent node
|
|
var parent = selected.findTreeParentNode();
|
|
if (parent !== null) diagram.select(parent);
|
|
}
|
|
} else if (e.key === "Up") {
|
|
var parent = selected.findTreeParentNode();
|
|
if (parent !== null) {
|
|
var list = this._sortTreeChildrenByY(parent);
|
|
var idx = list.indexOf(selected);
|
|
if (idx > 0) {
|
|
// if there is a previous sibling
|
|
var prev = list.elt(idx - 1);
|
|
// keep looking at the last child until it's a leaf or collapsed
|
|
while (prev !== null && prev.isTreeExpanded && !prev.isTreeLeaf) {
|
|
var children = this._sortTreeChildrenByY(prev);
|
|
prev = children.last();
|
|
}
|
|
if (prev !== null) diagram.select(prev);
|
|
} else {
|
|
// no previous sibling -- select parent
|
|
diagram.select(parent);
|
|
}
|
|
}
|
|
} else if (e.key === "Down") {
|
|
// if at an expanded parent, select the first child
|
|
if (selected.isTreeExpanded && !selected.isTreeLeaf) {
|
|
var first = this._sortTreeChildrenByY(selected).first();
|
|
if (first !== null) diagram.select(first);
|
|
} else {
|
|
while (selected !== null) {
|
|
var parent = selected.findTreeParentNode();
|
|
if (parent === null) break;
|
|
var list = this._sortTreeChildrenByY(parent);
|
|
var idx = list.indexOf(selected);
|
|
if (idx < list.length - 1) {
|
|
// select next lower node
|
|
diagram.select(list.elt(idx + 1));
|
|
break;
|
|
} else {
|
|
// already at bottom of list of children
|
|
selected = parent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// make sure the selection is now in the viewport, but not necessarily centered
|
|
var sel = diagram.selection.first();
|
|
if (sel !== null) diagram.scrollToRect(sel.actualBounds);
|
|
};
|
|
DrawCommandHandler.prototype._sortTreeChildrenByY = function (node) {
|
|
var list = new go.List().addAll(node.findTreeChildrenNodes());
|
|
list.sort(function (a, b) {
|
|
var aloc = a.location;
|
|
var bloc = b.location;
|
|
if (aloc.y < bloc.y) return -1;
|
|
if (aloc.y > bloc.y) return 1;
|
|
if (aloc.x < bloc.x) return -1;
|
|
if (aloc.x > bloc.x) return 1;
|
|
return 0;
|
|
});
|
|
return list;
|
|
};
|
|
|
|
/**
|
|
* Reset the last offset for pasting.
|
|
* @this {DrawCommandHandler}
|
|
* @param {Iterable.<Part>} coll a collection of {@link Part}s.
|
|
*/
|
|
DrawCommandHandler.prototype.copyToClipboard = function (coll) {
|
|
go.CommandHandler.prototype.copyToClipboard.call(this, coll);
|
|
this._lastPasteOffset.set(this.pasteOffset);
|
|
};
|
|
|
|
/**
|
|
* Paste from the clipboard with an offset incremented on each paste, and reset when copied.
|
|
* @this {DrawCommandHandler}
|
|
* @return {Set.<Part>} a collection of newly pasted {@link Part}s
|
|
*/
|
|
DrawCommandHandler.prototype.pasteFromClipboard = function () {
|
|
var coll = go.CommandHandler.prototype.pasteFromClipboard.call(this);
|
|
this.diagram.moveParts(coll, this._lastPasteOffset);
|
|
this._lastPasteOffset.add(this.pasteOffset);
|
|
return coll;
|
|
};
|
|
|
|
/**
|
|
* Gets or sets the arrow key behavior. Possible values are "move", "select", "scroll", and "tree".
|
|
* The default value is "move".
|
|
* @name DrawCommandHandler#arrowKeyBehavior
|
|
|
|
* @return {string}
|
|
*/
|
|
Object.defineProperty(DrawCommandHandler.prototype, "arrowKeyBehavior", {
|
|
get: function get() {
|
|
return this._arrowKeyBehavior;
|
|
},
|
|
set: function set(val) {
|
|
if (val !== "move" && val !== "select" && val !== "scroll" && val !== "tree" && val !== "none") {
|
|
throw new Error("DrawCommandHandler.arrowKeyBehavior must be either \"move\", \"select\", \"scroll\", \"tree\", or \"none\", not: " + val);
|
|
}
|
|
this._arrowKeyBehavior = val;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Gets or sets the offset at which each repeated pasteSelection() puts the new copied parts from the clipboard.
|
|
* The default value is (10,10).
|
|
* @name DrawCommandHandler#pasteOffset
|
|
|
|
* @return {Point}
|
|
*/
|
|
Object.defineProperty(DrawCommandHandler.prototype, "pasteOffset", {
|
|
get: function get() {
|
|
return this._pasteOffset;
|
|
},
|
|
set: function set(val) {
|
|
if (!(val instanceof go.Point)) throw new Error("DrawCommandHandler.pasteOffset must be a Point, not: " + val);
|
|
this._pasteOffset.set(val);
|
|
}
|
|
});
|
|
/* harmony default export */ var js_DrawCommandHandler = (DrawCommandHandler);
|
|
// EXTERNAL MODULE: ./public/js/go/Figures.js
|
|
var Figures = __webpack_require__(89071);
|
|
// EXTERNAL MODULE: ./node_modules/_gojs-react@1.1.2@gojs-react/lib/esm/gojsreact.js + 1 modules
|
|
var gojsreact = __webpack_require__(85160);
|
|
// EXTERNAL MODULE: ./node_modules/_react@17.0.2@react/jsx-runtime.js
|
|
var jsx_runtime = __webpack_require__(37712);
|
|
;// CONCATENATED MODULE: ./src/pages/Demo/index.tsx
|
|
|
|
|
|
|
|
window.go = go_module;
|
|
|
|
|
|
|
|
|
|
function FlowChart() {
|
|
var myDiagram = (0,_react_17_0_2_react.useRef)().current;
|
|
function initDiagram() {
|
|
var $ = go_module.GraphObject.make;
|
|
var colors = {
|
|
red: "#ff3333",
|
|
blue: "#3358ff",
|
|
green: "#25ad23",
|
|
magenta: "#d533ff",
|
|
purple: "#7d33ff",
|
|
orange: "#ff6233",
|
|
brown: "#8e571e",
|
|
white: "#ffffff",
|
|
black: "#000000",
|
|
beige: "#fffcd5",
|
|
extralightblue: "#d5ebff",
|
|
extralightred: "#f2dfe0",
|
|
lightblue: "#a5d2fa",
|
|
lightgray: "#cccccc",
|
|
lightgreen: "#b3e6b3",
|
|
lightred: "#fcbbbd"
|
|
};
|
|
myDiagram = new go_module.Diagram("myDiagramDiv", {
|
|
padding: 20,
|
|
// extra space when scrolled all the way
|
|
grid: $(go_module.Panel, "Grid",
|
|
// a simple 10x10 grid
|
|
$(go_module.Shape, "LineH", {
|
|
stroke: "lightgray",
|
|
strokeWidth: 0.5
|
|
}), $(go_module.Shape, "LineV", {
|
|
stroke: "lightgray",
|
|
strokeWidth: 0.5
|
|
})),
|
|
"draggingTool.isGridSnapEnabled": true,
|
|
handlesDragDropForTopLevelParts: true,
|
|
mouseDrop: function mouseDrop(e) {
|
|
var ok = e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true);
|
|
if (!ok) e.diagram.currentTool.doCancel();
|
|
},
|
|
commandHandler: $(js_DrawCommandHandler),
|
|
// support offset copy-and-paste
|
|
"clickCreatingTool.archetypeNodeData": {
|
|
text: "NEW NODE"
|
|
},
|
|
// create a new node by double-clicking in background
|
|
"PartCreated": function PartCreated(e) {
|
|
var node = e.subject; // the newly inserted Node -- now need to snap its location to the grid
|
|
node.location = node.location.copy().snapToGridPoint(e.diagram.grid.gridOrigin, e.diagram.grid.gridCellSize);
|
|
setTimeout(function () {
|
|
// and have the user start editing its text
|
|
e.diagram.commandHandler.editTextBlock();
|
|
}, 20);
|
|
},
|
|
"commandHandler.archetypeGroupData": {
|
|
isGroup: true,
|
|
text: "NEW GROUP"
|
|
},
|
|
"SelectionGrouped": function SelectionGrouped(e) {
|
|
var group = e.subject;
|
|
setTimeout(function () {
|
|
// and have the user start editing its text
|
|
e.diagram.commandHandler.editTextBlock();
|
|
});
|
|
},
|
|
"LinkRelinked": function LinkRelinked(e) {
|
|
// re-spread the connections of other links connected with both old and new nodes
|
|
var oldnode = e.parameter.part;
|
|
oldnode.invalidateConnectedLinks();
|
|
var link = e.subject;
|
|
if (e.diagram.toolManager.linkingTool.isForwards) {
|
|
link.toNode.invalidateConnectedLinks();
|
|
} else {
|
|
link.fromNode.invalidateConnectedLinks();
|
|
}
|
|
},
|
|
"undoManager.isEnabled": true
|
|
});
|
|
|
|
// Node template
|
|
|
|
myDiagram.nodeTemplate = $(go_module.Node, "Auto", {
|
|
locationSpot: go_module.Spot.Center,
|
|
locationObjectName: "SHAPE",
|
|
desiredSize: new go_module.Size(120, 60),
|
|
minSize: new go_module.Size(40, 40),
|
|
resizable: true,
|
|
resizeCellSize: new go_module.Size(20, 20)
|
|
},
|
|
// these Bindings are TwoWay because the DraggingTool and ResizingTool modify the target properties
|
|
new go_module.Binding("location", "loc", go_module.Point.parse).makeTwoWay(go_module.Point.stringify), new go_module.Binding("desiredSize", "size", go_module.Size.parse).makeTwoWay(go_module.Size.stringify), $(go_module.Shape, {
|
|
// the border
|
|
name: "SHAPE",
|
|
fill: colors.white,
|
|
cursor: "pointer",
|
|
portId: "",
|
|
fromLinkable: true,
|
|
toLinkable: true,
|
|
fromLinkableDuplicates: true,
|
|
toLinkableDuplicates: true,
|
|
fromSpot: go_module.Spot.AllSides,
|
|
toSpot: go_module.Spot.AllSides
|
|
}, new go_module.Binding("figure"), new go_module.Binding("fill"), new go_module.Binding("stroke", "color"), new go_module.Binding("strokeWidth", "thickness"), new go_module.Binding("strokeDashArray", "dash")),
|
|
// this Shape prevents mouse events from reaching the middle of the port
|
|
$(go_module.Shape, {
|
|
width: 100,
|
|
height: 40,
|
|
strokeWidth: 0,
|
|
fill: "transparent"
|
|
}), $(go_module.TextBlock, {
|
|
margin: 1,
|
|
textAlign: "center",
|
|
overflow: go_module.TextBlock.OverflowEllipsis,
|
|
editable: true
|
|
},
|
|
// this Binding is TwoWay due to the user editing the text with the TextEditingTool
|
|
new go_module.Binding("text").makeTwoWay(), new go_module.Binding("stroke", "color")));
|
|
myDiagram.nodeTemplate.toolTip = $("ToolTip",
|
|
// show some detailed information
|
|
$(go_module.Panel, "Vertical", {
|
|
maxSize: new go_module.Size(200, NaN)
|
|
},
|
|
// limit width but not height
|
|
$(go_module.TextBlock, {
|
|
font: "bold 10pt sans-serif",
|
|
textAlign: "center"
|
|
}, new go_module.Binding("text")), $(go_module.TextBlock, {
|
|
font: "10pt sans-serif",
|
|
textAlign: "center"
|
|
}, new go_module.Binding("text", "details"))));
|
|
|
|
// Node selection adornment
|
|
// Include four large triangular buttons so that the user can easily make a copy
|
|
// of the node, move it to be in that direction relative to the original node,
|
|
// and add a link to the new node.
|
|
|
|
function makeArrowButton(spot, fig) {
|
|
var maker = function maker(e, shape) {
|
|
e.handled = true;
|
|
e.diagram.model.commit(function (m) {
|
|
var selnode = shape.part.adornedPart;
|
|
// create a new node in the direction of the spot
|
|
var p = new go_module.Point().setRectSpot(selnode.actualBounds, spot);
|
|
p.subtract(selnode.location);
|
|
p.scale(2, 2);
|
|
p.x += Math.sign(p.x) * 30;
|
|
p.y += Math.sign(p.y) * 30;
|
|
p.add(selnode.location);
|
|
p.snapToGridPoint(e.diagram.grid.gridOrigin, e.diagram.grid.gridCellSize);
|
|
// make the new node a copy of the selected node
|
|
var nodedata = m.copyNodeData(selnode.data);
|
|
// add to same group as selected node
|
|
m.setGroupKeyForNodeData(nodedata, m.getGroupKeyForNodeData(selnode.data));
|
|
m.addNodeData(nodedata); // add to model
|
|
// create a link from the selected node to the new node
|
|
var linkdata = {
|
|
from: selnode.key,
|
|
to: m.getKeyForNodeData(nodedata)
|
|
};
|
|
m.addLinkData(linkdata); // add to model
|
|
// move the new node to the computed location, select it, and start to edit it
|
|
var newnode = e.diagram.findNodeForData(nodedata);
|
|
newnode.location = p;
|
|
e.diagram.select(newnode);
|
|
setTimeout(function () {
|
|
e.diagram.commandHandler.editTextBlock();
|
|
}, 20);
|
|
});
|
|
};
|
|
return $(go_module.Shape, {
|
|
figure: fig,
|
|
alignment: spot,
|
|
alignmentFocus: spot.opposite(),
|
|
width: spot.equals(go_module.Spot.Top) || spot.equals(go_module.Spot.Bottom) ? 25 : 18,
|
|
height: spot.equals(go_module.Spot.Top) || spot.equals(go_module.Spot.Bottom) ? 18 : 25,
|
|
fill: "orange",
|
|
stroke: colors.white,
|
|
strokeWidth: 4,
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.fill = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.fill = "orange";
|
|
},
|
|
isActionable: true,
|
|
// needed because it's in an Adornment
|
|
click: maker,
|
|
contextClick: maker
|
|
});
|
|
}
|
|
|
|
// create a button that brings up the context menu
|
|
function CMButton(options) {
|
|
return $(go_module.Shape, {
|
|
fill: "orange",
|
|
stroke: "rgba(0, 0, 0, 0)",
|
|
strokeWidth: 15,
|
|
background: "transparent",
|
|
geometryString: "F1 M0 0 b 0 360 -4 0 4 z M10 0 b 0 360 -4 0 4 z M20 0 b 0 360 -4 0 4",
|
|
// M10 0 A2 2 0 1 0 14 10 M20 0 A2 2 0 1 0 24 10,
|
|
isActionable: true,
|
|
cursor: "context-menu",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.fill = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.fill = "orange";
|
|
},
|
|
click: function click(e, shape) {
|
|
e.diagram.commandHandler.showContextMenu(shape.part.adornedPart);
|
|
}
|
|
}, options || {});
|
|
}
|
|
myDiagram.nodeTemplate.selectionAdornmentTemplate = $(go_module.Adornment, "Spot", $(go_module.Placeholder, {
|
|
padding: 10
|
|
}), makeArrowButton(go_module.Spot.Top, "TriangleUp"), makeArrowButton(go_module.Spot.Left, "TriangleLeft"), makeArrowButton(go_module.Spot.Right, "TriangleRight"), makeArrowButton(go_module.Spot.Bottom, "TriangleDown"), CMButton({
|
|
alignment: new go_module.Spot(0.75, 0)
|
|
}));
|
|
|
|
// Common context menu button definitions
|
|
|
|
// All buttons in context menu work on both click and contextClick,
|
|
// in case the user context-clicks on the button.
|
|
// All buttons modify the node data, not the Node, so the Bindings need not be TwoWay.
|
|
|
|
// A button-defining helper function that returns a click event handler.
|
|
// PROPNAME is the name of the data property that should be set to the given VALUE.
|
|
function ClickFunction(propname, value) {
|
|
return function (e, obj) {
|
|
e.handled = true; // don't let the click bubble up
|
|
e.diagram.model.commit(function (m) {
|
|
m.set(obj.part.adornedPart.data, propname, value);
|
|
});
|
|
};
|
|
}
|
|
|
|
// Create a context menu button for setting a data property with a color value.
|
|
function ColorButton(color, propname) {
|
|
if (!propname) propname = "color";
|
|
return $(go_module.Shape, {
|
|
width: 16,
|
|
height: 16,
|
|
stroke: "lightgray",
|
|
fill: color,
|
|
margin: 1,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.stroke = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.stroke = "lightgray";
|
|
},
|
|
click: ClickFunction(propname, color),
|
|
contextClick: ClickFunction(propname, color)
|
|
});
|
|
}
|
|
function LightFillButtons() {
|
|
// used by multiple context menus
|
|
return [$("ContextMenuButton", $(go_module.Panel, "Horizontal", ColorButton(colors.white, "fill"), ColorButton(colors.beige, "fill"), ColorButton(colors.extralightblue, "fill"), ColorButton(colors.extralightred, "fill"))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", ColorButton(colors.lightgray, "fill"), ColorButton(colors.lightgreen, "fill"), ColorButton(colors.lightblue, "fill"), ColorButton(colors.lightred, "fill")))];
|
|
}
|
|
function DarkColorButtons() {
|
|
// used by multiple context menus
|
|
return [$("ContextMenuButton", $(go_module.Panel, "Horizontal", ColorButton(colors.black), ColorButton(colors.green), ColorButton(colors.blue), ColorButton(colors.red))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", ColorButton(colors.white), ColorButton(colors.magenta), ColorButton(colors.purple), ColorButton(colors.orange)))];
|
|
}
|
|
|
|
// Create a context menu button for setting a data property with a stroke width value.
|
|
function ThicknessButton(sw, propname) {
|
|
if (!propname) propname = "thickness";
|
|
return $(go_module.Shape, "LineH", {
|
|
width: 16,
|
|
height: 16,
|
|
strokeWidth: sw,
|
|
margin: 1,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.background = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.background = "transparent";
|
|
},
|
|
click: ClickFunction(propname, sw),
|
|
contextClick: ClickFunction(propname, sw)
|
|
});
|
|
}
|
|
|
|
// Create a context menu button for setting a data property with a stroke dash Array value.
|
|
function DashButton(dash, propname) {
|
|
if (!propname) propname = "dash";
|
|
return $(go_module.Shape, "LineH", {
|
|
width: 24,
|
|
height: 16,
|
|
strokeWidth: 2,
|
|
strokeDashArray: dash,
|
|
margin: 1,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.background = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.background = "transparent";
|
|
},
|
|
click: ClickFunction(propname, dash),
|
|
contextClick: ClickFunction(propname, dash)
|
|
});
|
|
}
|
|
function StrokeOptionsButtons() {
|
|
// used by multiple context menus
|
|
return [$("ContextMenuButton", $(go_module.Panel, "Horizontal", ThicknessButton(1), ThicknessButton(2), ThicknessButton(3), ThicknessButton(4))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", DashButton(null), DashButton([2, 4]), DashButton([4, 4])))];
|
|
}
|
|
|
|
// Node context menu
|
|
|
|
function FigureButton(fig, propname) {
|
|
if (!propname) propname = "figure";
|
|
return $(go_module.Shape, {
|
|
width: 32,
|
|
height: 32,
|
|
scale: 0.5,
|
|
fill: "lightgray",
|
|
figure: fig,
|
|
margin: 1,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.fill = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.fill = "lightgray";
|
|
},
|
|
click: ClickFunction(propname, fig),
|
|
contextClick: ClickFunction(propname, fig)
|
|
});
|
|
}
|
|
myDiagram.nodeTemplate.contextMenu = $("ContextMenu", $("ContextMenuButton", $(go_module.Panel, "Horizontal", FigureButton("Rectangle"), FigureButton("RoundedRectangle"), FigureButton("Ellipse"), FigureButton("Diamond"))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", FigureButton("Parallelogram2"), FigureButton("ManualOperation"), FigureButton("Procedure"), FigureButton("Cylinder1"))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", FigureButton("Terminator"), FigureButton("CreateRequest"), FigureButton("Document"), FigureButton("TriangleDown"))), LightFillButtons(), DarkColorButtons(), StrokeOptionsButtons());
|
|
|
|
// Group template
|
|
|
|
myDiagram.groupTemplate = $(go_module.Group, "Spot", {
|
|
layerName: "Background",
|
|
ungroupable: true,
|
|
locationSpot: go_module.Spot.Center,
|
|
selectionObjectName: "BODY",
|
|
computesBoundsAfterDrag: true,
|
|
// allow dragging out of a Group that uses a Placeholder
|
|
handlesDragDropForMembers: true,
|
|
// don't need to define handlers on Nodes and Links
|
|
mouseDrop: function mouseDrop(e, grp) {
|
|
// add dropped nodes as members of the group
|
|
var ok = grp.addMembers(grp.diagram.selection, true);
|
|
if (!ok) grp.diagram.currentTool.doCancel();
|
|
},
|
|
avoidable: false
|
|
}, new go_module.Binding("location", "loc", go_module.Point.parse).makeTwoWay(go_module.Point.stringify), $(go_module.Panel, "Auto", {
|
|
name: "BODY"
|
|
}, $(go_module.Shape, {
|
|
parameter1: 10,
|
|
fill: colors.white,
|
|
strokeWidth: 2,
|
|
cursor: "pointer",
|
|
fromLinkable: true,
|
|
toLinkable: true,
|
|
fromLinkableDuplicates: true,
|
|
toLinkableDuplicates: true,
|
|
fromSpot: go_module.Spot.AllSides,
|
|
toSpot: go_module.Spot.AllSides
|
|
}, new go_module.Binding("fill"), new go_module.Binding("stroke", "color"), new go_module.Binding("strokeWidth", "thickness"), new go_module.Binding("strokeDashArray", "dash")), $(go_module.Placeholder, {
|
|
background: "transparent",
|
|
margin: 20
|
|
})), $(go_module.TextBlock, {
|
|
alignment: go_module.Spot.Top,
|
|
alignmentFocus: go_module.Spot.Bottom,
|
|
font: "bold 12pt sans-serif",
|
|
editable: true
|
|
}, new go_module.Binding("text"), new go_module.Binding("stroke", "color")));
|
|
myDiagram.groupTemplate.selectionAdornmentTemplate = $(go_module.Adornment, "Spot", $(go_module.Panel, "Auto", $(go_module.Shape, {
|
|
fill: null,
|
|
stroke: "dodgerblue",
|
|
strokeWidth: 3
|
|
}), $(go_module.Placeholder, {
|
|
margin: 1.5
|
|
})), CMButton({
|
|
alignment: go_module.Spot.TopRight,
|
|
alignmentFocus: go_module.Spot.BottomRight
|
|
}));
|
|
myDiagram.groupTemplate.contextMenu = $("ContextMenu", LightFillButtons(), DarkColorButtons(), StrokeOptionsButtons());
|
|
|
|
// Link template
|
|
|
|
myDiagram.linkTemplate = $(go_module.Link, {
|
|
layerName: "Foreground",
|
|
routing: go_module.Link.AvoidsNodes,
|
|
corner: 10,
|
|
fromShortLength: 10,
|
|
toShortLength: 15,
|
|
// assume arrowhead at "to" end, need to avoid bad appearance when path is thick
|
|
relinkableFrom: true,
|
|
relinkableTo: true,
|
|
reshapable: true,
|
|
resegmentable: true
|
|
}, new go_module.Binding("fromSpot", "fromSpot", go_module.Spot.parse), new go_module.Binding("toSpot", "toSpot", go_module.Spot.parse), new go_module.Binding("fromShortLength", "dir", function (dir) {
|
|
return dir >= 1 ? 10 : 0;
|
|
}), new go_module.Binding("toShortLength", "dir", function (dir) {
|
|
return dir >= 1 ? 10 : 0;
|
|
}), new go_module.Binding("points").makeTwoWay(),
|
|
// TwoWay due to user reshaping with LinkReshapingTool
|
|
|
|
$(go_module.Shape, {
|
|
strokeWidth: 2
|
|
}, new go_module.Binding("stroke", "color"), new go_module.Binding("strokeWidth", "thickness"), new go_module.Binding("strokeDashArray", "dash")), $(go_module.Shape,
|
|
// custom arrowheads to create the lifted effect
|
|
{
|
|
segmentIndex: 0,
|
|
segmentOffset: new go_module.Point(15, 0),
|
|
segmentOrientation: go_module.Link.OrientAlong,
|
|
alignmentFocus: go_module.Spot.Right,
|
|
figure: "circle",
|
|
width: 10,
|
|
strokeWidth: 0
|
|
}, new go_module.Binding("fill", "color"), new go_module.Binding("visible", "dir", function (dir) {
|
|
return dir === 1;
|
|
})), $(go_module.Shape, {
|
|
segmentIndex: -1,
|
|
segmentOffset: new go_module.Point(-10, 6),
|
|
segmentOrientation: go_module.Link.OrientPlus90,
|
|
alignmentFocus: go_module.Spot.Right,
|
|
figure: "triangle",
|
|
width: 12,
|
|
height: 12,
|
|
strokeWidth: 0
|
|
}, new go_module.Binding("fill", "color"), new go_module.Binding("visible", "dir", function (dir) {
|
|
return dir >= 1;
|
|
}), new go_module.Binding("width", "thickness", function (t) {
|
|
return 7 + 3 * t;
|
|
}),
|
|
// custom arrowhead must scale with the size of the while
|
|
new go_module.Binding("height", "thickness", function (t) {
|
|
return 7 + 3 * t;
|
|
}),
|
|
// while remaining centered on line
|
|
new go_module.Binding("segmentOffset", "thickness", function (t) {
|
|
return new go_module.Point(-15, 4 + 1.5 * t);
|
|
})), $(go_module.Shape, {
|
|
segmentIndex: 0,
|
|
segmentOffset: new go_module.Point(15, -6),
|
|
segmentOrientation: go_module.Link.OrientMinus90,
|
|
alignmentFocus: go_module.Spot.Right,
|
|
figure: "triangle",
|
|
width: 12,
|
|
height: 12,
|
|
strokeWidth: 0
|
|
}, new go_module.Binding("fill", "color"), new go_module.Binding("visible", "dir", function (dir) {
|
|
return dir === 2;
|
|
}), new go_module.Binding("width", "thickness", function (t) {
|
|
return 7 + 3 * t;
|
|
}), new go_module.Binding("height", "thickness", function (t) {
|
|
return 7 + 3 * t;
|
|
}), new go_module.Binding("segmentOffset", "thickness", function (t) {
|
|
return new go_module.Point(-15, 4 + 1.5 * t);
|
|
})), $(go_module.TextBlock, {
|
|
alignmentFocus: new go_module.Spot(0, 1, -4, 0),
|
|
editable: true
|
|
}, new go_module.Binding("text").makeTwoWay(),
|
|
// TwoWay due to user editing with TextEditingTool
|
|
new go_module.Binding("stroke", "color")));
|
|
myDiagram.linkTemplate.selectionAdornmentTemplate = $(go_module.Adornment,
|
|
// use a special selection Adornment that does not obscure the link path itself
|
|
$(go_module.Shape, {
|
|
// this uses a pathPattern with a gap in it, in order to avoid drawing on top of the link path Shape
|
|
isPanelMain: true,
|
|
stroke: "transparent",
|
|
strokeWidth: 6,
|
|
pathPattern: makeAdornmentPathPattern(2) // == thickness or strokeWidth
|
|
}, new go_module.Binding("pathPattern", "thickness", makeAdornmentPathPattern)), CMButton({
|
|
alignmentFocus: new go_module.Spot(0, 0, -6, -4)
|
|
}));
|
|
function makeAdornmentPathPattern(w) {
|
|
return $(go_module.Shape, {
|
|
stroke: "dodgerblue",
|
|
strokeWidth: 2,
|
|
strokeCap: "square",
|
|
geometryString: "M0 0 M4 2 H3 M4 " + (w + 4).toString() + " H3"
|
|
});
|
|
}
|
|
|
|
// Link context menu
|
|
// All buttons in context menu work on both click and contextClick,
|
|
// in case the user context-clicks on the button.
|
|
// All buttons modify the link data, not the Link, so the Bindings need not be TwoWay.
|
|
|
|
function ArrowButton(num) {
|
|
var geo = "M0 0 M8 16 M0 8 L16 8 M12 11 L16 8 L12 5";
|
|
if (num === 0) {
|
|
geo = "M0 0 M16 16 M0 8 L16 8";
|
|
} else if (num === 2) {
|
|
geo = "M0 0 M16 16 M0 8 L16 8 M12 11 L16 8 L12 5 M4 11 L0 8 L4 5";
|
|
}
|
|
return $(go_module.Shape, {
|
|
geometryString: geo,
|
|
margin: 2,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.background = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.background = "transparent";
|
|
},
|
|
click: ClickFunction("dir", num),
|
|
contextClick: ClickFunction("dir", num)
|
|
});
|
|
}
|
|
function AllSidesButton(to) {
|
|
var setter = function setter(e, shape) {
|
|
e.handled = true;
|
|
e.diagram.model.commit(function (m) {
|
|
var link = shape.part.adornedPart;
|
|
m.set(link.data, to ? "toSpot" : "fromSpot", go_module.Spot.stringify(go_module.Spot.AllSides));
|
|
// re-spread the connections of other links connected with the node
|
|
(to ? link.toNode : link.fromNode).invalidateConnectedLinks();
|
|
});
|
|
};
|
|
return $(go_module.Shape, {
|
|
width: 12,
|
|
height: 12,
|
|
fill: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.background = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.background = "transparent";
|
|
},
|
|
click: setter,
|
|
contextClick: setter
|
|
});
|
|
}
|
|
function SpotButton(spot, to) {
|
|
var ang = 0;
|
|
var side = go_module.Spot.RightSide;
|
|
if (spot.equals(go_module.Spot.Top)) {
|
|
ang = 270;
|
|
side = go_module.Spot.TopSide;
|
|
} else if (spot.equals(go_module.Spot.Left)) {
|
|
ang = 180;
|
|
side = go_module.Spot.LeftSide;
|
|
} else if (spot.equals(go_module.Spot.Bottom)) {
|
|
ang = 90;
|
|
side = go_module.Spot.BottomSide;
|
|
}
|
|
if (!to) ang -= 180;
|
|
var setter = function setter(e, shape) {
|
|
e.handled = true;
|
|
e.diagram.model.commit(function (m) {
|
|
var link = shape.part.adornedPart;
|
|
m.set(link.data, to ? "toSpot" : "fromSpot", go_module.Spot.stringify(side));
|
|
// re-spread the connections of other links connected with the node
|
|
(to ? link.toNode : link.fromNode).invalidateConnectedLinks();
|
|
});
|
|
};
|
|
return $(go_module.Shape, {
|
|
alignment: spot,
|
|
alignmentFocus: spot.opposite(),
|
|
geometryString: "M0 0 M12 12 M12 6 L1 6 L4 4 M1 6 L4 8",
|
|
angle: ang,
|
|
background: "transparent",
|
|
mouseEnter: function mouseEnter(e, shape) {
|
|
return shape.background = "dodgerblue";
|
|
},
|
|
mouseLeave: function mouseLeave(e, shape) {
|
|
return shape.background = "transparent";
|
|
},
|
|
click: setter,
|
|
contextClick: setter
|
|
});
|
|
}
|
|
myDiagram.linkTemplate.contextMenu = $("ContextMenu", DarkColorButtons(), StrokeOptionsButtons(), $("ContextMenuButton", $(go_module.Panel, "Horizontal", ArrowButton(0), ArrowButton(1), ArrowButton(2))), $("ContextMenuButton", $(go_module.Panel, "Horizontal", $(go_module.Panel, "Spot", AllSidesButton(false), SpotButton(go_module.Spot.Top, false), SpotButton(go_module.Spot.Left, false), SpotButton(go_module.Spot.Right, false), SpotButton(go_module.Spot.Bottom, false)), $(go_module.Panel, "Spot", {
|
|
margin: new go_module.Margin(0, 0, 0, 2)
|
|
}, AllSidesButton(true), SpotButton(go_module.Spot.Top, true), SpotButton(go_module.Spot.Left, true), SpotButton(go_module.Spot.Right, true), SpotButton(go_module.Spot.Bottom, true)))));
|
|
var initData = "{ \"class\": \"GraphLinksModel\",\n \"nodeDataArray\": [\n{\"text\":\"Find Problem\",\"key\":-9,\"loc\":\"-20 -140\",\"color\":\"#3358ff\",\"fill\":\"white\",\"figure\":\"Procedure\",\"thickness\":3},\n{\"text\":\"What do we want?\",\"key\":-10,\"loc\":\"-65 -324.305\",\"group\":-16,\"figure\":\"Ellipse\",\"fill\":\"white\"},\n{\"text\":\"What do our users want?\",\"key\":-11,\"loc\":\"105 -334.305\",\"group\":-20,\"figure\":\"Ellipse\",\"fill\":\"#ffffff\",\"color\":\"black\"},\n{\"text\":\"Meetings\",\"key\":-12,\"loc\":\"-65 -444.305\",\"group\":-16,\"figure\":\"TriangleDown\",\"fill\":\"#ffffff\"},\n{\"text\":\"Reviews\",\"key\":-13,\"loc\":\"105 -454.305\",\"group\":-20,\"figure\":\"TriangleDown\",\"fill\":\"#ffffff\",\"color\":\"black\"},\n{\"text\":\"Can we solve it?\",\"key\":-14,\"loc\":\"190 -140\",\"color\":\"#7d33ff\",\"fill\":\"#ffffff\",\"figure\":\"Diamond\",\"size\":\"140 80\",\"thickness\":3},\n{\"isGroup\":true,\"text\":\"Internal\",\"key\":-16,\"loc\":\"-65 -384.305\",\"fill\":\"#d5ebff\",\"dash\":null,\"thickness\":1,\"group\":-22},\n{\"isGroup\":true,\"text\":\"External\",\"key\":-20,\"loc\":\"105 -394.305\",\"fill\":\"#d5ebff\",\"dash\":null,\"thickness\":1,\"group\":-22},\n{\"isGroup\":true,\"text\":\"Sources\",\"key\":-22,\"loc\":\"20 -400\",\"fill\":\"#a5d2fa\",\"dash\":[4,4],\"color\":\"#3358ff\"}\n],\n \"linkDataArray\": [\n{\"from\":-12,\"to\":-10,\"points\":[-65,-414.305,-65,-404.305,-65,-384.305,-65,-384.305,-65,-364.305,-65,-354.305],\"dash\":null,\"dir\":1},\n{\"from\":-13,\"to\":-11,\"points\":[105,-424.305,105,-414.305,105,-394.305,105,-394.305,105,-374.305,105,-364.305],\"dash\":null,\"color\":\"#000000\",\"dir\":1},\n{\"from\":-10,\"to\":-9,\"points\":[-65,-294.305,-65,-284.305,-65,-232.1525,-40,-232.1525,-40,-180,-40,-170],\"dir\":2,\"dash\":[4,4]},\n{\"from\":-11,\"to\":-9,\"points\":[105,-304.305,105,-294.305,105,-237.1525,0,-237.1525,0,-180,0,-170],\"dash\":[4,4],\"dir\":2},\n{\"from\":-9,\"to\":-14,\"points\":[40,-150,58,-150,80,-150,80,-153.33333333333331,102,-153.33333333333331,120,-153.33333333333331],\"dir\":1,\"color\":\"#3358ff\"},\n{\"from\":-14,\"to\":-9,\"points\":[190,-100,190,-90,-20,-90,-20,-95,-20,-100,-20,-110],\"fromSpot\":\"BottomSide\",\"toSpot\":\"BottomSide\",\"text\":\"No\",\"color\":\"#ff3333\",\"thickness\":2,\"dir\":1},\n{\"from\":-9,\"to\":-14,\"points\":[40,-130,58,-130,80,-130,80,-126.66666666666666,102,-126.66666666666666,120,-126.66666666666666]}\n]}";
|
|
myDiagram.model = go_module.Model.fromJson(initData);
|
|
return myDiagram;
|
|
}
|
|
function save() {
|
|
console.log(JSON.stringify(myDiagram.model.toJson()));
|
|
myDiagram.isModified = false;
|
|
// 将图表保存为PNG图像
|
|
function saveAsPng() {
|
|
var imgs = myDiagram.makeImage();
|
|
document.body.appendChild(imgs);
|
|
return;
|
|
}
|
|
|
|
// 调用保存函数
|
|
saveAsPng();
|
|
}
|
|
return /*#__PURE__*/(0,jsx_runtime.jsxs)("div", {
|
|
style: {
|
|
width: "100%",
|
|
height: "100%"
|
|
},
|
|
onClick: save,
|
|
children: [/*#__PURE__*/(0,jsx_runtime.jsx)(gojsreact/* ReactDiagram */.FI, {
|
|
initDiagram: initDiagram,
|
|
divClassName: "diagram-component"
|
|
// nodeDataArray={[
|
|
// { key: 0, text: 'Alpha', color: 'lightblue', loc: '0 0' },
|
|
// { key: 1, text: 'Beta', color: 'orange', loc: '150 0' },
|
|
// { key: 2, text: 'Gamma', color: 'lightgreen', loc: '0 150' },
|
|
// { key: 3, text: 'Delta', color: 'pink', loc: '150 150' }
|
|
// ]}
|
|
// linkDataArray={[
|
|
// { key: -1, from: 0, to: 1 },
|
|
// { key: -2, from: 0, to: 2 },
|
|
// { key: -3, from: 1, to: 1 },
|
|
// { key: -4, from: 2, to: 3 },
|
|
// { key: -5, from: 3, to: 0 }
|
|
// ]}
|
|
// onModelChange={handleModelChange}
|
|
,
|
|
style: {
|
|
height: "800px"
|
|
}
|
|
}), /*#__PURE__*/(0,jsx_runtime.jsx)("div", {
|
|
id: "myDiagramDiv"
|
|
})]
|
|
});
|
|
}
|
|
/* harmony default export */ var Demo = (FlowChart);
|
|
|
|
/***/ })
|
|
|
|
}]); |