@joint/core 4.2.0-alpha.1 → 4.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/geometry.js +1 -1
- package/dist/geometry.min.js +2 -3
- package/dist/joint.d.ts +321 -55
- package/dist/joint.js +2499 -853
- package/dist/joint.min.js +2 -3
- package/dist/joint.nowrap.js +2499 -853
- package/dist/joint.nowrap.min.js +2 -3
- package/dist/vectorizer.js +1 -1
- package/dist/vectorizer.min.js +2 -3
- package/dist/version.mjs +1 -1
- package/package.json +12 -9
- package/src/config/index.mjs +3 -1
- package/src/dia/Cell.mjs +77 -80
- package/src/dia/CellCollection.mjs +136 -0
- package/src/dia/CellView.mjs +1 -2
- package/src/dia/Element.mjs +2 -3
- package/src/dia/Graph.mjs +610 -317
- package/src/dia/GraphLayer.mjs +53 -0
- package/src/dia/GraphLayerCollection.mjs +313 -0
- package/src/dia/GraphLayerView.mjs +128 -0
- package/src/dia/GraphLayersController.mjs +166 -0
- package/src/dia/GraphTopologyIndex.mjs +222 -0
- package/src/dia/{layers/GridLayer.mjs → GridLayerView.mjs} +23 -16
- package/src/dia/{PaperLayer.mjs → LayerView.mjs} +52 -17
- package/src/dia/LegacyGraphLayerView.mjs +14 -0
- package/src/dia/Paper.mjs +756 -423
- package/src/dia/ToolsView.mjs +3 -3
- package/src/dia/index.mjs +6 -1
- package/src/dia/ports.mjs +11 -2
- package/src/dia/symbols.mjs +24 -0
- package/src/mvc/Collection.mjs +19 -19
- package/src/mvc/Model.mjs +13 -10
- package/types/joint.d.ts +320 -54
package/dist/joint.nowrap.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! JointJS v4.2.0-
|
|
1
|
+
/*! JointJS v4.2.0-beta.2 (2025-11-04) - JavaScript diagramming library
|
|
2
2
|
|
|
3
3
|
This Source Code Form is subject to the terms of the Mozilla Public
|
|
4
4
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
@@ -12517,7 +12517,9 @@ var joint = (function (exports) {
|
|
|
12517
12517
|
defaultTheme: 'default',
|
|
12518
12518
|
// The maximum delay required for two consecutive touchend events to be interpreted
|
|
12519
12519
|
// as a double-tap.
|
|
12520
|
-
doubleTapInterval: 300
|
|
12520
|
+
doubleTapInterval: 300,
|
|
12521
|
+
// Name of the attribute used to store the layer id on the cell model.
|
|
12522
|
+
layerAttribute: 'layer'
|
|
12521
12523
|
};
|
|
12522
12524
|
|
|
12523
12525
|
// TODO: should not read config outside the mvc package
|
|
@@ -14447,16 +14449,12 @@ var joint = (function (exports) {
|
|
|
14447
14449
|
var Model = function (attributes, options) {
|
|
14448
14450
|
var attrs = attributes || {};
|
|
14449
14451
|
options || (options = {});
|
|
14452
|
+
this.eventPrefix = options.eventPrefix || '';
|
|
14450
14453
|
this.preinitialize.apply(this, arguments);
|
|
14451
14454
|
this.cid = uniqueId(this.cidPrefix);
|
|
14452
14455
|
this.attributes = {};
|
|
14453
14456
|
if (options.collection) this.collection = options.collection;
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
// Just _.defaults would work fine, but the additional _.extends
|
|
14457
|
-
// is in there for historical reasons. See #3843.
|
|
14458
|
-
attrs = defaults(assign({}, attributeDefaults, attrs), attributeDefaults);
|
|
14459
|
-
this.set(attrs, options);
|
|
14457
|
+
this._setDefaults(attrs, options);
|
|
14460
14458
|
this.changed = {};
|
|
14461
14459
|
this.initialize.apply(this, arguments);
|
|
14462
14460
|
};
|
|
@@ -14545,14 +14543,14 @@ var joint = (function (exports) {
|
|
|
14545
14543
|
if (this.idAttribute in attrs) {
|
|
14546
14544
|
var prevId = this.id;
|
|
14547
14545
|
this.id = this.get(this.idAttribute);
|
|
14548
|
-
this.trigger('changeId', this, prevId, options);
|
|
14546
|
+
this.trigger(this.eventPrefix + 'changeId', this, prevId, options);
|
|
14549
14547
|
}
|
|
14550
14548
|
|
|
14551
14549
|
// Trigger all relevant attribute changes.
|
|
14552
14550
|
if (!silent) {
|
|
14553
14551
|
if (changes.length) this._pending = options;
|
|
14554
14552
|
for (var i = 0; i < changes.length; i++) {
|
|
14555
|
-
this.trigger('change:' + changes[i], this, current[changes[i]], options);
|
|
14553
|
+
this.trigger(this.eventPrefix + 'change:' + changes[i], this, current[changes[i]], options);
|
|
14556
14554
|
}
|
|
14557
14555
|
}
|
|
14558
14556
|
|
|
@@ -14563,7 +14561,7 @@ var joint = (function (exports) {
|
|
|
14563
14561
|
while (this._pending) {
|
|
14564
14562
|
options = this._pending;
|
|
14565
14563
|
this._pending = false;
|
|
14566
|
-
this.trigger('change', this, options);
|
|
14564
|
+
this.trigger(this.eventPrefix + 'change', this, options);
|
|
14567
14565
|
}
|
|
14568
14566
|
}
|
|
14569
14567
|
this._pending = false;
|
|
@@ -14642,6 +14640,13 @@ var joint = (function (exports) {
|
|
|
14642
14640
|
validationError: error
|
|
14643
14641
|
}));
|
|
14644
14642
|
return false;
|
|
14643
|
+
},
|
|
14644
|
+
_setDefaults: function (ctorAttributes, options) {
|
|
14645
|
+
const attributeDefaults = result(this, 'defaults');
|
|
14646
|
+
// Just _.defaults would work fine, but the additional _.extends
|
|
14647
|
+
// is in there for historical reasons. See #3843.
|
|
14648
|
+
const attributes = defaults(assign({}, attributeDefaults, ctorAttributes), attributeDefaults);
|
|
14649
|
+
this.set(attributes, options);
|
|
14645
14650
|
}
|
|
14646
14651
|
});
|
|
14647
14652
|
|
|
@@ -15561,6 +15566,30 @@ var joint = (function (exports) {
|
|
|
15561
15566
|
assign(attributesNS, offsetAttributesNS);
|
|
15562
15567
|
const attributes = attributesNS;
|
|
15563
15568
|
|
|
15569
|
+
// Internal tags to identify objects as specific JointJS types.
|
|
15570
|
+
// Used instead of `instanceof` for performance and cross-frame safety.
|
|
15571
|
+
|
|
15572
|
+
// dia.Cell
|
|
15573
|
+
const CELL_MARKER = Symbol('joint.cellMarker');
|
|
15574
|
+
|
|
15575
|
+
// dia.CellCollection
|
|
15576
|
+
const CELL_COLLECTION_MARKER = Symbol('joint.cellCollectionMarker');
|
|
15577
|
+
|
|
15578
|
+
// dia.GraphLayer
|
|
15579
|
+
const GRAPH_LAYER_MARKER = Symbol('joint.graphLayerMarker');
|
|
15580
|
+
|
|
15581
|
+
// dia.GraphLayerCollection
|
|
15582
|
+
const GRAPH_LAYER_COLLECTION_MARKER = Symbol('joint.graphLayerCollectionMarker');
|
|
15583
|
+
|
|
15584
|
+
// dia.CellView
|
|
15585
|
+
const CELL_VIEW_MARKER = Symbol('joint.cellViewMarker');
|
|
15586
|
+
|
|
15587
|
+
// dia.LayerView
|
|
15588
|
+
const LAYER_VIEW_MARKER = Symbol('joint.layerViewMarker');
|
|
15589
|
+
|
|
15590
|
+
// dia.GraphLayerView
|
|
15591
|
+
const GRAPH_LAYER_VIEW_MARKER = Symbol('joint.graphLayerViewMarker');
|
|
15592
|
+
|
|
15564
15593
|
// Cell base model.
|
|
15565
15594
|
// --------------------------
|
|
15566
15595
|
|
|
@@ -15581,35 +15610,18 @@ var joint = (function (exports) {
|
|
|
15581
15610
|
}
|
|
15582
15611
|
}
|
|
15583
15612
|
const Cell = Model.extend({
|
|
15584
|
-
|
|
15585
|
-
//
|
|
15586
|
-
|
|
15587
|
-
|
|
15588
|
-
|
|
15589
|
-
if (
|
|
15590
|
-
// Check to support an older version
|
|
15591
|
-
this.preinitialize.apply(this, arguments);
|
|
15592
|
-
}
|
|
15593
|
-
this.cid = uniqueId('c');
|
|
15594
|
-
this.attributes = {};
|
|
15595
|
-
if (options && options.collection) this.collection = options.collection;
|
|
15596
|
-
if (options && options.parse) attrs = this.parse(attrs, options) || {};
|
|
15597
|
-
if (defaults = result(this, 'defaults')) {
|
|
15598
|
-
//<custom code>
|
|
15599
|
-
// Replaced the call to _.defaults with util.merge.
|
|
15613
|
+
cidPrefix: 'c',
|
|
15614
|
+
// Default attributes are merged deeply instead of shallowly.
|
|
15615
|
+
_setDefaults: function (ctorAttributes, options) {
|
|
15616
|
+
let attributes;
|
|
15617
|
+
const attributeDefaults = result(this, 'defaults');
|
|
15618
|
+
if (attributeDefaults) {
|
|
15600
15619
|
const customizer = options && options.mergeArrays === true ? false : config$3.cellDefaultsMergeStrategy || attributesMerger;
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
this.set(attrs, options);
|
|
15605
|
-
this.changed = {};
|
|
15606
|
-
if (options && options.portLayoutNamespace) {
|
|
15607
|
-
this.portLayoutNamespace = options.portLayoutNamespace;
|
|
15608
|
-
}
|
|
15609
|
-
if (options && options.portLabelLayoutNamespace) {
|
|
15610
|
-
this.portLabelLayoutNamespace = options.portLabelLayoutNamespace;
|
|
15620
|
+
attributes = merge({}, attributeDefaults, ctorAttributes, customizer);
|
|
15621
|
+
} else {
|
|
15622
|
+
attributes = ctorAttributes;
|
|
15611
15623
|
}
|
|
15612
|
-
this.
|
|
15624
|
+
this.set(attributes, options);
|
|
15613
15625
|
},
|
|
15614
15626
|
translate: function (dx, dy, opt) {
|
|
15615
15627
|
throw new Error('Must define a translate() method.');
|
|
@@ -15649,9 +15661,9 @@ var joint = (function (exports) {
|
|
|
15649
15661
|
}
|
|
15650
15662
|
return finalAttributes;
|
|
15651
15663
|
},
|
|
15652
|
-
initialize: function (
|
|
15664
|
+
initialize: function (attributes) {
|
|
15653
15665
|
const idAttribute = this.getIdAttribute();
|
|
15654
|
-
if (!
|
|
15666
|
+
if (!attributes || attributes[idAttribute] === undefined) {
|
|
15655
15667
|
this.set(idAttribute, this.generateId(), {
|
|
15656
15668
|
silent: true
|
|
15657
15669
|
});
|
|
@@ -15722,39 +15734,24 @@ var joint = (function (exports) {
|
|
|
15722
15734
|
this.ports = ports;
|
|
15723
15735
|
},
|
|
15724
15736
|
remove: function (opt = {}) {
|
|
15725
|
-
// Store the graph in a variable because `this.graph` won't be accessible
|
|
15726
|
-
// after `this.trigger('remove', ...)` down below.
|
|
15727
15737
|
const {
|
|
15728
15738
|
graph,
|
|
15729
15739
|
collection
|
|
15730
15740
|
} = this;
|
|
15731
|
-
|
|
15741
|
+
// If the cell is part of a graph, remove it using the graph API.
|
|
15742
|
+
// To make sure the cell is removed in a batch operation.
|
|
15743
|
+
if (graph) {
|
|
15744
|
+
graph.removeCell(this, opt);
|
|
15745
|
+
} else {
|
|
15732
15746
|
// The collection is a common mvc collection (not the graph collection).
|
|
15733
15747
|
if (collection) collection.remove(this, opt);
|
|
15734
|
-
return this;
|
|
15735
|
-
}
|
|
15736
|
-
graph.startBatch('remove');
|
|
15737
|
-
|
|
15738
|
-
// First, unembed this cell from its parent cell if there is one.
|
|
15739
|
-
const parentCell = this.getParentCell();
|
|
15740
|
-
if (parentCell) {
|
|
15741
|
-
parentCell.unembed(this, opt);
|
|
15742
15748
|
}
|
|
15743
|
-
|
|
15744
|
-
// Remove also all the cells, which were embedded into this cell
|
|
15745
|
-
const embeddedCells = this.getEmbeddedCells();
|
|
15746
|
-
for (let i = 0, n = embeddedCells.length; i < n; i++) {
|
|
15747
|
-
const embed = embeddedCells[i];
|
|
15748
|
-
if (embed) {
|
|
15749
|
-
embed.remove(opt);
|
|
15750
|
-
}
|
|
15751
|
-
}
|
|
15752
|
-
this.trigger('remove', this, graph.attributes.cells, opt);
|
|
15753
|
-
graph.stopBatch('remove');
|
|
15754
15749
|
return this;
|
|
15755
15750
|
},
|
|
15756
15751
|
toFront: function (opt) {
|
|
15757
|
-
|
|
15752
|
+
const {
|
|
15753
|
+
graph
|
|
15754
|
+
} = this;
|
|
15758
15755
|
if (graph) {
|
|
15759
15756
|
opt = defaults(opt || {}, {
|
|
15760
15757
|
foregroundEmbeds: true
|
|
@@ -15771,10 +15768,11 @@ var joint = (function (exports) {
|
|
|
15771
15768
|
cells = [this];
|
|
15772
15769
|
}
|
|
15773
15770
|
const sortedCells = opt.foregroundEmbeds ? cells : sortBy(cells, cell => cell.z());
|
|
15774
|
-
const
|
|
15771
|
+
const layerId = graph.getCellLayerId(this);
|
|
15772
|
+
const maxZ = graph.maxZIndex(layerId);
|
|
15775
15773
|
let z = maxZ - cells.length + 1;
|
|
15776
|
-
const
|
|
15777
|
-
let shouldUpdate =
|
|
15774
|
+
const layerCells = graph.getLayer(layerId).cellCollection.toArray();
|
|
15775
|
+
let shouldUpdate = layerCells.indexOf(sortedCells[0]) !== layerCells.length - cells.length;
|
|
15778
15776
|
if (!shouldUpdate) {
|
|
15779
15777
|
shouldUpdate = sortedCells.some(function (cell, index) {
|
|
15780
15778
|
return cell.z() !== z + index;
|
|
@@ -15792,7 +15790,9 @@ var joint = (function (exports) {
|
|
|
15792
15790
|
return this;
|
|
15793
15791
|
},
|
|
15794
15792
|
toBack: function (opt) {
|
|
15795
|
-
|
|
15793
|
+
const {
|
|
15794
|
+
graph
|
|
15795
|
+
} = this;
|
|
15796
15796
|
if (graph) {
|
|
15797
15797
|
opt = defaults(opt || {}, {
|
|
15798
15798
|
foregroundEmbeds: true
|
|
@@ -15809,9 +15809,10 @@ var joint = (function (exports) {
|
|
|
15809
15809
|
cells = [this];
|
|
15810
15810
|
}
|
|
15811
15811
|
const sortedCells = opt.foregroundEmbeds ? cells : sortBy(cells, cell => cell.z());
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15812
|
+
const layerId = graph.getCellLayerId(this);
|
|
15813
|
+
let z = graph.minZIndex(layerId);
|
|
15814
|
+
const layerCells = graph.getLayer(layerId).cellCollection.toArray();
|
|
15815
|
+
let shouldUpdate = layerCells.indexOf(sortedCells[0]) !== 0;
|
|
15815
15816
|
if (!shouldUpdate) {
|
|
15816
15817
|
shouldUpdate = sortedCells.some(function (cell, index) {
|
|
15817
15818
|
return cell.z() !== z + index;
|
|
@@ -16174,41 +16175,42 @@ var joint = (function (exports) {
|
|
|
16174
16175
|
opt = assign(defaults, opt);
|
|
16175
16176
|
var firstFrameTime = 0;
|
|
16176
16177
|
var interpolatingFunction;
|
|
16178
|
+
const transitionKey = Array.isArray(path) ? path.join(delim) : path;
|
|
16177
16179
|
var setter = function (runtime) {
|
|
16178
16180
|
var id, progress, propertyValue;
|
|
16179
16181
|
firstFrameTime = firstFrameTime || runtime;
|
|
16180
16182
|
runtime -= firstFrameTime;
|
|
16181
16183
|
progress = runtime / opt.duration;
|
|
16182
16184
|
if (progress < 1) {
|
|
16183
|
-
this._transitionIds[
|
|
16185
|
+
this._transitionIds[transitionKey] = id = nextFrame(setter);
|
|
16184
16186
|
} else {
|
|
16185
16187
|
progress = 1;
|
|
16186
|
-
delete this._transitionIds[
|
|
16188
|
+
delete this._transitionIds[transitionKey];
|
|
16187
16189
|
}
|
|
16188
16190
|
propertyValue = interpolatingFunction(opt.timingFunction(progress));
|
|
16189
16191
|
opt.transitionId = id;
|
|
16190
16192
|
this.prop(path, propertyValue, opt);
|
|
16191
|
-
if (!id) this.trigger('transition:end', this,
|
|
16193
|
+
if (!id) this.trigger('transition:end', this, transitionKey);
|
|
16192
16194
|
}.bind(this);
|
|
16193
16195
|
const {
|
|
16194
16196
|
_scheduledTransitionIds
|
|
16195
16197
|
} = this;
|
|
16196
16198
|
let initialId;
|
|
16197
16199
|
var initiator = callback => {
|
|
16198
|
-
if (_scheduledTransitionIds[
|
|
16199
|
-
_scheduledTransitionIds[
|
|
16200
|
-
if (_scheduledTransitionIds[
|
|
16201
|
-
delete _scheduledTransitionIds[
|
|
16200
|
+
if (_scheduledTransitionIds[transitionKey]) {
|
|
16201
|
+
_scheduledTransitionIds[transitionKey] = without(_scheduledTransitionIds[transitionKey], initialId);
|
|
16202
|
+
if (_scheduledTransitionIds[transitionKey].length === 0) {
|
|
16203
|
+
delete _scheduledTransitionIds[transitionKey];
|
|
16202
16204
|
}
|
|
16203
16205
|
}
|
|
16204
16206
|
this.stopPendingTransitions(path, delim);
|
|
16205
16207
|
interpolatingFunction = opt.valueFunction(getByPath(this.attributes, path, delim), value);
|
|
16206
|
-
this._transitionIds[
|
|
16207
|
-
this.trigger('transition:start', this,
|
|
16208
|
+
this._transitionIds[transitionKey] = nextFrame(callback);
|
|
16209
|
+
this.trigger('transition:start', this, transitionKey);
|
|
16208
16210
|
};
|
|
16209
16211
|
initialId = setTimeout(initiator, opt.delay, setter);
|
|
16210
|
-
_scheduledTransitionIds[
|
|
16211
|
-
_scheduledTransitionIds[
|
|
16212
|
+
_scheduledTransitionIds[transitionKey] || (_scheduledTransitionIds[transitionKey] = []);
|
|
16213
|
+
_scheduledTransitionIds[transitionKey].push(initialId);
|
|
16212
16214
|
return initialId;
|
|
16213
16215
|
},
|
|
16214
16216
|
getTransitions: function () {
|
|
@@ -16220,7 +16222,8 @@ var joint = (function (exports) {
|
|
|
16220
16222
|
} = this;
|
|
16221
16223
|
let transitions = Object.keys(_scheduledTransitionIds);
|
|
16222
16224
|
if (path) {
|
|
16223
|
-
|
|
16225
|
+
// Ensure all path segments are strings for `isEqual` comparison, since it strictly compares values
|
|
16226
|
+
const pathArray = Array.isArray(path) ? path.map(item => String(item)) : path.split(delim);
|
|
16224
16227
|
transitions = transitions.filter(key => {
|
|
16225
16228
|
return isEqual(pathArray, key.split(delim).slice(0, pathArray.length));
|
|
16226
16229
|
});
|
|
@@ -16240,7 +16243,8 @@ var joint = (function (exports) {
|
|
|
16240
16243
|
} = this;
|
|
16241
16244
|
let transitions = Object.keys(_transitionIds);
|
|
16242
16245
|
if (path) {
|
|
16243
|
-
|
|
16246
|
+
// Ensure all path segments are strings for `isEqual` comparison, since it strictly compares values
|
|
16247
|
+
const pathArray = Array.isArray(path) ? path.map(item => String(item)) : path.split(delim);
|
|
16244
16248
|
transitions = transitions.filter(key => {
|
|
16245
16249
|
return isEqual(pathArray, key.split(delim).slice(0, pathArray.length));
|
|
16246
16250
|
});
|
|
@@ -16258,7 +16262,7 @@ var joint = (function (exports) {
|
|
|
16258
16262
|
this.stopPendingTransitions(path, delim);
|
|
16259
16263
|
return this;
|
|
16260
16264
|
},
|
|
16261
|
-
// A
|
|
16265
|
+
// A shortcut making it easy to create constructs like the following:
|
|
16262
16266
|
// `var el = (new joint.shapes.standard.Rectangle()).addTo(graph)`.
|
|
16263
16267
|
addTo: function (graph, opt) {
|
|
16264
16268
|
graph.addCell(this, opt);
|
|
@@ -16340,6 +16344,29 @@ var joint = (function (exports) {
|
|
|
16340
16344
|
.getPointRotatedAroundCenter(this.angle(), x, y)
|
|
16341
16345
|
// Transform the absolute position into relative
|
|
16342
16346
|
.difference(this.position());
|
|
16347
|
+
},
|
|
16348
|
+
layer: function (layerId, opt) {
|
|
16349
|
+
const layerAttribute = config$3.layerAttribute;
|
|
16350
|
+
|
|
16351
|
+
// Getter:
|
|
16352
|
+
|
|
16353
|
+
// If `undefined` return the current layer ID
|
|
16354
|
+
if (layerId === undefined) {
|
|
16355
|
+
return this.get(layerAttribute) || null;
|
|
16356
|
+
}
|
|
16357
|
+
|
|
16358
|
+
// Setter:
|
|
16359
|
+
|
|
16360
|
+
// If strictly `null` unset the layer
|
|
16361
|
+
if (layerId === null) {
|
|
16362
|
+
return this.unset(layerAttribute, opt);
|
|
16363
|
+
}
|
|
16364
|
+
|
|
16365
|
+
// Otherwise set the layer ID
|
|
16366
|
+
if (!isString(layerId)) {
|
|
16367
|
+
throw new Error('dia.Cell: Layer id must be a string.');
|
|
16368
|
+
}
|
|
16369
|
+
return this.set(layerAttribute, layerId, opt);
|
|
16343
16370
|
}
|
|
16344
16371
|
}, {
|
|
16345
16372
|
getAttributeDefinition: function (attrName) {
|
|
@@ -16364,6 +16391,9 @@ var joint = (function (exports) {
|
|
|
16364
16391
|
return Cell;
|
|
16365
16392
|
}
|
|
16366
16393
|
});
|
|
16394
|
+
Object.defineProperty(Cell.prototype, CELL_MARKER, {
|
|
16395
|
+
value: true
|
|
16396
|
+
});
|
|
16367
16397
|
|
|
16368
16398
|
const wrapWith = function (object, methods, wrapper) {
|
|
16369
16399
|
if (isString(wrapper)) {
|
|
@@ -17394,7 +17424,17 @@ var joint = (function (exports) {
|
|
|
17394
17424
|
}
|
|
17395
17425
|
};
|
|
17396
17426
|
const elementPortPrototype = {
|
|
17397
|
-
_initializePorts: function () {
|
|
17427
|
+
_initializePorts: function (options) {
|
|
17428
|
+
if (options) {
|
|
17429
|
+
// Override port layout namespaces if provided in options
|
|
17430
|
+
if (options.portLayoutNamespace) {
|
|
17431
|
+
this.portLayoutNamespace = options.portLayoutNamespace;
|
|
17432
|
+
}
|
|
17433
|
+
// Override port label layout namespaces if provided in options
|
|
17434
|
+
if (options.portLabelLayoutNamespace) {
|
|
17435
|
+
this.portLabelLayoutNamespace = options.portLabelLayoutNamespace;
|
|
17436
|
+
}
|
|
17437
|
+
}
|
|
17398
17438
|
this._createPortData();
|
|
17399
17439
|
this.on('change:ports', function () {
|
|
17400
17440
|
this._processRemovedPort();
|
|
@@ -18076,8 +18116,8 @@ var joint = (function (exports) {
|
|
|
18076
18116
|
},
|
|
18077
18117
|
angle: 0
|
|
18078
18118
|
},
|
|
18079
|
-
initialize: function () {
|
|
18080
|
-
this._initializePorts();
|
|
18119
|
+
initialize: function (attributes, options) {
|
|
18120
|
+
this._initializePorts(options);
|
|
18081
18121
|
Cell.prototype.initialize.apply(this, arguments);
|
|
18082
18122
|
},
|
|
18083
18123
|
/**
|
|
@@ -21618,7 +21658,7 @@ var joint = (function (exports) {
|
|
|
21618
21658
|
for (i = 0; i < toAdd.length; i++) {
|
|
21619
21659
|
if (at != null) options.index = at + i;
|
|
21620
21660
|
model = toAdd[i];
|
|
21621
|
-
model.trigger('add', model, this, options);
|
|
21661
|
+
model.trigger(model.eventPrefix + 'add', model, this, options);
|
|
21622
21662
|
}
|
|
21623
21663
|
if (sort || orderChanged) this.trigger('sort', this, options);
|
|
21624
21664
|
if (toAdd.length || toRemove.length || toMerge.length) {
|
|
@@ -21681,7 +21721,7 @@ var joint = (function (exports) {
|
|
|
21681
21721
|
// properties, or an attributes object that is transformed through modelId.
|
|
21682
21722
|
get: function (obj) {
|
|
21683
21723
|
if (obj == null) return void 0;
|
|
21684
|
-
return this._byId
|
|
21724
|
+
return this._byId.get(obj) || this._byId.get(this.modelId(this._isModel(obj) ? obj.attributes : obj, obj.idAttribute)) || obj.cid && this._byId.get(obj.cid);
|
|
21685
21725
|
},
|
|
21686
21726
|
// Returns `true` if the model is in the collection.
|
|
21687
21727
|
has: function (obj) {
|
|
@@ -21720,7 +21760,8 @@ var joint = (function (exports) {
|
|
|
21720
21760
|
},
|
|
21721
21761
|
// Define how to uniquely identify models in the collection.
|
|
21722
21762
|
modelId: function (attrs, idAttribute) {
|
|
21723
|
-
|
|
21763
|
+
var _this$model$prototype;
|
|
21764
|
+
return attrs[idAttribute || ((_this$model$prototype = this.model.prototype) === null || _this$model$prototype === void 0 ? void 0 : _this$model$prototype.idAttribute) || 'id'];
|
|
21724
21765
|
},
|
|
21725
21766
|
// Get an iterator of all models in this collection.
|
|
21726
21767
|
values: function () {
|
|
@@ -21777,17 +21818,17 @@ var joint = (function (exports) {
|
|
|
21777
21818
|
_reset: function () {
|
|
21778
21819
|
this.length = 0;
|
|
21779
21820
|
this.models = [];
|
|
21780
|
-
this._byId =
|
|
21821
|
+
this._byId = new Map();
|
|
21781
21822
|
},
|
|
21782
21823
|
// Prepare a hash of attributes (or other model) to be added to this
|
|
21783
21824
|
// collection.
|
|
21784
21825
|
_prepareModel: function (attrs, options) {
|
|
21785
21826
|
if (this._isModel(attrs)) {
|
|
21786
|
-
if (!attrs.collection) attrs.collection = this;
|
|
21827
|
+
if (!options.dry && !attrs.collection) attrs.collection = this;
|
|
21787
21828
|
return attrs;
|
|
21788
21829
|
}
|
|
21789
21830
|
options = options ? clone$1(options) : {};
|
|
21790
|
-
options.collection = this;
|
|
21831
|
+
if (!options.dry) options.collection = this;
|
|
21791
21832
|
var model;
|
|
21792
21833
|
if (this.model.prototype) {
|
|
21793
21834
|
model = new this.model(attrs, options);
|
|
@@ -21811,12 +21852,12 @@ var joint = (function (exports) {
|
|
|
21811
21852
|
|
|
21812
21853
|
// Remove references before triggering 'remove' event to prevent an
|
|
21813
21854
|
// infinite loop. #3693
|
|
21814
|
-
|
|
21855
|
+
this._byId.delete(model.cid);
|
|
21815
21856
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21816
|
-
if (id != null)
|
|
21857
|
+
if (id != null) this._byId.delete(id);
|
|
21817
21858
|
if (!options.silent) {
|
|
21818
21859
|
options.index = index;
|
|
21819
|
-
model.trigger('remove', model, this, options);
|
|
21860
|
+
model.trigger(model.eventPrefix + 'remove', model, this, options);
|
|
21820
21861
|
}
|
|
21821
21862
|
removed.push(model);
|
|
21822
21863
|
this._removeReference(model, options);
|
|
@@ -21831,17 +21872,17 @@ var joint = (function (exports) {
|
|
|
21831
21872
|
},
|
|
21832
21873
|
// Internal method to create a model's ties to a collection.
|
|
21833
21874
|
_addReference: function (model, options) {
|
|
21834
|
-
this._byId
|
|
21875
|
+
this._byId.set(model.cid, model);
|
|
21835
21876
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21836
|
-
if (id != null) this._byId
|
|
21877
|
+
if (id != null) this._byId.set(id, model);
|
|
21837
21878
|
model.on('all', this._onModelEvent, this);
|
|
21838
21879
|
},
|
|
21839
21880
|
// Internal method to sever a model's ties to a collection.
|
|
21840
21881
|
_removeReference: function (model, options) {
|
|
21841
|
-
|
|
21882
|
+
this._byId.delete(model.cid);
|
|
21842
21883
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21843
|
-
if (id != null)
|
|
21844
|
-
if (this === model.collection) delete model.collection;
|
|
21884
|
+
if (id != null) this._byId.delete(id);
|
|
21885
|
+
if (!options.dry && this === model.collection) delete model.collection;
|
|
21845
21886
|
model.off('all', this._onModelEvent, this);
|
|
21846
21887
|
},
|
|
21847
21888
|
// Internal method called every time a model in the set fires an event.
|
|
@@ -21850,12 +21891,12 @@ var joint = (function (exports) {
|
|
|
21850
21891
|
// in other collections are ignored.
|
|
21851
21892
|
_onModelEvent: function (event, model, collection, options) {
|
|
21852
21893
|
if (model) {
|
|
21853
|
-
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
|
21894
|
+
if ((event === model.eventPrefix + 'add' || event === model.eventPrefix + 'remove') && collection !== this) return;
|
|
21854
21895
|
if (event === 'changeId') {
|
|
21855
21896
|
var prevId = this.modelId(model.previousAttributes(), model.idAttribute);
|
|
21856
21897
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21857
|
-
if (prevId != null)
|
|
21858
|
-
if (id != null) this._byId
|
|
21898
|
+
if (prevId != null) this._byId.delete(prevId);
|
|
21899
|
+
if (id != null) this._byId.set(id, model);
|
|
21859
21900
|
}
|
|
21860
21901
|
}
|
|
21861
21902
|
this.trigger.apply(this, arguments);
|
|
@@ -26681,21 +26722,181 @@ var joint = (function (exports) {
|
|
|
26681
26722
|
topRight: topRight
|
|
26682
26723
|
};
|
|
26683
26724
|
|
|
26684
|
-
|
|
26685
|
-
|
|
26686
|
-
|
|
26687
|
-
|
|
26688
|
-
|
|
26689
|
-
|
|
26690
|
-
|
|
26691
|
-
|
|
26692
|
-
|
|
26725
|
+
/**
|
|
26726
|
+
* @class GraphLayersController
|
|
26727
|
+
* @description Coordinates interactions between the graph and its layers.
|
|
26728
|
+
* Automatically moves cells between layers when the layer attribute changes.
|
|
26729
|
+
*/
|
|
26730
|
+
class GraphLayersController extends Listener {
|
|
26731
|
+
constructor(options) {
|
|
26732
|
+
super(options);
|
|
26733
|
+
|
|
26734
|
+
// Make sure there are no arguments passed to the callbacks.
|
|
26735
|
+
// See the `mvc.Listener` documentation for more details.
|
|
26736
|
+
this.callbackArguments = [];
|
|
26737
|
+
const graph = options.graph;
|
|
26738
|
+
if (!graph) {
|
|
26739
|
+
throw new Error('GraphLayersController: "graph" option is required.');
|
|
26740
|
+
}
|
|
26741
|
+
this.graph = graph;
|
|
26742
|
+
this.layerCollection = graph.layerCollection;
|
|
26743
|
+
this.startListening();
|
|
26744
|
+
}
|
|
26745
|
+
startListening() {
|
|
26746
|
+
// Handle all events from the layer collection and its inner cell collections.
|
|
26747
|
+
this.listenTo(this.layerCollection, 'all', this.onLayerCollectionEvent);
|
|
26748
|
+
}
|
|
26749
|
+
|
|
26750
|
+
/**
|
|
26751
|
+
* @description When a cell changes its layer attribute,
|
|
26752
|
+
* move the cell to the target layer.
|
|
26753
|
+
*/
|
|
26754
|
+
onCellChange(cell, options) {
|
|
26755
|
+
if (!cell.hasChanged(config$3.layerAttribute)) return;
|
|
26756
|
+
// Move the cell to the appropriate layer
|
|
26757
|
+
const targetLayerId = this.graph.getCellLayerId(cell);
|
|
26758
|
+
this.layerCollection.moveCellBetweenLayers(cell, targetLayerId, options);
|
|
26759
|
+
}
|
|
26760
|
+
|
|
26761
|
+
/**
|
|
26762
|
+
* @description When a cell is removed from a layer,
|
|
26763
|
+
* also remove its embeds and connected links from the graph.
|
|
26764
|
+
* Note: an embedded cell might come from a different layer,
|
|
26765
|
+
* so we can not use the layer's cell collection to remove it.
|
|
26766
|
+
*/
|
|
26767
|
+
onCellRemove(cell, options) {
|
|
26768
|
+
// If the cell is being moved from one layer to another,
|
|
26769
|
+
// no further action is needed.
|
|
26770
|
+
if (options.fromLayer) return;
|
|
26771
|
+
|
|
26772
|
+
// When replacing a cell, we do not want to remove its embeds or
|
|
26773
|
+
// unembed it from its parent.
|
|
26774
|
+
if (options.replace) return;
|
|
26775
|
+
|
|
26776
|
+
// First, unembed this cell from its parent cell if there is one.
|
|
26777
|
+
const parentCell = cell.getParentCell();
|
|
26778
|
+
if (parentCell) {
|
|
26779
|
+
parentCell.unembed(cell, options);
|
|
26780
|
+
}
|
|
26781
|
+
|
|
26782
|
+
// Remove also all the cells, which were embedded into this cell
|
|
26783
|
+
const embeddedCells = cell.getEmbeddedCells();
|
|
26784
|
+
for (let i = 0, n = embeddedCells.length; i < n; i++) {
|
|
26785
|
+
const embed = embeddedCells[i];
|
|
26786
|
+
if (embed) {
|
|
26787
|
+
this.layerCollection.removeCell(embed, options);
|
|
26788
|
+
}
|
|
26789
|
+
}
|
|
26790
|
+
|
|
26791
|
+
// When not clearing the whole graph or replacing the cell,
|
|
26792
|
+
// we don't want to remove the connected links.
|
|
26793
|
+
if (!options.clear) {
|
|
26794
|
+
// Applications might provide a `disconnectLinks` option set to `true` in order to
|
|
26795
|
+
// disconnect links when a cell is removed rather then removing them. The default
|
|
26796
|
+
// is to remove all the associated links.
|
|
26797
|
+
if (options.disconnectLinks) {
|
|
26798
|
+
this.graph.disconnectLinks(cell, options);
|
|
26799
|
+
} else {
|
|
26800
|
+
this.graph.removeLinks(cell, options);
|
|
26801
|
+
}
|
|
26802
|
+
}
|
|
26803
|
+
}
|
|
26804
|
+
onLayerCollectionEvent(eventName, model) {
|
|
26805
|
+
if (!model) return;
|
|
26806
|
+
if (model[CELL_MARKER]) {
|
|
26807
|
+
// First handle cell-specific cases that require custom processing,
|
|
26808
|
+
// then forward the event to the graph.
|
|
26809
|
+
// For example, when a cell is removed from a layer, its embeds and
|
|
26810
|
+
// connected links must be removed as well. Listeners on the graph
|
|
26811
|
+
// should receive removal notifications in the following order:
|
|
26812
|
+
// embeds → links → cell.
|
|
26813
|
+
switch (eventName) {
|
|
26814
|
+
case 'change':
|
|
26815
|
+
/* ('change', cell, options) */
|
|
26816
|
+
this.onCellChange.call(this, model, arguments[2]);
|
|
26817
|
+
break;
|
|
26818
|
+
case 'remove':
|
|
26819
|
+
/* ('remove', cell, collection, options) */
|
|
26820
|
+
// When a cell is removed from a layer,
|
|
26821
|
+
// ensure it is also removed from the graph.
|
|
26822
|
+
this.onCellRemove.call(this, model, arguments[3]);
|
|
26823
|
+
break;
|
|
26824
|
+
}
|
|
26825
|
+
// Notify the graph about cell events.
|
|
26826
|
+
this.forwardCellEvent.apply(this, arguments);
|
|
26827
|
+
return;
|
|
26828
|
+
}
|
|
26829
|
+
if (model[CELL_COLLECTION_MARKER]) {
|
|
26830
|
+
this.forwardCellCollectionEvent.apply(this, arguments);
|
|
26831
|
+
return;
|
|
26832
|
+
}
|
|
26833
|
+
if (model[GRAPH_LAYER_MARKER]) {
|
|
26834
|
+
this.forwardLayerEvent.apply(this, arguments);
|
|
26835
|
+
return;
|
|
26836
|
+
}
|
|
26837
|
+
if (model[GRAPH_LAYER_COLLECTION_MARKER]) {
|
|
26838
|
+
this.forwardLayerCollectionEvent.apply(this, arguments);
|
|
26839
|
+
return;
|
|
26840
|
+
}
|
|
26841
|
+
}
|
|
26842
|
+
forwardLayerEvent() {
|
|
26843
|
+
// Note: the layer event prefix is `layer:`
|
|
26844
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26845
|
+
}
|
|
26846
|
+
forwardCellEvent(eventName, cell) {
|
|
26847
|
+
var _arguments$;
|
|
26848
|
+
// Moving a cell from one layer to another is an internal operation
|
|
26849
|
+
// that should not be exposed at the graph level.
|
|
26850
|
+
// The single `move` event is triggered instead.
|
|
26851
|
+
if ((eventName === 'remove' || eventName === 'add') && (_arguments$ = arguments[3]) !== null && _arguments$ !== void 0 && _arguments$.fromLayer) return;
|
|
26852
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26853
|
+
}
|
|
26854
|
+
forwardCellCollectionEvent(eventName) {
|
|
26855
|
+
// Do not forward `layer:remove` or `layer:sort` events to the graph
|
|
26856
|
+
if (eventName !== 'sort') return;
|
|
26857
|
+
// Backwards compatibility:
|
|
26858
|
+
// Trigger 'sort' event for cell collection 'sort' events
|
|
26859
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26860
|
+
}
|
|
26861
|
+
forwardLayerCollectionEvent(eventName) {
|
|
26862
|
+
if (eventName === 'reset') {
|
|
26863
|
+
// Currently, there is no need to forward `layers:reset` event.
|
|
26864
|
+
// The graph `fromJSON()` triggers a single `reset` event after
|
|
26865
|
+
// resetting cells, layers and attributes.
|
|
26866
|
+
return;
|
|
26867
|
+
}
|
|
26868
|
+
// Forward layer collection events with `layers:` prefix.
|
|
26869
|
+
// For example `layers:reset` event when the layer collection is reset
|
|
26870
|
+
arguments[0] = 'layers:' + arguments[0];
|
|
26871
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26872
|
+
}
|
|
26873
|
+
}
|
|
26874
|
+
|
|
26875
|
+
/**
|
|
26876
|
+
* @class CellCollection
|
|
26877
|
+
* @description A CellCollection is a collection of cells which supports z-index management.
|
|
26878
|
+
* Additionally, it facilitates creating cell models from JSON using cellNamespace
|
|
26879
|
+
* and stores a reference to the graph when the cell model has been added.
|
|
26880
|
+
*/
|
|
26881
|
+
class CellCollection extends Collection {
|
|
26882
|
+
[CELL_COLLECTION_MARKER] = true;
|
|
26883
|
+
initialize(_models, opt) {
|
|
26884
|
+
this.layer = opt.layer;
|
|
26885
|
+
}
|
|
26886
|
+
|
|
26887
|
+
// Method for checking whether an object should be considered a model for
|
|
26888
|
+
// the purposes of adding to the collection.
|
|
26889
|
+
_isModel(model) {
|
|
26890
|
+
return Boolean(model[CELL_MARKER]);
|
|
26891
|
+
}
|
|
26892
|
+
|
|
26893
|
+
// Overriding the default `model` method to create cell models
|
|
26894
|
+
// based on their `type` attribute and the `cellNamespace` option.
|
|
26895
|
+
model(attrs, opt) {
|
|
26896
|
+
const namespace = this.cellNamespace;
|
|
26897
|
+
if (!namespace) {
|
|
26898
|
+
throw new Error('dia.CellCollection: cellNamespace is required to instantiate a Cell from JSON.');
|
|
26693
26899
|
}
|
|
26694
|
-
this.graph = opt.graph;
|
|
26695
|
-
},
|
|
26696
|
-
model: function (attrs, opt) {
|
|
26697
|
-
const collection = opt.collection;
|
|
26698
|
-
const namespace = collection.cellNamespace;
|
|
26699
26900
|
const {
|
|
26700
26901
|
type
|
|
26701
26902
|
} = attrs;
|
|
@@ -26706,56 +26907,474 @@ var joint = (function (exports) {
|
|
|
26706
26907
|
throw new Error(`dia.Graph: Could not find cell constructor for type: '${type}'. Make sure to add the constructor to 'cellNamespace'.`);
|
|
26707
26908
|
}
|
|
26708
26909
|
return new ModelClass(attrs, opt);
|
|
26709
|
-
}
|
|
26710
|
-
|
|
26711
|
-
|
|
26910
|
+
}
|
|
26911
|
+
|
|
26912
|
+
// Override to set graph reference
|
|
26913
|
+
_addReference(model, options) {
|
|
26914
|
+
super._addReference(model, options);
|
|
26915
|
+
|
|
26712
26916
|
// If not in `dry` mode and the model does not have a graph reference yet,
|
|
26713
26917
|
// set the reference.
|
|
26714
26918
|
if (!options.dry && !model.graph) {
|
|
26715
|
-
model.graph = this.graph;
|
|
26919
|
+
model.graph = this.layer.graph;
|
|
26716
26920
|
}
|
|
26717
|
-
}
|
|
26718
|
-
|
|
26719
|
-
|
|
26921
|
+
}
|
|
26922
|
+
|
|
26923
|
+
// Override to remove graph reference
|
|
26924
|
+
_removeReference(model, options) {
|
|
26925
|
+
super._removeReference(model, options);
|
|
26926
|
+
|
|
26720
26927
|
// If not in `dry` mode and the model has a reference to this exact graph,
|
|
26721
26928
|
// remove the reference.
|
|
26722
|
-
|
|
26929
|
+
// Note: graph reference is removed from the layer after the `remove` event is fired.
|
|
26930
|
+
// Due to this, event handlers can still access the graph during the `remove` event.
|
|
26931
|
+
if (!options.dry && model.graph === this.layer.graph) {
|
|
26723
26932
|
model.graph = null;
|
|
26724
26933
|
}
|
|
26725
|
-
}
|
|
26934
|
+
}
|
|
26935
|
+
|
|
26936
|
+
// remove graph reference additionally
|
|
26937
|
+
_removeReferenceFast(model, options) {
|
|
26938
|
+
model.off('all', this._onModelEvent, this);
|
|
26939
|
+
if (!options.dry) {
|
|
26940
|
+
// If not in `dry` mode and the model has a reference
|
|
26941
|
+
// to this exact graph/collection, remove the reference.
|
|
26942
|
+
if (this === model.collection) {
|
|
26943
|
+
delete model.collection;
|
|
26944
|
+
}
|
|
26945
|
+
if (model.graph === this.layer.graph) {
|
|
26946
|
+
model.graph = null;
|
|
26947
|
+
}
|
|
26948
|
+
}
|
|
26949
|
+
}
|
|
26950
|
+
|
|
26726
26951
|
// `comparator` makes it easy to sort cells based on their `z` index.
|
|
26727
|
-
comparator
|
|
26952
|
+
comparator(model) {
|
|
26728
26953
|
return model.get('z') || 0;
|
|
26729
26954
|
}
|
|
26730
|
-
});
|
|
26731
|
-
const Graph = Model.extend({
|
|
26732
|
-
initialize: function (attrs, opt) {
|
|
26733
|
-
opt = opt || {};
|
|
26734
26955
|
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
|
|
26956
|
+
// This method overrides base mvc.Collection implementation
|
|
26957
|
+
// in a way that improves performance of resetting large collections.
|
|
26958
|
+
// For layers specifically, there is an option where we put references
|
|
26959
|
+
// from the main collection in order to improve performance when
|
|
26960
|
+
// there is only one layer
|
|
26961
|
+
reset(models, options) {
|
|
26962
|
+
options = assign({}, {
|
|
26963
|
+
add: true,
|
|
26964
|
+
remove: false,
|
|
26965
|
+
merge: false
|
|
26966
|
+
}, options);
|
|
26967
|
+
for (let i = 0; i < this.models.length; i++) {
|
|
26968
|
+
this._removeReferenceFast(this.models[i], options);
|
|
26969
|
+
}
|
|
26970
|
+
options.previousModels = this.models;
|
|
26971
|
+
this._reset();
|
|
26972
|
+
for (let i = 0; i < models.length; i++) {
|
|
26973
|
+
const model = this._prepareModel(models[i], options);
|
|
26974
|
+
if (model) {
|
|
26975
|
+
this.models.push(model);
|
|
26976
|
+
this._addReference(model, options);
|
|
26977
|
+
}
|
|
26978
|
+
}
|
|
26979
|
+
this.length = this.models.length;
|
|
26980
|
+
const sort = this.comparator && options.sort !== false;
|
|
26981
|
+
if (sort) {
|
|
26982
|
+
this.sort({
|
|
26983
|
+
silent: true
|
|
26984
|
+
});
|
|
26985
|
+
}
|
|
26986
|
+
if (!options.silent) {
|
|
26987
|
+
this.trigger('reset', this, options);
|
|
26988
|
+
}
|
|
26989
|
+
return this.models;
|
|
26990
|
+
}
|
|
26991
|
+
minZIndex() {
|
|
26992
|
+
var _this$first;
|
|
26993
|
+
return ((_this$first = this.first()) === null || _this$first === void 0 ? void 0 : _this$first.get('z')) || 0;
|
|
26994
|
+
}
|
|
26995
|
+
maxZIndex() {
|
|
26996
|
+
var _this$last;
|
|
26997
|
+
return ((_this$last = this.last()) === null || _this$last === void 0 ? void 0 : _this$last.get('z')) || 0;
|
|
26998
|
+
}
|
|
26999
|
+
}
|
|
27000
|
+
|
|
27001
|
+
const DEFAULT_GRAPH_LAYER_TYPE = 'GraphLayer';
|
|
27002
|
+
|
|
27003
|
+
/**
|
|
27004
|
+
* @class GraphLayer
|
|
27005
|
+
* @description A GraphLayer is a model representing a single layer in a dia.Graph.
|
|
27006
|
+
*/
|
|
27007
|
+
class GraphLayer extends Model {
|
|
27008
|
+
[GRAPH_LAYER_MARKER] = true;
|
|
27009
|
+
preinitialize() {
|
|
27010
|
+
// This allows for propagating events from the inner `cellCollection` collection
|
|
27011
|
+
// without any prefix and therefore distinguish them from the events
|
|
27012
|
+
// fired by the GraphLayer model itself.
|
|
27013
|
+
this.eventPrefix = 'layer:';
|
|
27014
|
+
}
|
|
27015
|
+
defaults() {
|
|
27016
|
+
return {
|
|
27017
|
+
type: DEFAULT_GRAPH_LAYER_TYPE
|
|
27018
|
+
};
|
|
27019
|
+
}
|
|
27020
|
+
initialize(attrs, options = {}) {
|
|
27021
|
+
super.initialize(attrs, options);
|
|
27022
|
+
this.cellCollection = new CellCollection([], {
|
|
27023
|
+
layer: this
|
|
26742
27024
|
});
|
|
26743
|
-
Model.prototype.set.call(this, 'cells', cells);
|
|
26744
27025
|
|
|
26745
|
-
//
|
|
26746
|
-
|
|
26747
|
-
|
|
27026
|
+
// Forward all events from the inner `cellCollection` collection
|
|
27027
|
+
this.cellCollection.on('all', this.trigger, this);
|
|
27028
|
+
// Listen to cell changes to manage z-index sorting
|
|
27029
|
+
this.cellCollection.on('change', this.onCellChange, this);
|
|
27030
|
+
}
|
|
27031
|
+
onCellChange(cell, opt) {
|
|
27032
|
+
if (opt.sort === false || !cell.hasChanged('z')) return;
|
|
27033
|
+
this.cellCollection.sort();
|
|
27034
|
+
}
|
|
27035
|
+
|
|
27036
|
+
/**
|
|
27037
|
+
* @public
|
|
27038
|
+
* @description Returns all cells in this layer.
|
|
27039
|
+
*/
|
|
27040
|
+
getCells() {
|
|
27041
|
+
return this.cellCollection.toArray();
|
|
27042
|
+
}
|
|
27043
|
+
}
|
|
26748
27044
|
|
|
26749
|
-
|
|
26750
|
-
|
|
26751
|
-
|
|
27045
|
+
/**
|
|
27046
|
+
* @class GraphLayerCollection
|
|
27047
|
+
* @description A collection of layers used in dia.Graph. It facilitates creating layers from JSON using layerNamespace.
|
|
27048
|
+
*/
|
|
27049
|
+
const GraphLayerCollection = Collection.extend({
|
|
27050
|
+
defaultLayerNamespace: {
|
|
27051
|
+
GraphLayer
|
|
27052
|
+
},
|
|
27053
|
+
/**
|
|
27054
|
+
* @override
|
|
27055
|
+
* @description Initializes the collection and sets up the layer and cell namespaces.
|
|
27056
|
+
*/
|
|
27057
|
+
initialize: function (_models, options = {}) {
|
|
27058
|
+
const {
|
|
27059
|
+
layerNamespace,
|
|
27060
|
+
cellNamespace,
|
|
27061
|
+
graph
|
|
27062
|
+
} = options;
|
|
26752
27063
|
|
|
26753
|
-
//
|
|
26754
|
-
//
|
|
26755
|
-
|
|
26756
|
-
|
|
26757
|
-
//
|
|
27064
|
+
// Initialize the namespace that holds all available layer classes.
|
|
27065
|
+
// Custom namespaces are merged with the default ones.
|
|
27066
|
+
this.layerNamespace = assign({}, this.defaultLayerNamespace, layerNamespace);
|
|
27067
|
+
|
|
27068
|
+
// Initialize the namespace for all cell model classes, if provided.
|
|
27069
|
+
if (cellNamespace) {
|
|
27070
|
+
this.cellNamespace = cellNamespace;
|
|
27071
|
+
} else {
|
|
27072
|
+
/* eslint-disable no-undef */
|
|
27073
|
+
this.cellNamespace = typeof joint !== 'undefined' && has(joint, 'shapes') ? joint.shapes : null;
|
|
27074
|
+
/* eslint-enable no-undef */
|
|
27075
|
+
}
|
|
27076
|
+
this.graph = graph;
|
|
27077
|
+
},
|
|
27078
|
+
/**
|
|
27079
|
+
* @override
|
|
27080
|
+
* @description Overrides the default `model` method
|
|
27081
|
+
* to create layer models based on their `type` attribute.
|
|
27082
|
+
*/
|
|
27083
|
+
model: function (attrs, opt) {
|
|
27084
|
+
const collection = opt.collection;
|
|
27085
|
+
const namespace = collection.layerNamespace;
|
|
27086
|
+
const {
|
|
27087
|
+
type
|
|
27088
|
+
} = attrs;
|
|
27089
|
+
|
|
27090
|
+
// Find the model class based on the `type` attribute in the cell namespace
|
|
27091
|
+
const GraphLayerClass = getByPath(namespace, type, '.');
|
|
27092
|
+
if (!GraphLayerClass) {
|
|
27093
|
+
throw new Error(`dia.Graph: Could not find layer constructor for type: '${type}'. Make sure to add the constructor to 'layerNamespace'.`);
|
|
27094
|
+
}
|
|
27095
|
+
return new GraphLayerClass(attrs, opt);
|
|
27096
|
+
},
|
|
27097
|
+
// Override to set graph reference
|
|
27098
|
+
_addReference(layer, options) {
|
|
27099
|
+
Collection.prototype._addReference.call(this, layer, options);
|
|
27100
|
+
|
|
27101
|
+
// assign graph and cellNamespace references
|
|
27102
|
+
// to the added layer
|
|
27103
|
+
layer.graph = this.graph;
|
|
27104
|
+
layer.cellCollection.cellNamespace = this.cellNamespace;
|
|
27105
|
+
},
|
|
27106
|
+
// Override to remove graph reference
|
|
27107
|
+
_removeReference(layer, options) {
|
|
27108
|
+
Collection.prototype._removeReference.call(this, layer, options);
|
|
27109
|
+
|
|
27110
|
+
// remove graph and cellNamespace references
|
|
27111
|
+
// from the removed layer
|
|
27112
|
+
layer.graph = null;
|
|
27113
|
+
layer.cellCollection.cellNamespace = null;
|
|
27114
|
+
},
|
|
27115
|
+
/**
|
|
27116
|
+
* @override
|
|
27117
|
+
* @description Overrides the default `_prepareModel` method
|
|
27118
|
+
* to set default layer type if missing.
|
|
27119
|
+
*/
|
|
27120
|
+
_prepareModel: function (attrs, options) {
|
|
27121
|
+
if (!attrs[GRAPH_LAYER_MARKER]) {
|
|
27122
|
+
// Add a mandatory `type` attribute if missing
|
|
27123
|
+
if (!attrs.type) {
|
|
27124
|
+
const preparedAttributes = clone$1(attrs);
|
|
27125
|
+
preparedAttributes.type = DEFAULT_GRAPH_LAYER_TYPE;
|
|
27126
|
+
arguments[0] = preparedAttributes;
|
|
27127
|
+
}
|
|
27128
|
+
}
|
|
27129
|
+
return Collection.prototype._prepareModel.apply(this, arguments);
|
|
27130
|
+
},
|
|
27131
|
+
/**
|
|
27132
|
+
* @override
|
|
27133
|
+
* @description Add an assertion to prevent direct resetting of the collection.
|
|
27134
|
+
*/
|
|
27135
|
+
reset(models, options) {
|
|
27136
|
+
this._assertInternalCall(options);
|
|
27137
|
+
return Collection.prototype.reset.apply(this, arguments);
|
|
27138
|
+
},
|
|
27139
|
+
/**
|
|
27140
|
+
* @override
|
|
27141
|
+
* @description Add an assertion to prevent direct addition of layers.
|
|
27142
|
+
*/
|
|
27143
|
+
add(models, options) {
|
|
27144
|
+
this._assertInternalCall(options);
|
|
27145
|
+
return Collection.prototype.add.apply(this, arguments);
|
|
27146
|
+
},
|
|
27147
|
+
/**
|
|
27148
|
+
* @override
|
|
27149
|
+
* @description Add an assertion to prevent direct removal of layers.
|
|
27150
|
+
*/
|
|
27151
|
+
remove(models, options) {
|
|
27152
|
+
this._assertInternalCall(options);
|
|
27153
|
+
return Collection.prototype.remove.apply(this, arguments);
|
|
27154
|
+
},
|
|
27155
|
+
/**
|
|
27156
|
+
* @override
|
|
27157
|
+
* @description Overrides the default `_onModelEvent` method
|
|
27158
|
+
* to distinguish between events coming from different model types.
|
|
27159
|
+
*/
|
|
27160
|
+
_onModelEvent(_, model) {
|
|
27161
|
+
if (model && model[CELL_MARKER]) {
|
|
27162
|
+
// Do not filter cell `add` and `remove` events
|
|
27163
|
+
// See `mvc.Collection` for more details
|
|
27164
|
+
this.trigger.apply(this, arguments);
|
|
27165
|
+
return;
|
|
27166
|
+
}
|
|
26758
27167
|
|
|
27168
|
+
// For other events, use the default behavior
|
|
27169
|
+
Collection.prototype._onModelEvent.apply(this, arguments);
|
|
27170
|
+
},
|
|
27171
|
+
/**
|
|
27172
|
+
* @protected
|
|
27173
|
+
* @description Asserts that the collection manipulation
|
|
27174
|
+
* is done via internal graph methods. Otherwise, it throws an error.
|
|
27175
|
+
* This is a temporary measure until layers API is stabilized.
|
|
27176
|
+
*/
|
|
27177
|
+
_assertInternalCall(options) {
|
|
27178
|
+
if (options && !options.graph && !options.silent) {
|
|
27179
|
+
throw new Error('dia.GraphLayerCollection: direct manipulation of the collection is not supported, use graph methods instead.');
|
|
27180
|
+
}
|
|
27181
|
+
},
|
|
27182
|
+
/**
|
|
27183
|
+
* @public
|
|
27184
|
+
* @description Inserts a layer before another layer or at the end if `beforeLayerId` is null.
|
|
27185
|
+
*/
|
|
27186
|
+
insert(layerInit, beforeLayerId = null, options = {}) {
|
|
27187
|
+
const id = layerInit.id;
|
|
27188
|
+
if (id === beforeLayerId) {
|
|
27189
|
+
// Inserting before itself is a no-op
|
|
27190
|
+
return;
|
|
27191
|
+
}
|
|
27192
|
+
if (beforeLayerId && !this.has(beforeLayerId)) {
|
|
27193
|
+
throw new Error(`dia.GraphLayerCollection: Layer "${beforeLayerId}" does not exist`);
|
|
27194
|
+
}
|
|
27195
|
+
|
|
27196
|
+
// See if the layer is already in the collection
|
|
27197
|
+
let currentIndex = -1;
|
|
27198
|
+
if (this.has(id)) {
|
|
27199
|
+
currentIndex = this.findIndex(l => l.id === id);
|
|
27200
|
+
if (currentIndex === this.length - 1 && !beforeLayerId) {
|
|
27201
|
+
// The layer is already at the end
|
|
27202
|
+
return;
|
|
27203
|
+
}
|
|
27204
|
+
// Remove the layer from its current position
|
|
27205
|
+
this.remove(id, {
|
|
27206
|
+
silent: true
|
|
27207
|
+
});
|
|
27208
|
+
}
|
|
27209
|
+
|
|
27210
|
+
// At what index to insert the layer?
|
|
27211
|
+
let insertAt;
|
|
27212
|
+
if (!beforeLayerId) {
|
|
27213
|
+
insertAt = this.length;
|
|
27214
|
+
} else {
|
|
27215
|
+
insertAt = this.findIndex(l => l.id === beforeLayerId);
|
|
27216
|
+
}
|
|
27217
|
+
if (currentIndex !== -1) {
|
|
27218
|
+
// Re-insert the layer at the new position.
|
|
27219
|
+
this.add(layerInit, {
|
|
27220
|
+
at: insertAt,
|
|
27221
|
+
silent: true
|
|
27222
|
+
});
|
|
27223
|
+
// Trigger `sort` event manually
|
|
27224
|
+
// since we are not using collection sorting workflow
|
|
27225
|
+
this.trigger('sort', this, options);
|
|
27226
|
+
} else {
|
|
27227
|
+
// Add to the collection and trigger an event
|
|
27228
|
+
// when new layer has been added
|
|
27229
|
+
this.add(layerInit, {
|
|
27230
|
+
...options,
|
|
27231
|
+
at: insertAt
|
|
27232
|
+
});
|
|
27233
|
+
}
|
|
27234
|
+
},
|
|
27235
|
+
/**
|
|
27236
|
+
* @public
|
|
27237
|
+
* @description Finds and returns a cell by its id from all layers.
|
|
27238
|
+
*/
|
|
27239
|
+
getCell(cellRef) {
|
|
27240
|
+
// TODO: should we create a map of cells for faster lookup?
|
|
27241
|
+
for (const layer of this.models) {
|
|
27242
|
+
const cell = layer.cellCollection.get(cellRef);
|
|
27243
|
+
if (cell) {
|
|
27244
|
+
return cell;
|
|
27245
|
+
}
|
|
27246
|
+
}
|
|
27247
|
+
// Backward compatibility: return undefined if cell is not found
|
|
27248
|
+
return undefined;
|
|
27249
|
+
},
|
|
27250
|
+
/**
|
|
27251
|
+
* @public
|
|
27252
|
+
* @description Returns all cells in all layers in the correct order.
|
|
27253
|
+
*/
|
|
27254
|
+
getCells() {
|
|
27255
|
+
const layers = this.models;
|
|
27256
|
+
if (layers.length === 1) {
|
|
27257
|
+
// Single layer:
|
|
27258
|
+
// Fast path, just return the copy of the only layer's cells
|
|
27259
|
+
return layers[0].getCells();
|
|
27260
|
+
}
|
|
27261
|
+
// Multiple layers:
|
|
27262
|
+
// Each layer has its models sorted already, so we can just concatenate
|
|
27263
|
+
// them in the order of layers.
|
|
27264
|
+
const cells = [];
|
|
27265
|
+
for (const layer of layers) {
|
|
27266
|
+
Array.prototype.push.apply(cells, layer.cellCollection.models);
|
|
27267
|
+
}
|
|
27268
|
+
return cells;
|
|
27269
|
+
},
|
|
27270
|
+
/**
|
|
27271
|
+
* @public
|
|
27272
|
+
* @description Removes a cell from its current layer.
|
|
27273
|
+
*/
|
|
27274
|
+
removeCell(cell, options = {}) {
|
|
27275
|
+
var _cell$collection;
|
|
27276
|
+
const cellCollection = (_cell$collection = cell.collection) === null || _cell$collection === void 0 || (_cell$collection = _cell$collection.layer) === null || _cell$collection === void 0 ? void 0 : _cell$collection.cellCollection;
|
|
27277
|
+
if (!cellCollection) return;
|
|
27278
|
+
cellCollection.remove(cell, options);
|
|
27279
|
+
},
|
|
27280
|
+
/**
|
|
27281
|
+
* @public
|
|
27282
|
+
* @description Move a cell from its current layer to a target layer.
|
|
27283
|
+
*/
|
|
27284
|
+
moveCellBetweenLayers(cell, targetLayerId, options = {}) {
|
|
27285
|
+
var _cell$collection2;
|
|
27286
|
+
const sourceLayer = (_cell$collection2 = cell.collection) === null || _cell$collection2 === void 0 ? void 0 : _cell$collection2.layer;
|
|
27287
|
+
if (!sourceLayer) {
|
|
27288
|
+
throw new Error('dia.GraphLayerCollection: cannot move a cell that is not part of any layer.');
|
|
27289
|
+
}
|
|
27290
|
+
const targetLayer = this.get(targetLayerId);
|
|
27291
|
+
if (!targetLayer) {
|
|
27292
|
+
throw new Error(`dia.GraphLayerCollection: cannot move cell to layer '${targetLayerId}' because such layer does not exist.`);
|
|
27293
|
+
}
|
|
27294
|
+
if (sourceLayer === targetLayer) {
|
|
27295
|
+
// 1. The provided cell is already in the target layer
|
|
27296
|
+
// 2. Implicit default layer vs. explicit default (or vice versa)
|
|
27297
|
+
// No follow-up action needed
|
|
27298
|
+
return;
|
|
27299
|
+
}
|
|
27300
|
+
const moveOptions = {
|
|
27301
|
+
...options,
|
|
27302
|
+
fromLayer: sourceLayer.id,
|
|
27303
|
+
toLayer: targetLayer.id
|
|
27304
|
+
};
|
|
27305
|
+
// Move the cell between the two layer collections
|
|
27306
|
+
sourceLayer.cellCollection.remove(cell, moveOptions);
|
|
27307
|
+
targetLayer.cellCollection.add(cell, moveOptions);
|
|
27308
|
+
// Trigger a single `move` event to ease distinguishing layer moves
|
|
27309
|
+
// from add/remove operations
|
|
27310
|
+
cell.trigger('move', cell, moveOptions);
|
|
27311
|
+
},
|
|
27312
|
+
/**
|
|
27313
|
+
* @public
|
|
27314
|
+
* @description Adds a cell to the specified layer.
|
|
27315
|
+
*/
|
|
27316
|
+
addCellToLayer(cell, layerId, options = {}) {
|
|
27317
|
+
const targetLayer = this.get(layerId);
|
|
27318
|
+
if (!targetLayer) {
|
|
27319
|
+
throw new Error(`dia.GraphLayerCollection: layer "${layerId}" does not exist.`);
|
|
27320
|
+
}
|
|
27321
|
+
const addOptions = {
|
|
27322
|
+
...options,
|
|
27323
|
+
toLayer: targetLayer.id
|
|
27324
|
+
};
|
|
27325
|
+
// Add the cell to the target layer collection
|
|
27326
|
+
targetLayer.cellCollection.add(cell, addOptions);
|
|
27327
|
+
}
|
|
27328
|
+
});
|
|
27329
|
+
Object.defineProperty(GraphLayerCollection.prototype, GRAPH_LAYER_COLLECTION_MARKER, {
|
|
27330
|
+
value: true
|
|
27331
|
+
});
|
|
27332
|
+
|
|
27333
|
+
/**
|
|
27334
|
+
* @class GraphTopologyIndex
|
|
27335
|
+
* @description Maintains an index of the graph topology (adjacency list)
|
|
27336
|
+
* for fast graph queries.
|
|
27337
|
+
*/
|
|
27338
|
+
class GraphTopologyIndex extends Listener {
|
|
27339
|
+
constructor(options) {
|
|
27340
|
+
super(options);
|
|
27341
|
+
|
|
27342
|
+
// Make sure there are no arguments passed to the callbacks.
|
|
27343
|
+
// See the `mvc.Listener` documentation for more details.
|
|
27344
|
+
this.callbackArguments = [];
|
|
27345
|
+
this.layerCollection = options.layerCollection;
|
|
27346
|
+
if (!this.layerCollection) {
|
|
27347
|
+
throw new Error('GraphTopologyIndex: "layerCollection" option is required.');
|
|
27348
|
+
}
|
|
27349
|
+
this.initializeIndex();
|
|
27350
|
+
this.startListening();
|
|
27351
|
+
}
|
|
27352
|
+
|
|
27353
|
+
/**
|
|
27354
|
+
* @public
|
|
27355
|
+
* @description Start listening to graph and layer collection events
|
|
27356
|
+
* to maintain the topology index.
|
|
27357
|
+
*/
|
|
27358
|
+
startListening() {
|
|
27359
|
+
this.listenTo(this.layerCollection.graph, {
|
|
27360
|
+
'add': this._restructureOnAdd,
|
|
27361
|
+
'remove': this._restructureOnRemove,
|
|
27362
|
+
'reset': this._restructureOnReset
|
|
27363
|
+
});
|
|
27364
|
+
// Listening to the collection instead of the graph
|
|
27365
|
+
// to avoid reacting to graph attribute change events
|
|
27366
|
+
// e.g. graph.set('source', ...);
|
|
27367
|
+
this.listenTo(this.layerCollection, {
|
|
27368
|
+
'change:source': this._restructureOnChangeSource,
|
|
27369
|
+
'change:target': this._restructureOnChangeTarget
|
|
27370
|
+
});
|
|
27371
|
+
}
|
|
27372
|
+
|
|
27373
|
+
/**
|
|
27374
|
+
* @protected
|
|
27375
|
+
* @description Initialize the internal data structures.
|
|
27376
|
+
*/
|
|
27377
|
+
initializeIndex() {
|
|
26759
27378
|
// Outgoing edges per node. Note that we use a hash-table for the list
|
|
26760
27379
|
// of outgoing edges for a faster lookup.
|
|
26761
27380
|
// [nodeId] -> Object [edgeId] -> true
|
|
@@ -26771,21 +27390,27 @@ var joint = (function (exports) {
|
|
|
26771
27390
|
// having to go through the whole cells array.
|
|
26772
27391
|
// [edgeId] -> true
|
|
26773
27392
|
this._edges = {};
|
|
26774
|
-
|
|
26775
|
-
|
|
26776
|
-
|
|
26777
|
-
|
|
26778
|
-
|
|
26779
|
-
|
|
26780
|
-
|
|
26781
|
-
|
|
26782
|
-
|
|
26783
|
-
this.
|
|
26784
|
-
}
|
|
26785
|
-
|
|
27393
|
+
}
|
|
27394
|
+
|
|
27395
|
+
/**
|
|
27396
|
+
* @protected
|
|
27397
|
+
* @description Restructure the topology index on graph reset.
|
|
27398
|
+
* E.g. when fromJSON or resetCells is called.
|
|
27399
|
+
*/
|
|
27400
|
+
_restructureOnReset() {
|
|
27401
|
+
this.initializeIndex();
|
|
27402
|
+
this.layerCollection.getCells().forEach(this._restructureOnAdd, this);
|
|
27403
|
+
}
|
|
27404
|
+
|
|
27405
|
+
/**
|
|
27406
|
+
* @protected
|
|
27407
|
+
* @description Restructure the topology index on cell addition.
|
|
27408
|
+
* @param {dia.Cell} cell - The cell being added.
|
|
27409
|
+
*/
|
|
27410
|
+
_restructureOnAdd(cell) {
|
|
26786
27411
|
if (cell.isLink()) {
|
|
26787
27412
|
this._edges[cell.id] = true;
|
|
26788
|
-
|
|
27413
|
+
const {
|
|
26789
27414
|
source,
|
|
26790
27415
|
target
|
|
26791
27416
|
} = cell.attributes;
|
|
@@ -26798,11 +27423,17 @@ var joint = (function (exports) {
|
|
|
26798
27423
|
} else {
|
|
26799
27424
|
this._nodes[cell.id] = true;
|
|
26800
27425
|
}
|
|
26801
|
-
}
|
|
26802
|
-
|
|
27426
|
+
}
|
|
27427
|
+
|
|
27428
|
+
/**
|
|
27429
|
+
* @protected
|
|
27430
|
+
* @description Restructure the topology index on cell removal.
|
|
27431
|
+
* @param {dia.Cell} cell - The cell being removed.
|
|
27432
|
+
*/
|
|
27433
|
+
_restructureOnRemove(cell) {
|
|
26803
27434
|
if (cell.isLink()) {
|
|
26804
27435
|
delete this._edges[cell.id];
|
|
26805
|
-
|
|
27436
|
+
const {
|
|
26806
27437
|
source,
|
|
26807
27438
|
target
|
|
26808
27439
|
} = cell.attributes;
|
|
@@ -26815,89 +27446,222 @@ var joint = (function (exports) {
|
|
|
26815
27446
|
} else {
|
|
26816
27447
|
delete this._nodes[cell.id];
|
|
26817
27448
|
}
|
|
26818
|
-
}
|
|
26819
|
-
|
|
26820
|
-
|
|
26821
|
-
|
|
26822
|
-
|
|
26823
|
-
|
|
26824
|
-
|
|
26825
|
-
|
|
26826
|
-
|
|
26827
|
-
},
|
|
26828
|
-
_restructureOnChangeSource: function (link) {
|
|
26829
|
-
var prevSource = link.previous('source');
|
|
27449
|
+
}
|
|
27450
|
+
|
|
27451
|
+
/**
|
|
27452
|
+
* @protected
|
|
27453
|
+
* @description Restructure the topology index on link source change.
|
|
27454
|
+
* @param {dia.Link} link - The link being changed.
|
|
27455
|
+
*/
|
|
27456
|
+
_restructureOnChangeSource(link) {
|
|
27457
|
+
const prevSource = link.previous('source');
|
|
26830
27458
|
if (prevSource.id && this._out[prevSource.id]) {
|
|
26831
27459
|
delete this._out[prevSource.id][link.id];
|
|
26832
27460
|
}
|
|
26833
|
-
|
|
27461
|
+
const source = link.attributes.source;
|
|
26834
27462
|
if (source.id) {
|
|
26835
27463
|
(this._out[source.id] || (this._out[source.id] = {}))[link.id] = true;
|
|
26836
27464
|
}
|
|
26837
|
-
}
|
|
26838
|
-
|
|
26839
|
-
|
|
27465
|
+
}
|
|
27466
|
+
|
|
27467
|
+
/**
|
|
27468
|
+
* @protected
|
|
27469
|
+
* @description Restructure the topology index on link target change.
|
|
27470
|
+
* @param {dia.Link} link - The link being changed.
|
|
27471
|
+
*/
|
|
27472
|
+
_restructureOnChangeTarget(link) {
|
|
27473
|
+
const prevTarget = link.previous('target');
|
|
26840
27474
|
if (prevTarget.id && this._in[prevTarget.id]) {
|
|
26841
27475
|
delete this._in[prevTarget.id][link.id];
|
|
26842
27476
|
}
|
|
26843
|
-
|
|
27477
|
+
const target = link.get('target');
|
|
26844
27478
|
if (target.id) {
|
|
26845
27479
|
(this._in[target.id] || (this._in[target.id] = {}))[link.id] = true;
|
|
26846
27480
|
}
|
|
26847
|
-
}
|
|
26848
|
-
|
|
26849
|
-
|
|
26850
|
-
|
|
26851
|
-
|
|
26852
|
-
|
|
26853
|
-
|
|
26854
|
-
|
|
26855
|
-
|
|
26856
|
-
return this.
|
|
27481
|
+
}
|
|
27482
|
+
|
|
27483
|
+
/**
|
|
27484
|
+
* @public
|
|
27485
|
+
* @description Get all outbound edges for the node. Time complexity: O(1).
|
|
27486
|
+
* @param {string} nodeId - The id of the node.
|
|
27487
|
+
* @returns {Object} - An object of the form: [edgeId] -> true.
|
|
27488
|
+
*/
|
|
27489
|
+
getOutboundEdges(nodeId) {
|
|
27490
|
+
return this._out[nodeId] || {};
|
|
27491
|
+
}
|
|
27492
|
+
|
|
27493
|
+
/**
|
|
27494
|
+
* @public
|
|
27495
|
+
* @description Get all inbound edges for the node. Time complexity: O(1).
|
|
27496
|
+
* @param {string} nodeId - The id of the node.
|
|
27497
|
+
* @returns {Object} - An object of the form: [edgeId] -> true.
|
|
27498
|
+
*/
|
|
27499
|
+
getInboundEdges(nodeId) {
|
|
27500
|
+
return this._in[nodeId] || {};
|
|
27501
|
+
}
|
|
27502
|
+
|
|
27503
|
+
/**
|
|
27504
|
+
* @public
|
|
27505
|
+
* @description Get all sink nodes (leafs) in the graph. Time complexity: O(|V|).
|
|
27506
|
+
* @returns {string[]} - Array of node ids.
|
|
27507
|
+
*/
|
|
27508
|
+
getSinkNodes() {
|
|
27509
|
+
const sinks = [];
|
|
27510
|
+
for (const nodeId in this._nodes) {
|
|
27511
|
+
if (!this._out[nodeId] || isEmpty(this._out[nodeId])) {
|
|
27512
|
+
sinks.push(nodeId);
|
|
27513
|
+
}
|
|
27514
|
+
}
|
|
27515
|
+
return sinks;
|
|
27516
|
+
}
|
|
27517
|
+
|
|
27518
|
+
/**
|
|
27519
|
+
* @public
|
|
27520
|
+
* @description Get all source nodes (roots) in the graph. Time complexity: O(|V|).
|
|
27521
|
+
* @returns {string[]} - Array of node ids.
|
|
27522
|
+
*/
|
|
27523
|
+
getSourceNodes() {
|
|
27524
|
+
const sources = [];
|
|
27525
|
+
for (const nodeId in this._nodes) {
|
|
27526
|
+
if (!this._in[nodeId] || isEmpty(this._in[nodeId])) {
|
|
27527
|
+
sources.push(nodeId);
|
|
27528
|
+
}
|
|
27529
|
+
}
|
|
27530
|
+
return sources;
|
|
27531
|
+
}
|
|
27532
|
+
|
|
27533
|
+
/**
|
|
27534
|
+
* @public
|
|
27535
|
+
* @description Return `true` if `nodeId` is a source node (root). Time complexity: O(1).
|
|
27536
|
+
* @param {string} nodeId - The id of the node to check.
|
|
27537
|
+
* @returns {boolean}
|
|
27538
|
+
*/
|
|
27539
|
+
isSourceNode(nodeId) {
|
|
27540
|
+
return !this._in[nodeId] || isEmpty(this._in[nodeId]);
|
|
27541
|
+
}
|
|
27542
|
+
|
|
27543
|
+
/**
|
|
27544
|
+
* @public
|
|
27545
|
+
* @description Return `true` if `nodeId` is a sink node (leaf). Time complexity: O(1).
|
|
27546
|
+
* @param {string} nodeId - The id of the node to check.
|
|
27547
|
+
* @returns {boolean}
|
|
27548
|
+
*/
|
|
27549
|
+
isSinkNode(nodeId) {
|
|
27550
|
+
return !this._out[nodeId] || isEmpty(this._out[nodeId]);
|
|
27551
|
+
}
|
|
27552
|
+
}
|
|
27553
|
+
|
|
27554
|
+
// The ID of the default graph layer.
|
|
27555
|
+
const DEFAULT_LAYER_ID = 'cells';
|
|
27556
|
+
const Graph = Model.extend({
|
|
27557
|
+
/**
|
|
27558
|
+
* @todo Remove in v5.0.0
|
|
27559
|
+
* @description In legacy mode, the information about layers is not
|
|
27560
|
+
* exported into JSON.
|
|
27561
|
+
*/
|
|
27562
|
+
legacyMode: true,
|
|
27563
|
+
/**
|
|
27564
|
+
* @protected
|
|
27565
|
+
* @description The ID of the default layer.
|
|
27566
|
+
*/
|
|
27567
|
+
defaultLayerId: DEFAULT_LAYER_ID,
|
|
27568
|
+
initialize: function (attrs, options = {}) {
|
|
27569
|
+
const layerCollection = this.layerCollection = new GraphLayerCollection([], {
|
|
27570
|
+
layerNamespace: options.layerNamespace,
|
|
27571
|
+
cellNamespace: options.cellNamespace,
|
|
27572
|
+
graph: this,
|
|
27573
|
+
/** @deprecated use cellNamespace instead */
|
|
27574
|
+
model: options.cellModel
|
|
27575
|
+
});
|
|
27576
|
+
|
|
27577
|
+
// The default setup includes a single default layer.
|
|
27578
|
+
layerCollection.add({
|
|
27579
|
+
id: DEFAULT_LAYER_ID
|
|
27580
|
+
}, {
|
|
27581
|
+
graph: this.cid
|
|
27582
|
+
});
|
|
27583
|
+
|
|
27584
|
+
/**
|
|
27585
|
+
* @todo Remove in v5.0.0
|
|
27586
|
+
* @description Retain legacy 'cells' collection in attributes for backward compatibility.
|
|
27587
|
+
* Applicable only when the default layer setup is used.
|
|
27588
|
+
*/
|
|
27589
|
+
this.attributes.cells = this.getLayer(DEFAULT_LAYER_ID).cellCollection;
|
|
27590
|
+
|
|
27591
|
+
// Controller that manages communication between the graph and its layers.
|
|
27592
|
+
this.layersController = new GraphLayersController({
|
|
27593
|
+
graph: this
|
|
27594
|
+
});
|
|
27595
|
+
|
|
27596
|
+
// `Graph` keeps an internal data structure (an adjacency list)
|
|
27597
|
+
// for fast graph queries. All changes that affect the structure of the graph
|
|
27598
|
+
// must be reflected in the `al` object. This object provides fast answers to
|
|
27599
|
+
// questions such as "what are the neighbors of this node" or "what
|
|
27600
|
+
// are the sibling links of this link".
|
|
27601
|
+
this.topologyIndex = new GraphTopologyIndex({
|
|
27602
|
+
layerCollection
|
|
27603
|
+
});
|
|
27604
|
+
this._batches = {};
|
|
26857
27605
|
},
|
|
26858
27606
|
toJSON: function (opt = {}) {
|
|
26859
|
-
|
|
26860
|
-
|
|
26861
|
-
|
|
26862
|
-
|
|
27607
|
+
const {
|
|
27608
|
+
layerCollection
|
|
27609
|
+
} = this;
|
|
27610
|
+
// Get the graph model attributes as a base JSON.
|
|
27611
|
+
const json = Model.prototype.toJSON.apply(this, arguments);
|
|
27612
|
+
|
|
27613
|
+
// Add `cells` array holding all the cells in the graph.
|
|
27614
|
+
json.cells = this.getCells().map(cell => cell.toJSON(opt.cellAttributes));
|
|
27615
|
+
if (this.legacyMode) {
|
|
27616
|
+
// Backwards compatibility for legacy setup
|
|
27617
|
+
// with single default layer 'cells'.
|
|
27618
|
+
// In this case, we do not need to export layers.
|
|
27619
|
+
return json;
|
|
27620
|
+
}
|
|
27621
|
+
|
|
27622
|
+
// Add `layers` array holding all the layers in the graph.
|
|
27623
|
+
json.layers = layerCollection.toJSON();
|
|
27624
|
+
|
|
27625
|
+
// Add `defaultLayer` property indicating the default layer ID.
|
|
27626
|
+
json.defaultLayer = this.defaultLayerId;
|
|
26863
27627
|
return json;
|
|
26864
27628
|
},
|
|
26865
27629
|
fromJSON: function (json, opt) {
|
|
26866
|
-
|
|
27630
|
+
const {
|
|
27631
|
+
cells,
|
|
27632
|
+
layers,
|
|
27633
|
+
defaultLayer,
|
|
27634
|
+
...attributes
|
|
27635
|
+
} = json;
|
|
27636
|
+
if (!cells) {
|
|
26867
27637
|
throw new Error('Graph JSON must contain cells array.');
|
|
26868
27638
|
}
|
|
26869
|
-
return this.set(json, opt);
|
|
26870
|
-
},
|
|
26871
|
-
set: function (key, val, opt) {
|
|
26872
|
-
var attrs;
|
|
26873
27639
|
|
|
26874
|
-
//
|
|
26875
|
-
|
|
26876
|
-
|
|
26877
|
-
|
|
26878
|
-
}
|
|
26879
|
-
|
|
27640
|
+
// The `fromJSON` should trigger a single 'reset' event at the end.
|
|
27641
|
+
// Set all attributes silently for now.
|
|
27642
|
+
this.set(attributes, {
|
|
27643
|
+
silent: true
|
|
27644
|
+
});
|
|
27645
|
+
if (layers) {
|
|
27646
|
+
// Reset the layers collection
|
|
27647
|
+
// (`layers:reset` is not forwarded to the graph).
|
|
27648
|
+
this._resetLayers(layers, defaultLayer, opt);
|
|
26880
27649
|
}
|
|
26881
|
-
|
|
26882
|
-
|
|
26883
|
-
|
|
26884
|
-
this.resetCells(attrs.cells, opt);
|
|
26885
|
-
attrs = omit(attrs, 'cells');
|
|
27650
|
+
if (cells) {
|
|
27651
|
+
// Reset the cells collection and trigger the 'reset' event.
|
|
27652
|
+
this.resetCells(cells, opt);
|
|
26886
27653
|
}
|
|
26887
|
-
|
|
26888
|
-
// The rest of the attributes are applied via original set method.
|
|
26889
|
-
return Model.prototype.set.call(this, attrs, opt);
|
|
27654
|
+
return this;
|
|
26890
27655
|
},
|
|
27656
|
+
/** @deprecated */
|
|
26891
27657
|
clear: function (opt) {
|
|
26892
27658
|
opt = assign({}, opt, {
|
|
26893
27659
|
clear: true
|
|
26894
27660
|
});
|
|
26895
|
-
|
|
26896
|
-
if (
|
|
27661
|
+
const cells = this.getCells();
|
|
27662
|
+
if (cells.length === 0) return this;
|
|
26897
27663
|
this.startBatch('clear', opt);
|
|
26898
|
-
|
|
26899
|
-
// The elements come after the links.
|
|
26900
|
-
var cells = collection.sortBy(function (cell) {
|
|
27664
|
+
const sortedCells = sortBy(cells, cell => {
|
|
26901
27665
|
return cell.isLink() ? 1 : 2;
|
|
26902
27666
|
});
|
|
26903
27667
|
do {
|
|
@@ -26905,43 +27669,56 @@ var joint = (function (exports) {
|
|
|
26905
27669
|
// Note that all the links are removed first, so it's
|
|
26906
27670
|
// safe to remove the elements without removing the connected
|
|
26907
27671
|
// links first.
|
|
26908
|
-
|
|
26909
|
-
} while (
|
|
27672
|
+
this.layerCollection.removeCell(sortedCells.shift(), opt);
|
|
27673
|
+
} while (sortedCells.length > 0);
|
|
26910
27674
|
this.stopBatch('clear');
|
|
26911
27675
|
return this;
|
|
26912
27676
|
},
|
|
26913
|
-
_prepareCell: function (
|
|
26914
|
-
let
|
|
26915
|
-
if (
|
|
26916
|
-
|
|
27677
|
+
_prepareCell: function (cellInit, opt) {
|
|
27678
|
+
let cellAttributes;
|
|
27679
|
+
if (cellInit[CELL_MARKER]) {
|
|
27680
|
+
cellAttributes = cellInit.attributes;
|
|
26917
27681
|
} else {
|
|
26918
|
-
|
|
27682
|
+
cellAttributes = cellInit;
|
|
26919
27683
|
}
|
|
26920
|
-
if (!isString(
|
|
27684
|
+
if (!isString(cellAttributes.type)) {
|
|
26921
27685
|
throw new TypeError('dia.Graph: cell type must be a string.');
|
|
26922
27686
|
}
|
|
26923
|
-
|
|
27687
|
+
|
|
27688
|
+
// Backward compatibility: prior v4.2, z-index was not set during reset.
|
|
27689
|
+
if (opt && opt.ensureZIndex) {
|
|
27690
|
+
if (cellAttributes.z === undefined) {
|
|
27691
|
+
const layerId = cellAttributes[config$3.layerAttribute] || this.defaultLayerId;
|
|
27692
|
+
const zIndex = this.maxZIndex(layerId) + 1;
|
|
27693
|
+
if (cellInit[CELL_MARKER]) {
|
|
27694
|
+
// Set with event in case there is a listener
|
|
27695
|
+
// directly on the cell instance
|
|
27696
|
+
// (the cell is not part of graph yet)
|
|
27697
|
+
cellInit.set('z', zIndex, opt);
|
|
27698
|
+
} else {
|
|
27699
|
+
cellAttributes.z = zIndex;
|
|
27700
|
+
}
|
|
27701
|
+
}
|
|
27702
|
+
}
|
|
27703
|
+
return cellInit;
|
|
26924
27704
|
},
|
|
26925
|
-
minZIndex: function () {
|
|
26926
|
-
|
|
26927
|
-
return
|
|
27705
|
+
minZIndex: function (layerId = this.defaultLayerId) {
|
|
27706
|
+
const layer = this.getLayer(layerId);
|
|
27707
|
+
return layer.cellCollection.minZIndex();
|
|
26928
27708
|
},
|
|
26929
|
-
maxZIndex: function () {
|
|
26930
|
-
|
|
26931
|
-
return
|
|
27709
|
+
maxZIndex: function (layerId = this.defaultLayerId) {
|
|
27710
|
+
const layer = this.getLayer(layerId);
|
|
27711
|
+
return layer.cellCollection.maxZIndex();
|
|
26932
27712
|
},
|
|
26933
|
-
addCell: function (
|
|
26934
|
-
if (Array.isArray(
|
|
26935
|
-
return this.addCells(
|
|
27713
|
+
addCell: function (cellInit, options) {
|
|
27714
|
+
if (Array.isArray(cellInit)) {
|
|
27715
|
+
return this.addCells(cellInit, options);
|
|
26936
27716
|
}
|
|
26937
|
-
|
|
26938
|
-
|
|
26939
|
-
|
|
26940
|
-
|
|
26941
|
-
|
|
26942
|
-
cell.z = this.maxZIndex() + 1;
|
|
26943
|
-
}
|
|
26944
|
-
this.get('cells').add(this._prepareCell(cell, opt), opt || {});
|
|
27717
|
+
this._prepareCell(cellInit, {
|
|
27718
|
+
...options,
|
|
27719
|
+
ensureZIndex: true
|
|
27720
|
+
});
|
|
27721
|
+
this.layerCollection.addCellToLayer(cellInit, this.getCellLayerId(cellInit), options);
|
|
26945
27722
|
return this;
|
|
26946
27723
|
},
|
|
26947
27724
|
addCells: function (cells, opt) {
|
|
@@ -26949,50 +27726,278 @@ var joint = (function (exports) {
|
|
|
26949
27726
|
cells = flattenDeep(cells);
|
|
26950
27727
|
opt.maxPosition = opt.position = cells.length - 1;
|
|
26951
27728
|
this.startBatch('add', opt);
|
|
26952
|
-
cells.forEach(
|
|
27729
|
+
cells.forEach(cell => {
|
|
26953
27730
|
this.addCell(cell, opt);
|
|
26954
27731
|
opt.position--;
|
|
26955
|
-
}
|
|
27732
|
+
});
|
|
26956
27733
|
this.stopBatch('add', opt);
|
|
26957
27734
|
return this;
|
|
26958
27735
|
},
|
|
26959
|
-
|
|
26960
|
-
|
|
26961
|
-
|
|
26962
|
-
|
|
26963
|
-
|
|
26964
|
-
|
|
26965
|
-
|
|
26966
|
-
|
|
27736
|
+
/**
|
|
27737
|
+
* @public
|
|
27738
|
+
* @description Reset the cells in the graph.
|
|
27739
|
+
* Useful for bulk operations and optimizations.
|
|
27740
|
+
*/
|
|
27741
|
+
resetCells: function (cellInits, options) {
|
|
27742
|
+
const {
|
|
27743
|
+
layerCollection
|
|
27744
|
+
} = this;
|
|
27745
|
+
// Note: `cellInits` is always an array and `options` is always an object.
|
|
27746
|
+
// See `wrappers.cells` at the end of this file.
|
|
27747
|
+
|
|
27748
|
+
// When resetting cells, do not set z-index if not provided.
|
|
27749
|
+
const prepareOptions = {
|
|
27750
|
+
...options,
|
|
27751
|
+
ensureZIndex: false
|
|
27752
|
+
};
|
|
27753
|
+
|
|
27754
|
+
// Initialize a map of layer IDs to arrays of cells
|
|
27755
|
+
const layerCellsMap = layerCollection.reduce((map, layer) => {
|
|
27756
|
+
map[layer.id] = [];
|
|
27757
|
+
return map;
|
|
27758
|
+
}, {});
|
|
27759
|
+
|
|
27760
|
+
// Distribute cells into their respective layers
|
|
27761
|
+
for (let i = 0; i < cellInits.length; i++) {
|
|
27762
|
+
const cellInit = cellInits[i];
|
|
27763
|
+
const layerId = this.getCellLayerId(cellInit);
|
|
27764
|
+
if (layerId in layerCellsMap) {
|
|
27765
|
+
this._prepareCell(cellInit, prepareOptions);
|
|
27766
|
+
layerCellsMap[layerId].push(cellInit);
|
|
27767
|
+
} else {
|
|
27768
|
+
throw new Error(`dia.Graph: Layer "${layerId}" does not exist.`);
|
|
27769
|
+
}
|
|
27770
|
+
}
|
|
27771
|
+
|
|
27772
|
+
// Reset each layer's cell collection with the corresponding cells.
|
|
27773
|
+
layerCollection.each(layer => {
|
|
27774
|
+
layer.cellCollection.reset(layerCellsMap[layer.id], options);
|
|
27775
|
+
});
|
|
27776
|
+
|
|
27777
|
+
// Trigger a single `reset` event on the graph
|
|
27778
|
+
// (while multiple `reset` events are triggered on layers).
|
|
27779
|
+
// Backwards compatibility: use default layer collection
|
|
27780
|
+
// The `collection` parameter is retained for backwards compatibility,
|
|
27781
|
+
// and it is subject to removal in future releases.
|
|
27782
|
+
this.trigger('reset', this.getDefaultLayer().cellCollection, options);
|
|
26967
27783
|
return this;
|
|
26968
27784
|
},
|
|
26969
|
-
|
|
26970
|
-
|
|
26971
|
-
|
|
26972
|
-
|
|
26973
|
-
|
|
27785
|
+
/**
|
|
27786
|
+
* @public
|
|
27787
|
+
* @description Get the layer ID in which the cell resides.
|
|
27788
|
+
* Cells without an explicit layer are assigned to the default layer.
|
|
27789
|
+
* @param {dia.Cell | Object} cellInit - Cell model or attributes.
|
|
27790
|
+
* @returns {string} - The layer ID.
|
|
27791
|
+
*/
|
|
27792
|
+
getCellLayerId: function (cellInit) {
|
|
27793
|
+
if (!cellInit) {
|
|
27794
|
+
throw new Error('dia.Graph: No cell provided.');
|
|
27795
|
+
}
|
|
27796
|
+
const cellAttributes = cellInit[CELL_MARKER] ? cellInit.attributes : cellInit;
|
|
27797
|
+
return cellAttributes[config$3.layerAttribute] || this.defaultLayerId;
|
|
27798
|
+
},
|
|
27799
|
+
/**
|
|
27800
|
+
* @protected
|
|
27801
|
+
* @description Reset the layers in the graph.
|
|
27802
|
+
* It assumes the existing cells have been removed beforehand
|
|
27803
|
+
* or can be discarded.
|
|
27804
|
+
*/
|
|
27805
|
+
_resetLayers: function (layers, defaultLayerId, options = {}) {
|
|
27806
|
+
if (!Array.isArray(layers) || layers.length === 0) {
|
|
27807
|
+
throw new Error('dia.Graph: At least one layer must be defined.');
|
|
27808
|
+
}
|
|
27809
|
+
|
|
27810
|
+
// Resetting layers disables legacy mode
|
|
27811
|
+
this.legacyMode = false;
|
|
27812
|
+
this.layerCollection.reset(layers, {
|
|
27813
|
+
...options,
|
|
27814
|
+
graph: this.cid
|
|
27815
|
+
});
|
|
27816
|
+
|
|
27817
|
+
// If no default layer is specified, use the first layer as default
|
|
27818
|
+
if (defaultLayerId) {
|
|
27819
|
+
// The default layer must be one of the defined layers
|
|
27820
|
+
if (!this.hasLayer(defaultLayerId)) {
|
|
27821
|
+
throw new Error(`dia.Graph: default layer "${defaultLayerId}" does not exist.`);
|
|
27822
|
+
}
|
|
27823
|
+
this.defaultLayerId = defaultLayerId;
|
|
27824
|
+
} else {
|
|
27825
|
+
this.defaultLayerId = this.layerCollection.at(0).id;
|
|
26974
27826
|
}
|
|
26975
27827
|
return this;
|
|
26976
27828
|
},
|
|
26977
|
-
|
|
26978
|
-
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
|
|
27829
|
+
/**
|
|
27830
|
+
* @public
|
|
27831
|
+
* @description Remove multiple cells from the graph.
|
|
27832
|
+
* @param {Array<dia.Cell | dia.Cell.ID>} cellRefs - Array of cell references (models or IDs) to remove.
|
|
27833
|
+
* @param {Object} [options] - Removal options. See {@link dia.Graph#removeCell}.
|
|
27834
|
+
*/
|
|
27835
|
+
removeCells: function (cellRefs, options) {
|
|
27836
|
+
if (!cellRefs.length) return this;
|
|
27837
|
+
// Remove multiple cells in a single batch
|
|
27838
|
+
this.startBatch('remove');
|
|
27839
|
+
for (const cellRef of cellRefs) {
|
|
27840
|
+
if (!cellRef) continue;
|
|
27841
|
+
let cell;
|
|
27842
|
+
if (cellRef[CELL_MARKER]) {
|
|
27843
|
+
cell = cellRef;
|
|
26985
27844
|
} else {
|
|
26986
|
-
this.
|
|
27845
|
+
cell = this.getCell(cellRef);
|
|
27846
|
+
if (!cell) {
|
|
27847
|
+
// The cell might have been already removed (embedded cell, connected link, etc.)
|
|
27848
|
+
continue;
|
|
27849
|
+
}
|
|
26987
27850
|
}
|
|
27851
|
+
this.layerCollection.removeCell(cell, options);
|
|
26988
27852
|
}
|
|
26989
|
-
|
|
26990
|
-
|
|
26991
|
-
|
|
26992
|
-
|
|
26993
|
-
|
|
26994
|
-
|
|
26995
|
-
|
|
27853
|
+
this.stopBatch('remove');
|
|
27854
|
+
return this;
|
|
27855
|
+
},
|
|
27856
|
+
/**
|
|
27857
|
+
* @protected
|
|
27858
|
+
* @description Replace an existing cell with a new cell.
|
|
27859
|
+
*/
|
|
27860
|
+
_replaceCell: function (currentCell, newCellInit, opt = {}) {
|
|
27861
|
+
const batchName = 'replace-cell';
|
|
27862
|
+
const replaceOptions = {
|
|
27863
|
+
...opt,
|
|
27864
|
+
replace: true
|
|
27865
|
+
};
|
|
27866
|
+
this.startBatch(batchName, opt);
|
|
27867
|
+
// 1. Remove the cell without removing connected links or embedded cells.
|
|
27868
|
+
this.layerCollection.removeCell(currentCell, replaceOptions);
|
|
27869
|
+
const newCellInitAttributes = newCellInit[CELL_MARKER] ? newCellInit.attributes : newCellInit;
|
|
27870
|
+
// 2. Combine the current cell attributes with the new cell attributes
|
|
27871
|
+
const replacementCellAttributes = Object.assign({}, currentCell.attributes, newCellInitAttributes);
|
|
27872
|
+
let replacement;
|
|
27873
|
+
if (newCellInit[CELL_MARKER]) {
|
|
27874
|
+
// If the new cell is a model, set the merged attributes on the model
|
|
27875
|
+
newCellInit.set(replacementCellAttributes, replaceOptions);
|
|
27876
|
+
replacement = newCellInit;
|
|
27877
|
+
} else {
|
|
27878
|
+
replacement = replacementCellAttributes;
|
|
27879
|
+
}
|
|
27880
|
+
|
|
27881
|
+
// 3. Add the replacement cell
|
|
27882
|
+
this.addCell(replacement, replaceOptions);
|
|
27883
|
+
this.stopBatch(batchName);
|
|
27884
|
+
},
|
|
27885
|
+
/**
|
|
27886
|
+
* @protected
|
|
27887
|
+
* @description Synchronize a single graph cell with the provided cell (model or attributes).
|
|
27888
|
+
* If the cell with the same `id` exists, it is updated. If the cell does not exist, it is added.
|
|
27889
|
+
* If the existing cell type is different from the incoming cell type, the existing cell is replaced.
|
|
27890
|
+
*/
|
|
27891
|
+
_syncCell: function (cellInit, opt = {}) {
|
|
27892
|
+
const cellAttributes = cellInit[CELL_MARKER] ? cellInit.attributes : cellInit;
|
|
27893
|
+
const currentCell = this.getCell(cellInit.id);
|
|
27894
|
+
if (currentCell) {
|
|
27895
|
+
// `cellInit` is either a model or attributes object
|
|
27896
|
+
if ('type' in cellAttributes && currentCell.get('type') !== cellAttributes.type) {
|
|
27897
|
+
// Replace the cell if the type has changed
|
|
27898
|
+
this._replaceCell(currentCell, cellInit, opt);
|
|
27899
|
+
} else {
|
|
27900
|
+
// Update existing cell
|
|
27901
|
+
// Note: the existing cell attributes are not removed,
|
|
27902
|
+
// if they're missing in `cellAttributes`.
|
|
27903
|
+
currentCell.set(cellAttributes, opt);
|
|
27904
|
+
}
|
|
27905
|
+
} else {
|
|
27906
|
+
// The cell does not exist yet, add it
|
|
27907
|
+
this.addCell(cellInit, opt);
|
|
27908
|
+
}
|
|
27909
|
+
},
|
|
27910
|
+
/**
|
|
27911
|
+
* @public
|
|
27912
|
+
* @description Synchronize the graph cells with the provided array of cells (models or attributes).
|
|
27913
|
+
*/
|
|
27914
|
+
syncCells: function (cellInits, opt = {}) {
|
|
27915
|
+
const batchName = 'sync-cells';
|
|
27916
|
+
const {
|
|
27917
|
+
remove = false,
|
|
27918
|
+
...setOpt
|
|
27919
|
+
} = opt;
|
|
27920
|
+
let currentCells, newCellsMap;
|
|
27921
|
+
if (remove) {
|
|
27922
|
+
// We need to track existing cells to remove the missing ones later
|
|
27923
|
+
currentCells = this.getCells();
|
|
27924
|
+
newCellsMap = new Map();
|
|
27925
|
+
}
|
|
27926
|
+
|
|
27927
|
+
// Observe changes to the graph cells
|
|
27928
|
+
let changeObserver, changedLayers;
|
|
27929
|
+
const shouldSort = opt.sort !== false;
|
|
27930
|
+
if (shouldSort) {
|
|
27931
|
+
changeObserver = new Listener();
|
|
27932
|
+
changedLayers = new Set();
|
|
27933
|
+
changeObserver.listenTo(this, {
|
|
27934
|
+
'add': cell => {
|
|
27935
|
+
changedLayers.add(this.getCellLayerId(cell));
|
|
27936
|
+
},
|
|
27937
|
+
'change': cell => {
|
|
27938
|
+
if (cell.hasChanged(config$3.layerAttribute) || cell.hasChanged('z')) {
|
|
27939
|
+
changedLayers.add(this.getCellLayerId(cell));
|
|
27940
|
+
}
|
|
27941
|
+
}
|
|
27942
|
+
});
|
|
27943
|
+
}
|
|
27944
|
+
this.startBatch(batchName, opt);
|
|
27945
|
+
|
|
27946
|
+
// Prevent multiple sorts during sync
|
|
27947
|
+
setOpt.sort = false;
|
|
27948
|
+
|
|
27949
|
+
// Add or update incoming cells
|
|
27950
|
+
for (const cellInit of cellInits) {
|
|
27951
|
+
if (remove) {
|
|
27952
|
+
// only track existence
|
|
27953
|
+
newCellsMap.set(cellInit.id, true);
|
|
27954
|
+
}
|
|
27955
|
+
this._syncCell(cellInit, setOpt);
|
|
27956
|
+
}
|
|
27957
|
+
if (remove) {
|
|
27958
|
+
// Remove cells not present in the incoming array
|
|
27959
|
+
for (const cell of currentCells) {
|
|
27960
|
+
if (!newCellsMap.has(cell.id)) {
|
|
27961
|
+
this.layerCollection.removeCell(cell, setOpt);
|
|
27962
|
+
}
|
|
27963
|
+
}
|
|
27964
|
+
}
|
|
27965
|
+
if (shouldSort) {
|
|
27966
|
+
// Sort layers that had changes affecting z-index or layer
|
|
27967
|
+
changeObserver.stopListening();
|
|
27968
|
+
for (const layerId of changedLayers) {
|
|
27969
|
+
this.getLayer(layerId).cellCollection.sort(opt);
|
|
27970
|
+
}
|
|
27971
|
+
}
|
|
27972
|
+
this.stopBatch(batchName);
|
|
27973
|
+
},
|
|
27974
|
+
/**
|
|
27975
|
+
* @public
|
|
27976
|
+
* @description Remove a cell from the graph.
|
|
27977
|
+
* @param {dia.Cell} cell
|
|
27978
|
+
* @param {Object} [options]
|
|
27979
|
+
* @param {boolean} [options.disconnectLinks=false] - If `true`, the connected links are
|
|
27980
|
+
* disconnected instead of removed.
|
|
27981
|
+
* @param {boolean} [options.clear=false] - If `true`, the connected links
|
|
27982
|
+
* are kept. @internal
|
|
27983
|
+
* @param {boolean} [options.replace=false] - If `true`, the connected links and
|
|
27984
|
+
* embedded cells are kept. @internal
|
|
27985
|
+
* @throws Will throw an error if no cell is provided
|
|
27986
|
+
* @throws Will throw an error if the ID of the cell to remove
|
|
27987
|
+
* does not exist in the graph
|
|
27988
|
+
**/
|
|
27989
|
+
removeCell: function (cellRef, options) {
|
|
27990
|
+
if (!cellRef) {
|
|
27991
|
+
throw new Error('dia.Graph: no cell provided.');
|
|
27992
|
+
}
|
|
27993
|
+
const cell = cellRef[CELL_MARKER] ? cellRef : this.getCell(cellRef);
|
|
27994
|
+
if (!cell) {
|
|
27995
|
+
throw new Error('dia.Graph: cell to remove does not exist in the graph.');
|
|
27996
|
+
}
|
|
27997
|
+
if (cell.graph !== this) return;
|
|
27998
|
+
this.startBatch('remove');
|
|
27999
|
+
cell.collection.remove(cell, options);
|
|
28000
|
+
this.stopBatch('remove');
|
|
26996
28001
|
},
|
|
26997
28002
|
transferCellEmbeds: function (sourceCell, targetCell, opt = {}) {
|
|
26998
28003
|
const batchName = 'transfer-embeds';
|
|
@@ -27022,24 +28027,249 @@ var joint = (function (exports) {
|
|
|
27022
28027
|
});
|
|
27023
28028
|
this.stopBatch(batchName);
|
|
27024
28029
|
},
|
|
27025
|
-
|
|
27026
|
-
|
|
27027
|
-
|
|
28030
|
+
/**
|
|
28031
|
+
* @private
|
|
28032
|
+
* Helper method for addLayer and moveLayer methods
|
|
28033
|
+
*/
|
|
28034
|
+
_getBeforeLayerIdFromOptions(options, layer = null) {
|
|
28035
|
+
let {
|
|
28036
|
+
before = null,
|
|
28037
|
+
index
|
|
28038
|
+
} = options;
|
|
28039
|
+
if (before && index !== undefined) {
|
|
28040
|
+
throw new Error('dia.Graph: Options "before" and "index" are mutually exclusive.');
|
|
28041
|
+
}
|
|
28042
|
+
let computedBefore;
|
|
28043
|
+
if (index !== undefined) {
|
|
28044
|
+
const layersArray = this.getLayers();
|
|
28045
|
+
if (index >= layersArray.length) {
|
|
28046
|
+
// If index is greater than the number of layers,
|
|
28047
|
+
// return before as null (move to the end).
|
|
28048
|
+
computedBefore = null;
|
|
28049
|
+
} else if (index < 0) {
|
|
28050
|
+
// If index is negative, move to the beginning.
|
|
28051
|
+
computedBefore = layersArray[0].id;
|
|
28052
|
+
} else {
|
|
28053
|
+
var _layersArray$index;
|
|
28054
|
+
const originalIndex = layersArray.indexOf(layer);
|
|
28055
|
+
if (originalIndex !== -1 && index > originalIndex) {
|
|
28056
|
+
// If moving a layer upwards in the stack, we need to adjust the index
|
|
28057
|
+
// to account for the layer being removed from its original position.
|
|
28058
|
+
index += 1;
|
|
28059
|
+
}
|
|
28060
|
+
// Otherwise, get the layer ID at the specified index.
|
|
28061
|
+
computedBefore = ((_layersArray$index = layersArray[index]) === null || _layersArray$index === void 0 ? void 0 : _layersArray$index.id) || null;
|
|
28062
|
+
}
|
|
28063
|
+
} else {
|
|
28064
|
+
computedBefore = before;
|
|
28065
|
+
}
|
|
28066
|
+
return computedBefore;
|
|
28067
|
+
},
|
|
28068
|
+
/**
|
|
28069
|
+
* @public
|
|
28070
|
+
* Adds a new layer to the graph.
|
|
28071
|
+
* @param {GraphLayer | GraphLayerJSON} layerInit
|
|
28072
|
+
* @param {*} options
|
|
28073
|
+
* @param {string | null} [options.before] - ID of the layer
|
|
28074
|
+
* before which to insert the new layer. If `null`, the layer is added at the end.
|
|
28075
|
+
* @param {number} [options.index] - Zero-based index to which to add the layer.
|
|
28076
|
+
* @throws Will throw an error if the layer to add is invalid
|
|
28077
|
+
* @throws Will throw an error if a layer with the same ID already exists
|
|
28078
|
+
* @throws Will throw if `before` reference is invalid
|
|
28079
|
+
*/
|
|
28080
|
+
addLayer(layerInit, options = {}) {
|
|
28081
|
+
if (!layerInit || !layerInit.id) {
|
|
28082
|
+
throw new Error('dia.Graph: Layer to add is invalid.');
|
|
28083
|
+
}
|
|
28084
|
+
if (this.hasLayer(layerInit.id)) {
|
|
28085
|
+
throw new Error(`dia.Graph: Layer "${layerInit.id}" already exists.`);
|
|
28086
|
+
}
|
|
28087
|
+
const {
|
|
28088
|
+
before = null,
|
|
28089
|
+
index,
|
|
28090
|
+
...insertOptions
|
|
28091
|
+
} = options;
|
|
28092
|
+
insertOptions.graph = this.cid;
|
|
28093
|
+
|
|
28094
|
+
// Adding a new layer disables legacy mode
|
|
28095
|
+
this.legacyMode = false;
|
|
28096
|
+
const beforeId = this._getBeforeLayerIdFromOptions({
|
|
28097
|
+
before,
|
|
28098
|
+
index
|
|
28099
|
+
});
|
|
28100
|
+
this.layerCollection.insert(layerInit, beforeId, insertOptions);
|
|
28101
|
+
},
|
|
28102
|
+
/**
|
|
28103
|
+
* @public
|
|
28104
|
+
* Moves an existing layer to a new position in the layer stack.
|
|
28105
|
+
* @param {string | GraphLayer} layerRef - ID or reference of the layer to move.
|
|
28106
|
+
* @param {*} options
|
|
28107
|
+
* @param {string | null} [options.before] - ID of the layer
|
|
28108
|
+
* before which to insert the moved layer. If `null`, the layer is moved to the end.
|
|
28109
|
+
* @param {number} [options.index] - Zero-based index to which to move the layer.
|
|
28110
|
+
* @throws Will throw an error if the layer to move does not exist
|
|
28111
|
+
* @throws Will throw an error if `before` reference is invalid
|
|
28112
|
+
* @throws Will throw an error if both `before` and `index` options are provided
|
|
28113
|
+
*/
|
|
28114
|
+
moveLayer(layerRef, options = {}) {
|
|
28115
|
+
if (!layerRef || !this.hasLayer(layerRef)) {
|
|
28116
|
+
throw new Error('dia.Graph: Layer to move does not exist.');
|
|
28117
|
+
}
|
|
28118
|
+
const layer = this.getLayer(layerRef);
|
|
28119
|
+
const {
|
|
28120
|
+
before = null,
|
|
28121
|
+
index,
|
|
28122
|
+
...insertOptions
|
|
28123
|
+
} = options;
|
|
28124
|
+
insertOptions.graph = this.cid;
|
|
28125
|
+
|
|
28126
|
+
// Moving a layer disables legacy mode
|
|
28127
|
+
this.legacyMode = false;
|
|
28128
|
+
const beforeId = this._getBeforeLayerIdFromOptions({
|
|
28129
|
+
before,
|
|
28130
|
+
index
|
|
28131
|
+
}, layer);
|
|
28132
|
+
this.layerCollection.insert(layer, beforeId, insertOptions);
|
|
28133
|
+
},
|
|
28134
|
+
/**
|
|
28135
|
+
* @public
|
|
28136
|
+
* Removes an existing layer from the graph.
|
|
28137
|
+
* @param {string | GraphLayer} layerRef - ID or reference of the layer to remove.
|
|
28138
|
+
* @param {*} options
|
|
28139
|
+
* @throws Will throw an error if no layer is provided
|
|
28140
|
+
* @throws Will throw an error if the layer to remove does not exist
|
|
28141
|
+
*/
|
|
28142
|
+
removeLayer(layerRef, options = {}) {
|
|
28143
|
+
if (!layerRef) {
|
|
28144
|
+
throw new Error('dia.Graph: No layer provided.');
|
|
28145
|
+
}
|
|
28146
|
+
|
|
28147
|
+
// The layer must exist
|
|
28148
|
+
const layerId = layerRef.id ? layerRef.id : layerRef;
|
|
28149
|
+
const layer = this.getLayer(layerId);
|
|
28150
|
+
|
|
28151
|
+
// Prevent removing the default layer
|
|
28152
|
+
// Note: if there is only one layer, it is also the default layer.
|
|
28153
|
+
const {
|
|
28154
|
+
id: defaultLayerId
|
|
28155
|
+
} = this.getDefaultLayer();
|
|
28156
|
+
if (layerId === defaultLayerId) {
|
|
28157
|
+
throw new Error('dia.Graph: default layer cannot be removed.');
|
|
28158
|
+
}
|
|
28159
|
+
|
|
28160
|
+
// A layer with cells cannot be removed
|
|
28161
|
+
if (layer.cellCollection.length > 0) {
|
|
28162
|
+
throw new Error(`dia.Graph: Layer "${layerId}" cannot be removed because it is not empty.`);
|
|
28163
|
+
}
|
|
28164
|
+
this.layerCollection.remove(layerId, {
|
|
28165
|
+
...options,
|
|
28166
|
+
graph: this.cid
|
|
28167
|
+
});
|
|
28168
|
+
},
|
|
28169
|
+
getDefaultLayer() {
|
|
28170
|
+
return this.layerCollection.get(this.defaultLayerId);
|
|
28171
|
+
},
|
|
28172
|
+
setDefaultLayer(layerRef, options = {}) {
|
|
28173
|
+
if (!layerRef) {
|
|
28174
|
+
throw new Error('dia.Graph: No default layer ID provided.');
|
|
28175
|
+
}
|
|
28176
|
+
|
|
28177
|
+
// Make sure the layer exists
|
|
28178
|
+
const defaultLayerId = layerRef.id ? layerRef.id : layerRef;
|
|
28179
|
+
const defaultLayer = this.getLayer(defaultLayerId);
|
|
28180
|
+
|
|
28181
|
+
// If the default layer is not changing, do nothing
|
|
28182
|
+
const currentDefaultLayerId = this.defaultLayerId;
|
|
28183
|
+
if (defaultLayerId === currentDefaultLayerId) {
|
|
28184
|
+
// The default layer stays the same
|
|
28185
|
+
return;
|
|
28186
|
+
}
|
|
28187
|
+
|
|
28188
|
+
// Get all cells that belong to the current default layer implicitly
|
|
28189
|
+
const implicitLayerCells = this.getImplicitLayerCells();
|
|
28190
|
+
|
|
28191
|
+
// Set the new default layer ID
|
|
28192
|
+
this.defaultLayerId = defaultLayerId;
|
|
28193
|
+
const batchName = 'default-layer-change';
|
|
28194
|
+
this.startBatch(batchName, options);
|
|
28195
|
+
if (implicitLayerCells.length > 0) {
|
|
28196
|
+
// Reassign any cells lacking an explicit layer to the new default layer.
|
|
28197
|
+
// Do not sort yet, wait until all cells are moved.
|
|
28198
|
+
const moveOptions = {
|
|
28199
|
+
...options,
|
|
28200
|
+
sort: false
|
|
28201
|
+
};
|
|
28202
|
+
for (const cell of implicitLayerCells) {
|
|
28203
|
+
this.layerCollection.moveCellBetweenLayers(cell, defaultLayerId, moveOptions);
|
|
28204
|
+
}
|
|
28205
|
+
// Now sort the new default layer
|
|
28206
|
+
if (options.sort !== false) {
|
|
28207
|
+
defaultLayer.cellCollection.sort(options);
|
|
28208
|
+
}
|
|
28209
|
+
}
|
|
28210
|
+
|
|
28211
|
+
// Pretend to trigger the event on the layer itself.
|
|
28212
|
+
// It will bubble up as `layer:default` event on the graph.
|
|
28213
|
+
defaultLayer.trigger(defaultLayer.eventPrefix + 'default', defaultLayer, {
|
|
28214
|
+
...options,
|
|
28215
|
+
previousDefaultLayerId: currentDefaultLayerId
|
|
28216
|
+
});
|
|
28217
|
+
this.stopBatch(batchName, options);
|
|
28218
|
+
},
|
|
28219
|
+
/**
|
|
28220
|
+
* @protected
|
|
28221
|
+
* @description Get all cells that do not have an explicit layer assigned.
|
|
28222
|
+
* These cells belong to the default layer implicitly.
|
|
28223
|
+
* @return {Array<dia.Cell>} Array of cells without an explicit layer.
|
|
28224
|
+
*/
|
|
28225
|
+
getImplicitLayerCells() {
|
|
28226
|
+
return this.getDefaultLayer().cellCollection.filter(cell => {
|
|
28227
|
+
return cell.get(config$3.layerAttribute) == null;
|
|
28228
|
+
});
|
|
28229
|
+
},
|
|
28230
|
+
getLayer(layerId) {
|
|
28231
|
+
if (!this.hasLayer(layerId)) {
|
|
28232
|
+
throw new Error(`dia.Graph: Layer "${layerId}" does not exist.`);
|
|
28233
|
+
}
|
|
28234
|
+
return this.layerCollection.get(layerId);
|
|
28235
|
+
},
|
|
28236
|
+
hasLayer(layerRef) {
|
|
28237
|
+
return this.layerCollection.has(layerRef);
|
|
28238
|
+
},
|
|
28239
|
+
getLayers() {
|
|
28240
|
+
return this.layerCollection.toArray();
|
|
28241
|
+
},
|
|
28242
|
+
getCell: function (cellRef) {
|
|
28243
|
+
return this.layerCollection.getCell(cellRef);
|
|
27028
28244
|
},
|
|
27029
28245
|
getCells: function () {
|
|
27030
|
-
return this.
|
|
28246
|
+
return this.layerCollection.getCells();
|
|
27031
28247
|
},
|
|
27032
28248
|
getElements: function () {
|
|
27033
|
-
return this.
|
|
28249
|
+
return this.getCells().filter(cell => cell.isElement());
|
|
27034
28250
|
},
|
|
27035
28251
|
getLinks: function () {
|
|
27036
|
-
return this.
|
|
28252
|
+
return this.getCells().filter(cell => cell.isLink());
|
|
27037
28253
|
},
|
|
27038
|
-
getFirstCell: function () {
|
|
27039
|
-
|
|
28254
|
+
getFirstCell: function (layerId) {
|
|
28255
|
+
let layer;
|
|
28256
|
+
if (!layerId) {
|
|
28257
|
+
// Get the first cell from the bottom-most layer
|
|
28258
|
+
layer = this.getLayers().at(0);
|
|
28259
|
+
} else {
|
|
28260
|
+
layer = this.getLayer(layerId);
|
|
28261
|
+
}
|
|
28262
|
+
return layer.cellCollection.models.at(0);
|
|
27040
28263
|
},
|
|
27041
|
-
getLastCell: function () {
|
|
27042
|
-
|
|
28264
|
+
getLastCell: function (layerId) {
|
|
28265
|
+
let layer;
|
|
28266
|
+
if (!layerId) {
|
|
28267
|
+
// Get the last cell from the top-most layer
|
|
28268
|
+
layer = this.getLayers().at(-1);
|
|
28269
|
+
} else {
|
|
28270
|
+
layer = this.getLayer(layerId);
|
|
28271
|
+
}
|
|
28272
|
+
return layer.cellCollection.models.at(-1);
|
|
27043
28273
|
},
|
|
27044
28274
|
// Get all inbound and outbound links connected to the cell `model`.
|
|
27045
28275
|
getConnectedLinks: function (model, opt) {
|
|
@@ -27063,12 +28293,13 @@ var joint = (function (exports) {
|
|
|
27063
28293
|
addInbounds(this, model);
|
|
27064
28294
|
}
|
|
27065
28295
|
function addOutbounds(graph, model) {
|
|
27066
|
-
forIn(graph.getOutboundEdges(model.id), function (_, edge) {
|
|
28296
|
+
forIn(graph.topologyIndex.getOutboundEdges(model.id), function (_, edge) {
|
|
27067
28297
|
// skip links that were already added
|
|
27068
28298
|
// (those must be self-loop links)
|
|
27069
28299
|
// (because they are inbound and outbound edges of the same two elements)
|
|
27070
28300
|
if (edges[edge]) return;
|
|
27071
28301
|
var link = graph.getCell(edge);
|
|
28302
|
+
if (!link) return;
|
|
27072
28303
|
links.push(link);
|
|
27073
28304
|
edges[edge] = true;
|
|
27074
28305
|
if (indirect) {
|
|
@@ -27087,12 +28318,13 @@ var joint = (function (exports) {
|
|
|
27087
28318
|
}
|
|
27088
28319
|
}
|
|
27089
28320
|
function addInbounds(graph, model) {
|
|
27090
|
-
forIn(graph.getInboundEdges(model.id), function (_, edge) {
|
|
28321
|
+
forIn(graph.topologyIndex.getInboundEdges(model.id), function (_, edge) {
|
|
27091
28322
|
// skip links that were already added
|
|
27092
28323
|
// (those must be self-loop links)
|
|
27093
28324
|
// (because they are inbound and outbound edges of the same two elements)
|
|
27094
28325
|
if (edges[edge]) return;
|
|
27095
28326
|
var link = graph.getCell(edge);
|
|
28327
|
+
if (!link) return;
|
|
27096
28328
|
links.push(link);
|
|
27097
28329
|
edges[edge] = true;
|
|
27098
28330
|
if (indirect) {
|
|
@@ -27127,7 +28359,7 @@ var joint = (function (exports) {
|
|
|
27127
28359
|
embeddedCells.forEach(function (cell) {
|
|
27128
28360
|
if (cell.isLink()) return;
|
|
27129
28361
|
if (outbound) {
|
|
27130
|
-
forIn(this.getOutboundEdges(cell.id), function (exists, edge) {
|
|
28362
|
+
forIn(this.topologyIndex.getOutboundEdges(cell.id), function (exists, edge) {
|
|
27131
28363
|
if (!edges[edge]) {
|
|
27132
28364
|
var edgeCell = this.getCell(edge);
|
|
27133
28365
|
var {
|
|
@@ -27147,7 +28379,7 @@ var joint = (function (exports) {
|
|
|
27147
28379
|
}.bind(this));
|
|
27148
28380
|
}
|
|
27149
28381
|
if (inbound) {
|
|
27150
|
-
forIn(this.getInboundEdges(cell.id), function (exists, edge) {
|
|
28382
|
+
forIn(this.topologyIndex.getInboundEdges(cell.id), function (exists, edge) {
|
|
27151
28383
|
if (!edges[edge]) {
|
|
27152
28384
|
var edgeCell = this.getCell(edge);
|
|
27153
28385
|
var {
|
|
@@ -27426,31 +28658,19 @@ var joint = (function (exports) {
|
|
|
27426
28658
|
},
|
|
27427
28659
|
// Get all the roots of the graph. Time complexity: O(|V|).
|
|
27428
28660
|
getSources: function () {
|
|
27429
|
-
|
|
27430
|
-
forIn(this._nodes, function (exists, node) {
|
|
27431
|
-
if (!this._in[node] || isEmpty(this._in[node])) {
|
|
27432
|
-
sources.push(this.getCell(node));
|
|
27433
|
-
}
|
|
27434
|
-
}.bind(this));
|
|
27435
|
-
return sources;
|
|
28661
|
+
return this.topologyIndex.getSourceNodes().map(nodeId => this.getCell(nodeId));
|
|
27436
28662
|
},
|
|
27437
28663
|
// Get all the leafs of the graph. Time complexity: O(|V|).
|
|
27438
28664
|
getSinks: function () {
|
|
27439
|
-
|
|
27440
|
-
forIn(this._nodes, function (exists, node) {
|
|
27441
|
-
if (!this._out[node] || isEmpty(this._out[node])) {
|
|
27442
|
-
sinks.push(this.getCell(node));
|
|
27443
|
-
}
|
|
27444
|
-
}.bind(this));
|
|
27445
|
-
return sinks;
|
|
28665
|
+
return this.topologyIndex.getSinkNodes().map(nodeId => this.getCell(nodeId));
|
|
27446
28666
|
},
|
|
27447
28667
|
// Return `true` if `element` is a root. Time complexity: O(1).
|
|
27448
28668
|
isSource: function (element) {
|
|
27449
|
-
return
|
|
28669
|
+
return this.topologyIndex.isSourceNode(element.id);
|
|
27450
28670
|
},
|
|
27451
28671
|
// Return `true` if `element` is a leaf. Time complexity: O(1).
|
|
27452
28672
|
isSink: function (element) {
|
|
27453
|
-
return
|
|
28673
|
+
return this.topologyIndex.isSinkNode(element.id);
|
|
27454
28674
|
},
|
|
27455
28675
|
// Return `true` is `elementB` is a successor of `elementA`. Return `false` otherwise.
|
|
27456
28676
|
isSuccessor: function (elementA, elementB) {
|
|
@@ -27521,8 +28741,10 @@ var joint = (function (exports) {
|
|
|
27521
28741
|
});
|
|
27522
28742
|
},
|
|
27523
28743
|
// Remove links connected to the cell `model` completely.
|
|
27524
|
-
removeLinks: function (
|
|
27525
|
-
|
|
28744
|
+
removeLinks: function (cell, opt) {
|
|
28745
|
+
this.getConnectedLinks(cell).forEach(link => {
|
|
28746
|
+
this.layerCollection.removeCell(link, opt);
|
|
28747
|
+
});
|
|
27526
28748
|
},
|
|
27527
28749
|
// Find all cells at given point
|
|
27528
28750
|
|
|
@@ -27713,85 +28935,6 @@ var joint = (function (exports) {
|
|
|
27713
28935
|
});
|
|
27714
28936
|
wrapWith(Graph.prototype, ['resetCells', 'addCells', 'removeCells'], wrappers.cells);
|
|
27715
28937
|
|
|
27716
|
-
const LayersNames = {
|
|
27717
|
-
GRID: 'grid',
|
|
27718
|
-
CELLS: 'cells',
|
|
27719
|
-
BACK: 'back',
|
|
27720
|
-
FRONT: 'front',
|
|
27721
|
-
TOOLS: 'tools',
|
|
27722
|
-
LABELS: 'labels'
|
|
27723
|
-
};
|
|
27724
|
-
const PaperLayer = View.extend({
|
|
27725
|
-
tagName: 'g',
|
|
27726
|
-
svgElement: true,
|
|
27727
|
-
pivotNodes: null,
|
|
27728
|
-
defaultTheme: null,
|
|
27729
|
-
options: {
|
|
27730
|
-
name: ''
|
|
27731
|
-
},
|
|
27732
|
-
className: function () {
|
|
27733
|
-
const {
|
|
27734
|
-
name
|
|
27735
|
-
} = this.options;
|
|
27736
|
-
if (!name) return null;
|
|
27737
|
-
return addClassNamePrefix(`${name}-layer`);
|
|
27738
|
-
},
|
|
27739
|
-
init: function () {
|
|
27740
|
-
this.pivotNodes = {};
|
|
27741
|
-
},
|
|
27742
|
-
insertSortedNode: function (node, z) {
|
|
27743
|
-
this.el.insertBefore(node, this.insertPivot(z));
|
|
27744
|
-
},
|
|
27745
|
-
insertNode: function (node) {
|
|
27746
|
-
const {
|
|
27747
|
-
el
|
|
27748
|
-
} = this;
|
|
27749
|
-
if (node.parentNode !== el) {
|
|
27750
|
-
el.appendChild(node);
|
|
27751
|
-
}
|
|
27752
|
-
},
|
|
27753
|
-
insertPivot: function (z) {
|
|
27754
|
-
const {
|
|
27755
|
-
el,
|
|
27756
|
-
pivotNodes
|
|
27757
|
-
} = this;
|
|
27758
|
-
z = +z;
|
|
27759
|
-
z || (z = 0);
|
|
27760
|
-
let pivotNode = pivotNodes[z];
|
|
27761
|
-
if (pivotNode) return pivotNode;
|
|
27762
|
-
pivotNode = pivotNodes[z] = document.createComment('z-index:' + (z + 1));
|
|
27763
|
-
let neighborZ = -Infinity;
|
|
27764
|
-
for (let currentZ in pivotNodes) {
|
|
27765
|
-
currentZ = +currentZ;
|
|
27766
|
-
if (currentZ < z && currentZ > neighborZ) {
|
|
27767
|
-
neighborZ = currentZ;
|
|
27768
|
-
if (neighborZ === z - 1) continue;
|
|
27769
|
-
}
|
|
27770
|
-
}
|
|
27771
|
-
if (neighborZ !== -Infinity) {
|
|
27772
|
-
const neighborPivot = pivotNodes[neighborZ];
|
|
27773
|
-
// Insert After
|
|
27774
|
-
el.insertBefore(pivotNode, neighborPivot.nextSibling);
|
|
27775
|
-
} else {
|
|
27776
|
-
// First Child
|
|
27777
|
-
el.insertBefore(pivotNode, el.firstChild);
|
|
27778
|
-
}
|
|
27779
|
-
return pivotNode;
|
|
27780
|
-
},
|
|
27781
|
-
removePivots: function () {
|
|
27782
|
-
const {
|
|
27783
|
-
el,
|
|
27784
|
-
pivotNodes
|
|
27785
|
-
} = this;
|
|
27786
|
-
for (let z in pivotNodes) el.removeChild(pivotNodes[z]);
|
|
27787
|
-
this.pivotNodes = {};
|
|
27788
|
-
},
|
|
27789
|
-
isEmpty: function () {
|
|
27790
|
-
// Check if the layer has any child elements (pivot comments are not counted).
|
|
27791
|
-
return this.el.children.length === 0;
|
|
27792
|
-
}
|
|
27793
|
-
});
|
|
27794
|
-
|
|
27795
28938
|
const calcAttributesList = ['transform', 'x', 'y', 'cx', 'cy', 'dx', 'dy', 'x1', 'y1', 'x2', 'y2', 'points', 'd', 'r', 'rx', 'ry', 'width', 'height', 'stroke-width', 'font-size'];
|
|
27796
28939
|
const positiveValueList = ['r', 'rx', 'ry', 'width', 'height', 'stroke-width', 'font-size'];
|
|
27797
28940
|
const calcAttributes = calcAttributesList.reduce((acc, attrName) => {
|
|
@@ -29033,7 +30176,6 @@ var joint = (function (exports) {
|
|
|
29033
30176
|
// Internal tag to identify this object as a cell view instance.
|
|
29034
30177
|
// Used instead of `instanceof` for performance and cross-frame safety.
|
|
29035
30178
|
|
|
29036
|
-
const CELL_VIEW_MARKER = Symbol('joint.cellViewMarker');
|
|
29037
30179
|
Object.defineProperty(CellView.prototype, CELL_VIEW_MARKER, {
|
|
29038
30180
|
value: true
|
|
29039
30181
|
});
|
|
@@ -31841,6 +32983,231 @@ var joint = (function (exports) {
|
|
|
31841
32983
|
}
|
|
31842
32984
|
});
|
|
31843
32985
|
|
|
32986
|
+
const LayerView = View.extend({
|
|
32987
|
+
tagName: 'g',
|
|
32988
|
+
svgElement: true,
|
|
32989
|
+
pivotNodes: null,
|
|
32990
|
+
defaultTheme: null,
|
|
32991
|
+
UPDATE_PRIORITY: 4,
|
|
32992
|
+
options: {
|
|
32993
|
+
id: ''
|
|
32994
|
+
},
|
|
32995
|
+
paper: null,
|
|
32996
|
+
init: function () {
|
|
32997
|
+
this.pivotNodes = {};
|
|
32998
|
+
this.id = this.options.id || this.cid;
|
|
32999
|
+
},
|
|
33000
|
+
setPaperReference: function (paper) {
|
|
33001
|
+
this.paper = paper;
|
|
33002
|
+
this.afterPaperReferenceSet(paper);
|
|
33003
|
+
},
|
|
33004
|
+
unsetPaperReference: function () {
|
|
33005
|
+
this.beforePaperReferenceUnset();
|
|
33006
|
+
this.paper = null;
|
|
33007
|
+
},
|
|
33008
|
+
assertPaperReference() {
|
|
33009
|
+
if (!this.paper) {
|
|
33010
|
+
throw new Error('LayerView: paper reference is not set.');
|
|
33011
|
+
}
|
|
33012
|
+
},
|
|
33013
|
+
afterPaperReferenceSet: function () {
|
|
33014
|
+
// Can be overridden in subclasses.
|
|
33015
|
+
},
|
|
33016
|
+
beforePaperReferenceUnset: function () {
|
|
33017
|
+
// Can be overridden in subclasses.
|
|
33018
|
+
},
|
|
33019
|
+
// prevents id to be set on the DOM element
|
|
33020
|
+
_setAttributes: function (attrs) {
|
|
33021
|
+
const newAttrs = clone$1(attrs);
|
|
33022
|
+
delete newAttrs.id;
|
|
33023
|
+
View.prototype._setAttributes.call(this, newAttrs);
|
|
33024
|
+
},
|
|
33025
|
+
className: function () {
|
|
33026
|
+
const {
|
|
33027
|
+
id
|
|
33028
|
+
} = this.options;
|
|
33029
|
+
return addClassNamePrefix(`${id}-layer`);
|
|
33030
|
+
},
|
|
33031
|
+
insertSortedNode: function (node, z) {
|
|
33032
|
+
this.el.insertBefore(node, this.insertPivot(z));
|
|
33033
|
+
},
|
|
33034
|
+
insertNode: function (node) {
|
|
33035
|
+
const {
|
|
33036
|
+
el
|
|
33037
|
+
} = this;
|
|
33038
|
+
if (node.parentNode !== el) {
|
|
33039
|
+
el.appendChild(node);
|
|
33040
|
+
}
|
|
33041
|
+
},
|
|
33042
|
+
insertPivot: function (z) {
|
|
33043
|
+
const {
|
|
33044
|
+
el,
|
|
33045
|
+
pivotNodes
|
|
33046
|
+
} = this;
|
|
33047
|
+
z = +z;
|
|
33048
|
+
z || (z = 0);
|
|
33049
|
+
let pivotNode = pivotNodes[z];
|
|
33050
|
+
if (pivotNode) return pivotNode;
|
|
33051
|
+
pivotNode = pivotNodes[z] = document.createComment('z-index:' + (z + 1));
|
|
33052
|
+
let neighborZ = -Infinity;
|
|
33053
|
+
for (let currentZ in pivotNodes) {
|
|
33054
|
+
currentZ = +currentZ;
|
|
33055
|
+
if (currentZ < z && currentZ > neighborZ) {
|
|
33056
|
+
neighborZ = currentZ;
|
|
33057
|
+
if (neighborZ === z - 1) continue;
|
|
33058
|
+
}
|
|
33059
|
+
}
|
|
33060
|
+
if (neighborZ !== -Infinity) {
|
|
33061
|
+
const neighborPivot = pivotNodes[neighborZ];
|
|
33062
|
+
// Insert After
|
|
33063
|
+
el.insertBefore(pivotNode, neighborPivot.nextSibling);
|
|
33064
|
+
} else {
|
|
33065
|
+
// First Child
|
|
33066
|
+
el.insertBefore(pivotNode, el.firstChild);
|
|
33067
|
+
}
|
|
33068
|
+
return pivotNode;
|
|
33069
|
+
},
|
|
33070
|
+
removePivots: function () {
|
|
33071
|
+
const {
|
|
33072
|
+
el,
|
|
33073
|
+
pivotNodes
|
|
33074
|
+
} = this;
|
|
33075
|
+
for (let z in pivotNodes) el.removeChild(pivotNodes[z]);
|
|
33076
|
+
this.pivotNodes = {};
|
|
33077
|
+
},
|
|
33078
|
+
isEmpty: function () {
|
|
33079
|
+
// Check if the layer has any child elements (pivot comments are not counted).
|
|
33080
|
+
return this.el.children.length === 0;
|
|
33081
|
+
},
|
|
33082
|
+
reset: function () {
|
|
33083
|
+
this.removePivots();
|
|
33084
|
+
}
|
|
33085
|
+
});
|
|
33086
|
+
Object.defineProperty(LayerView.prototype, LAYER_VIEW_MARKER, {
|
|
33087
|
+
value: true
|
|
33088
|
+
});
|
|
33089
|
+
|
|
33090
|
+
/**
|
|
33091
|
+
* @class GraphLayerView
|
|
33092
|
+
* @description A GraphLayerView is responsible for managing the rendering of cell views inside a layer.
|
|
33093
|
+
* It listens to the corresponding GraphLayer model and updates the DOM accordingly.
|
|
33094
|
+
* It uses dia.Paper sorting options to sort cell views in the DOM based on their `z` attribute.
|
|
33095
|
+
*/
|
|
33096
|
+
const GraphLayerView = LayerView.extend({
|
|
33097
|
+
SORT_DELAYING_BATCHES: ['add', 'to-front', 'to-back'],
|
|
33098
|
+
style: {
|
|
33099
|
+
webkitUserSelect: 'none',
|
|
33100
|
+
userSelect: 'none'
|
|
33101
|
+
},
|
|
33102
|
+
graph: null,
|
|
33103
|
+
init() {
|
|
33104
|
+
LayerView.prototype.init.apply(this, arguments);
|
|
33105
|
+
this.graph = this.model.graph;
|
|
33106
|
+
},
|
|
33107
|
+
className: function () {
|
|
33108
|
+
const {
|
|
33109
|
+
id
|
|
33110
|
+
} = this.options;
|
|
33111
|
+
return [addClassNamePrefix(`${id}-layer`), addClassNamePrefix('cells')].join(' ');
|
|
33112
|
+
},
|
|
33113
|
+
afterPaperReferenceSet(paper) {
|
|
33114
|
+
this.listenTo(this.model, 'sort', this.onCellCollectionSort);
|
|
33115
|
+
this.listenTo(this.model, 'change', this.onCellChange);
|
|
33116
|
+
this.listenTo(this.model, 'move', this.onCellMove);
|
|
33117
|
+
this.listenTo(this.graph, 'batch:stop', this.onGraphBatchStop);
|
|
33118
|
+
},
|
|
33119
|
+
beforePaperReferenceUnset() {
|
|
33120
|
+
this.stopListening(this.model);
|
|
33121
|
+
this.stopListening(this.graph);
|
|
33122
|
+
},
|
|
33123
|
+
onCellCollectionSort() {
|
|
33124
|
+
if (this.graph.hasActiveBatch(this.SORT_DELAYING_BATCHES)) return;
|
|
33125
|
+
this.sort();
|
|
33126
|
+
},
|
|
33127
|
+
onCellMove(cell, opt = {}) {
|
|
33128
|
+
// When a cell is moved from one layer to another,
|
|
33129
|
+
// request insertion of its view in the new layer.
|
|
33130
|
+
this.paper.requestCellViewInsertion(cell, opt);
|
|
33131
|
+
},
|
|
33132
|
+
onCellChange(cell, opt) {
|
|
33133
|
+
if (!cell.hasChanged('z')) return;
|
|
33134
|
+
// Re-insert the cell view to maintain correct z-ordering
|
|
33135
|
+
if (this.paper.options.sorting === sortingTypes.APPROX) {
|
|
33136
|
+
this.paper.requestCellViewInsertion(cell, opt);
|
|
33137
|
+
}
|
|
33138
|
+
},
|
|
33139
|
+
onGraphBatchStop(data) {
|
|
33140
|
+
const name = data && data.batchName;
|
|
33141
|
+
const sortDelayingBatches = this.SORT_DELAYING_BATCHES;
|
|
33142
|
+
// After certain batches, sorting may be required
|
|
33143
|
+
if (sortDelayingBatches.includes(name) && !this.graph.hasActiveBatch(sortDelayingBatches)) {
|
|
33144
|
+
this.sort();
|
|
33145
|
+
}
|
|
33146
|
+
},
|
|
33147
|
+
sort() {
|
|
33148
|
+
this.assertPaperReference();
|
|
33149
|
+
const {
|
|
33150
|
+
paper
|
|
33151
|
+
} = this;
|
|
33152
|
+
if (!paper.isExactSorting()) {
|
|
33153
|
+
// noop
|
|
33154
|
+
return;
|
|
33155
|
+
}
|
|
33156
|
+
if (paper.isFrozen()) {
|
|
33157
|
+
// sort views once unfrozen
|
|
33158
|
+
paper._updates.sort = true;
|
|
33159
|
+
return;
|
|
33160
|
+
}
|
|
33161
|
+
this.sortExact();
|
|
33162
|
+
},
|
|
33163
|
+
sortExact() {
|
|
33164
|
+
// Run insertion sort algorithm in order to efficiently sort DOM elements according to their
|
|
33165
|
+
// associated model `z` attribute.
|
|
33166
|
+
const cellNodes = Array.from(this.el.children).filter(node => node.getAttribute('model-id'));
|
|
33167
|
+
const cellCollection = this.model.cellCollection;
|
|
33168
|
+
sortElements(cellNodes, function (a, b) {
|
|
33169
|
+
const cellA = cellCollection.get(a.getAttribute('model-id'));
|
|
33170
|
+
const cellB = cellCollection.get(b.getAttribute('model-id'));
|
|
33171
|
+
const zA = cellA.attributes.z || 0;
|
|
33172
|
+
const zB = cellB.attributes.z || 0;
|
|
33173
|
+
return zA === zB ? 0 : zA < zB ? -1 : 1;
|
|
33174
|
+
});
|
|
33175
|
+
},
|
|
33176
|
+
insertCellView(cellView) {
|
|
33177
|
+
this.assertPaperReference();
|
|
33178
|
+
const {
|
|
33179
|
+
paper
|
|
33180
|
+
} = this;
|
|
33181
|
+
const {
|
|
33182
|
+
el,
|
|
33183
|
+
model
|
|
33184
|
+
} = cellView;
|
|
33185
|
+
switch (paper.options.sorting) {
|
|
33186
|
+
case sortingTypes.APPROX:
|
|
33187
|
+
this.insertSortedNode(el, model.get('z'));
|
|
33188
|
+
break;
|
|
33189
|
+
case sortingTypes.EXACT:
|
|
33190
|
+
default:
|
|
33191
|
+
this.insertNode(el);
|
|
33192
|
+
break;
|
|
33193
|
+
}
|
|
33194
|
+
}
|
|
33195
|
+
});
|
|
33196
|
+
Object.defineProperty(GraphLayerView.prototype, GRAPH_LAYER_VIEW_MARKER, {
|
|
33197
|
+
value: true
|
|
33198
|
+
});
|
|
33199
|
+
|
|
33200
|
+
/**
|
|
33201
|
+
* @class LegacyGraphLayerView
|
|
33202
|
+
* @description A legacy GraphLayerView with an additional class name for backward compatibility.
|
|
33203
|
+
*/
|
|
33204
|
+
const LegacyGraphLayerView = GraphLayerView.extend({
|
|
33205
|
+
className: function () {
|
|
33206
|
+
const className = GraphLayerView.prototype.className.apply(this, arguments);
|
|
33207
|
+
return className + ' ' + addClassNamePrefix('viewport');
|
|
33208
|
+
}
|
|
33209
|
+
});
|
|
33210
|
+
|
|
31844
33211
|
/**
|
|
31845
33212
|
* Deque implementation for managing a double-ended queue.
|
|
31846
33213
|
* This implementation uses a doubly linked list for efficient operations.
|
|
@@ -31963,23 +33330,24 @@ var joint = (function (exports) {
|
|
|
31963
33330
|
}
|
|
31964
33331
|
}
|
|
31965
33332
|
|
|
31966
|
-
const
|
|
33333
|
+
const GridLayerView = LayerView.extend({
|
|
31967
33334
|
style: {
|
|
31968
33335
|
'pointer-events': 'none'
|
|
31969
33336
|
},
|
|
31970
33337
|
_gridCache: null,
|
|
31971
33338
|
_gridSettings: null,
|
|
31972
33339
|
init() {
|
|
31973
|
-
|
|
31974
|
-
|
|
31975
|
-
options: {
|
|
31976
|
-
paper
|
|
31977
|
-
}
|
|
31978
|
-
} = this;
|
|
33340
|
+
LayerView.prototype.init.apply(this, arguments);
|
|
33341
|
+
this.paper = this.options.paper;
|
|
31979
33342
|
this._gridCache = null;
|
|
31980
33343
|
this._gridSettings = [];
|
|
33344
|
+
},
|
|
33345
|
+
afterPaperReferenceSet(paper) {
|
|
31981
33346
|
this.listenTo(paper, 'transform resize', this.updateGrid);
|
|
31982
33347
|
},
|
|
33348
|
+
beforePaperReferenceUnset(paper) {
|
|
33349
|
+
this.stopListening(paper);
|
|
33350
|
+
},
|
|
31983
33351
|
setGrid(drawGrid) {
|
|
31984
33352
|
this._gridSettings = this.getGridSettings(drawGrid);
|
|
31985
33353
|
this.renderGrid();
|
|
@@ -32004,9 +33372,7 @@ var joint = (function (exports) {
|
|
|
32004
33372
|
},
|
|
32005
33373
|
renderGrid() {
|
|
32006
33374
|
const {
|
|
32007
|
-
|
|
32008
|
-
paper
|
|
32009
|
-
}
|
|
33375
|
+
paper
|
|
32010
33376
|
} = this;
|
|
32011
33377
|
const {
|
|
32012
33378
|
_gridSettings: gridSettings
|
|
@@ -32051,9 +33417,7 @@ var joint = (function (exports) {
|
|
|
32051
33417
|
const {
|
|
32052
33418
|
_gridCache: grid,
|
|
32053
33419
|
_gridSettings: gridSettings,
|
|
32054
|
-
|
|
32055
|
-
paper
|
|
32056
|
-
}
|
|
33420
|
+
paper
|
|
32057
33421
|
} = this;
|
|
32058
33422
|
if (!grid) return;
|
|
32059
33423
|
const {
|
|
@@ -32087,7 +33451,7 @@ var joint = (function (exports) {
|
|
|
32087
33451
|
});
|
|
32088
33452
|
},
|
|
32089
33453
|
_getPatternId(index) {
|
|
32090
|
-
return `pattern_${this.
|
|
33454
|
+
return `pattern_${this.paper.cid}_${index}`;
|
|
32091
33455
|
},
|
|
32092
33456
|
_getGridRefs() {
|
|
32093
33457
|
let {
|
|
@@ -32122,27 +33486,27 @@ var joint = (function (exports) {
|
|
|
32122
33486
|
return grid;
|
|
32123
33487
|
},
|
|
32124
33488
|
_resolveDrawGridOption(opt) {
|
|
32125
|
-
|
|
33489
|
+
const namespace = this.options.patterns;
|
|
32126
33490
|
if (isString(opt) && Array.isArray(namespace[opt])) {
|
|
32127
33491
|
return namespace[opt].map(function (item) {
|
|
32128
33492
|
return assign({}, item);
|
|
32129
33493
|
});
|
|
32130
33494
|
}
|
|
32131
|
-
|
|
33495
|
+
const options = opt || {
|
|
32132
33496
|
args: [{}]
|
|
32133
33497
|
};
|
|
32134
|
-
|
|
32135
|
-
|
|
33498
|
+
const isArray = Array.isArray(options);
|
|
33499
|
+
let name = options.name;
|
|
32136
33500
|
if (!isArray && !name && !options.markup) {
|
|
32137
33501
|
name = 'dot';
|
|
32138
33502
|
}
|
|
32139
33503
|
if (name && Array.isArray(namespace[name])) {
|
|
32140
|
-
|
|
33504
|
+
const pattern = namespace[name].map(function (item) {
|
|
32141
33505
|
return assign({}, item);
|
|
32142
33506
|
});
|
|
32143
|
-
|
|
33507
|
+
const args = Array.isArray(options.args) ? options.args : [options.args || {}];
|
|
32144
33508
|
defaults(args[0], omit(opt, 'args'));
|
|
32145
|
-
for (
|
|
33509
|
+
for (let i = 0; i < args.length; i++) {
|
|
32146
33510
|
if (pattern[i]) {
|
|
32147
33511
|
assign(pattern[i], args[i]);
|
|
32148
33512
|
}
|
|
@@ -32159,6 +33523,15 @@ var joint = (function (exports) {
|
|
|
32159
33523
|
}
|
|
32160
33524
|
});
|
|
32161
33525
|
|
|
33526
|
+
const paperLayers = {
|
|
33527
|
+
GRID: 'grid',
|
|
33528
|
+
BACK: 'back',
|
|
33529
|
+
/** @deprecated */
|
|
33530
|
+
CELLS: 'cells',
|
|
33531
|
+
FRONT: 'front',
|
|
33532
|
+
TOOLS: 'tools',
|
|
33533
|
+
LABELS: 'labels'
|
|
33534
|
+
};
|
|
32162
33535
|
const sortingTypes = {
|
|
32163
33536
|
NONE: 'sorting-none',
|
|
32164
33537
|
APPROX: 'sorting-approximate',
|
|
@@ -32191,18 +33564,205 @@ var joint = (function (exports) {
|
|
|
32191
33564
|
}
|
|
32192
33565
|
}
|
|
32193
33566
|
};
|
|
32194
|
-
const
|
|
32195
|
-
|
|
32196
|
-
|
|
32197
|
-
|
|
33567
|
+
const gridPatterns = {
|
|
33568
|
+
dot: [{
|
|
33569
|
+
color: '#AAAAAA',
|
|
33570
|
+
thickness: 1,
|
|
33571
|
+
markup: 'rect',
|
|
33572
|
+
render: function (el, opt) {
|
|
33573
|
+
V(el).attr({
|
|
33574
|
+
width: opt.thickness,
|
|
33575
|
+
height: opt.thickness,
|
|
33576
|
+
fill: opt.color
|
|
33577
|
+
});
|
|
33578
|
+
}
|
|
33579
|
+
}],
|
|
33580
|
+
fixedDot: [{
|
|
33581
|
+
color: '#AAAAAA',
|
|
33582
|
+
thickness: 1,
|
|
33583
|
+
markup: 'rect',
|
|
33584
|
+
render: function (el, opt) {
|
|
33585
|
+
V(el).attr({
|
|
33586
|
+
fill: opt.color
|
|
33587
|
+
});
|
|
33588
|
+
},
|
|
33589
|
+
update: function (el, opt, paper) {
|
|
33590
|
+
const {
|
|
33591
|
+
sx,
|
|
33592
|
+
sy
|
|
33593
|
+
} = paper.scale();
|
|
33594
|
+
const width = sx <= 1 ? opt.thickness : opt.thickness / sx;
|
|
33595
|
+
const height = sy <= 1 ? opt.thickness : opt.thickness / sy;
|
|
33596
|
+
V(el).attr({
|
|
33597
|
+
width,
|
|
33598
|
+
height
|
|
33599
|
+
});
|
|
33600
|
+
}
|
|
33601
|
+
}],
|
|
33602
|
+
mesh: [{
|
|
33603
|
+
color: '#AAAAAA',
|
|
33604
|
+
thickness: 1,
|
|
33605
|
+
markup: 'path',
|
|
33606
|
+
render: function (el, opt) {
|
|
33607
|
+
var d;
|
|
33608
|
+
var width = opt.width;
|
|
33609
|
+
var height = opt.height;
|
|
33610
|
+
var thickness = opt.thickness;
|
|
33611
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33612
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33613
|
+
} else {
|
|
33614
|
+
d = 'M 0 0 0 0';
|
|
33615
|
+
}
|
|
33616
|
+
V(el).attr({
|
|
33617
|
+
'd': d,
|
|
33618
|
+
stroke: opt.color,
|
|
33619
|
+
'stroke-width': opt.thickness
|
|
33620
|
+
});
|
|
33621
|
+
}
|
|
33622
|
+
}],
|
|
33623
|
+
doubleMesh: [{
|
|
33624
|
+
color: '#AAAAAA',
|
|
33625
|
+
thickness: 1,
|
|
33626
|
+
markup: 'path',
|
|
33627
|
+
render: function (el, opt) {
|
|
33628
|
+
var d;
|
|
33629
|
+
var width = opt.width;
|
|
33630
|
+
var height = opt.height;
|
|
33631
|
+
var thickness = opt.thickness;
|
|
33632
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33633
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33634
|
+
} else {
|
|
33635
|
+
d = 'M 0 0 0 0';
|
|
33636
|
+
}
|
|
33637
|
+
V(el).attr({
|
|
33638
|
+
'd': d,
|
|
33639
|
+
stroke: opt.color,
|
|
33640
|
+
'stroke-width': opt.thickness
|
|
33641
|
+
});
|
|
33642
|
+
}
|
|
33643
|
+
}, {
|
|
33644
|
+
color: '#000000',
|
|
33645
|
+
thickness: 3,
|
|
33646
|
+
scaleFactor: 4,
|
|
33647
|
+
markup: 'path',
|
|
33648
|
+
render: function (el, opt) {
|
|
33649
|
+
var d;
|
|
33650
|
+
var width = opt.width;
|
|
33651
|
+
var height = opt.height;
|
|
33652
|
+
var thickness = opt.thickness;
|
|
33653
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33654
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33655
|
+
} else {
|
|
33656
|
+
d = 'M 0 0 0 0';
|
|
33657
|
+
}
|
|
33658
|
+
V(el).attr({
|
|
33659
|
+
'd': d,
|
|
33660
|
+
stroke: opt.color,
|
|
33661
|
+
'stroke-width': opt.thickness
|
|
33662
|
+
});
|
|
33663
|
+
}
|
|
33664
|
+
}]
|
|
33665
|
+
};
|
|
33666
|
+
const backgroundPatterns = {
|
|
33667
|
+
flipXy: function (img) {
|
|
33668
|
+
// d b
|
|
33669
|
+
// q p
|
|
33670
|
+
|
|
33671
|
+
var canvas = document.createElement('canvas');
|
|
33672
|
+
var imgWidth = img.width;
|
|
33673
|
+
var imgHeight = img.height;
|
|
33674
|
+
canvas.width = 2 * imgWidth;
|
|
33675
|
+
canvas.height = 2 * imgHeight;
|
|
33676
|
+
var ctx = canvas.getContext('2d');
|
|
33677
|
+
// top-left image
|
|
33678
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33679
|
+
// xy-flipped bottom-right image
|
|
33680
|
+
ctx.setTransform(-1, 0, 0, -1, canvas.width, canvas.height);
|
|
33681
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33682
|
+
// x-flipped top-right image
|
|
33683
|
+
ctx.setTransform(-1, 0, 0, 1, canvas.width, 0);
|
|
33684
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33685
|
+
// y-flipped bottom-left image
|
|
33686
|
+
ctx.setTransform(1, 0, 0, -1, 0, canvas.height);
|
|
33687
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33688
|
+
return canvas;
|
|
33689
|
+
},
|
|
33690
|
+
flipX: function (img) {
|
|
33691
|
+
// d b
|
|
33692
|
+
// d b
|
|
33693
|
+
|
|
33694
|
+
var canvas = document.createElement('canvas');
|
|
33695
|
+
var imgWidth = img.width;
|
|
33696
|
+
var imgHeight = img.height;
|
|
33697
|
+
canvas.width = imgWidth * 2;
|
|
33698
|
+
canvas.height = imgHeight;
|
|
33699
|
+
var ctx = canvas.getContext('2d');
|
|
33700
|
+
// left image
|
|
33701
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33702
|
+
// flipped right image
|
|
33703
|
+
ctx.translate(2 * imgWidth, 0);
|
|
33704
|
+
ctx.scale(-1, 1);
|
|
33705
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33706
|
+
return canvas;
|
|
33707
|
+
},
|
|
33708
|
+
flipY: function (img) {
|
|
33709
|
+
// d d
|
|
33710
|
+
// q q
|
|
33711
|
+
|
|
33712
|
+
var canvas = document.createElement('canvas');
|
|
33713
|
+
var imgWidth = img.width;
|
|
33714
|
+
var imgHeight = img.height;
|
|
33715
|
+
canvas.width = imgWidth;
|
|
33716
|
+
canvas.height = imgHeight * 2;
|
|
33717
|
+
var ctx = canvas.getContext('2d');
|
|
33718
|
+
// top image
|
|
33719
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33720
|
+
// flipped bottom image
|
|
33721
|
+
ctx.translate(0, 2 * imgHeight);
|
|
33722
|
+
ctx.scale(1, -1);
|
|
33723
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33724
|
+
return canvas;
|
|
33725
|
+
},
|
|
33726
|
+
watermark: function (img, opt) {
|
|
33727
|
+
// d
|
|
33728
|
+
// d
|
|
33729
|
+
|
|
33730
|
+
opt = opt || {};
|
|
33731
|
+
var imgWidth = img.width;
|
|
33732
|
+
var imgHeight = img.height;
|
|
33733
|
+
var canvas = document.createElement('canvas');
|
|
33734
|
+
canvas.width = imgWidth * 3;
|
|
33735
|
+
canvas.height = imgHeight * 3;
|
|
33736
|
+
var ctx = canvas.getContext('2d');
|
|
33737
|
+
var angle = isNumber(opt.watermarkAngle) ? -opt.watermarkAngle : -20;
|
|
33738
|
+
var radians = toRad(angle);
|
|
33739
|
+
var stepX = canvas.width / 4;
|
|
33740
|
+
var stepY = canvas.height / 4;
|
|
33741
|
+
for (var i = 0; i < 4; i++) {
|
|
33742
|
+
for (var j = 0; j < 4; j++) {
|
|
33743
|
+
if ((i + j) % 2 > 0) {
|
|
33744
|
+
// reset the current transformations
|
|
33745
|
+
ctx.setTransform(1, 0, 0, 1, (2 * i - 1) * stepX, (2 * j - 1) * stepY);
|
|
33746
|
+
ctx.rotate(radians);
|
|
33747
|
+
ctx.drawImage(img, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight);
|
|
33748
|
+
}
|
|
33749
|
+
}
|
|
33750
|
+
}
|
|
33751
|
+
return canvas;
|
|
33752
|
+
}
|
|
33753
|
+
};
|
|
33754
|
+
const implicitLayers = [{
|
|
33755
|
+
id: paperLayers.GRID,
|
|
33756
|
+
type: 'GridLayerView',
|
|
33757
|
+
patterns: gridPatterns
|
|
32198
33758
|
}, {
|
|
32199
|
-
|
|
33759
|
+
id: paperLayers.BACK
|
|
32200
33760
|
}, {
|
|
32201
|
-
|
|
33761
|
+
id: paperLayers.LABELS
|
|
32202
33762
|
}, {
|
|
32203
|
-
|
|
33763
|
+
id: paperLayers.FRONT
|
|
32204
33764
|
}, {
|
|
32205
|
-
|
|
33765
|
+
id: paperLayers.TOOLS
|
|
32206
33766
|
}];
|
|
32207
33767
|
const CELL_VIEW_PLACEHOLDER_MARKER = Symbol('joint.cellViewPlaceholderMarker');
|
|
32208
33768
|
const Paper = View.extend({
|
|
@@ -32272,7 +33832,7 @@ var joint = (function (exports) {
|
|
|
32272
33832
|
// Do not create hard dependency on the joint.shapes.standard namespace (by importing the standard.Link model directly)
|
|
32273
33833
|
const {
|
|
32274
33834
|
cellNamespace
|
|
32275
|
-
} = this.model.
|
|
33835
|
+
} = this.model.layerCollection;
|
|
32276
33836
|
const ctor = getByPath(cellNamespace, ['standard', 'Link']);
|
|
32277
33837
|
if (!ctor) throw new Error('dia.Paper: no default link model found. Use `options.defaultLink` to specify a default link model.');
|
|
32278
33838
|
return new ctor();
|
|
@@ -32358,12 +33918,24 @@ var joint = (function (exports) {
|
|
|
32358
33918
|
viewManagement: false,
|
|
32359
33919
|
// no docs yet
|
|
32360
33920
|
onViewUpdate: function (view, flag, priority, opt, paper) {
|
|
32361
|
-
|
|
32362
|
-
|
|
32363
|
-
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
|
|
33921
|
+
if (opt.mounting || opt.isolate) {
|
|
33922
|
+
// Do not update connected links when:
|
|
33923
|
+
// - the view was just mounted (added back to the paper by viewport function)
|
|
33924
|
+
// - the change was marked as `isolate`.
|
|
33925
|
+
return;
|
|
33926
|
+
}
|
|
33927
|
+
// Always update connected links when the view model was replaced with another model
|
|
33928
|
+
// with the same id.
|
|
33929
|
+
// Note: the removal is done in 2 steps: remove the old model, add the new model.
|
|
33930
|
+
// We update connected links on the add step.
|
|
33931
|
+
if (!(opt.replace && opt.add)) {
|
|
33932
|
+
if (flag & (paper.FLAG_INSERT | paper.FLAG_REMOVE)) {
|
|
33933
|
+
// Do not update connected links when:
|
|
33934
|
+
// - the view was just inserted (added to the graph and rendered)
|
|
33935
|
+
// - the view model was just removed from the graph
|
|
33936
|
+
return;
|
|
33937
|
+
}
|
|
33938
|
+
}
|
|
32367
33939
|
paper.requestConnectedLinksUpdate(view, priority, opt);
|
|
32368
33940
|
},
|
|
32369
33941
|
// no docs yet
|
|
@@ -32380,6 +33952,7 @@ var joint = (function (exports) {
|
|
|
32380
33952
|
// Default namespaces
|
|
32381
33953
|
|
|
32382
33954
|
cellViewNamespace: null,
|
|
33955
|
+
layerViewNamespace: null,
|
|
32383
33956
|
routerNamespace: null,
|
|
32384
33957
|
connectorNamespace: null,
|
|
32385
33958
|
highlighterNamespace: highlighters,
|
|
@@ -32427,10 +34000,11 @@ var joint = (function (exports) {
|
|
|
32427
34000
|
}
|
|
32428
34001
|
`,
|
|
32429
34002
|
svg: null,
|
|
32430
|
-
viewport: null,
|
|
32431
34003
|
defs: null,
|
|
32432
34004
|
tools: null,
|
|
32433
34005
|
layers: null,
|
|
34006
|
+
// deprecated, use layers element instead
|
|
34007
|
+
viewport: null,
|
|
32434
34008
|
// For storing the current transformation matrix (CTM) of the paper's viewport.
|
|
32435
34009
|
_viewportMatrix: null,
|
|
32436
34010
|
// For verifying whether the CTM is up-to-date. The viewport transform attribute
|
|
@@ -32440,7 +34014,6 @@ var joint = (function (exports) {
|
|
|
32440
34014
|
_updates: null,
|
|
32441
34015
|
// Paper Layers
|
|
32442
34016
|
_layers: null,
|
|
32443
|
-
SORT_DELAYING_BATCHES: ['add', 'to-front', 'to-back'],
|
|
32444
34017
|
UPDATE_DELAYING_BATCHES: ['translate'],
|
|
32445
34018
|
// If you interact with these elements,
|
|
32446
34019
|
// the default interaction such as `element move` is prevented.
|
|
@@ -32460,12 +34033,13 @@ var joint = (function (exports) {
|
|
|
32460
34033
|
// The find buffer is used to extend the area of the search
|
|
32461
34034
|
// to mitigate the differences between the model and view geometry.
|
|
32462
34035
|
DEFAULT_FIND_BUFFER: 200,
|
|
32463
|
-
// Default layer to insert the cell views into.
|
|
32464
|
-
DEFAULT_CELL_LAYER: LayersNames.CELLS,
|
|
32465
|
-
// Update flags
|
|
32466
34036
|
FLAG_INSERT: 1 << 30,
|
|
32467
34037
|
FLAG_REMOVE: 1 << 29,
|
|
32468
34038
|
FLAG_INIT: 1 << 28,
|
|
34039
|
+
// Layers that are always present on the paper (e.g. grid, back, front, tools)
|
|
34040
|
+
implicitLayers,
|
|
34041
|
+
// Reference layer for inserting new graph layers.
|
|
34042
|
+
graphLayerRefId: paperLayers.LABELS,
|
|
32469
34043
|
init: function () {
|
|
32470
34044
|
const {
|
|
32471
34045
|
options
|
|
@@ -32475,6 +34049,12 @@ var joint = (function (exports) {
|
|
|
32475
34049
|
options.cellViewNamespace = typeof joint !== 'undefined' && has(joint, 'shapes') ? joint.shapes : null;
|
|
32476
34050
|
/* eslint-enable no-undef */
|
|
32477
34051
|
}
|
|
34052
|
+
const defaultLayerViewNamespace = {
|
|
34053
|
+
LayerView,
|
|
34054
|
+
GraphLayerView,
|
|
34055
|
+
GridLayerView
|
|
34056
|
+
};
|
|
34057
|
+
this.layerViewNamespace = defaultsDeep({}, options.layerViewNamespace || {}, defaultLayerViewNamespace);
|
|
32478
34058
|
const model = this.model = options.model || new Graph();
|
|
32479
34059
|
|
|
32480
34060
|
// This property tells us if we need to keep the compatibility
|
|
@@ -32484,18 +34064,17 @@ var joint = (function (exports) {
|
|
|
32484
34064
|
// Layers (SVGGroups)
|
|
32485
34065
|
this._layers = {
|
|
32486
34066
|
viewsMap: {},
|
|
32487
|
-
namesMap: {},
|
|
32488
34067
|
order: []
|
|
32489
34068
|
};
|
|
32490
|
-
this.cloneOptions();
|
|
32491
|
-
this.render();
|
|
32492
|
-
this._setDimensions();
|
|
32493
|
-
this.startListening();
|
|
32494
34069
|
|
|
32495
34070
|
// Hash of all cell views.
|
|
32496
34071
|
this._views = {};
|
|
32497
34072
|
this._viewPlaceholders = {};
|
|
32498
34073
|
this._idToCid = {};
|
|
34074
|
+
this.cloneOptions();
|
|
34075
|
+
this.render();
|
|
34076
|
+
this._setDimensions();
|
|
34077
|
+
this.startListening();
|
|
32499
34078
|
|
|
32500
34079
|
// Mouse wheel events buffer
|
|
32501
34080
|
this._mw_evt_buffer = {
|
|
@@ -32504,7 +34083,7 @@ var joint = (function (exports) {
|
|
|
32504
34083
|
};
|
|
32505
34084
|
|
|
32506
34085
|
// Render existing cells in the graph
|
|
32507
|
-
this.resetViews(model.
|
|
34086
|
+
this.resetViews(model.getCells());
|
|
32508
34087
|
},
|
|
32509
34088
|
_resetUpdates: function () {
|
|
32510
34089
|
if (this._updates && this._updates.id) cancelFrame(this._updates.id);
|
|
@@ -32524,7 +34103,8 @@ var joint = (function (exports) {
|
|
|
32524
34103
|
},
|
|
32525
34104
|
startListening: function () {
|
|
32526
34105
|
var model = this.model;
|
|
32527
|
-
this.listenTo(model, 'add', this.onCellAdded).listenTo(model, 'remove', this.onCellRemoved).listenTo(model, '
|
|
34106
|
+
this.listenTo(model, 'add', this.onCellAdded).listenTo(model, 'remove', this.onCellRemoved).listenTo(model, 'reset', this.onGraphReset).listenTo(model, 'batch:stop', this.onGraphBatchStop);
|
|
34107
|
+
this.listenTo(model, 'layer:add', this.onGraphLayerAdd).listenTo(model, 'layer:remove', this.onGraphLayerRemove).listenTo(model, 'layers:sort', this.onGraphLayerCollectionSort);
|
|
32528
34108
|
this.on('cell:highlight', this.onCellHighlight).on('cell:unhighlight', this.onCellUnhighlight).on('transform', this.update);
|
|
32529
34109
|
},
|
|
32530
34110
|
onCellAdded: function (cell, _, opt) {
|
|
@@ -32550,22 +34130,15 @@ var joint = (function (exports) {
|
|
|
32550
34130
|
this.requestViewUpdate(viewLike, this.FLAG_REMOVE, viewLike.UPDATE_PRIORITY, opt);
|
|
32551
34131
|
}
|
|
32552
34132
|
},
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32557
|
-
|
|
32558
|
-
|
|
32559
|
-
|
|
32560
|
-
|
|
32561
|
-
|
|
32562
|
-
onGraphReset: function (collection, opt) {
|
|
32563
|
-
this.resetLayers();
|
|
32564
|
-
this.resetViews(collection.models, opt);
|
|
32565
|
-
},
|
|
32566
|
-
onGraphSort: function () {
|
|
32567
|
-
if (this.model.hasActiveBatch(this.SORT_DELAYING_BATCHES)) return;
|
|
32568
|
-
this.sortViews();
|
|
34133
|
+
onGraphReset: function (_collection, opt) {
|
|
34134
|
+
// Re-render all graph layer views
|
|
34135
|
+
// but keep the implicit layer views.
|
|
34136
|
+
this.renderGraphLayerViews();
|
|
34137
|
+
this.resetLayerViews();
|
|
34138
|
+
// Backward compatibility: reassign the `cells` property
|
|
34139
|
+
// with the default layer view.
|
|
34140
|
+
this.assertLayerViews();
|
|
34141
|
+
this.resetViews(this.model.getCells(), opt);
|
|
32569
34142
|
},
|
|
32570
34143
|
onGraphBatchStop: function (data) {
|
|
32571
34144
|
if (this.isFrozen() || this.isIdle()) return;
|
|
@@ -32577,10 +34150,92 @@ var joint = (function (exports) {
|
|
|
32577
34150
|
this.updateViews(data);
|
|
32578
34151
|
}
|
|
32579
34152
|
}
|
|
32580
|
-
|
|
32581
|
-
|
|
32582
|
-
|
|
34153
|
+
},
|
|
34154
|
+
/**
|
|
34155
|
+
* @protected
|
|
34156
|
+
* @description When a new layer is added to the graph, we create a new layer view
|
|
34157
|
+
**/
|
|
34158
|
+
onGraphLayerAdd: function (layer, _, opt) {
|
|
34159
|
+
if (this.hasLayerView(layer.id)) return;
|
|
34160
|
+
const layerView = this.createLayerView({
|
|
34161
|
+
id: layer.id,
|
|
34162
|
+
model: layer
|
|
34163
|
+
});
|
|
34164
|
+
const layers = this.model.getLayers();
|
|
34165
|
+
let before;
|
|
34166
|
+
// Note: There is always at least one graph layer.
|
|
34167
|
+
if (layers[layers.length - 1] === layer) {
|
|
34168
|
+
// This is the last layer, so insert before the labels layer
|
|
34169
|
+
before = paperLayers.LABELS;
|
|
34170
|
+
} else {
|
|
34171
|
+
// There is a layer after the current one, so insert before that one
|
|
34172
|
+
const index = layers.indexOf(layer);
|
|
34173
|
+
before = layers[index + 1].id;
|
|
32583
34174
|
}
|
|
34175
|
+
this.addLayerView(layerView, {
|
|
34176
|
+
before
|
|
34177
|
+
});
|
|
34178
|
+
},
|
|
34179
|
+
/**
|
|
34180
|
+
* @protected
|
|
34181
|
+
* @description When a layer is removed from the graph, we remove the corresponding layer view
|
|
34182
|
+
**/
|
|
34183
|
+
onGraphLayerRemove: function (layer, _, opt) {
|
|
34184
|
+
if (!this.hasLayerView(layer)) return;
|
|
34185
|
+
|
|
34186
|
+
// Request layer removal. Since the UPDATE_PRIORITY is lower
|
|
34187
|
+
// than cells update priority, the cell views will be removed first.
|
|
34188
|
+
this.requestLayerViewRemoval(layer);
|
|
34189
|
+
},
|
|
34190
|
+
/**
|
|
34191
|
+
* @protected
|
|
34192
|
+
* @description When the graph layer collection is sorted,
|
|
34193
|
+
* we reorder all graph layer views.
|
|
34194
|
+
**/
|
|
34195
|
+
onGraphLayerCollectionSort: function (layerCollection) {
|
|
34196
|
+
layerCollection.each(layer => {
|
|
34197
|
+
if (!this.hasLayerView(layer)) return;
|
|
34198
|
+
this.moveLayerView(layer, {
|
|
34199
|
+
before: this.graphLayerRefId
|
|
34200
|
+
});
|
|
34201
|
+
});
|
|
34202
|
+
},
|
|
34203
|
+
/**
|
|
34204
|
+
* @protected
|
|
34205
|
+
* @description Resets all graph layer views.
|
|
34206
|
+
*/
|
|
34207
|
+
renderGraphLayerViews: function () {
|
|
34208
|
+
// Remove all existing graph layer views
|
|
34209
|
+
// Note: we don't use `getGraphLayerViews()` here because
|
|
34210
|
+
// rendered graph layer views could be different from the ones
|
|
34211
|
+
// in the graph layer collection (`onResetGraphLayerCollectionReset`).
|
|
34212
|
+
this.getLayerViews().forEach(layerView => {
|
|
34213
|
+
if (!layerView[GRAPH_LAYER_VIEW_MARKER]) return;
|
|
34214
|
+
this._removeLayerView(layerView);
|
|
34215
|
+
});
|
|
34216
|
+
// Create and insert new graph layer views
|
|
34217
|
+
this.model.getLayers().forEach(layer => {
|
|
34218
|
+
const layerView = this.createLayerView({
|
|
34219
|
+
id: layer.id,
|
|
34220
|
+
model: layer
|
|
34221
|
+
});
|
|
34222
|
+
// Insert the layer view into the paper layers, just before the labels layer.
|
|
34223
|
+
// All cell layers are positioned between the "back" and "labels" layers,
|
|
34224
|
+
// with the default "cells" layer originally occupying this position.
|
|
34225
|
+
this.addLayerView(layerView, {
|
|
34226
|
+
before: this.graphLayerRefId
|
|
34227
|
+
});
|
|
34228
|
+
});
|
|
34229
|
+
},
|
|
34230
|
+
/**
|
|
34231
|
+
* @protected
|
|
34232
|
+
* @description Renders all implicit layer views.
|
|
34233
|
+
*/
|
|
34234
|
+
renderImplicitLayerViews: function () {
|
|
34235
|
+
this.implicitLayers.forEach(layerInit => {
|
|
34236
|
+
const layerView = this.createLayerView(layerInit);
|
|
34237
|
+
this.addLayerView(layerView);
|
|
34238
|
+
});
|
|
32584
34239
|
},
|
|
32585
34240
|
cloneOptions: function () {
|
|
32586
34241
|
const {
|
|
@@ -32675,136 +34330,295 @@ var joint = (function (exports) {
|
|
|
32675
34330
|
}]
|
|
32676
34331
|
}];
|
|
32677
34332
|
},
|
|
32678
|
-
|
|
32679
|
-
|
|
34333
|
+
/**
|
|
34334
|
+
* @public
|
|
34335
|
+
* @description Checks whether the layer view exists by the given layer id or layer model.
|
|
34336
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34337
|
+
* @return {boolean} True if the layer view exists, false otherwise.
|
|
34338
|
+
*/
|
|
34339
|
+
hasLayerView(layerRef) {
|
|
34340
|
+
let layerId;
|
|
34341
|
+
if (isString(layerRef)) {
|
|
34342
|
+
layerId = layerRef;
|
|
34343
|
+
} else if (layerRef) {
|
|
34344
|
+
layerId = layerRef.id;
|
|
34345
|
+
} else {
|
|
34346
|
+
return false;
|
|
34347
|
+
}
|
|
34348
|
+
return layerId in this._layers.viewsMap;
|
|
32680
34349
|
},
|
|
32681
|
-
|
|
32682
|
-
|
|
32683
|
-
|
|
32684
|
-
|
|
32685
|
-
|
|
32686
|
-
|
|
32687
|
-
|
|
32688
|
-
|
|
34350
|
+
/**
|
|
34351
|
+
* @public
|
|
34352
|
+
* @description Returns the layer view by the given layer id or layer model.
|
|
34353
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34354
|
+
* @return {dia.LayerView} The layer view.
|
|
34355
|
+
* @throws {Error} if the layer view is not found
|
|
34356
|
+
*/
|
|
34357
|
+
getLayerView(layerRef) {
|
|
34358
|
+
let layerId;
|
|
34359
|
+
if (isString(layerRef)) {
|
|
34360
|
+
layerId = layerRef;
|
|
34361
|
+
} else if (layerRef) {
|
|
34362
|
+
layerId = layerRef.id;
|
|
34363
|
+
} else {
|
|
34364
|
+
throw new Error('dia.Paper: No layer provided.');
|
|
34365
|
+
}
|
|
34366
|
+
const layerView = this._layers.viewsMap[layerId];
|
|
34367
|
+
if (!layerView) {
|
|
34368
|
+
throw new Error(`dia.Paper: Unknown layer view "${layerId}".`);
|
|
34369
|
+
}
|
|
34370
|
+
return layerView;
|
|
32689
34371
|
},
|
|
32690
|
-
|
|
32691
|
-
|
|
34372
|
+
/**
|
|
34373
|
+
* @deprecated use `getLayerView(layerId).el` instead
|
|
34374
|
+
*/
|
|
34375
|
+
getLayerNode(layerId) {
|
|
34376
|
+
return this.getLayerView(layerId).el;
|
|
32692
34377
|
},
|
|
32693
|
-
|
|
32694
|
-
|
|
34378
|
+
/**
|
|
34379
|
+
* @protected
|
|
34380
|
+
* @description Removes the given layer view from the paper.
|
|
34381
|
+
* It does not check whether the layer view is empty.
|
|
34382
|
+
* @param {dia.LayerView} layerView - The layer view to remove.
|
|
34383
|
+
*/
|
|
34384
|
+
_removeLayerView(layerView) {
|
|
34385
|
+
this._unregisterLayerView(layerView);
|
|
32695
34386
|
layerView.remove();
|
|
32696
34387
|
},
|
|
32697
|
-
|
|
32698
|
-
|
|
32699
|
-
|
|
32700
|
-
|
|
32701
|
-
|
|
32702
|
-
|
|
32703
|
-
|
|
32704
|
-
|
|
32705
|
-
|
|
32706
|
-
order.splice(order.indexOf(layerName), 1);
|
|
32707
|
-
delete namesMap[layerView.cid];
|
|
32708
|
-
delete viewsMap[layerName];
|
|
34388
|
+
/**
|
|
34389
|
+
* @protected
|
|
34390
|
+
* @description Removes all layer views from the paper.
|
|
34391
|
+
* It does not check whether the layer views are empty.
|
|
34392
|
+
*/
|
|
34393
|
+
_removeLayerViews: function () {
|
|
34394
|
+
Object.values(this._layers.viewsMap).forEach(layerView => {
|
|
34395
|
+
this._removeLayerView(layerView);
|
|
34396
|
+
});
|
|
32709
34397
|
},
|
|
32710
|
-
|
|
34398
|
+
/**
|
|
34399
|
+
* @protected
|
|
34400
|
+
* @description Unregisters the given layer view from the paper.
|
|
34401
|
+
* @param {dia.LayerView} layerView - The layer view to unregister.
|
|
34402
|
+
*/
|
|
34403
|
+
_unregisterLayerView(layerView) {
|
|
32711
34404
|
const {
|
|
32712
34405
|
_layers: {
|
|
32713
34406
|
viewsMap,
|
|
32714
|
-
namesMap,
|
|
32715
34407
|
order
|
|
32716
34408
|
}
|
|
32717
34409
|
} = this;
|
|
32718
|
-
|
|
32719
|
-
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
order.
|
|
34410
|
+
const layerId = layerView.id;
|
|
34411
|
+
// Remove the layer id from the order list.
|
|
34412
|
+
const layerIndex = order.indexOf(layerId);
|
|
34413
|
+
if (layerIndex !== -1) {
|
|
34414
|
+
order.splice(layerIndex, 1);
|
|
32723
34415
|
}
|
|
32724
|
-
|
|
32725
|
-
|
|
34416
|
+
// Unlink the layer view from the paper.
|
|
34417
|
+
layerView.unsetPaperReference();
|
|
34418
|
+
// Remove the layer view from the paper's registry.
|
|
34419
|
+
delete viewsMap[layerId];
|
|
32726
34420
|
},
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32735
|
-
|
|
32736
|
-
|
|
34421
|
+
/**
|
|
34422
|
+
* @protected
|
|
34423
|
+
* @description Registers the given layer view in the paper.
|
|
34424
|
+
* @param {dia.LayerView} layerView - The layer view to register.
|
|
34425
|
+
* @throws {Error} if the layer view is not an instance of dia.LayerView
|
|
34426
|
+
* @throws {Error} if the layer view already exists in the paper
|
|
34427
|
+
*/
|
|
34428
|
+
_registerLayerView(layerView) {
|
|
34429
|
+
if (!layerView || !layerView[LAYER_VIEW_MARKER]) {
|
|
34430
|
+
throw new Error('dia.Paper: The layer view must be an instance of dia.LayerView.');
|
|
32737
34431
|
}
|
|
32738
|
-
if (
|
|
32739
|
-
|
|
34432
|
+
if (this.hasLayerView(layerView.id)) {
|
|
34433
|
+
throw new Error(`dia.Paper: The layer view "${layerView.id}" already exists.`);
|
|
34434
|
+
}
|
|
34435
|
+
// Link the layer view back to the paper.
|
|
34436
|
+
layerView.setPaperReference(this);
|
|
34437
|
+
// Store the layer view in the paper's registry.
|
|
34438
|
+
this._layers.viewsMap[layerView.id] = layerView;
|
|
32740
34439
|
},
|
|
32741
|
-
|
|
34440
|
+
/**
|
|
34441
|
+
* @public
|
|
34442
|
+
* @description Removes the layer view by the given layer id or layer model.
|
|
34443
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34444
|
+
* @throws {Error} if the layer view is not empty
|
|
34445
|
+
*/
|
|
34446
|
+
removeLayerView(layerRef) {
|
|
34447
|
+
const layerView = this.getLayerView(layerRef);
|
|
34448
|
+
if (!layerView.isEmpty()) {
|
|
34449
|
+
throw new Error('dia.Paper: The layer view is not empty.');
|
|
34450
|
+
}
|
|
34451
|
+
this._removeLayerView(layerView);
|
|
34452
|
+
},
|
|
34453
|
+
/**
|
|
34454
|
+
* @protected
|
|
34455
|
+
* @description Schedules the layer view removal by the given layer id or layer model.
|
|
34456
|
+
* The actual removal will be performed during the paper update cycle.
|
|
34457
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34458
|
+
* @param {Object} [opt] - Update options.
|
|
34459
|
+
*/
|
|
34460
|
+
requestLayerViewRemoval(layerRef, opt) {
|
|
34461
|
+
const layerView = this.getLayerView(layerRef);
|
|
32742
34462
|
const {
|
|
32743
|
-
|
|
32744
|
-
namesMap
|
|
32745
|
-
}
|
|
34463
|
+
FLAG_REMOVE
|
|
32746
34464
|
} = this;
|
|
32747
|
-
|
|
34465
|
+
const {
|
|
34466
|
+
UPDATE_PRIORITY
|
|
34467
|
+
} = layerView;
|
|
34468
|
+
this.requestViewUpdate(layerView, FLAG_REMOVE, UPDATE_PRIORITY, opt);
|
|
32748
34469
|
},
|
|
32749
|
-
|
|
32750
|
-
|
|
32751
|
-
|
|
32752
|
-
|
|
32753
|
-
|
|
34470
|
+
/**
|
|
34471
|
+
* @public
|
|
34472
|
+
* @internal not documented
|
|
34473
|
+
* @description Schedules the cell view insertion into the appropriate layer view.
|
|
34474
|
+
* The actual insertion will be performed during the paper update cycle.
|
|
34475
|
+
* @param {dia.Cell} cell - The cell model whose view should be inserted.
|
|
34476
|
+
* @param {Object} [opt] - Update options.
|
|
34477
|
+
*/
|
|
34478
|
+
requestCellViewInsertion(cell, opt) {
|
|
34479
|
+
const viewLike = this._getCellViewLike(cell);
|
|
34480
|
+
if (!viewLike) return;
|
|
34481
|
+
this.requestViewUpdate(viewLike, this.FLAG_INSERT, viewLike.UPDATE_PRIORITY, opt);
|
|
34482
|
+
},
|
|
34483
|
+
/**
|
|
34484
|
+
* @private
|
|
34485
|
+
* Helper method for addLayerView and moveLayerView methods
|
|
34486
|
+
*/
|
|
34487
|
+
_getBeforeLayerViewFromOptions(layerView, options) {
|
|
34488
|
+
let {
|
|
34489
|
+
before = null,
|
|
34490
|
+
index
|
|
34491
|
+
} = options;
|
|
34492
|
+
if (before && index !== undefined) {
|
|
34493
|
+
throw new Error('dia.Paper: Options "before" and "index" are mutually exclusive.');
|
|
34494
|
+
}
|
|
34495
|
+
let computedBefore;
|
|
34496
|
+
if (index !== undefined) {
|
|
34497
|
+
const {
|
|
34498
|
+
_layers: {
|
|
34499
|
+
order
|
|
34500
|
+
}
|
|
34501
|
+
} = this;
|
|
34502
|
+
if (index >= order.length) {
|
|
34503
|
+
// If index is greater than the number of layers,
|
|
34504
|
+
// return before as null (move to the end).
|
|
34505
|
+
computedBefore = null;
|
|
34506
|
+
} else if (index < 0) {
|
|
34507
|
+
// If index is negative, move to the beginning.
|
|
34508
|
+
computedBefore = order[0];
|
|
32754
34509
|
} else {
|
|
32755
|
-
|
|
34510
|
+
const originalIndex = order.indexOf(layerView.id);
|
|
34511
|
+
if (originalIndex !== -1 && index > originalIndex) {
|
|
34512
|
+
// If moving a layer upwards in the stack, we need to adjust the index
|
|
34513
|
+
// to account for the layer being removed from its original position.
|
|
34514
|
+
index += 1;
|
|
34515
|
+
}
|
|
34516
|
+
// Otherwise, get the layer ID at the specified index.
|
|
34517
|
+
computedBefore = order[index] || null;
|
|
32756
34518
|
}
|
|
34519
|
+
} else {
|
|
34520
|
+
computedBefore = before;
|
|
32757
34521
|
}
|
|
32758
|
-
return
|
|
34522
|
+
return computedBefore ? this.getLayerView(computedBefore) : null;
|
|
32759
34523
|
},
|
|
32760
|
-
|
|
32761
|
-
|
|
34524
|
+
/**
|
|
34525
|
+
* @public
|
|
34526
|
+
* @description Adds the layer view to the paper.
|
|
34527
|
+
* @param {dia.LayerView} layerView - The layer view to add.
|
|
34528
|
+
* @param {Object} [options] - Adding options.
|
|
34529
|
+
* @param {string|dia.GraphLayer} [options.before] - Layer id or layer model before
|
|
34530
|
+
*/
|
|
34531
|
+
addLayerView(layerView, options = {}) {
|
|
34532
|
+
this._registerLayerView(layerView);
|
|
34533
|
+
const beforeLayerView = this._getBeforeLayerViewFromOptions(layerView, options);
|
|
34534
|
+
this.insertLayerView(layerView, beforeLayerView);
|
|
32762
34535
|
},
|
|
32763
|
-
|
|
32764
|
-
|
|
32765
|
-
|
|
32766
|
-
|
|
32767
|
-
|
|
32768
|
-
|
|
34536
|
+
/**
|
|
34537
|
+
* @public
|
|
34538
|
+
* @description Moves the layer view.
|
|
34539
|
+
* @param {Paper.LayerRef} layerRef - The layer view reference to move.
|
|
34540
|
+
* @param {Object} [options] - Moving options.
|
|
34541
|
+
* @param {Paper.LayerRef} [options.before] - Layer id or layer model before
|
|
34542
|
+
* @param {number} [options.index] - Zero-based index to which to move the layer view.
|
|
34543
|
+
*/
|
|
34544
|
+
moveLayerView(layerRef, options = {}) {
|
|
34545
|
+
const layerView = this.getLayerView(layerRef);
|
|
34546
|
+
const beforeLayerView = this._getBeforeLayerViewFromOptions(layerView, options);
|
|
34547
|
+
this.insertLayerView(layerView, beforeLayerView);
|
|
32769
34548
|
},
|
|
32770
|
-
|
|
32771
|
-
|
|
32772
|
-
|
|
32773
|
-
|
|
32774
|
-
|
|
32775
|
-
|
|
32776
|
-
|
|
32777
|
-
|
|
32778
|
-
|
|
32779
|
-
|
|
34549
|
+
/**
|
|
34550
|
+
* @protected
|
|
34551
|
+
* @description Inserts the layer view into the paper.
|
|
34552
|
+
* If the layer view already exists in the paper, it is moved to the new position.
|
|
34553
|
+
* @param {dia.LayerView} layerView - The layer view to insert.
|
|
34554
|
+
* @param {dia.LayerView} [before] - Layer view before
|
|
34555
|
+
* which the layer view should be inserted.
|
|
34556
|
+
*/
|
|
34557
|
+
insertLayerView(layerView, beforeLayerView) {
|
|
34558
|
+
const layerId = layerView.id;
|
|
32780
34559
|
const {
|
|
32781
|
-
|
|
32782
|
-
|
|
32783
|
-
|
|
32784
|
-
|
|
32785
|
-
|
|
32786
|
-
|
|
32787
|
-
|
|
32788
|
-
|
|
34560
|
+
_layers: {
|
|
34561
|
+
order
|
|
34562
|
+
}
|
|
34563
|
+
} = this;
|
|
34564
|
+
const currentLayerIndex = order.indexOf(layerId);
|
|
34565
|
+
|
|
34566
|
+
// Should the layer view be inserted before another layer view?
|
|
34567
|
+
if (beforeLayerView) {
|
|
34568
|
+
const beforeLayerViewId = beforeLayerView.id;
|
|
34569
|
+
if (layerId === beforeLayerViewId) {
|
|
34570
|
+
// The layer view is already in the right place.
|
|
34571
|
+
return;
|
|
34572
|
+
}
|
|
34573
|
+
let beforeLayerPosition = order.indexOf(beforeLayerViewId);
|
|
34574
|
+
// Remove from the `order` list if the layer view is already in the order.
|
|
34575
|
+
if (currentLayerIndex !== -1) {
|
|
34576
|
+
if (currentLayerIndex < beforeLayerPosition) {
|
|
34577
|
+
beforeLayerPosition -= 1;
|
|
34578
|
+
}
|
|
34579
|
+
order.splice(currentLayerIndex, 1);
|
|
34580
|
+
}
|
|
34581
|
+
order.splice(beforeLayerPosition, 0, layerId);
|
|
32789
34582
|
this.layers.insertBefore(layerView.el, beforeLayerView.el);
|
|
34583
|
+
return;
|
|
32790
34584
|
}
|
|
34585
|
+
|
|
34586
|
+
// Remove from the `order` list if the layer view is already in the order.
|
|
34587
|
+
// This is needed for the case when the layer view is inserted in the new position.
|
|
34588
|
+
if (currentLayerIndex !== -1) {
|
|
34589
|
+
order.splice(currentLayerIndex, 1);
|
|
34590
|
+
}
|
|
34591
|
+
order.push(layerId);
|
|
34592
|
+
this.layers.appendChild(layerView.el);
|
|
32791
34593
|
},
|
|
32792
|
-
|
|
32793
|
-
|
|
32794
|
-
|
|
32795
|
-
|
|
32796
|
-
|
|
32797
|
-
|
|
32798
|
-
insertBefore
|
|
32799
|
-
});
|
|
32800
|
-
},
|
|
32801
|
-
getLayerNames() {
|
|
32802
|
-
// Returns a sorted array of layer names.
|
|
34594
|
+
/**
|
|
34595
|
+
* @protected
|
|
34596
|
+
* @description Returns an array of layer view ids in the order they are rendered.
|
|
34597
|
+
* @returns {string[]} An array of layer view ids.
|
|
34598
|
+
*/
|
|
34599
|
+
getLayerViewOrder() {
|
|
32803
34600
|
return this._layers.order.slice();
|
|
32804
34601
|
},
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
34602
|
+
/**
|
|
34603
|
+
* @public
|
|
34604
|
+
* @description Returns an array of layer views in the order they are rendered.
|
|
34605
|
+
* @returns {dia.LayerView[]} An array of layer views.
|
|
34606
|
+
*/
|
|
34607
|
+
getLayerViews() {
|
|
34608
|
+
return this.getLayerViewOrder().map(id => this.getLayerView(id));
|
|
34609
|
+
},
|
|
34610
|
+
/**
|
|
34611
|
+
* @public
|
|
34612
|
+
* @description Returns an array of graph layer views in the order they are rendered.
|
|
34613
|
+
* @returns {dia.GraphLayerView[]} An array of graph layer views.
|
|
34614
|
+
*/
|
|
34615
|
+
getGraphLayerViews() {
|
|
34616
|
+
const {
|
|
34617
|
+
_layers: {
|
|
34618
|
+
viewsMap
|
|
34619
|
+
}
|
|
34620
|
+
} = this;
|
|
34621
|
+
return this.model.getLayers().map(layer => viewsMap[layer.id]);
|
|
32808
34622
|
},
|
|
32809
34623
|
render: function () {
|
|
32810
34624
|
this.renderChildren();
|
|
@@ -32824,7 +34638,7 @@ var joint = (function (exports) {
|
|
|
32824
34638
|
this.svg = svg;
|
|
32825
34639
|
this.defs = defs;
|
|
32826
34640
|
this.layers = layers;
|
|
32827
|
-
this.
|
|
34641
|
+
this.renderLayerViews();
|
|
32828
34642
|
V.ensureId(svg);
|
|
32829
34643
|
this.addStylesheet(stylesheet);
|
|
32830
34644
|
if (options.background) {
|
|
@@ -32839,60 +34653,79 @@ var joint = (function (exports) {
|
|
|
32839
34653
|
if (!css) return;
|
|
32840
34654
|
V(this.svg).prepend(V.createSVGStyle(css));
|
|
32841
34655
|
},
|
|
32842
|
-
|
|
32843
|
-
|
|
32844
|
-
|
|
32845
|
-
|
|
32846
|
-
|
|
32847
|
-
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
|
|
32853
|
-
|
|
34656
|
+
/**
|
|
34657
|
+
* @protected
|
|
34658
|
+
* @description Creates a layer view instance based on the provided options.
|
|
34659
|
+
* It finds the appropriate layer view constructor from the paper's
|
|
34660
|
+
* `layerViewNamespace` and instantiates it.
|
|
34661
|
+
* @param {*} options See `dia.LayerView` options.
|
|
34662
|
+
* @returns {dia.LayerView}
|
|
34663
|
+
*/
|
|
34664
|
+
createLayerView(options) {
|
|
34665
|
+
if (options == null) {
|
|
34666
|
+
throw new Error('dia.Paper: Layer view options are required.');
|
|
34667
|
+
}
|
|
34668
|
+
if (options.id == null) {
|
|
34669
|
+
throw new Error('dia.Paper: Layer view id is required.');
|
|
34670
|
+
}
|
|
34671
|
+
const viewOptions = clone$1(options);
|
|
34672
|
+
let viewConstructor;
|
|
34673
|
+
if (viewOptions.model) {
|
|
34674
|
+
const modelType = viewOptions.model.get('type') || viewOptions.model.constructor.name;
|
|
34675
|
+
const type = modelType + 'View';
|
|
34676
|
+
|
|
34677
|
+
// For backward compatibility we use the LegacyGraphLayerView for the default `cells` layer.
|
|
34678
|
+
if (this.model.layersController.legacyMode) {
|
|
34679
|
+
viewConstructor = LegacyGraphLayerView;
|
|
34680
|
+
} else {
|
|
34681
|
+
viewConstructor = this.layerViewNamespace[type] || LayerView;
|
|
34682
|
+
}
|
|
34683
|
+
} else {
|
|
34684
|
+
// Paper layers
|
|
34685
|
+
const type = viewOptions.type;
|
|
34686
|
+
viewConstructor = this.layerViewNamespace[type] || LayerView;
|
|
32854
34687
|
}
|
|
34688
|
+
return new viewConstructor(viewOptions);
|
|
32855
34689
|
},
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
|
|
32859
|
-
|
|
34690
|
+
/**
|
|
34691
|
+
* @protected
|
|
34692
|
+
* @description Renders all paper layer views and graph layer views.
|
|
34693
|
+
*/
|
|
34694
|
+
renderLayerViews: function () {
|
|
34695
|
+
this._removeLayerViews();
|
|
34696
|
+
// Render the paper layers.
|
|
34697
|
+
this.renderImplicitLayerViews();
|
|
34698
|
+
// Render the layers.
|
|
34699
|
+
this.renderGraphLayerViews();
|
|
34700
|
+
// Ensure that essential layer views are present.
|
|
34701
|
+
this.assertLayerViews();
|
|
32860
34702
|
},
|
|
32861
|
-
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
|
|
32868
|
-
const
|
|
32869
|
-
const
|
|
34703
|
+
/**
|
|
34704
|
+
* @protected
|
|
34705
|
+
* @description Ensures that essential layer views are present on the paper.
|
|
34706
|
+
* @throws {Error} if any of the essential layer views is missing
|
|
34707
|
+
*/
|
|
34708
|
+
assertLayerViews: function () {
|
|
34709
|
+
// Throws an exception if essential layer views are missing.
|
|
34710
|
+
const cellsLayerView = this.getLayerView(this.model.getDefaultLayer().id);
|
|
34711
|
+
const toolsLayerView = this.getLayerView(paperLayers.TOOLS);
|
|
34712
|
+
const labelsLayerView = this.getLayerView(paperLayers.LABELS);
|
|
34713
|
+
|
|
32870
34714
|
// backwards compatibility
|
|
32871
34715
|
this.tools = toolsLayerView.el;
|
|
32872
34716
|
this.cells = this.viewport = cellsLayerView.el;
|
|
32873
|
-
//
|
|
32874
|
-
|
|
34717
|
+
// Backwards compatibility: same as `LegacyGraphLayerView` we keep
|
|
34718
|
+
// the `viewport` class on the labels layer.
|
|
32875
34719
|
labelsLayerView.vel.addClass(addClassNamePrefix('viewport'));
|
|
32876
|
-
cellsLayerView.el.style.webkitUserSelect = 'none';
|
|
32877
|
-
cellsLayerView.el.style.userSelect = 'none';
|
|
32878
34720
|
labelsLayerView.el.style.webkitUserSelect = 'none';
|
|
32879
34721
|
labelsLayerView.el.style.userSelect = 'none';
|
|
32880
34722
|
},
|
|
32881
|
-
|
|
32882
|
-
|
|
32883
|
-
|
|
32884
|
-
|
|
32885
|
-
|
|
32886
|
-
|
|
32887
|
-
Object.values(viewsMap).forEach(layerView => this._removeLayer(layerView));
|
|
32888
|
-
},
|
|
32889
|
-
resetLayers: function () {
|
|
32890
|
-
const {
|
|
32891
|
-
_layers: {
|
|
32892
|
-
viewsMap
|
|
32893
|
-
}
|
|
32894
|
-
} = this;
|
|
32895
|
-
Object.values(viewsMap).forEach(layerView => layerView.removePivots());
|
|
34723
|
+
/**
|
|
34724
|
+
* @protected
|
|
34725
|
+
* @description Resets all layer views.
|
|
34726
|
+
*/
|
|
34727
|
+
resetLayerViews: function () {
|
|
34728
|
+
this.getLayerViews().forEach(layerView => layerView.reset());
|
|
32896
34729
|
},
|
|
32897
34730
|
update: function () {
|
|
32898
34731
|
if (this._background) {
|
|
@@ -33008,26 +34841,25 @@ var joint = (function (exports) {
|
|
|
33008
34841
|
return this;
|
|
33009
34842
|
},
|
|
33010
34843
|
clientMatrix: function () {
|
|
33011
|
-
return V.createSVGMatrix(this.
|
|
34844
|
+
return V.createSVGMatrix(this.layers.getScreenCTM());
|
|
33012
34845
|
},
|
|
33013
34846
|
requestConnectedLinksUpdate: function (view, priority, opt) {
|
|
33014
|
-
if (view
|
|
33015
|
-
|
|
33016
|
-
|
|
33017
|
-
|
|
33018
|
-
|
|
33019
|
-
|
|
33020
|
-
|
|
33021
|
-
|
|
33022
|
-
|
|
33023
|
-
|
|
33024
|
-
|
|
33025
|
-
|
|
33026
|
-
}
|
|
34847
|
+
if (!view || !view[CELL_VIEW_MARKER]) return;
|
|
34848
|
+
var model = view.model;
|
|
34849
|
+
var links = this.model.getConnectedLinks(model);
|
|
34850
|
+
for (var j = 0, n = links.length; j < n; j++) {
|
|
34851
|
+
var link = links[j];
|
|
34852
|
+
var linkView = this._getCellViewLike(link);
|
|
34853
|
+
if (!linkView) continue;
|
|
34854
|
+
// We do not have to update placeholder views.
|
|
34855
|
+
// They will be updated on initial render.
|
|
34856
|
+
if (linkView[CELL_VIEW_PLACEHOLDER_MARKER]) continue;
|
|
34857
|
+
var nextPriority = Math.max(priority + 1, linkView.UPDATE_PRIORITY);
|
|
34858
|
+
this.scheduleViewUpdate(linkView, linkView.getFlag(LinkView.Flags.UPDATE), nextPriority, opt);
|
|
33027
34859
|
}
|
|
33028
34860
|
},
|
|
33029
34861
|
forcePostponedViewUpdate: function (view, flag) {
|
|
33030
|
-
if (!view || !
|
|
34862
|
+
if (!view || !view[CELL_VIEW_MARKER]) return false;
|
|
33031
34863
|
const model = view.model;
|
|
33032
34864
|
if (model.isElement()) return false;
|
|
33033
34865
|
const dumpOptions = {
|
|
@@ -33142,6 +34974,12 @@ var joint = (function (exports) {
|
|
|
33142
34974
|
const {
|
|
33143
34975
|
model
|
|
33144
34976
|
} = view;
|
|
34977
|
+
if (view[GRAPH_LAYER_VIEW_MARKER]) {
|
|
34978
|
+
if (flag & FLAG_REMOVE) {
|
|
34979
|
+
this.removeLayerView(view);
|
|
34980
|
+
return 0;
|
|
34981
|
+
}
|
|
34982
|
+
}
|
|
33145
34983
|
if (view[CELL_VIEW_MARKER]) {
|
|
33146
34984
|
if (flag & FLAG_REMOVE) {
|
|
33147
34985
|
this.removeView(model);
|
|
@@ -33741,7 +35579,7 @@ var joint = (function (exports) {
|
|
|
33741
35579
|
}
|
|
33742
35580
|
this.options.frozen = updates.keyFrozen = false;
|
|
33743
35581
|
if (updates.sort) {
|
|
33744
|
-
this.
|
|
35582
|
+
this.sortLayerViews();
|
|
33745
35583
|
updates.sort = false;
|
|
33746
35584
|
}
|
|
33747
35585
|
},
|
|
@@ -33769,8 +35607,8 @@ var joint = (function (exports) {
|
|
|
33769
35607
|
this.freeze();
|
|
33770
35608
|
this._updates.disabled = true;
|
|
33771
35609
|
//clean up all DOM elements/views to prevent memory leaks
|
|
33772
|
-
this.removeLayers();
|
|
33773
35610
|
this.removeViews();
|
|
35611
|
+
this._removeLayerViews();
|
|
33774
35612
|
},
|
|
33775
35613
|
getComputedSize: function () {
|
|
33776
35614
|
var options = this.options;
|
|
@@ -34008,7 +35846,17 @@ var joint = (function (exports) {
|
|
|
34008
35846
|
if (opt && opt.useModelGeometry) {
|
|
34009
35847
|
return this.model.getBBox() || new Rect();
|
|
34010
35848
|
}
|
|
34011
|
-
|
|
35849
|
+
const graphLayerViews = this.getGraphLayerViews();
|
|
35850
|
+
// Return an empty rectangle if there are no layers
|
|
35851
|
+
// should not happen in practice
|
|
35852
|
+
if (graphLayerViews.length === 0) {
|
|
35853
|
+
return new Rect();
|
|
35854
|
+
}
|
|
35855
|
+
|
|
35856
|
+
// Combine content area rectangles from all layers,
|
|
35857
|
+
// considering only graph layer views to exclude non-cell elements (e.g., grid, tools)
|
|
35858
|
+
const bbox = Rect.fromRectUnion(...graphLayerViews.map(view => view.vel.getBBox()));
|
|
35859
|
+
return bbox;
|
|
34012
35860
|
},
|
|
34013
35861
|
// Return the dimensions of the content bbox in the paper units (as it appears on screen).
|
|
34014
35862
|
getContentBBox: function (opt) {
|
|
@@ -34084,7 +35932,7 @@ var joint = (function (exports) {
|
|
|
34084
35932
|
cid,
|
|
34085
35933
|
model: cell,
|
|
34086
35934
|
interactive,
|
|
34087
|
-
labelsLayer: labelsLayer === true ?
|
|
35935
|
+
labelsLayer: labelsLayer === true ? paperLayers.LABELS : labelsLayer
|
|
34088
35936
|
});
|
|
34089
35937
|
},
|
|
34090
35938
|
_resolveCellViewClass: function (cell) {
|
|
@@ -34245,7 +36093,7 @@ var joint = (function (exports) {
|
|
|
34245
36093
|
this.unfreeze({
|
|
34246
36094
|
key
|
|
34247
36095
|
});
|
|
34248
|
-
this.
|
|
36096
|
+
this.sortLayerViews();
|
|
34249
36097
|
},
|
|
34250
36098
|
removeViews: function () {
|
|
34251
36099
|
// Remove all views and their references from the paper.
|
|
@@ -34259,7 +36107,7 @@ var joint = (function (exports) {
|
|
|
34259
36107
|
this._viewPlaceholders = {};
|
|
34260
36108
|
this._idToCid = {};
|
|
34261
36109
|
},
|
|
34262
|
-
|
|
36110
|
+
sortLayerViews: function () {
|
|
34263
36111
|
if (!this.isExactSorting()) {
|
|
34264
36112
|
// noop
|
|
34265
36113
|
return;
|
|
@@ -34269,38 +36117,16 @@ var joint = (function (exports) {
|
|
|
34269
36117
|
this._updates.sort = true;
|
|
34270
36118
|
return;
|
|
34271
36119
|
}
|
|
34272
|
-
this.
|
|
36120
|
+
this.sortLayerViewsExact();
|
|
34273
36121
|
},
|
|
34274
|
-
|
|
34275
|
-
|
|
34276
|
-
// associated model `z` attribute.
|
|
34277
|
-
|
|
34278
|
-
var cellNodes = Array.from(this.cells.childNodes).filter(node => node.getAttribute('model-id'));
|
|
34279
|
-
var cells = this.model.get('cells');
|
|
34280
|
-
sortElements(cellNodes, function (a, b) {
|
|
34281
|
-
var cellA = cells.get(a.getAttribute('model-id'));
|
|
34282
|
-
var cellB = cells.get(b.getAttribute('model-id'));
|
|
34283
|
-
var zA = cellA.attributes.z || 0;
|
|
34284
|
-
var zB = cellB.attributes.z || 0;
|
|
34285
|
-
return zA === zB ? 0 : zA < zB ? -1 : 1;
|
|
34286
|
-
});
|
|
36122
|
+
sortLayerViewsExact: function () {
|
|
36123
|
+
this.getGraphLayerViews().forEach(view => view.sortExact());
|
|
34287
36124
|
},
|
|
34288
36125
|
insertView: function (view, isInitialInsert) {
|
|
34289
|
-
|
|
34290
|
-
|
|
34291
|
-
|
|
34292
|
-
|
|
34293
|
-
const layerName = model.get('layer') || this.DEFAULT_CELL_LAYER;
|
|
34294
|
-
const layerView = this.getLayerView(layerName);
|
|
34295
|
-
switch (this.options.sorting) {
|
|
34296
|
-
case sortingTypes.APPROX:
|
|
34297
|
-
layerView.insertSortedNode(el, model.get('z'));
|
|
34298
|
-
break;
|
|
34299
|
-
case sortingTypes.EXACT:
|
|
34300
|
-
default:
|
|
34301
|
-
layerView.insertNode(el);
|
|
34302
|
-
break;
|
|
34303
|
-
}
|
|
36126
|
+
// layer can be null if it is added to the graph with 'dry' option
|
|
36127
|
+
const layerId = this.model.getCellLayerId(view.model);
|
|
36128
|
+
const layerView = this.getLayerView(layerId);
|
|
36129
|
+
layerView.insertCellView(view);
|
|
34304
36130
|
view.onMount(isInitialInsert);
|
|
34305
36131
|
},
|
|
34306
36132
|
_hideView: function (viewLike) {
|
|
@@ -34355,7 +36181,7 @@ var joint = (function (exports) {
|
|
|
34355
36181
|
// Find the first view climbing up the DOM tree starting at element `el`. Note that `el` can also
|
|
34356
36182
|
// be a selector or a jQuery object.
|
|
34357
36183
|
findView: function ($el) {
|
|
34358
|
-
var el = isString($el) ? this.
|
|
36184
|
+
var el = isString($el) ? this.layers.querySelector($el) : $el instanceof $ ? $el[0] : $el;
|
|
34359
36185
|
var id = this.findAttribute('model-id', el);
|
|
34360
36186
|
if (id) return this._views[id];
|
|
34361
36187
|
return undefined;
|
|
@@ -34393,7 +36219,7 @@ var joint = (function (exports) {
|
|
|
34393
36219
|
var views = this.model.getElements().map(this.findViewByModel, this);
|
|
34394
36220
|
return views.filter(function (view) {
|
|
34395
36221
|
return view && view.vel.getBBox({
|
|
34396
|
-
target: this.
|
|
36222
|
+
target: this.layers
|
|
34397
36223
|
}).containsPoint(p);
|
|
34398
36224
|
}, this);
|
|
34399
36225
|
},
|
|
@@ -34407,7 +36233,7 @@ var joint = (function (exports) {
|
|
|
34407
36233
|
var method = opt.strict ? 'containsRect' : 'intersect';
|
|
34408
36234
|
return views.filter(function (view) {
|
|
34409
36235
|
return view && rect[method](view.vel.getBBox({
|
|
34410
|
-
target: this.
|
|
36236
|
+
target: this.layers
|
|
34411
36237
|
}));
|
|
34412
36238
|
}, this);
|
|
34413
36239
|
},
|
|
@@ -35191,7 +37017,7 @@ var joint = (function (exports) {
|
|
|
35191
37017
|
if (this.GUARDED_TAG_NAMES.includes(target.tagName)) {
|
|
35192
37018
|
return true;
|
|
35193
37019
|
}
|
|
35194
|
-
if (view && view.model && view.model
|
|
37020
|
+
if (view && view.model && view.model[CELL_MARKER]) {
|
|
35195
37021
|
return false;
|
|
35196
37022
|
}
|
|
35197
37023
|
if (this.el === target || this.svg.contains(target)) {
|
|
@@ -35206,12 +37032,12 @@ var joint = (function (exports) {
|
|
|
35206
37032
|
options.gridSize = gridSize;
|
|
35207
37033
|
if (options.drawGrid && !options.drawGridSize) {
|
|
35208
37034
|
// Do not redraw the grid if the `drawGridSize` is set.
|
|
35209
|
-
this.getLayerView(
|
|
37035
|
+
this.getLayerView(paperLayers.GRID).renderGrid();
|
|
35210
37036
|
}
|
|
35211
37037
|
return this;
|
|
35212
37038
|
},
|
|
35213
37039
|
setGrid: function (drawGrid) {
|
|
35214
|
-
this.getLayerView(
|
|
37040
|
+
this.getLayerView(paperLayers.GRID).setGrid(drawGrid);
|
|
35215
37041
|
return this;
|
|
35216
37042
|
},
|
|
35217
37043
|
updateBackgroundImage: function (opt) {
|
|
@@ -35536,194 +37362,9 @@ var joint = (function (exports) {
|
|
|
35536
37362
|
}
|
|
35537
37363
|
}, {
|
|
35538
37364
|
sorting: sortingTypes,
|
|
35539
|
-
Layers:
|
|
35540
|
-
backgroundPatterns
|
|
35541
|
-
|
|
35542
|
-
// d b
|
|
35543
|
-
// q p
|
|
35544
|
-
|
|
35545
|
-
var canvas = document.createElement('canvas');
|
|
35546
|
-
var imgWidth = img.width;
|
|
35547
|
-
var imgHeight = img.height;
|
|
35548
|
-
canvas.width = 2 * imgWidth;
|
|
35549
|
-
canvas.height = 2 * imgHeight;
|
|
35550
|
-
var ctx = canvas.getContext('2d');
|
|
35551
|
-
// top-left image
|
|
35552
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35553
|
-
// xy-flipped bottom-right image
|
|
35554
|
-
ctx.setTransform(-1, 0, 0, -1, canvas.width, canvas.height);
|
|
35555
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35556
|
-
// x-flipped top-right image
|
|
35557
|
-
ctx.setTransform(-1, 0, 0, 1, canvas.width, 0);
|
|
35558
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35559
|
-
// y-flipped bottom-left image
|
|
35560
|
-
ctx.setTransform(1, 0, 0, -1, 0, canvas.height);
|
|
35561
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35562
|
-
return canvas;
|
|
35563
|
-
},
|
|
35564
|
-
flipX: function (img) {
|
|
35565
|
-
// d b
|
|
35566
|
-
// d b
|
|
35567
|
-
|
|
35568
|
-
var canvas = document.createElement('canvas');
|
|
35569
|
-
var imgWidth = img.width;
|
|
35570
|
-
var imgHeight = img.height;
|
|
35571
|
-
canvas.width = imgWidth * 2;
|
|
35572
|
-
canvas.height = imgHeight;
|
|
35573
|
-
var ctx = canvas.getContext('2d');
|
|
35574
|
-
// left image
|
|
35575
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35576
|
-
// flipped right image
|
|
35577
|
-
ctx.translate(2 * imgWidth, 0);
|
|
35578
|
-
ctx.scale(-1, 1);
|
|
35579
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35580
|
-
return canvas;
|
|
35581
|
-
},
|
|
35582
|
-
flipY: function (img) {
|
|
35583
|
-
// d d
|
|
35584
|
-
// q q
|
|
35585
|
-
|
|
35586
|
-
var canvas = document.createElement('canvas');
|
|
35587
|
-
var imgWidth = img.width;
|
|
35588
|
-
var imgHeight = img.height;
|
|
35589
|
-
canvas.width = imgWidth;
|
|
35590
|
-
canvas.height = imgHeight * 2;
|
|
35591
|
-
var ctx = canvas.getContext('2d');
|
|
35592
|
-
// top image
|
|
35593
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35594
|
-
// flipped bottom image
|
|
35595
|
-
ctx.translate(0, 2 * imgHeight);
|
|
35596
|
-
ctx.scale(1, -1);
|
|
35597
|
-
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
35598
|
-
return canvas;
|
|
35599
|
-
},
|
|
35600
|
-
watermark: function (img, opt) {
|
|
35601
|
-
// d
|
|
35602
|
-
// d
|
|
35603
|
-
|
|
35604
|
-
opt = opt || {};
|
|
35605
|
-
var imgWidth = img.width;
|
|
35606
|
-
var imgHeight = img.height;
|
|
35607
|
-
var canvas = document.createElement('canvas');
|
|
35608
|
-
canvas.width = imgWidth * 3;
|
|
35609
|
-
canvas.height = imgHeight * 3;
|
|
35610
|
-
var ctx = canvas.getContext('2d');
|
|
35611
|
-
var angle = isNumber(opt.watermarkAngle) ? -opt.watermarkAngle : -20;
|
|
35612
|
-
var radians = toRad(angle);
|
|
35613
|
-
var stepX = canvas.width / 4;
|
|
35614
|
-
var stepY = canvas.height / 4;
|
|
35615
|
-
for (var i = 0; i < 4; i++) {
|
|
35616
|
-
for (var j = 0; j < 4; j++) {
|
|
35617
|
-
if ((i + j) % 2 > 0) {
|
|
35618
|
-
// reset the current transformations
|
|
35619
|
-
ctx.setTransform(1, 0, 0, 1, (2 * i - 1) * stepX, (2 * j - 1) * stepY);
|
|
35620
|
-
ctx.rotate(radians);
|
|
35621
|
-
ctx.drawImage(img, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight);
|
|
35622
|
-
}
|
|
35623
|
-
}
|
|
35624
|
-
}
|
|
35625
|
-
return canvas;
|
|
35626
|
-
}
|
|
35627
|
-
},
|
|
35628
|
-
gridPatterns: {
|
|
35629
|
-
dot: [{
|
|
35630
|
-
color: '#AAAAAA',
|
|
35631
|
-
thickness: 1,
|
|
35632
|
-
markup: 'rect',
|
|
35633
|
-
render: function (el, opt) {
|
|
35634
|
-
V(el).attr({
|
|
35635
|
-
width: opt.thickness,
|
|
35636
|
-
height: opt.thickness,
|
|
35637
|
-
fill: opt.color
|
|
35638
|
-
});
|
|
35639
|
-
}
|
|
35640
|
-
}],
|
|
35641
|
-
fixedDot: [{
|
|
35642
|
-
color: '#AAAAAA',
|
|
35643
|
-
thickness: 1,
|
|
35644
|
-
markup: 'rect',
|
|
35645
|
-
render: function (el, opt) {
|
|
35646
|
-
V(el).attr({
|
|
35647
|
-
fill: opt.color
|
|
35648
|
-
});
|
|
35649
|
-
},
|
|
35650
|
-
update: function (el, opt, paper) {
|
|
35651
|
-
const {
|
|
35652
|
-
sx,
|
|
35653
|
-
sy
|
|
35654
|
-
} = paper.scale();
|
|
35655
|
-
const width = sx <= 1 ? opt.thickness : opt.thickness / sx;
|
|
35656
|
-
const height = sy <= 1 ? opt.thickness : opt.thickness / sy;
|
|
35657
|
-
V(el).attr({
|
|
35658
|
-
width,
|
|
35659
|
-
height
|
|
35660
|
-
});
|
|
35661
|
-
}
|
|
35662
|
-
}],
|
|
35663
|
-
mesh: [{
|
|
35664
|
-
color: '#AAAAAA',
|
|
35665
|
-
thickness: 1,
|
|
35666
|
-
markup: 'path',
|
|
35667
|
-
render: function (el, opt) {
|
|
35668
|
-
var d;
|
|
35669
|
-
var width = opt.width;
|
|
35670
|
-
var height = opt.height;
|
|
35671
|
-
var thickness = opt.thickness;
|
|
35672
|
-
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
35673
|
-
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
35674
|
-
} else {
|
|
35675
|
-
d = 'M 0 0 0 0';
|
|
35676
|
-
}
|
|
35677
|
-
V(el).attr({
|
|
35678
|
-
'd': d,
|
|
35679
|
-
stroke: opt.color,
|
|
35680
|
-
'stroke-width': opt.thickness
|
|
35681
|
-
});
|
|
35682
|
-
}
|
|
35683
|
-
}],
|
|
35684
|
-
doubleMesh: [{
|
|
35685
|
-
color: '#AAAAAA',
|
|
35686
|
-
thickness: 1,
|
|
35687
|
-
markup: 'path',
|
|
35688
|
-
render: function (el, opt) {
|
|
35689
|
-
var d;
|
|
35690
|
-
var width = opt.width;
|
|
35691
|
-
var height = opt.height;
|
|
35692
|
-
var thickness = opt.thickness;
|
|
35693
|
-
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
35694
|
-
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
35695
|
-
} else {
|
|
35696
|
-
d = 'M 0 0 0 0';
|
|
35697
|
-
}
|
|
35698
|
-
V(el).attr({
|
|
35699
|
-
'd': d,
|
|
35700
|
-
stroke: opt.color,
|
|
35701
|
-
'stroke-width': opt.thickness
|
|
35702
|
-
});
|
|
35703
|
-
}
|
|
35704
|
-
}, {
|
|
35705
|
-
color: '#000000',
|
|
35706
|
-
thickness: 3,
|
|
35707
|
-
scaleFactor: 4,
|
|
35708
|
-
markup: 'path',
|
|
35709
|
-
render: function (el, opt) {
|
|
35710
|
-
var d;
|
|
35711
|
-
var width = opt.width;
|
|
35712
|
-
var height = opt.height;
|
|
35713
|
-
var thickness = opt.thickness;
|
|
35714
|
-
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
35715
|
-
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
35716
|
-
} else {
|
|
35717
|
-
d = 'M 0 0 0 0';
|
|
35718
|
-
}
|
|
35719
|
-
V(el).attr({
|
|
35720
|
-
'd': d,
|
|
35721
|
-
stroke: opt.color,
|
|
35722
|
-
'stroke-width': opt.thickness
|
|
35723
|
-
});
|
|
35724
|
-
}
|
|
35725
|
-
}]
|
|
35726
|
-
}
|
|
37365
|
+
Layers: paperLayers,
|
|
37366
|
+
backgroundPatterns,
|
|
37367
|
+
gridPatterns
|
|
35727
37368
|
});
|
|
35728
37369
|
|
|
35729
37370
|
const ToolView = View.extend({
|
|
@@ -35822,7 +37463,7 @@ var joint = (function (exports) {
|
|
|
35822
37463
|
tools: null,
|
|
35823
37464
|
relatedView: null,
|
|
35824
37465
|
name: null
|
|
35825
|
-
// layer?:
|
|
37466
|
+
// layer?: Paper.Layers.TOOLS
|
|
35826
37467
|
// z?: number
|
|
35827
37468
|
},
|
|
35828
37469
|
configure: function (options) {
|
|
@@ -35936,7 +37577,7 @@ var joint = (function (exports) {
|
|
|
35936
37577
|
},
|
|
35937
37578
|
getLayer() {
|
|
35938
37579
|
const {
|
|
35939
|
-
layer =
|
|
37580
|
+
layer = Paper.Layers.TOOLS
|
|
35940
37581
|
} = this.options;
|
|
35941
37582
|
return layer;
|
|
35942
37583
|
},
|
|
@@ -35965,21 +37606,26 @@ var joint = (function (exports) {
|
|
|
35965
37606
|
|
|
35966
37607
|
var index$2 = {
|
|
35967
37608
|
__proto__: null,
|
|
35968
|
-
CELL_VIEW_MARKER: CELL_VIEW_MARKER,
|
|
35969
37609
|
Cell: Cell,
|
|
37610
|
+
CellCollection: CellCollection,
|
|
35970
37611
|
CellView: CellView,
|
|
37612
|
+
DEFAULT_GRAPH_LAYER_TYPE: DEFAULT_GRAPH_LAYER_TYPE,
|
|
35971
37613
|
Element: Element$1,
|
|
35972
37614
|
ElementView: ElementView,
|
|
35973
37615
|
Graph: Graph,
|
|
37616
|
+
GraphLayer: GraphLayer,
|
|
37617
|
+
GraphLayerCollection: GraphLayerCollection,
|
|
37618
|
+
GraphLayerView: GraphLayerView,
|
|
37619
|
+
GridLayerView: GridLayerView,
|
|
35974
37620
|
HighlighterView: HighlighterView,
|
|
35975
|
-
|
|
37621
|
+
LayerView: LayerView,
|
|
35976
37622
|
Link: Link$1,
|
|
35977
37623
|
LinkView: LinkView,
|
|
35978
37624
|
Paper: Paper,
|
|
35979
|
-
PaperLayer: PaperLayer,
|
|
35980
37625
|
ToolView: ToolView,
|
|
35981
37626
|
ToolsView: ToolsView,
|
|
35982
|
-
attributes: attributes
|
|
37627
|
+
attributes: attributes,
|
|
37628
|
+
sortingTypes: sortingTypes
|
|
35983
37629
|
};
|
|
35984
37630
|
|
|
35985
37631
|
// Vertex Handles
|
|
@@ -37986,7 +39632,7 @@ var joint = (function (exports) {
|
|
|
37986
39632
|
Remove: Remove
|
|
37987
39633
|
};
|
|
37988
39634
|
|
|
37989
|
-
var version = "4.2.0-
|
|
39635
|
+
var version = "4.2.0-beta.2";
|
|
37990
39636
|
|
|
37991
39637
|
const Vectorizer = V;
|
|
37992
39638
|
const layout$1 = {
|