UNPKG

@reactodia/workspace

Version:

Reactodia Workspace -- library for visual interaction with graphs in a form of a diagram.

1,333 lines (1,305 loc) 179 kB
import * as __WEBPACK_EXTERNAL_MODULE__reactodia_worker_proxy_protocol_0beb1c9e__ from "@reactodia/worker-proxy/protocol"; /******/ var __webpack_modules__ = ([ /* 0 */, /* 1 */ /***/ ((module) => { module.exports = __WEBPACK_EXTERNAL_MODULE__reactodia_worker_proxy_protocol_0beb1c9e__; /***/ }), /* 2 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ blockingDefaultLayout: () => (/* binding */ blockingDefaultLayout), /* harmony export */ colaFlowLayout: () => (/* binding */ colaFlowLayout), /* harmony export */ colaForceLayout: () => (/* binding */ colaForceLayout), /* harmony export */ colaRemoveOverlaps: () => (/* binding */ colaRemoveOverlaps), /* harmony export */ evaluateColaLayout: () => (/* binding */ evaluateColaLayout), /* harmony export */ getContentFittingBoxForLayout: () => (/* binding */ getContentFittingBoxForLayout), /* harmony export */ layoutPadded: () => (/* binding */ layoutPadded), /* harmony export */ layoutPaddedBiasFree: () => (/* binding */ layoutPaddedBiasFree) /* harmony export */ }); /* harmony import */ var webcola__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var webcola__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webcola__WEBPACK_IMPORTED_MODULE_0__); function evaluateColaLayout(graph, state, evaluateLayout) { const nodes = new Map(); const links = []; for (const [id, node] of Object.entries(graph.nodes)) { const bounds = Object.hasOwn(state.bounds, id) ? state.bounds[id] : undefined; nodes.set(id, { x: bounds ? bounds.x : 0, y: bounds ? bounds.y : 0, width: bounds ? bounds.width : undefined, height: bounds ? bounds.height : undefined, fixed: node.fixed ? 1 : 0, }); } for (const link of graph.links) { const source = nodes.get(link.source); const target = nodes.get(link.target); if (source && target) { links.push({ source, target }); } } evaluateLayout(nodes, links); const bounds = Object.create(null); for (const [id, node] of nodes) { bounds[id] = { x: node.x, y: node.y, width: node.width ?? 0, height: node.height ?? 0, }; } return { bounds }; } function colaForceLayout(graph, state, options) { const { preferredLinkLength = 200, avoidOverlaps = true, } = options ?? {}; return evaluateColaLayout(graph, state, (nodes, links) => { const layout = new webcola__WEBPACK_IMPORTED_MODULE_0__.Layout() .nodes(Array.from(nodes.values())) .links(links) .avoidOverlaps(avoidOverlaps) .convergenceThreshold(1e-9) .jaccardLinkLengths(preferredLinkLength) .handleDisconnected(true); layout.start(30, 0, 10, undefined, false); }); } function colaFlowLayout(graph, state, options) { const { axis = 'y', minSeparation = 200, preferredLinkLength = 50, avoidOverlaps = true, } = options ?? {}; return evaluateColaLayout(graph, state, (nodes, links) => { const layout = new webcola__WEBPACK_IMPORTED_MODULE_0__.Layout() .nodes(Array.from(nodes.values())) .links(links) .avoidOverlaps(avoidOverlaps) .flowLayout(axis, minSeparation) .symmetricDiffLinkLengths(preferredLinkLength); layout.start(10, 20, 20, undefined, false); }); } function colaRemoveOverlaps(state) { const nodeRectangles = new Map(); for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) { nodeRectangles.set(id, new webcola__WEBPACK_IMPORTED_MODULE_0__.Rectangle(x, x + width, y, y + height)); } webcola__WEBPACK_IMPORTED_MODULE_0__.removeOverlaps(Array.from(nodeRectangles.values())); const bounds = Object.create(null); for (const [id, { x, y }] of nodeRectangles) { const nodeBounds = Object.hasOwn(state.bounds, id) ? state.bounds[id] : undefined; bounds[id] = { x, y, width: nodeBounds ? nodeBounds.width : 0, height: nodeBounds ? nodeBounds.height : 0, }; } return { bounds }; } function layoutPadded(state, padding) { if (!padding) { return { state, unwrap: transformed => transformed }; } const paddedBounds = Object.create(null); for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) { paddedBounds[id] = { x: x - padding.x, y: y - padding.y, width: width + padding.x * 2, height: height + padding.y * 2, }; } const paddedState = { bounds: paddedBounds }; return { state: paddedState, unwrap: transformed => { const shrinkBounds = Object.create(null); for (const [id, { x, y, width, height }] of Object.entries(transformed.bounds)) { shrinkBounds[id] = { x: x + padding.x, y: y + padding.y, width: width - padding.x * 2, height: height - padding.y * 2, }; } return { bounds: shrinkBounds }; } }; } function layoutPaddedBiasFree(state, padding) { const extendedBounds = Object.create(null); let compressX = Infinity; let compressY = Infinity; for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) { const maxSide = Math.max(width, height); compressX = Math.min(width ? (maxSide / width) : 1, compressX); compressY = Math.min(height ? (maxSide / height) : 1, compressY); extendedBounds[id] = { x, y, width: maxSide, height: maxSide, }; } const padded = layoutPadded({ bounds: extendedBounds }, padding); return { state: padded.state, unwrap: transformed => { const withoutPadding = padded.unwrap(transformed); const fittingBox = getContentFittingBoxForLayout(withoutPadding); const uncompressedBounds = Object.create(null); for (const [id, bounds] of Object.entries(withoutPadding.bounds)) { const initialBounds = Object.hasOwn(state.bounds, id) ? state.bounds[id] : undefined; uncompressedBounds[id] = { x: (bounds.x - fittingBox.x) / compressX + fittingBox.x, y: (bounds.y - fittingBox.y) / compressY + fittingBox.y, width: initialBounds ? initialBounds.width : bounds.width, height: initialBounds ? initialBounds.height : bounds.height, }; } return { bounds: uncompressedBounds }; } }; } function blockingDefaultLayout(graph, state, options) { const { preferredLinkLength = 200, padding = { x: 50, y: 50 }, } = options ?? {}; const withForce = colaForceLayout(graph, state, { preferredLinkLength, avoidOverlaps: false, }); const padded = layoutPaddedBiasFree(withForce, padding); const withoutOverlaps = colaRemoveOverlaps(padded.state); const result = padded.unwrap(withoutOverlaps); return Promise.resolve(result); } function getContentFittingBoxForLayout(state) { let minX = Infinity, minY = Infinity; let maxX = -Infinity, maxY = -Infinity; for (const [id, { x, y, width, height }] of Object.entries(state.bounds)) { minX = Math.min(minX, x); minY = Math.min(minY, y); maxX = Math.max(maxX, x + width); maxY = Math.max(maxY, y + height); } return { x: Number.isFinite(minX) ? minX : 0, y: Number.isFinite(minY) ? minY : 0, width: Number.isFinite(minX) && Number.isFinite(maxX) ? (maxX - minX) : 0, height: Number.isFinite(minY) && Number.isFinite(maxY) ? (maxY - minY) : 0, }; } /***/ }), /* 3 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", ({ value: true })); __export(__webpack_require__(4)); __export(__webpack_require__(16)); __export(__webpack_require__(8)); __export(__webpack_require__(14)); __export(__webpack_require__(19)); __export(__webpack_require__(15)); __export(__webpack_require__(5)); __export(__webpack_require__(20)); __export(__webpack_require__(7)); __export(__webpack_require__(6)); __export(__webpack_require__(13)); __export(__webpack_require__(11)); __export(__webpack_require__(9)); __export(__webpack_require__(12)); __export(__webpack_require__(10)); __export(__webpack_require__(21)); /***/ }), /* 4 */ /***/ (function(__unused_webpack_module, exports, __webpack_require__) { 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 __()); }; })(); Object.defineProperty(exports, "__esModule", ({ value: true })); var layout_1 = __webpack_require__(5); var LayoutAdaptor = (function (_super) { __extends(LayoutAdaptor, _super); function LayoutAdaptor(options) { var _this = _super.call(this) || this; var self = _this; var o = options; if (o.trigger) { _this.trigger = o.trigger; } if (o.kick) { _this.kick = o.kick; } if (o.drag) { _this.drag = o.drag; } if (o.on) { _this.on = o.on; } _this.dragstart = _this.dragStart = layout_1.Layout.dragStart; _this.dragend = _this.dragEnd = layout_1.Layout.dragEnd; return _this; } LayoutAdaptor.prototype.trigger = function (e) { }; ; LayoutAdaptor.prototype.kick = function () { }; ; LayoutAdaptor.prototype.drag = function () { }; ; LayoutAdaptor.prototype.on = function (eventType, listener) { return this; }; ; return LayoutAdaptor; }(layout_1.Layout)); exports.LayoutAdaptor = LayoutAdaptor; function adaptor(options) { return new LayoutAdaptor(options); } exports.adaptor = adaptor; /***/ }), /* 5 */ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { Object.defineProperty(exports, "__esModule", ({ value: true })); var powergraph = __webpack_require__(6); var linklengths_1 = __webpack_require__(7); var descent_1 = __webpack_require__(8); var rectangle_1 = __webpack_require__(9); var shortestpaths_1 = __webpack_require__(12); var geom_1 = __webpack_require__(14); var handledisconnected_1 = __webpack_require__(15); var EventType; (function (EventType) { EventType[EventType["start"] = 0] = "start"; EventType[EventType["tick"] = 1] = "tick"; EventType[EventType["end"] = 2] = "end"; })(EventType = exports.EventType || (exports.EventType = {})); ; function isGroup(g) { return typeof g.leaves !== 'undefined' || typeof g.groups !== 'undefined'; } var Layout = (function () { function Layout() { var _this = this; this._canvasSize = [1, 1]; this._linkDistance = 20; this._defaultNodeSize = 10; this._linkLengthCalculator = null; this._linkType = null; this._avoidOverlaps = false; this._handleDisconnected = true; this._running = false; this._nodes = []; this._groups = []; this._rootGroup = null; this._links = []; this._constraints = []; this._distanceMatrix = null; this._descent = null; this._directedLinkConstraints = null; this._threshold = 0.01; this._visibilityGraph = null; this._groupCompactness = 1e-6; this.event = null; this.linkAccessor = { getSourceIndex: Layout.getSourceIndex, getTargetIndex: Layout.getTargetIndex, setLength: Layout.setLinkLength, getType: function (l) { return typeof _this._linkType === "function" ? _this._linkType(l) : 0; } }; } Layout.prototype.on = function (e, listener) { if (!this.event) this.event = {}; if (typeof e === 'string') { this.event[EventType[e]] = listener; } else { this.event[e] = listener; } return this; }; Layout.prototype.trigger = function (e) { if (this.event && typeof this.event[e.type] !== 'undefined') { this.event[e.type](e); } }; Layout.prototype.kick = function () { while (!this.tick()) ; }; Layout.prototype.tick = function () { if (this._alpha < this._threshold) { this._running = false; this.trigger({ type: EventType.end, alpha: this._alpha = 0, stress: this._lastStress }); return true; } var n = this._nodes.length, m = this._links.length; var o, i; this._descent.locks.clear(); for (i = 0; i < n; ++i) { o = this._nodes[i]; if (o.fixed) { if (typeof o.px === 'undefined' || typeof o.py === 'undefined') { o.px = o.x; o.py = o.y; } var p = [o.px, o.py]; this._descent.locks.add(i, p); } } var s1 = this._descent.rungeKutta(); if (s1 === 0) { this._alpha = 0; } else if (typeof this._lastStress !== 'undefined') { this._alpha = s1; } this._lastStress = s1; this.updateNodePositions(); this.trigger({ type: EventType.tick, alpha: this._alpha, stress: this._lastStress }); return false; }; Layout.prototype.updateNodePositions = function () { var x = this._descent.x[0], y = this._descent.x[1]; var o, i = this._nodes.length; while (i--) { o = this._nodes[i]; o.x = x[i]; o.y = y[i]; } }; Layout.prototype.nodes = function (v) { if (!v) { if (this._nodes.length === 0 && this._links.length > 0) { var n = 0; this._links.forEach(function (l) { n = Math.max(n, l.source, l.target); }); this._nodes = new Array(++n); for (var i = 0; i < n; ++i) { this._nodes[i] = {}; } } return this._nodes; } this._nodes = v; return this; }; Layout.prototype.groups = function (x) { var _this = this; if (!x) return this._groups; this._groups = x; this._rootGroup = {}; this._groups.forEach(function (g) { if (typeof g.padding === "undefined") g.padding = 1; if (typeof g.leaves !== "undefined") { g.leaves.forEach(function (v, i) { if (typeof v === 'number') (g.leaves[i] = _this._nodes[v]).parent = g; }); } if (typeof g.groups !== "undefined") { g.groups.forEach(function (gi, i) { if (typeof gi === 'number') (g.groups[i] = _this._groups[gi]).parent = g; }); } }); this._rootGroup.leaves = this._nodes.filter(function (v) { return typeof v.parent === 'undefined'; }); this._rootGroup.groups = this._groups.filter(function (g) { return typeof g.parent === 'undefined'; }); return this; }; Layout.prototype.powerGraphGroups = function (f) { var g = powergraph.getGroups(this._nodes, this._links, this.linkAccessor, this._rootGroup); this.groups(g.groups); f(g); return this; }; Layout.prototype.avoidOverlaps = function (v) { if (!arguments.length) return this._avoidOverlaps; this._avoidOverlaps = v; return this; }; Layout.prototype.handleDisconnected = function (v) { if (!arguments.length) return this._handleDisconnected; this._handleDisconnected = v; return this; }; Layout.prototype.flowLayout = function (axis, minSeparation) { if (!arguments.length) axis = 'y'; this._directedLinkConstraints = { axis: axis, getMinSeparation: typeof minSeparation === 'number' ? function () { return minSeparation; } : minSeparation }; return this; }; Layout.prototype.links = function (x) { if (!arguments.length) return this._links; this._links = x; return this; }; Layout.prototype.constraints = function (c) { if (!arguments.length) return this._constraints; this._constraints = c; return this; }; Layout.prototype.distanceMatrix = function (d) { if (!arguments.length) return this._distanceMatrix; this._distanceMatrix = d; return this; }; Layout.prototype.size = function (x) { if (!x) return this._canvasSize; this._canvasSize = x; return this; }; Layout.prototype.defaultNodeSize = function (x) { if (!x) return this._defaultNodeSize; this._defaultNodeSize = x; return this; }; Layout.prototype.groupCompactness = function (x) { if (!x) return this._groupCompactness; this._groupCompactness = x; return this; }; Layout.prototype.linkDistance = function (x) { if (!x) { return this._linkDistance; } this._linkDistance = typeof x === "function" ? x : +x; this._linkLengthCalculator = null; return this; }; Layout.prototype.linkType = function (f) { this._linkType = f; return this; }; Layout.prototype.convergenceThreshold = function (x) { if (!x) return this._threshold; this._threshold = typeof x === "function" ? x : +x; return this; }; Layout.prototype.alpha = function (x) { if (!arguments.length) return this._alpha; else { x = +x; if (this._alpha) { if (x > 0) this._alpha = x; else this._alpha = 0; } else if (x > 0) { if (!this._running) { this._running = true; this.trigger({ type: EventType.start, alpha: this._alpha = x }); this.kick(); } } return this; } }; Layout.prototype.getLinkLength = function (link) { return typeof this._linkDistance === "function" ? +(this._linkDistance(link)) : this._linkDistance; }; Layout.setLinkLength = function (link, length) { link.length = length; }; Layout.prototype.getLinkType = function (link) { return typeof this._linkType === "function" ? this._linkType(link) : 0; }; Layout.prototype.symmetricDiffLinkLengths = function (idealLength, w) { var _this = this; if (w === void 0) { w = 1; } this.linkDistance(function (l) { return idealLength * l.length; }); this._linkLengthCalculator = function () { return linklengths_1.symmetricDiffLinkLengths(_this._links, _this.linkAccessor, w); }; return this; }; Layout.prototype.jaccardLinkLengths = function (idealLength, w) { var _this = this; if (w === void 0) { w = 1; } this.linkDistance(function (l) { return idealLength * l.length; }); this._linkLengthCalculator = function () { return linklengths_1.jaccardLinkLengths(_this._links, _this.linkAccessor, w); }; return this; }; Layout.prototype.start = function (initialUnconstrainedIterations, initialUserConstraintIterations, initialAllConstraintsIterations, gridSnapIterations, keepRunning, centerGraph) { var _this = this; if (initialUnconstrainedIterations === void 0) { initialUnconstrainedIterations = 0; } if (initialUserConstraintIterations === void 0) { initialUserConstraintIterations = 0; } if (initialAllConstraintsIterations === void 0) { initialAllConstraintsIterations = 0; } if (gridSnapIterations === void 0) { gridSnapIterations = 0; } if (keepRunning === void 0) { keepRunning = true; } if (centerGraph === void 0) { centerGraph = true; } var i, j, n = this.nodes().length, N = n + 2 * this._groups.length, m = this._links.length, w = this._canvasSize[0], h = this._canvasSize[1]; var x = new Array(N), y = new Array(N); var G = null; var ao = this._avoidOverlaps; this._nodes.forEach(function (v, i) { v.index = i; if (typeof v.x === 'undefined') { v.x = w / 2, v.y = h / 2; } x[i] = v.x, y[i] = v.y; }); if (this._linkLengthCalculator) this._linkLengthCalculator(); var distances; if (this._distanceMatrix) { distances = this._distanceMatrix; } else { distances = (new shortestpaths_1.Calculator(N, this._links, Layout.getSourceIndex, Layout.getTargetIndex, function (l) { return _this.getLinkLength(l); })).DistanceMatrix(); G = descent_1.Descent.createSquareMatrix(N, function () { return 2; }); this._links.forEach(function (l) { if (typeof l.source == "number") l.source = _this._nodes[l.source]; if (typeof l.target == "number") l.target = _this._nodes[l.target]; }); this._links.forEach(function (e) { var u = Layout.getSourceIndex(e), v = Layout.getTargetIndex(e); G[u][v] = G[v][u] = e.weight || 1; }); } var D = descent_1.Descent.createSquareMatrix(N, function (i, j) { return distances[i][j]; }); if (this._rootGroup && typeof this._rootGroup.groups !== 'undefined') { var i = n; var addAttraction = function (i, j, strength, idealDistance) { G[i][j] = G[j][i] = strength; D[i][j] = D[j][i] = idealDistance; }; this._groups.forEach(function (g) { addAttraction(i, i + 1, _this._groupCompactness, 0.1); x[i] = 0, y[i++] = 0; x[i] = 0, y[i++] = 0; }); } else this._rootGroup = { leaves: this._nodes, groups: [] }; var curConstraints = this._constraints || []; if (this._directedLinkConstraints) { this.linkAccessor.getMinSeparation = this._directedLinkConstraints.getMinSeparation; curConstraints = curConstraints.concat(linklengths_1.generateDirectedEdgeConstraints(n, this._links, this._directedLinkConstraints.axis, (this.linkAccessor))); } this.avoidOverlaps(false); this._descent = new descent_1.Descent([x, y], D); this._descent.locks.clear(); for (var i = 0; i < n; ++i) { var o = this._nodes[i]; if (o.fixed) { o.px = o.x; o.py = o.y; var p = [o.x, o.y]; this._descent.locks.add(i, p); } } this._descent.threshold = this._threshold; this.initialLayout(initialUnconstrainedIterations, x, y); if (curConstraints.length > 0) this._descent.project = new rectangle_1.Projection(this._nodes, this._groups, this._rootGroup, curConstraints).projectFunctions(); this._descent.run(initialUserConstraintIterations); this.separateOverlappingComponents(w, h, centerGraph); this.avoidOverlaps(ao); if (ao) { this._nodes.forEach(function (v, i) { v.x = x[i], v.y = y[i]; }); this._descent.project = new rectangle_1.Projection(this._nodes, this._groups, this._rootGroup, curConstraints, true).projectFunctions(); this._nodes.forEach(function (v, i) { x[i] = v.x, y[i] = v.y; }); } this._descent.G = G; this._descent.run(initialAllConstraintsIterations); if (gridSnapIterations) { this._descent.snapStrength = 1000; this._descent.snapGridSize = this._nodes[0].width; this._descent.numGridSnapNodes = n; this._descent.scaleSnapByMaxH = n != N; var G0 = descent_1.Descent.createSquareMatrix(N, function (i, j) { if (i >= n || j >= n) return G[i][j]; return 0; }); this._descent.G = G0; this._descent.run(gridSnapIterations); } this.updateNodePositions(); this.separateOverlappingComponents(w, h, centerGraph); return keepRunning ? this.resume() : this; }; Layout.prototype.initialLayout = function (iterations, x, y) { if (this._groups.length > 0 && iterations > 0) { var n = this._nodes.length; var edges = this._links.map(function (e) { return ({ source: e.source.index, target: e.target.index }); }); var vs = this._nodes.map(function (v) { return ({ index: v.index }); }); this._groups.forEach(function (g, i) { vs.push({ index: g.index = n + i }); }); this._groups.forEach(function (g, i) { if (typeof g.leaves !== 'undefined') g.leaves.forEach(function (v) { return edges.push({ source: g.index, target: v.index }); }); if (typeof g.groups !== 'undefined') g.groups.forEach(function (gg) { return edges.push({ source: g.index, target: gg.index }); }); }); new Layout() .size(this.size()) .nodes(vs) .links(edges) .avoidOverlaps(false) .linkDistance(this.linkDistance()) .symmetricDiffLinkLengths(5) .convergenceThreshold(1e-4) .start(iterations, 0, 0, 0, false); this._nodes.forEach(function (v) { x[v.index] = vs[v.index].x; y[v.index] = vs[v.index].y; }); } else { this._descent.run(iterations); } }; Layout.prototype.separateOverlappingComponents = function (width, height, centerGraph) { var _this = this; if (centerGraph === void 0) { centerGraph = true; } if (!this._distanceMatrix && this._handleDisconnected) { var x_1 = this._descent.x[0], y_1 = this._descent.x[1]; this._nodes.forEach(function (v, i) { v.x = x_1[i], v.y = y_1[i]; }); var graphs = handledisconnected_1.separateGraphs(this._nodes, this._links); handledisconnected_1.applyPacking(graphs, width, height, this._defaultNodeSize, 1, centerGraph); this._nodes.forEach(function (v, i) { _this._descent.x[0][i] = v.x, _this._descent.x[1][i] = v.y; if (v.bounds) { v.bounds.setXCentre(v.x); v.bounds.setYCentre(v.y); } }); } }; Layout.prototype.resume = function () { return this.alpha(0.1); }; Layout.prototype.stop = function () { return this.alpha(0); }; Layout.prototype.prepareEdgeRouting = function (nodeMargin) { if (nodeMargin === void 0) { nodeMargin = 0; } this._visibilityGraph = new geom_1.TangentVisibilityGraph(this._nodes.map(function (v) { return v.bounds.inflate(-nodeMargin).vertices(); })); }; Layout.prototype.routeEdge = function (edge, ah, draw) { if (ah === void 0) { ah = 5; } var lineData = []; var vg2 = new geom_1.TangentVisibilityGraph(this._visibilityGraph.P, { V: this._visibilityGraph.V, E: this._visibilityGraph.E }), port1 = { x: edge.source.x, y: edge.source.y }, port2 = { x: edge.target.x, y: edge.target.y }, start = vg2.addPoint(port1, edge.source.index), end = vg2.addPoint(port2, edge.target.index); vg2.addEdgeIfVisible(port1, port2, edge.source.index, edge.target.index); if (typeof draw !== 'undefined') { draw(vg2); } var sourceInd = function (e) { return e.source.id; }, targetInd = function (e) { return e.target.id; }, length = function (e) { return e.length(); }, spCalc = new shortestpaths_1.Calculator(vg2.V.length, vg2.E, sourceInd, targetInd, length), shortestPath = spCalc.PathFromNodeToNode(start.id, end.id); if (shortestPath.length === 1 || shortestPath.length === vg2.V.length) { var route = rectangle_1.makeEdgeBetween(edge.source.innerBounds, edge.target.innerBounds, ah); lineData = [route.sourceIntersection, route.arrowStart]; } else { var n = shortestPath.length - 2, p = vg2.V[shortestPath[n]].p, q = vg2.V[shortestPath[0]].p, lineData = [edge.source.innerBounds.rayIntersection(p.x, p.y)]; for (var i = n; i >= 0; --i) lineData.push(vg2.V[shortestPath[i]].p); lineData.push(rectangle_1.makeEdgeTo(q, edge.target.innerBounds, ah)); } return lineData; }; Layout.getSourceIndex = function (e) { return typeof e.source === 'number' ? e.source : e.source.index; }; Layout.getTargetIndex = function (e) { return typeof e.target === 'number' ? e.target : e.target.index; }; Layout.linkId = function (e) { return Layout.getSourceIndex(e) + "-" + Layout.getTargetIndex(e); }; Layout.dragStart = function (d) { if (isGroup(d)) { Layout.storeOffset(d, Layout.dragOrigin(d)); } else { Layout.stopNode(d); d.fixed |= 2; } }; Layout.stopNode = function (v) { v.px = v.x; v.py = v.y; }; Layout.storeOffset = function (d, origin) { if (typeof d.leaves !== 'undefined') { d.leaves.forEach(function (v) { v.fixed |= 2; Layout.stopNode(v); v._dragGroupOffsetX = v.x - origin.x; v._dragGroupOffsetY = v.y - origin.y; }); } if (typeof d.groups !== 'undefined') { d.groups.forEach(function (g) { return Layout.storeOffset(g, origin); }); } }; Layout.dragOrigin = function (d) { if (isGroup(d)) { return { x: d.bounds.cx(), y: d.bounds.cy() }; } else { return d; } }; Layout.drag = function (d, position) { if (isGroup(d)) { if (typeof d.leaves !== 'undefined') { d.leaves.forEach(function (v) { d.bounds.setXCentre(position.x); d.bounds.setYCentre(position.y); v.px = v._dragGroupOffsetX + position.x; v.py = v._dragGroupOffsetY + position.y; }); } if (typeof d.groups !== 'undefined') { d.groups.forEach(function (g) { return Layout.drag(g, position); }); } } else { d.px = position.x; d.py = position.y; } }; Layout.dragEnd = function (d) { if (isGroup(d)) { if (typeof d.leaves !== 'undefined') { d.leaves.forEach(function (v) { Layout.dragEnd(v); delete v._dragGroupOffsetX; delete v._dragGroupOffsetY; }); } if (typeof d.groups !== 'undefined') { d.groups.forEach(Layout.dragEnd); } } else { d.fixed &= ~6; } }; Layout.mouseOver = function (d) { d.fixed |= 4; d.px = d.x, d.py = d.y; }; Layout.mouseOut = function (d) { d.fixed &= ~4; }; return Layout; }()); exports.Layout = Layout; /***/ }), /* 6 */ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); var PowerEdge = (function () { function PowerEdge(source, target, type) { this.source = source; this.target = target; this.type = type; } return PowerEdge; }()); exports.PowerEdge = PowerEdge; var Configuration = (function () { function Configuration(n, edges, linkAccessor, rootGroup) { var _this = this; this.linkAccessor = linkAccessor; this.modules = new Array(n); this.roots = []; if (rootGroup) { this.initModulesFromGroup(rootGroup); } else { this.roots.push(new ModuleSet()); for (var i = 0; i < n; ++i) this.roots[0].add(this.modules[i] = new Module(i)); } this.R = edges.length; edges.forEach(function (e) { var s = _this.modules[linkAccessor.getSourceIndex(e)], t = _this.modules[linkAccessor.getTargetIndex(e)], type = linkAccessor.getType(e); s.outgoing.add(type, t); t.incoming.add(type, s); }); } Configuration.prototype.initModulesFromGroup = function (group) { var moduleSet = new ModuleSet(); this.roots.push(moduleSet); for (var i = 0; i < group.leaves.length; ++i) { var node = group.leaves[i]; var module = new Module(node.id); this.modules[node.id] = module; moduleSet.add(module); } if (group.groups) { for (var j = 0; j < group.groups.length; ++j) { var child = group.groups[j]; var definition = {}; for (var prop in child) if (prop !== "leaves" && prop !== "groups" && child.hasOwnProperty(prop)) definition[prop] = child[prop]; moduleSet.add(new Module(-1 - j, new LinkSets(), new LinkSets(), this.initModulesFromGroup(child), definition)); } } return moduleSet; }; Configuration.prototype.merge = function (a, b, k) { if (k === void 0) { k = 0; } var inInt = a.incoming.intersection(b.incoming), outInt = a.outgoing.intersection(b.outgoing); var children = new ModuleSet(); children.add(a); children.add(b); var m = new Module(this.modules.length, outInt, inInt, children); this.modules.push(m); var update = function (s, i, o) { s.forAll(function (ms, linktype) { ms.forAll(function (n) { var nls = n[i]; nls.add(linktype, m); nls.remove(linktype, a); nls.remove(linktype, b); a[o].remove(linktype, n); b[o].remove(linktype, n); }); }); }; update(outInt, "incoming", "outgoing"); update(inInt, "outgoing", "incoming"); this.R -= inInt.count() + outInt.count(); this.roots[k].remove(a); this.roots[k].remove(b); this.roots[k].add(m); return m; }; Configuration.prototype.rootMerges = function (k) { if (k === void 0) { k = 0; } var rs = this.roots[k].modules(); var n = rs.length; var merges = new Array(n * (n - 1)); var ctr = 0; for (var i = 0, i_ = n - 1; i < i_; ++i) { for (var j = i + 1; j < n; ++j) { var a = rs[i], b = rs[j]; merges[ctr] = { id: ctr, nEdges: this.nEdges(a, b), a: a, b: b }; ctr++; } } return merges; }; Configuration.prototype.greedyMerge = function () { for (var i = 0; i < this.roots.length; ++i) { if (this.roots[i].modules().length < 2) continue; var ms = this.rootMerges(i).sort(function (a, b) { return a.nEdges == b.nEdges ? a.id - b.id : a.nEdges - b.nEdges; }); var m = ms[0]; if (m.nEdges >= this.R) continue; this.merge(m.a, m.b, i); return true; } }; Configuration.prototype.nEdges = function (a, b) { var inInt = a.incoming.intersection(b.incoming), outInt = a.outgoing.intersection(b.outgoing); return this.R - inInt.count() - outInt.count(); }; Configuration.prototype.getGroupHierarchy = function (retargetedEdges) { var _this = this; var groups = []; var root = {}; toGroups(this.roots[0], root, groups); var es = this.allEdges(); es.forEach(function (e) { var a = _this.modules[e.source]; var b = _this.modules[e.target]; retargetedEdges.push(new PowerEdge(typeof a.gid === "undefined" ? e.source : groups[a.gid], typeof b.gid === "undefined" ? e.target : groups[b.gid], e.type)); }); return groups; }; Configuration.prototype.allEdges = function () { var es = []; Configuration.getEdges(this.roots[0], es); return es; }; Configuration.getEdges = function (modules, es) { modules.forAll(function (m) { m.getEdges(es); Configuration.getEdges(m.children, es); }); }; return Configuration; }()); exports.Configuration = Configuration; function toGroups(modules, group, groups) { modules.forAll(function (m) { if (m.isLeaf()) { if (!group.leaves) group.leaves = []; group.leaves.push(m.id); } else { var g = group; m.gid = groups.length; if (!m.isIsland() || m.isPredefined()) { g = { id: m.gid }; if (m.isPredefined()) for (var prop in m.definition) g[prop] = m.definition[prop]; if (!group.groups) group.groups = []; group.groups.push(m.gid); groups.push(g); } toGroups(m.children, g, groups); } }); } var Module = (function () { function Module(id, outgoing, incoming, children, definition) { if (outgoing === void 0) { outgoing = new LinkSets(); } if (incoming === void 0) { incoming = new LinkSets(); } if (children === void 0) { children = new ModuleSet(); } this.id = id; this.outgoing = outgoing; this.incoming = incoming; this.children = children; this.definition = definition; } Module.prototype.getEdges = function (es) { var _this = this; this.outgoing.forAll(function (ms, edgetype) { ms.forAll(function (target) { es.push(new PowerEdge(_this.id, target.id, edgetype)); }); }); }; Module.prototype.isLeaf = function () { return this.children.count() === 0; }; Module.prototype.isIsland = function () { return this.outgoing.count() === 0 && this.incoming.count() === 0; }; Module.prototype.isPredefined = function () { return typeof this.definition !== "undefined"; }; return Module; }()); exports.Module = Module; function intersection(m, n) { var i = {}; for (var v in m) if (v in n) i[v] = m[v]; return i; } var ModuleSet = (function () { function ModuleSet() { this.table = {}; } ModuleSet.prototype.count = function () { return Object.keys(this.table).length; }; ModuleSet.prototype.intersection = function (other) { var result = new ModuleSet(); result.table = intersection(this.table, other.table); return result; }; ModuleSet.prototype.intersectionCount = function (other) { return this.intersection(other).count(); }; ModuleSet.prototype.contains = function (id) { return id in this.table; }; ModuleSet.prototype.add = function (m) { this.table[m.id] = m; }; ModuleSet.prototype.remove = function (m) { delete this.table[m.id]; }; ModuleSet.prototype.forAll = function (f) { for (var mid in this.table) { f(this.table[mid]); } }; ModuleSet.prototype.modules = function () { var vs = []; this.forAll(function (m) { if (!m.isPredefined()) vs.push(m); }); return vs; }; return ModuleSet; }()); exports.ModuleSet = ModuleSet; var LinkSets = (function () { function LinkSets() { this.sets = {}; this.n = 0; } LinkSets.prototype.count = function () { return this.n; }; LinkSets.prototype.contains = function (id) { var result = false; this.forAllModules(function (m) { if (!result && m.id == id) { result = true; } }); return result; }; LinkSets.prototype.add = function (linktype, m) { var s = linktype in this.sets ? this.sets[linktype] : this.sets[linktype] = new ModuleSet(); s.add(m); ++this.n; }; LinkSets.prototype.remove = function (linktype, m) { var ms = this.sets[linktype]; ms.remove(m); if (ms.count() === 0) { delete this.sets[linktype]; } --this.n; }; LinkSets.prototype.forAll = function (f) { for (var linktype in this.sets) { f(this.sets[linktype], Number(linktype)); } }; LinkSets.prototype.forAllModules = function (f) { this.forAll(function (ms, lt) { return ms.forAll(f); }); }; LinkSets.prototype.intersection = function (other) { var result = new LinkSets(); this.forAll(function (ms, lt) { if (lt in other.sets) { var i = ms.intersection(other.sets[lt]), n = i.count(); if (n > 0) { result.sets[lt] = i; result.n += n; } } }); return result; }; return LinkSets; }()); exports.LinkSets = LinkSets; function intersectionCount(m, n) { return Object.keys(intersection(m, n)).length; } function getGroups(nodes, links, la, rootGroup) { var n = nodes.length, c = new Configuration(n, links, la, rootGroup); while (c.greedyMerge()) ; var powerEdges = []; var g = c.getGroupHierarchy(powerEdges); powerEdges.forEach(function (e) { var f = function (end) { var g = e[end]; if (typeof g == "number") e[end] = nodes[g]; }; f("source"); f("target"); }); return { groups: g, powerEdges: powerEdges }; } exports.getGroups = getGroups; /***/ }), /* 7 */ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); function unionCount(a, b) { var u = {}; for (var i in a) u[i] = {}; for (var i in b) u[i] = {}; return Object.keys(u).length; } function intersectionCount(a, b) { var n = 0; for (var i in a) if (typeof b[i] !== 'undefined') ++n; return n; } function getNeighbours(links, la) { var neighbours = {}; var addNeighbours = function (u, v) { if (typeof neighbours[u] === 'undefined') neighbours[u] = {}; neighbours[u][v] = {}; }; links.forEach(function (e) { var u = la.getSourceIndex(e), v = la.getTargetIndex(e); addNeighbours(u, v); addNeighbours(v, u); }); return neighbours; } function computeLinkLengths(links, w, f, la) { var neighbours = getNeighbours(links, la); links.forEach(function (l) { var a = neighbours[la.getSourceIndex(l)]; var b = neighbours[la.getTargetIndex(l)]; la.setLength(l, 1 + w * f(a, b)); }); } function symmetricDiffLinkLengths(links, la, w) { if (w === void 0) { w = 1; } computeLinkLengths(links, w, function (a, b) { return Math.sqrt(unionCount(a, b) - intersectionCount(a, b)); }, la); } exports.symmetricDiffLinkLengths = symmetricDiffLinkLengths; function jaccardLinkLengths(links, la, w) { if (w === void 0) { w = 1; } computeLinkLengths(links, w, function (a, b) { return Math.min(Object.keys(a).length, Object.keys(b).length) < 1.1 ? 0 : intersectionCount(a, b) / unionCount(a, b); }, la); } exports.jaccardLinkLengths = jaccardLinkLengths; function generateDirectedEdgeConstraints(n, links, axis, la) { var components = stronglyConnectedComponents(n, links, la); var nodes = {}; components.forEach(function (c, i) { return c.forEach(function (v) { return nodes[v] = i; }); }); var constraints = []; links.forEach(function (l) { var ui = la.getSourceIndex(l), vi = la.getTargetIndex(l), u = nodes[ui], v = nodes[vi]; if (u !== v) { constraints.push({ axis: axis, left: ui, right: vi, gap: la.getMinSeparation(l) }); } }); return constraints; } exports.generateDirectedEdgeConstraints = generateDirectedEdgeConstraints; function stronglyConnectedComponents(numVertices, edges, la) { var nodes = []; var index = 0; var stack = []; var components = []; function strongConnect(v) { v.index = v.lowlink = index++; stack.push(v); v.onStack = true; for (var _i = 0, _a = v.out; _i < _a.length; _i++) { var w = _a[_i]; if (typeof w.index === 'undefined') { strongConnect(w); v.lowlink = Math.min(v.lowlink, w.lowlink); } else if (w.onStack) { v.lowlink = Math.min(v.lowlink, w.index); } } if (v.lowlink === v.index) { var component = []; while (stack.length) { w = stack.pop(); w.onStack = false; component.push(w); if (w === v) break; } components.push(component.map(function (v) { return v.id; })); } } for (var i = 0; i < numVertices; i++) { nodes.push({ id: i, out: [] }); } for (var _i = 0, edges_1 = edges; _i < edges_1.length; _i++) { var e = edges_1[_i]; var v_1 = nodes[la.getSourceIndex(e)], w = nodes[la.getTargetIndex(e)]; v_1.out.push(w); } for (var _a = 0, nodes_1 = nodes; _a < nodes_1.length; _a++) { var v = nodes_1[_a]; if (typeof v.index === 'undefined') strongConnect(v); } return components; } exports.stronglyConnectedComponents = stronglyConnectedComponents; /***/ }), /* 8 */ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); var Locks = (function () { function Locks() { this.locks = {}; } Locks.prototype.add = function (id, x) { this.locks[id] = x; }; Locks.prototype.clear = function () { this.locks = {}; }; Locks.prototype.isEmpty = function () { for (var l in this.locks) return false; return true; }; Locks.prototype.apply = function (f) { for (var l in this.locks) { f(Number(l), this.locks[l]); } }; return Locks; }()); exports.Locks = Locks; var Descent = (function () { function Descent(x, D, G) { if (G === void 0) { G = null; } this.D = D; this.G = G; this.threshold = 0.0001; this.numGridSnapNodes = 0; this.snapGridSize = 100; this.snapStrength = 1000; this.scaleSnapByMaxH = false; this.random = new PseudoRandom(); this.project = null; this.x = x; this.k = x.length; var n = this.n = x[0].length; this.H = new Array(this.k); this.g = new Array(this.k); this