@joint/core 4.2.0-alpha.1 → 4.2.0-beta.1
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 +2492 -853
- package/dist/joint.min.js +2 -3
- package/dist/joint.nowrap.js +2492 -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 +7 -7
- 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.1 (2025-11-03) - 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,7 @@ var joint = (function (exports) {
|
|
|
21720
21760
|
},
|
|
21721
21761
|
// Define how to uniquely identify models in the collection.
|
|
21722
21762
|
modelId: function (attrs, idAttribute) {
|
|
21723
|
-
return attrs[idAttribute || this.model.prototype
|
|
21763
|
+
return attrs[idAttribute || this.model.prototype?.idAttribute || 'id'];
|
|
21724
21764
|
},
|
|
21725
21765
|
// Get an iterator of all models in this collection.
|
|
21726
21766
|
values: function () {
|
|
@@ -21777,17 +21817,17 @@ var joint = (function (exports) {
|
|
|
21777
21817
|
_reset: function () {
|
|
21778
21818
|
this.length = 0;
|
|
21779
21819
|
this.models = [];
|
|
21780
|
-
this._byId =
|
|
21820
|
+
this._byId = new Map();
|
|
21781
21821
|
},
|
|
21782
21822
|
// Prepare a hash of attributes (or other model) to be added to this
|
|
21783
21823
|
// collection.
|
|
21784
21824
|
_prepareModel: function (attrs, options) {
|
|
21785
21825
|
if (this._isModel(attrs)) {
|
|
21786
|
-
if (!attrs.collection) attrs.collection = this;
|
|
21826
|
+
if (!options.dry && !attrs.collection) attrs.collection = this;
|
|
21787
21827
|
return attrs;
|
|
21788
21828
|
}
|
|
21789
21829
|
options = options ? clone$1(options) : {};
|
|
21790
|
-
options.collection = this;
|
|
21830
|
+
if (!options.dry) options.collection = this;
|
|
21791
21831
|
var model;
|
|
21792
21832
|
if (this.model.prototype) {
|
|
21793
21833
|
model = new this.model(attrs, options);
|
|
@@ -21811,12 +21851,12 @@ var joint = (function (exports) {
|
|
|
21811
21851
|
|
|
21812
21852
|
// Remove references before triggering 'remove' event to prevent an
|
|
21813
21853
|
// infinite loop. #3693
|
|
21814
|
-
|
|
21854
|
+
this._byId.delete(model.cid);
|
|
21815
21855
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21816
|
-
if (id != null)
|
|
21856
|
+
if (id != null) this._byId.delete(id);
|
|
21817
21857
|
if (!options.silent) {
|
|
21818
21858
|
options.index = index;
|
|
21819
|
-
model.trigger('remove', model, this, options);
|
|
21859
|
+
model.trigger(model.eventPrefix + 'remove', model, this, options);
|
|
21820
21860
|
}
|
|
21821
21861
|
removed.push(model);
|
|
21822
21862
|
this._removeReference(model, options);
|
|
@@ -21831,17 +21871,17 @@ var joint = (function (exports) {
|
|
|
21831
21871
|
},
|
|
21832
21872
|
// Internal method to create a model's ties to a collection.
|
|
21833
21873
|
_addReference: function (model, options) {
|
|
21834
|
-
this._byId
|
|
21874
|
+
this._byId.set(model.cid, model);
|
|
21835
21875
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21836
|
-
if (id != null) this._byId
|
|
21876
|
+
if (id != null) this._byId.set(id, model);
|
|
21837
21877
|
model.on('all', this._onModelEvent, this);
|
|
21838
21878
|
},
|
|
21839
21879
|
// Internal method to sever a model's ties to a collection.
|
|
21840
21880
|
_removeReference: function (model, options) {
|
|
21841
|
-
|
|
21881
|
+
this._byId.delete(model.cid);
|
|
21842
21882
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21843
|
-
if (id != null)
|
|
21844
|
-
if (this === model.collection) delete model.collection;
|
|
21883
|
+
if (id != null) this._byId.delete(id);
|
|
21884
|
+
if (!options.dry && this === model.collection) delete model.collection;
|
|
21845
21885
|
model.off('all', this._onModelEvent, this);
|
|
21846
21886
|
},
|
|
21847
21887
|
// Internal method called every time a model in the set fires an event.
|
|
@@ -21850,12 +21890,12 @@ var joint = (function (exports) {
|
|
|
21850
21890
|
// in other collections are ignored.
|
|
21851
21891
|
_onModelEvent: function (event, model, collection, options) {
|
|
21852
21892
|
if (model) {
|
|
21853
|
-
if ((event === 'add' || event === 'remove') && collection !== this) return;
|
|
21893
|
+
if ((event === model.eventPrefix + 'add' || event === model.eventPrefix + 'remove') && collection !== this) return;
|
|
21854
21894
|
if (event === 'changeId') {
|
|
21855
21895
|
var prevId = this.modelId(model.previousAttributes(), model.idAttribute);
|
|
21856
21896
|
var id = this.modelId(model.attributes, model.idAttribute);
|
|
21857
|
-
if (prevId != null)
|
|
21858
|
-
if (id != null) this._byId
|
|
21897
|
+
if (prevId != null) this._byId.delete(prevId);
|
|
21898
|
+
if (id != null) this._byId.set(id, model);
|
|
21859
21899
|
}
|
|
21860
21900
|
}
|
|
21861
21901
|
this.trigger.apply(this, arguments);
|
|
@@ -26681,21 +26721,180 @@ var joint = (function (exports) {
|
|
|
26681
26721
|
topRight: topRight
|
|
26682
26722
|
};
|
|
26683
26723
|
|
|
26684
|
-
|
|
26685
|
-
|
|
26686
|
-
|
|
26687
|
-
|
|
26688
|
-
|
|
26689
|
-
|
|
26690
|
-
|
|
26691
|
-
|
|
26692
|
-
|
|
26724
|
+
/**
|
|
26725
|
+
* @class GraphLayersController
|
|
26726
|
+
* @description Coordinates interactions between the graph and its layers.
|
|
26727
|
+
* Automatically moves cells between layers when the layer attribute changes.
|
|
26728
|
+
*/
|
|
26729
|
+
class GraphLayersController extends Listener {
|
|
26730
|
+
constructor(options) {
|
|
26731
|
+
super(options);
|
|
26732
|
+
|
|
26733
|
+
// Make sure there are no arguments passed to the callbacks.
|
|
26734
|
+
// See the `mvc.Listener` documentation for more details.
|
|
26735
|
+
this.callbackArguments = [];
|
|
26736
|
+
const graph = options.graph;
|
|
26737
|
+
if (!graph) {
|
|
26738
|
+
throw new Error('GraphLayersController: "graph" option is required.');
|
|
26739
|
+
}
|
|
26740
|
+
this.graph = graph;
|
|
26741
|
+
this.layerCollection = graph.layerCollection;
|
|
26742
|
+
this.startListening();
|
|
26743
|
+
}
|
|
26744
|
+
startListening() {
|
|
26745
|
+
// Handle all events from the layer collection and its inner cell collections.
|
|
26746
|
+
this.listenTo(this.layerCollection, 'all', this.onLayerCollectionEvent);
|
|
26747
|
+
}
|
|
26748
|
+
|
|
26749
|
+
/**
|
|
26750
|
+
* @description When a cell changes its layer attribute,
|
|
26751
|
+
* move the cell to the target layer.
|
|
26752
|
+
*/
|
|
26753
|
+
onCellChange(cell, options) {
|
|
26754
|
+
if (!cell.hasChanged(config$3.layerAttribute)) return;
|
|
26755
|
+
// Move the cell to the appropriate layer
|
|
26756
|
+
const targetLayerId = this.graph.getCellLayerId(cell);
|
|
26757
|
+
this.layerCollection.moveCellBetweenLayers(cell, targetLayerId, options);
|
|
26758
|
+
}
|
|
26759
|
+
|
|
26760
|
+
/**
|
|
26761
|
+
* @description When a cell is removed from a layer,
|
|
26762
|
+
* also remove its embeds and connected links from the graph.
|
|
26763
|
+
* Note: an embedded cell might come from a different layer,
|
|
26764
|
+
* so we can not use the layer's cell collection to remove it.
|
|
26765
|
+
*/
|
|
26766
|
+
onCellRemove(cell, options) {
|
|
26767
|
+
// If the cell is being moved from one layer to another,
|
|
26768
|
+
// no further action is needed.
|
|
26769
|
+
if (options.fromLayer) return;
|
|
26770
|
+
|
|
26771
|
+
// When replacing a cell, we do not want to remove its embeds or
|
|
26772
|
+
// unembed it from its parent.
|
|
26773
|
+
if (options.replace) return;
|
|
26774
|
+
|
|
26775
|
+
// First, unembed this cell from its parent cell if there is one.
|
|
26776
|
+
const parentCell = cell.getParentCell();
|
|
26777
|
+
if (parentCell) {
|
|
26778
|
+
parentCell.unembed(cell, options);
|
|
26779
|
+
}
|
|
26780
|
+
|
|
26781
|
+
// Remove also all the cells, which were embedded into this cell
|
|
26782
|
+
const embeddedCells = cell.getEmbeddedCells();
|
|
26783
|
+
for (let i = 0, n = embeddedCells.length; i < n; i++) {
|
|
26784
|
+
const embed = embeddedCells[i];
|
|
26785
|
+
if (embed) {
|
|
26786
|
+
this.layerCollection.removeCell(embed, options);
|
|
26787
|
+
}
|
|
26788
|
+
}
|
|
26789
|
+
|
|
26790
|
+
// When not clearing the whole graph or replacing the cell,
|
|
26791
|
+
// we don't want to remove the connected links.
|
|
26792
|
+
if (!options.clear) {
|
|
26793
|
+
// Applications might provide a `disconnectLinks` option set to `true` in order to
|
|
26794
|
+
// disconnect links when a cell is removed rather then removing them. The default
|
|
26795
|
+
// is to remove all the associated links.
|
|
26796
|
+
if (options.disconnectLinks) {
|
|
26797
|
+
this.graph.disconnectLinks(cell, options);
|
|
26798
|
+
} else {
|
|
26799
|
+
this.graph.removeLinks(cell, options);
|
|
26800
|
+
}
|
|
26801
|
+
}
|
|
26802
|
+
}
|
|
26803
|
+
onLayerCollectionEvent(eventName, model) {
|
|
26804
|
+
if (!model) return;
|
|
26805
|
+
if (model[CELL_MARKER]) {
|
|
26806
|
+
// First handle cell-specific cases that require custom processing,
|
|
26807
|
+
// then forward the event to the graph.
|
|
26808
|
+
// For example, when a cell is removed from a layer, its embeds and
|
|
26809
|
+
// connected links must be removed as well. Listeners on the graph
|
|
26810
|
+
// should receive removal notifications in the following order:
|
|
26811
|
+
// embeds → links → cell.
|
|
26812
|
+
switch (eventName) {
|
|
26813
|
+
case 'change':
|
|
26814
|
+
/* ('change', cell, options) */
|
|
26815
|
+
this.onCellChange.call(this, model, arguments[2]);
|
|
26816
|
+
break;
|
|
26817
|
+
case 'remove':
|
|
26818
|
+
/* ('remove', cell, collection, options) */
|
|
26819
|
+
// When a cell is removed from a layer,
|
|
26820
|
+
// ensure it is also removed from the graph.
|
|
26821
|
+
this.onCellRemove.call(this, model, arguments[3]);
|
|
26822
|
+
break;
|
|
26823
|
+
}
|
|
26824
|
+
// Notify the graph about cell events.
|
|
26825
|
+
this.forwardCellEvent.apply(this, arguments);
|
|
26826
|
+
return;
|
|
26827
|
+
}
|
|
26828
|
+
if (model[CELL_COLLECTION_MARKER]) {
|
|
26829
|
+
this.forwardCellCollectionEvent.apply(this, arguments);
|
|
26830
|
+
return;
|
|
26831
|
+
}
|
|
26832
|
+
if (model[GRAPH_LAYER_MARKER]) {
|
|
26833
|
+
this.forwardLayerEvent.apply(this, arguments);
|
|
26834
|
+
return;
|
|
26835
|
+
}
|
|
26836
|
+
if (model[GRAPH_LAYER_COLLECTION_MARKER]) {
|
|
26837
|
+
this.forwardLayerCollectionEvent.apply(this, arguments);
|
|
26838
|
+
return;
|
|
26839
|
+
}
|
|
26840
|
+
}
|
|
26841
|
+
forwardLayerEvent() {
|
|
26842
|
+
// Note: the layer event prefix is `layer:`
|
|
26843
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26844
|
+
}
|
|
26845
|
+
forwardCellEvent(eventName, cell) {
|
|
26846
|
+
// Moving a cell from one layer to another is an internal operation
|
|
26847
|
+
// that should not be exposed at the graph level.
|
|
26848
|
+
// The single `move` event is triggered instead.
|
|
26849
|
+
if ((eventName === 'remove' || eventName === 'add') && arguments[3]?.fromLayer) return;
|
|
26850
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26851
|
+
}
|
|
26852
|
+
forwardCellCollectionEvent(eventName) {
|
|
26853
|
+
// Do not forward `layer:remove` or `layer:sort` events to the graph
|
|
26854
|
+
if (eventName !== 'sort') return;
|
|
26855
|
+
// Backwards compatibility:
|
|
26856
|
+
// Trigger 'sort' event for cell collection 'sort' events
|
|
26857
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26858
|
+
}
|
|
26859
|
+
forwardLayerCollectionEvent(eventName) {
|
|
26860
|
+
if (eventName === 'reset') {
|
|
26861
|
+
// Currently, there is no need to forward `layers:reset` event.
|
|
26862
|
+
// The graph `fromJSON()` triggers a single `reset` event after
|
|
26863
|
+
// resetting cells, layers and attributes.
|
|
26864
|
+
return;
|
|
26865
|
+
}
|
|
26866
|
+
// Forward layer collection events with `layers:` prefix.
|
|
26867
|
+
// For example `layers:reset` event when the layer collection is reset
|
|
26868
|
+
arguments[0] = 'layers:' + arguments[0];
|
|
26869
|
+
this.graph.trigger.apply(this.graph, arguments);
|
|
26870
|
+
}
|
|
26871
|
+
}
|
|
26872
|
+
|
|
26873
|
+
/**
|
|
26874
|
+
* @class CellCollection
|
|
26875
|
+
* @description A CellCollection is a collection of cells which supports z-index management.
|
|
26876
|
+
* Additionally, it facilitates creating cell models from JSON using cellNamespace
|
|
26877
|
+
* and stores a reference to the graph when the cell model has been added.
|
|
26878
|
+
*/
|
|
26879
|
+
class CellCollection extends Collection {
|
|
26880
|
+
[CELL_COLLECTION_MARKER] = true;
|
|
26881
|
+
initialize(_models, opt) {
|
|
26882
|
+
this.layer = opt.layer;
|
|
26883
|
+
}
|
|
26884
|
+
|
|
26885
|
+
// Method for checking whether an object should be considered a model for
|
|
26886
|
+
// the purposes of adding to the collection.
|
|
26887
|
+
_isModel(model) {
|
|
26888
|
+
return Boolean(model[CELL_MARKER]);
|
|
26889
|
+
}
|
|
26890
|
+
|
|
26891
|
+
// Overriding the default `model` method to create cell models
|
|
26892
|
+
// based on their `type` attribute and the `cellNamespace` option.
|
|
26893
|
+
model(attrs, opt) {
|
|
26894
|
+
const namespace = this.cellNamespace;
|
|
26895
|
+
if (!namespace) {
|
|
26896
|
+
throw new Error('dia.CellCollection: cellNamespace is required to instantiate a Cell from JSON.');
|
|
26693
26897
|
}
|
|
26694
|
-
this.graph = opt.graph;
|
|
26695
|
-
},
|
|
26696
|
-
model: function (attrs, opt) {
|
|
26697
|
-
const collection = opt.collection;
|
|
26698
|
-
const namespace = collection.cellNamespace;
|
|
26699
26898
|
const {
|
|
26700
26899
|
type
|
|
26701
26900
|
} = attrs;
|
|
@@ -26706,56 +26905,470 @@ var joint = (function (exports) {
|
|
|
26706
26905
|
throw new Error(`dia.Graph: Could not find cell constructor for type: '${type}'. Make sure to add the constructor to 'cellNamespace'.`);
|
|
26707
26906
|
}
|
|
26708
26907
|
return new ModelClass(attrs, opt);
|
|
26709
|
-
}
|
|
26710
|
-
|
|
26711
|
-
|
|
26908
|
+
}
|
|
26909
|
+
|
|
26910
|
+
// Override to set graph reference
|
|
26911
|
+
_addReference(model, options) {
|
|
26912
|
+
super._addReference(model, options);
|
|
26913
|
+
|
|
26712
26914
|
// If not in `dry` mode and the model does not have a graph reference yet,
|
|
26713
26915
|
// set the reference.
|
|
26714
26916
|
if (!options.dry && !model.graph) {
|
|
26715
|
-
model.graph = this.graph;
|
|
26917
|
+
model.graph = this.layer.graph;
|
|
26716
26918
|
}
|
|
26717
|
-
}
|
|
26718
|
-
|
|
26719
|
-
|
|
26919
|
+
}
|
|
26920
|
+
|
|
26921
|
+
// Override to remove graph reference
|
|
26922
|
+
_removeReference(model, options) {
|
|
26923
|
+
super._removeReference(model, options);
|
|
26924
|
+
|
|
26720
26925
|
// If not in `dry` mode and the model has a reference to this exact graph,
|
|
26721
26926
|
// remove the reference.
|
|
26722
|
-
|
|
26927
|
+
// Note: graph reference is removed from the layer after the `remove` event is fired.
|
|
26928
|
+
// Due to this, event handlers can still access the graph during the `remove` event.
|
|
26929
|
+
if (!options.dry && model.graph === this.layer.graph) {
|
|
26723
26930
|
model.graph = null;
|
|
26724
26931
|
}
|
|
26725
|
-
}
|
|
26932
|
+
}
|
|
26933
|
+
|
|
26934
|
+
// remove graph reference additionally
|
|
26935
|
+
_removeReferenceFast(model, options) {
|
|
26936
|
+
model.off('all', this._onModelEvent, this);
|
|
26937
|
+
if (!options.dry) {
|
|
26938
|
+
// If not in `dry` mode and the model has a reference
|
|
26939
|
+
// to this exact graph/collection, remove the reference.
|
|
26940
|
+
if (this === model.collection) {
|
|
26941
|
+
delete model.collection;
|
|
26942
|
+
}
|
|
26943
|
+
if (model.graph === this.layer.graph) {
|
|
26944
|
+
model.graph = null;
|
|
26945
|
+
}
|
|
26946
|
+
}
|
|
26947
|
+
}
|
|
26948
|
+
|
|
26726
26949
|
// `comparator` makes it easy to sort cells based on their `z` index.
|
|
26727
|
-
comparator
|
|
26950
|
+
comparator(model) {
|
|
26728
26951
|
return model.get('z') || 0;
|
|
26729
26952
|
}
|
|
26730
|
-
});
|
|
26731
|
-
const Graph = Model.extend({
|
|
26732
|
-
initialize: function (attrs, opt) {
|
|
26733
|
-
opt = opt || {};
|
|
26734
26953
|
|
|
26735
|
-
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
|
|
26954
|
+
// This method overrides base mvc.Collection implementation
|
|
26955
|
+
// in a way that improves performance of resetting large collections.
|
|
26956
|
+
// For layers specifically, there is an option where we put references
|
|
26957
|
+
// from the main collection in order to improve performance when
|
|
26958
|
+
// there is only one layer
|
|
26959
|
+
reset(models, options) {
|
|
26960
|
+
options = assign({}, {
|
|
26961
|
+
add: true,
|
|
26962
|
+
remove: false,
|
|
26963
|
+
merge: false
|
|
26964
|
+
}, options);
|
|
26965
|
+
for (let i = 0; i < this.models.length; i++) {
|
|
26966
|
+
this._removeReferenceFast(this.models[i], options);
|
|
26967
|
+
}
|
|
26968
|
+
options.previousModels = this.models;
|
|
26969
|
+
this._reset();
|
|
26970
|
+
for (let i = 0; i < models.length; i++) {
|
|
26971
|
+
const model = this._prepareModel(models[i], options);
|
|
26972
|
+
if (model) {
|
|
26973
|
+
this.models.push(model);
|
|
26974
|
+
this._addReference(model, options);
|
|
26975
|
+
}
|
|
26976
|
+
}
|
|
26977
|
+
this.length = this.models.length;
|
|
26978
|
+
const sort = this.comparator && options.sort !== false;
|
|
26979
|
+
if (sort) {
|
|
26980
|
+
this.sort({
|
|
26981
|
+
silent: true
|
|
26982
|
+
});
|
|
26983
|
+
}
|
|
26984
|
+
if (!options.silent) {
|
|
26985
|
+
this.trigger('reset', this, options);
|
|
26986
|
+
}
|
|
26987
|
+
return this.models;
|
|
26988
|
+
}
|
|
26989
|
+
minZIndex() {
|
|
26990
|
+
return this.first()?.get('z') || 0;
|
|
26991
|
+
}
|
|
26992
|
+
maxZIndex() {
|
|
26993
|
+
return this.last()?.get('z') || 0;
|
|
26994
|
+
}
|
|
26995
|
+
}
|
|
26996
|
+
|
|
26997
|
+
const DEFAULT_GRAPH_LAYER_TYPE = 'GraphLayer';
|
|
26998
|
+
|
|
26999
|
+
/**
|
|
27000
|
+
* @class GraphLayer
|
|
27001
|
+
* @description A GraphLayer is a model representing a single layer in a dia.Graph.
|
|
27002
|
+
*/
|
|
27003
|
+
class GraphLayer extends Model {
|
|
27004
|
+
[GRAPH_LAYER_MARKER] = true;
|
|
27005
|
+
preinitialize() {
|
|
27006
|
+
// This allows for propagating events from the inner `cellCollection` collection
|
|
27007
|
+
// without any prefix and therefore distinguish them from the events
|
|
27008
|
+
// fired by the GraphLayer model itself.
|
|
27009
|
+
this.eventPrefix = 'layer:';
|
|
27010
|
+
}
|
|
27011
|
+
defaults() {
|
|
27012
|
+
return {
|
|
27013
|
+
type: DEFAULT_GRAPH_LAYER_TYPE
|
|
27014
|
+
};
|
|
27015
|
+
}
|
|
27016
|
+
initialize(attrs, options = {}) {
|
|
27017
|
+
super.initialize(attrs, options);
|
|
27018
|
+
this.cellCollection = new CellCollection([], {
|
|
27019
|
+
layer: this
|
|
26742
27020
|
});
|
|
26743
|
-
Model.prototype.set.call(this, 'cells', cells);
|
|
26744
27021
|
|
|
26745
|
-
//
|
|
26746
|
-
|
|
26747
|
-
|
|
27022
|
+
// Forward all events from the inner `cellCollection` collection
|
|
27023
|
+
this.cellCollection.on('all', this.trigger, this);
|
|
27024
|
+
// Listen to cell changes to manage z-index sorting
|
|
27025
|
+
this.cellCollection.on('change', this.onCellChange, this);
|
|
27026
|
+
}
|
|
27027
|
+
onCellChange(cell, opt) {
|
|
27028
|
+
if (opt.sort === false || !cell.hasChanged('z')) return;
|
|
27029
|
+
this.cellCollection.sort();
|
|
27030
|
+
}
|
|
27031
|
+
|
|
27032
|
+
/**
|
|
27033
|
+
* @public
|
|
27034
|
+
* @description Returns all cells in this layer.
|
|
27035
|
+
*/
|
|
27036
|
+
getCells() {
|
|
27037
|
+
return this.cellCollection.toArray();
|
|
27038
|
+
}
|
|
27039
|
+
}
|
|
26748
27040
|
|
|
26749
|
-
|
|
26750
|
-
|
|
26751
|
-
|
|
27041
|
+
/**
|
|
27042
|
+
* @class GraphLayerCollection
|
|
27043
|
+
* @description A collection of layers used in dia.Graph. It facilitates creating layers from JSON using layerNamespace.
|
|
27044
|
+
*/
|
|
27045
|
+
const GraphLayerCollection = Collection.extend({
|
|
27046
|
+
defaultLayerNamespace: {
|
|
27047
|
+
GraphLayer
|
|
27048
|
+
},
|
|
27049
|
+
/**
|
|
27050
|
+
* @override
|
|
27051
|
+
* @description Initializes the collection and sets up the layer and cell namespaces.
|
|
27052
|
+
*/
|
|
27053
|
+
initialize: function (_models, options = {}) {
|
|
27054
|
+
const {
|
|
27055
|
+
layerNamespace,
|
|
27056
|
+
cellNamespace,
|
|
27057
|
+
graph
|
|
27058
|
+
} = options;
|
|
26752
27059
|
|
|
26753
|
-
//
|
|
26754
|
-
//
|
|
26755
|
-
|
|
26756
|
-
|
|
26757
|
-
//
|
|
27060
|
+
// Initialize the namespace that holds all available layer classes.
|
|
27061
|
+
// Custom namespaces are merged with the default ones.
|
|
27062
|
+
this.layerNamespace = assign({}, this.defaultLayerNamespace, layerNamespace);
|
|
27063
|
+
|
|
27064
|
+
// Initialize the namespace for all cell model classes, if provided.
|
|
27065
|
+
if (cellNamespace) {
|
|
27066
|
+
this.cellNamespace = cellNamespace;
|
|
27067
|
+
} else {
|
|
27068
|
+
/* eslint-disable no-undef */
|
|
27069
|
+
this.cellNamespace = typeof joint !== 'undefined' && has(joint, 'shapes') ? joint.shapes : null;
|
|
27070
|
+
/* eslint-enable no-undef */
|
|
27071
|
+
}
|
|
27072
|
+
this.graph = graph;
|
|
27073
|
+
},
|
|
27074
|
+
/**
|
|
27075
|
+
* @override
|
|
27076
|
+
* @description Overrides the default `model` method
|
|
27077
|
+
* to create layer models based on their `type` attribute.
|
|
27078
|
+
*/
|
|
27079
|
+
model: function (attrs, opt) {
|
|
27080
|
+
const collection = opt.collection;
|
|
27081
|
+
const namespace = collection.layerNamespace;
|
|
27082
|
+
const {
|
|
27083
|
+
type
|
|
27084
|
+
} = attrs;
|
|
27085
|
+
|
|
27086
|
+
// Find the model class based on the `type` attribute in the cell namespace
|
|
27087
|
+
const GraphLayerClass = getByPath(namespace, type, '.');
|
|
27088
|
+
if (!GraphLayerClass) {
|
|
27089
|
+
throw new Error(`dia.Graph: Could not find layer constructor for type: '${type}'. Make sure to add the constructor to 'layerNamespace'.`);
|
|
27090
|
+
}
|
|
27091
|
+
return new GraphLayerClass(attrs, opt);
|
|
27092
|
+
},
|
|
27093
|
+
// Override to set graph reference
|
|
27094
|
+
_addReference(layer, options) {
|
|
27095
|
+
Collection.prototype._addReference.call(this, layer, options);
|
|
27096
|
+
|
|
27097
|
+
// assign graph and cellNamespace references
|
|
27098
|
+
// to the added layer
|
|
27099
|
+
layer.graph = this.graph;
|
|
27100
|
+
layer.cellCollection.cellNamespace = this.cellNamespace;
|
|
27101
|
+
},
|
|
27102
|
+
// Override to remove graph reference
|
|
27103
|
+
_removeReference(layer, options) {
|
|
27104
|
+
Collection.prototype._removeReference.call(this, layer, options);
|
|
27105
|
+
|
|
27106
|
+
// remove graph and cellNamespace references
|
|
27107
|
+
// from the removed layer
|
|
27108
|
+
layer.graph = null;
|
|
27109
|
+
layer.cellCollection.cellNamespace = null;
|
|
27110
|
+
},
|
|
27111
|
+
/**
|
|
27112
|
+
* @override
|
|
27113
|
+
* @description Overrides the default `_prepareModel` method
|
|
27114
|
+
* to set default layer type if missing.
|
|
27115
|
+
*/
|
|
27116
|
+
_prepareModel: function (attrs, options) {
|
|
27117
|
+
if (!attrs[GRAPH_LAYER_MARKER]) {
|
|
27118
|
+
// Add a mandatory `type` attribute if missing
|
|
27119
|
+
if (!attrs.type) {
|
|
27120
|
+
const preparedAttributes = clone$1(attrs);
|
|
27121
|
+
preparedAttributes.type = DEFAULT_GRAPH_LAYER_TYPE;
|
|
27122
|
+
arguments[0] = preparedAttributes;
|
|
27123
|
+
}
|
|
27124
|
+
}
|
|
27125
|
+
return Collection.prototype._prepareModel.apply(this, arguments);
|
|
27126
|
+
},
|
|
27127
|
+
/**
|
|
27128
|
+
* @override
|
|
27129
|
+
* @description Add an assertion to prevent direct resetting of the collection.
|
|
27130
|
+
*/
|
|
27131
|
+
reset(models, options) {
|
|
27132
|
+
this._assertInternalCall(options);
|
|
27133
|
+
return Collection.prototype.reset.apply(this, arguments);
|
|
27134
|
+
},
|
|
27135
|
+
/**
|
|
27136
|
+
* @override
|
|
27137
|
+
* @description Add an assertion to prevent direct addition of layers.
|
|
27138
|
+
*/
|
|
27139
|
+
add(models, options) {
|
|
27140
|
+
this._assertInternalCall(options);
|
|
27141
|
+
return Collection.prototype.add.apply(this, arguments);
|
|
27142
|
+
},
|
|
27143
|
+
/**
|
|
27144
|
+
* @override
|
|
27145
|
+
* @description Add an assertion to prevent direct removal of layers.
|
|
27146
|
+
*/
|
|
27147
|
+
remove(models, options) {
|
|
27148
|
+
this._assertInternalCall(options);
|
|
27149
|
+
return Collection.prototype.remove.apply(this, arguments);
|
|
27150
|
+
},
|
|
27151
|
+
/**
|
|
27152
|
+
* @override
|
|
27153
|
+
* @description Overrides the default `_onModelEvent` method
|
|
27154
|
+
* to distinguish between events coming from different model types.
|
|
27155
|
+
*/
|
|
27156
|
+
_onModelEvent(_, model) {
|
|
27157
|
+
if (model && model[CELL_MARKER]) {
|
|
27158
|
+
// Do not filter cell `add` and `remove` events
|
|
27159
|
+
// See `mvc.Collection` for more details
|
|
27160
|
+
this.trigger.apply(this, arguments);
|
|
27161
|
+
return;
|
|
27162
|
+
}
|
|
26758
27163
|
|
|
27164
|
+
// For other events, use the default behavior
|
|
27165
|
+
Collection.prototype._onModelEvent.apply(this, arguments);
|
|
27166
|
+
},
|
|
27167
|
+
/**
|
|
27168
|
+
* @protected
|
|
27169
|
+
* @description Asserts that the collection manipulation
|
|
27170
|
+
* is done via internal graph methods. Otherwise, it throws an error.
|
|
27171
|
+
* This is a temporary measure until layers API is stabilized.
|
|
27172
|
+
*/
|
|
27173
|
+
_assertInternalCall(options) {
|
|
27174
|
+
if (options && !options.graph && !options.silent) {
|
|
27175
|
+
throw new Error('dia.GraphLayerCollection: direct manipulation of the collection is not supported, use graph methods instead.');
|
|
27176
|
+
}
|
|
27177
|
+
},
|
|
27178
|
+
/**
|
|
27179
|
+
* @public
|
|
27180
|
+
* @description Inserts a layer before another layer or at the end if `beforeLayerId` is null.
|
|
27181
|
+
*/
|
|
27182
|
+
insert(layerInit, beforeLayerId = null, options = {}) {
|
|
27183
|
+
const id = layerInit.id;
|
|
27184
|
+
if (id === beforeLayerId) {
|
|
27185
|
+
// Inserting before itself is a no-op
|
|
27186
|
+
return;
|
|
27187
|
+
}
|
|
27188
|
+
if (beforeLayerId && !this.has(beforeLayerId)) {
|
|
27189
|
+
throw new Error(`dia.GraphLayerCollection: Layer "${beforeLayerId}" does not exist`);
|
|
27190
|
+
}
|
|
27191
|
+
|
|
27192
|
+
// See if the layer is already in the collection
|
|
27193
|
+
let currentIndex = -1;
|
|
27194
|
+
if (this.has(id)) {
|
|
27195
|
+
currentIndex = this.findIndex(l => l.id === id);
|
|
27196
|
+
if (currentIndex === this.length - 1 && !beforeLayerId) {
|
|
27197
|
+
// The layer is already at the end
|
|
27198
|
+
return;
|
|
27199
|
+
}
|
|
27200
|
+
// Remove the layer from its current position
|
|
27201
|
+
this.remove(id, {
|
|
27202
|
+
silent: true
|
|
27203
|
+
});
|
|
27204
|
+
}
|
|
27205
|
+
|
|
27206
|
+
// At what index to insert the layer?
|
|
27207
|
+
let insertAt;
|
|
27208
|
+
if (!beforeLayerId) {
|
|
27209
|
+
insertAt = this.length;
|
|
27210
|
+
} else {
|
|
27211
|
+
insertAt = this.findIndex(l => l.id === beforeLayerId);
|
|
27212
|
+
}
|
|
27213
|
+
if (currentIndex !== -1) {
|
|
27214
|
+
// Re-insert the layer at the new position.
|
|
27215
|
+
this.add(layerInit, {
|
|
27216
|
+
at: insertAt,
|
|
27217
|
+
silent: true
|
|
27218
|
+
});
|
|
27219
|
+
// Trigger `sort` event manually
|
|
27220
|
+
// since we are not using collection sorting workflow
|
|
27221
|
+
this.trigger('sort', this, options);
|
|
27222
|
+
} else {
|
|
27223
|
+
// Add to the collection and trigger an event
|
|
27224
|
+
// when new layer has been added
|
|
27225
|
+
this.add(layerInit, {
|
|
27226
|
+
...options,
|
|
27227
|
+
at: insertAt
|
|
27228
|
+
});
|
|
27229
|
+
}
|
|
27230
|
+
},
|
|
27231
|
+
/**
|
|
27232
|
+
* @public
|
|
27233
|
+
* @description Finds and returns a cell by its id from all layers.
|
|
27234
|
+
*/
|
|
27235
|
+
getCell(cellRef) {
|
|
27236
|
+
// TODO: should we create a map of cells for faster lookup?
|
|
27237
|
+
for (const layer of this.models) {
|
|
27238
|
+
const cell = layer.cellCollection.get(cellRef);
|
|
27239
|
+
if (cell) {
|
|
27240
|
+
return cell;
|
|
27241
|
+
}
|
|
27242
|
+
}
|
|
27243
|
+
// Backward compatibility: return undefined if cell is not found
|
|
27244
|
+
return undefined;
|
|
27245
|
+
},
|
|
27246
|
+
/**
|
|
27247
|
+
* @public
|
|
27248
|
+
* @description Returns all cells in all layers in the correct order.
|
|
27249
|
+
*/
|
|
27250
|
+
getCells() {
|
|
27251
|
+
const layers = this.models;
|
|
27252
|
+
if (layers.length === 1) {
|
|
27253
|
+
// Single layer:
|
|
27254
|
+
// Fast path, just return the copy of the only layer's cells
|
|
27255
|
+
return layers[0].getCells();
|
|
27256
|
+
}
|
|
27257
|
+
// Multiple layers:
|
|
27258
|
+
// Each layer has its models sorted already, so we can just concatenate
|
|
27259
|
+
// them in the order of layers.
|
|
27260
|
+
const cells = [];
|
|
27261
|
+
for (const layer of layers) {
|
|
27262
|
+
Array.prototype.push.apply(cells, layer.cellCollection.models);
|
|
27263
|
+
}
|
|
27264
|
+
return cells;
|
|
27265
|
+
},
|
|
27266
|
+
/**
|
|
27267
|
+
* @public
|
|
27268
|
+
* @description Removes a cell from its current layer.
|
|
27269
|
+
*/
|
|
27270
|
+
removeCell(cell, options = {}) {
|
|
27271
|
+
const cellCollection = cell.collection?.layer?.cellCollection;
|
|
27272
|
+
if (!cellCollection) return;
|
|
27273
|
+
cellCollection.remove(cell, options);
|
|
27274
|
+
},
|
|
27275
|
+
/**
|
|
27276
|
+
* @public
|
|
27277
|
+
* @description Move a cell from its current layer to a target layer.
|
|
27278
|
+
*/
|
|
27279
|
+
moveCellBetweenLayers(cell, targetLayerId, options = {}) {
|
|
27280
|
+
const sourceLayer = cell.collection?.layer;
|
|
27281
|
+
if (!sourceLayer) {
|
|
27282
|
+
throw new Error('dia.GraphLayerCollection: cannot move a cell that is not part of any layer.');
|
|
27283
|
+
}
|
|
27284
|
+
const targetLayer = this.get(targetLayerId);
|
|
27285
|
+
if (!targetLayer) {
|
|
27286
|
+
throw new Error(`dia.GraphLayerCollection: cannot move cell to layer '${targetLayerId}' because such layer does not exist.`);
|
|
27287
|
+
}
|
|
27288
|
+
if (sourceLayer === targetLayer) {
|
|
27289
|
+
// 1. The provided cell is already in the target layer
|
|
27290
|
+
// 2. Implicit default layer vs. explicit default (or vice versa)
|
|
27291
|
+
// No follow-up action needed
|
|
27292
|
+
return;
|
|
27293
|
+
}
|
|
27294
|
+
const moveOptions = {
|
|
27295
|
+
...options,
|
|
27296
|
+
fromLayer: sourceLayer.id,
|
|
27297
|
+
toLayer: targetLayer.id
|
|
27298
|
+
};
|
|
27299
|
+
// Move the cell between the two layer collections
|
|
27300
|
+
sourceLayer.cellCollection.remove(cell, moveOptions);
|
|
27301
|
+
targetLayer.cellCollection.add(cell, moveOptions);
|
|
27302
|
+
// Trigger a single `move` event to ease distinguishing layer moves
|
|
27303
|
+
// from add/remove operations
|
|
27304
|
+
cell.trigger('move', cell, moveOptions);
|
|
27305
|
+
},
|
|
27306
|
+
/**
|
|
27307
|
+
* @public
|
|
27308
|
+
* @description Adds a cell to the specified layer.
|
|
27309
|
+
*/
|
|
27310
|
+
addCellToLayer(cell, layerId, options = {}) {
|
|
27311
|
+
const targetLayer = this.get(layerId);
|
|
27312
|
+
if (!targetLayer) {
|
|
27313
|
+
throw new Error(`dia.GraphLayerCollection: layer "${layerId}" does not exist.`);
|
|
27314
|
+
}
|
|
27315
|
+
const addOptions = {
|
|
27316
|
+
...options,
|
|
27317
|
+
toLayer: targetLayer.id
|
|
27318
|
+
};
|
|
27319
|
+
// Add the cell to the target layer collection
|
|
27320
|
+
targetLayer.cellCollection.add(cell, addOptions);
|
|
27321
|
+
}
|
|
27322
|
+
});
|
|
27323
|
+
Object.defineProperty(GraphLayerCollection.prototype, GRAPH_LAYER_COLLECTION_MARKER, {
|
|
27324
|
+
value: true
|
|
27325
|
+
});
|
|
27326
|
+
|
|
27327
|
+
/**
|
|
27328
|
+
* @class GraphTopologyIndex
|
|
27329
|
+
* @description Maintains an index of the graph topology (adjacency list)
|
|
27330
|
+
* for fast graph queries.
|
|
27331
|
+
*/
|
|
27332
|
+
class GraphTopologyIndex extends Listener {
|
|
27333
|
+
constructor(options) {
|
|
27334
|
+
super(options);
|
|
27335
|
+
|
|
27336
|
+
// Make sure there are no arguments passed to the callbacks.
|
|
27337
|
+
// See the `mvc.Listener` documentation for more details.
|
|
27338
|
+
this.callbackArguments = [];
|
|
27339
|
+
this.layerCollection = options.layerCollection;
|
|
27340
|
+
if (!this.layerCollection) {
|
|
27341
|
+
throw new Error('GraphTopologyIndex: "layerCollection" option is required.');
|
|
27342
|
+
}
|
|
27343
|
+
this.initializeIndex();
|
|
27344
|
+
this.startListening();
|
|
27345
|
+
}
|
|
27346
|
+
|
|
27347
|
+
/**
|
|
27348
|
+
* @public
|
|
27349
|
+
* @description Start listening to graph and layer collection events
|
|
27350
|
+
* to maintain the topology index.
|
|
27351
|
+
*/
|
|
27352
|
+
startListening() {
|
|
27353
|
+
this.listenTo(this.layerCollection.graph, {
|
|
27354
|
+
'add': this._restructureOnAdd,
|
|
27355
|
+
'remove': this._restructureOnRemove,
|
|
27356
|
+
'reset': this._restructureOnReset
|
|
27357
|
+
});
|
|
27358
|
+
// Listening to the collection instead of the graph
|
|
27359
|
+
// to avoid reacting to graph attribute change events
|
|
27360
|
+
// e.g. graph.set('source', ...);
|
|
27361
|
+
this.listenTo(this.layerCollection, {
|
|
27362
|
+
'change:source': this._restructureOnChangeSource,
|
|
27363
|
+
'change:target': this._restructureOnChangeTarget
|
|
27364
|
+
});
|
|
27365
|
+
}
|
|
27366
|
+
|
|
27367
|
+
/**
|
|
27368
|
+
* @protected
|
|
27369
|
+
* @description Initialize the internal data structures.
|
|
27370
|
+
*/
|
|
27371
|
+
initializeIndex() {
|
|
26759
27372
|
// Outgoing edges per node. Note that we use a hash-table for the list
|
|
26760
27373
|
// of outgoing edges for a faster lookup.
|
|
26761
27374
|
// [nodeId] -> Object [edgeId] -> true
|
|
@@ -26771,21 +27384,27 @@ var joint = (function (exports) {
|
|
|
26771
27384
|
// having to go through the whole cells array.
|
|
26772
27385
|
// [edgeId] -> true
|
|
26773
27386
|
this._edges = {};
|
|
26774
|
-
|
|
26775
|
-
|
|
26776
|
-
|
|
26777
|
-
|
|
26778
|
-
|
|
26779
|
-
|
|
26780
|
-
|
|
26781
|
-
|
|
26782
|
-
|
|
26783
|
-
this.
|
|
26784
|
-
}
|
|
26785
|
-
|
|
27387
|
+
}
|
|
27388
|
+
|
|
27389
|
+
/**
|
|
27390
|
+
* @protected
|
|
27391
|
+
* @description Restructure the topology index on graph reset.
|
|
27392
|
+
* E.g. when fromJSON or resetCells is called.
|
|
27393
|
+
*/
|
|
27394
|
+
_restructureOnReset() {
|
|
27395
|
+
this.initializeIndex();
|
|
27396
|
+
this.layerCollection.getCells().forEach(this._restructureOnAdd, this);
|
|
27397
|
+
}
|
|
27398
|
+
|
|
27399
|
+
/**
|
|
27400
|
+
* @protected
|
|
27401
|
+
* @description Restructure the topology index on cell addition.
|
|
27402
|
+
* @param {dia.Cell} cell - The cell being added.
|
|
27403
|
+
*/
|
|
27404
|
+
_restructureOnAdd(cell) {
|
|
26786
27405
|
if (cell.isLink()) {
|
|
26787
27406
|
this._edges[cell.id] = true;
|
|
26788
|
-
|
|
27407
|
+
const {
|
|
26789
27408
|
source,
|
|
26790
27409
|
target
|
|
26791
27410
|
} = cell.attributes;
|
|
@@ -26798,11 +27417,17 @@ var joint = (function (exports) {
|
|
|
26798
27417
|
} else {
|
|
26799
27418
|
this._nodes[cell.id] = true;
|
|
26800
27419
|
}
|
|
26801
|
-
}
|
|
26802
|
-
|
|
27420
|
+
}
|
|
27421
|
+
|
|
27422
|
+
/**
|
|
27423
|
+
* @protected
|
|
27424
|
+
* @description Restructure the topology index on cell removal.
|
|
27425
|
+
* @param {dia.Cell} cell - The cell being removed.
|
|
27426
|
+
*/
|
|
27427
|
+
_restructureOnRemove(cell) {
|
|
26803
27428
|
if (cell.isLink()) {
|
|
26804
27429
|
delete this._edges[cell.id];
|
|
26805
|
-
|
|
27430
|
+
const {
|
|
26806
27431
|
source,
|
|
26807
27432
|
target
|
|
26808
27433
|
} = cell.attributes;
|
|
@@ -26815,89 +27440,222 @@ var joint = (function (exports) {
|
|
|
26815
27440
|
} else {
|
|
26816
27441
|
delete this._nodes[cell.id];
|
|
26817
27442
|
}
|
|
26818
|
-
}
|
|
26819
|
-
|
|
26820
|
-
|
|
26821
|
-
|
|
26822
|
-
|
|
26823
|
-
|
|
26824
|
-
|
|
26825
|
-
|
|
26826
|
-
|
|
26827
|
-
},
|
|
26828
|
-
_restructureOnChangeSource: function (link) {
|
|
26829
|
-
var prevSource = link.previous('source');
|
|
27443
|
+
}
|
|
27444
|
+
|
|
27445
|
+
/**
|
|
27446
|
+
* @protected
|
|
27447
|
+
* @description Restructure the topology index on link source change.
|
|
27448
|
+
* @param {dia.Link} link - The link being changed.
|
|
27449
|
+
*/
|
|
27450
|
+
_restructureOnChangeSource(link) {
|
|
27451
|
+
const prevSource = link.previous('source');
|
|
26830
27452
|
if (prevSource.id && this._out[prevSource.id]) {
|
|
26831
27453
|
delete this._out[prevSource.id][link.id];
|
|
26832
27454
|
}
|
|
26833
|
-
|
|
27455
|
+
const source = link.attributes.source;
|
|
26834
27456
|
if (source.id) {
|
|
26835
27457
|
(this._out[source.id] || (this._out[source.id] = {}))[link.id] = true;
|
|
26836
27458
|
}
|
|
26837
|
-
}
|
|
26838
|
-
|
|
26839
|
-
|
|
27459
|
+
}
|
|
27460
|
+
|
|
27461
|
+
/**
|
|
27462
|
+
* @protected
|
|
27463
|
+
* @description Restructure the topology index on link target change.
|
|
27464
|
+
* @param {dia.Link} link - The link being changed.
|
|
27465
|
+
*/
|
|
27466
|
+
_restructureOnChangeTarget(link) {
|
|
27467
|
+
const prevTarget = link.previous('target');
|
|
26840
27468
|
if (prevTarget.id && this._in[prevTarget.id]) {
|
|
26841
27469
|
delete this._in[prevTarget.id][link.id];
|
|
26842
27470
|
}
|
|
26843
|
-
|
|
27471
|
+
const target = link.get('target');
|
|
26844
27472
|
if (target.id) {
|
|
26845
27473
|
(this._in[target.id] || (this._in[target.id] = {}))[link.id] = true;
|
|
26846
27474
|
}
|
|
26847
|
-
}
|
|
26848
|
-
|
|
26849
|
-
|
|
26850
|
-
|
|
26851
|
-
|
|
26852
|
-
|
|
26853
|
-
|
|
26854
|
-
|
|
26855
|
-
|
|
26856
|
-
return this.
|
|
27475
|
+
}
|
|
27476
|
+
|
|
27477
|
+
/**
|
|
27478
|
+
* @public
|
|
27479
|
+
* @description Get all outbound edges for the node. Time complexity: O(1).
|
|
27480
|
+
* @param {string} nodeId - The id of the node.
|
|
27481
|
+
* @returns {Object} - An object of the form: [edgeId] -> true.
|
|
27482
|
+
*/
|
|
27483
|
+
getOutboundEdges(nodeId) {
|
|
27484
|
+
return this._out[nodeId] || {};
|
|
27485
|
+
}
|
|
27486
|
+
|
|
27487
|
+
/**
|
|
27488
|
+
* @public
|
|
27489
|
+
* @description Get all inbound edges for the node. Time complexity: O(1).
|
|
27490
|
+
* @param {string} nodeId - The id of the node.
|
|
27491
|
+
* @returns {Object} - An object of the form: [edgeId] -> true.
|
|
27492
|
+
*/
|
|
27493
|
+
getInboundEdges(nodeId) {
|
|
27494
|
+
return this._in[nodeId] || {};
|
|
27495
|
+
}
|
|
27496
|
+
|
|
27497
|
+
/**
|
|
27498
|
+
* @public
|
|
27499
|
+
* @description Get all sink nodes (leafs) in the graph. Time complexity: O(|V|).
|
|
27500
|
+
* @returns {string[]} - Array of node ids.
|
|
27501
|
+
*/
|
|
27502
|
+
getSinkNodes() {
|
|
27503
|
+
const sinks = [];
|
|
27504
|
+
for (const nodeId in this._nodes) {
|
|
27505
|
+
if (!this._out[nodeId] || isEmpty(this._out[nodeId])) {
|
|
27506
|
+
sinks.push(nodeId);
|
|
27507
|
+
}
|
|
27508
|
+
}
|
|
27509
|
+
return sinks;
|
|
27510
|
+
}
|
|
27511
|
+
|
|
27512
|
+
/**
|
|
27513
|
+
* @public
|
|
27514
|
+
* @description Get all source nodes (roots) in the graph. Time complexity: O(|V|).
|
|
27515
|
+
* @returns {string[]} - Array of node ids.
|
|
27516
|
+
*/
|
|
27517
|
+
getSourceNodes() {
|
|
27518
|
+
const sources = [];
|
|
27519
|
+
for (const nodeId in this._nodes) {
|
|
27520
|
+
if (!this._in[nodeId] || isEmpty(this._in[nodeId])) {
|
|
27521
|
+
sources.push(nodeId);
|
|
27522
|
+
}
|
|
27523
|
+
}
|
|
27524
|
+
return sources;
|
|
27525
|
+
}
|
|
27526
|
+
|
|
27527
|
+
/**
|
|
27528
|
+
* @public
|
|
27529
|
+
* @description Return `true` if `nodeId` is a source node (root). Time complexity: O(1).
|
|
27530
|
+
* @param {string} nodeId - The id of the node to check.
|
|
27531
|
+
* @returns {boolean}
|
|
27532
|
+
*/
|
|
27533
|
+
isSourceNode(nodeId) {
|
|
27534
|
+
return !this._in[nodeId] || isEmpty(this._in[nodeId]);
|
|
27535
|
+
}
|
|
27536
|
+
|
|
27537
|
+
/**
|
|
27538
|
+
* @public
|
|
27539
|
+
* @description Return `true` if `nodeId` is a sink node (leaf). Time complexity: O(1).
|
|
27540
|
+
* @param {string} nodeId - The id of the node to check.
|
|
27541
|
+
* @returns {boolean}
|
|
27542
|
+
*/
|
|
27543
|
+
isSinkNode(nodeId) {
|
|
27544
|
+
return !this._out[nodeId] || isEmpty(this._out[nodeId]);
|
|
27545
|
+
}
|
|
27546
|
+
}
|
|
27547
|
+
|
|
27548
|
+
// The ID of the default graph layer.
|
|
27549
|
+
const DEFAULT_LAYER_ID = 'cells';
|
|
27550
|
+
const Graph = Model.extend({
|
|
27551
|
+
/**
|
|
27552
|
+
* @todo Remove in v5.0.0
|
|
27553
|
+
* @description In legacy mode, the information about layers is not
|
|
27554
|
+
* exported into JSON.
|
|
27555
|
+
*/
|
|
27556
|
+
legacyMode: true,
|
|
27557
|
+
/**
|
|
27558
|
+
* @protected
|
|
27559
|
+
* @description The ID of the default layer.
|
|
27560
|
+
*/
|
|
27561
|
+
defaultLayerId: DEFAULT_LAYER_ID,
|
|
27562
|
+
initialize: function (attrs, options = {}) {
|
|
27563
|
+
const layerCollection = this.layerCollection = new GraphLayerCollection([], {
|
|
27564
|
+
layerNamespace: options.layerNamespace,
|
|
27565
|
+
cellNamespace: options.cellNamespace,
|
|
27566
|
+
graph: this,
|
|
27567
|
+
/** @deprecated use cellNamespace instead */
|
|
27568
|
+
model: options.cellModel
|
|
27569
|
+
});
|
|
27570
|
+
|
|
27571
|
+
// The default setup includes a single default layer.
|
|
27572
|
+
layerCollection.add({
|
|
27573
|
+
id: DEFAULT_LAYER_ID
|
|
27574
|
+
}, {
|
|
27575
|
+
graph: this.cid
|
|
27576
|
+
});
|
|
27577
|
+
|
|
27578
|
+
/**
|
|
27579
|
+
* @todo Remove in v5.0.0
|
|
27580
|
+
* @description Retain legacy 'cells' collection in attributes for backward compatibility.
|
|
27581
|
+
* Applicable only when the default layer setup is used.
|
|
27582
|
+
*/
|
|
27583
|
+
this.attributes.cells = this.getLayer(DEFAULT_LAYER_ID).cellCollection;
|
|
27584
|
+
|
|
27585
|
+
// Controller that manages communication between the graph and its layers.
|
|
27586
|
+
this.layersController = new GraphLayersController({
|
|
27587
|
+
graph: this
|
|
27588
|
+
});
|
|
27589
|
+
|
|
27590
|
+
// `Graph` keeps an internal data structure (an adjacency list)
|
|
27591
|
+
// for fast graph queries. All changes that affect the structure of the graph
|
|
27592
|
+
// must be reflected in the `al` object. This object provides fast answers to
|
|
27593
|
+
// questions such as "what are the neighbors of this node" or "what
|
|
27594
|
+
// are the sibling links of this link".
|
|
27595
|
+
this.topologyIndex = new GraphTopologyIndex({
|
|
27596
|
+
layerCollection
|
|
27597
|
+
});
|
|
27598
|
+
this._batches = {};
|
|
26857
27599
|
},
|
|
26858
27600
|
toJSON: function (opt = {}) {
|
|
26859
|
-
|
|
26860
|
-
|
|
26861
|
-
|
|
26862
|
-
|
|
27601
|
+
const {
|
|
27602
|
+
layerCollection
|
|
27603
|
+
} = this;
|
|
27604
|
+
// Get the graph model attributes as a base JSON.
|
|
27605
|
+
const json = Model.prototype.toJSON.apply(this, arguments);
|
|
27606
|
+
|
|
27607
|
+
// Add `cells` array holding all the cells in the graph.
|
|
27608
|
+
json.cells = this.getCells().map(cell => cell.toJSON(opt.cellAttributes));
|
|
27609
|
+
if (this.legacyMode) {
|
|
27610
|
+
// Backwards compatibility for legacy setup
|
|
27611
|
+
// with single default layer 'cells'.
|
|
27612
|
+
// In this case, we do not need to export layers.
|
|
27613
|
+
return json;
|
|
27614
|
+
}
|
|
27615
|
+
|
|
27616
|
+
// Add `layers` array holding all the layers in the graph.
|
|
27617
|
+
json.layers = layerCollection.toJSON();
|
|
27618
|
+
|
|
27619
|
+
// Add `defaultLayer` property indicating the default layer ID.
|
|
27620
|
+
json.defaultLayer = this.defaultLayerId;
|
|
26863
27621
|
return json;
|
|
26864
27622
|
},
|
|
26865
27623
|
fromJSON: function (json, opt) {
|
|
26866
|
-
|
|
27624
|
+
const {
|
|
27625
|
+
cells,
|
|
27626
|
+
layers,
|
|
27627
|
+
defaultLayer,
|
|
27628
|
+
...attributes
|
|
27629
|
+
} = json;
|
|
27630
|
+
if (!cells) {
|
|
26867
27631
|
throw new Error('Graph JSON must contain cells array.');
|
|
26868
27632
|
}
|
|
26869
|
-
return this.set(json, opt);
|
|
26870
|
-
},
|
|
26871
|
-
set: function (key, val, opt) {
|
|
26872
|
-
var attrs;
|
|
26873
27633
|
|
|
26874
|
-
//
|
|
26875
|
-
|
|
26876
|
-
|
|
26877
|
-
|
|
26878
|
-
}
|
|
26879
|
-
|
|
27634
|
+
// The `fromJSON` should trigger a single 'reset' event at the end.
|
|
27635
|
+
// Set all attributes silently for now.
|
|
27636
|
+
this.set(attributes, {
|
|
27637
|
+
silent: true
|
|
27638
|
+
});
|
|
27639
|
+
if (layers) {
|
|
27640
|
+
// Reset the layers collection
|
|
27641
|
+
// (`layers:reset` is not forwarded to the graph).
|
|
27642
|
+
this._resetLayers(layers, defaultLayer, opt);
|
|
26880
27643
|
}
|
|
26881
|
-
|
|
26882
|
-
|
|
26883
|
-
|
|
26884
|
-
this.resetCells(attrs.cells, opt);
|
|
26885
|
-
attrs = omit(attrs, 'cells');
|
|
27644
|
+
if (cells) {
|
|
27645
|
+
// Reset the cells collection and trigger the 'reset' event.
|
|
27646
|
+
this.resetCells(cells, opt);
|
|
26886
27647
|
}
|
|
26887
|
-
|
|
26888
|
-
// The rest of the attributes are applied via original set method.
|
|
26889
|
-
return Model.prototype.set.call(this, attrs, opt);
|
|
27648
|
+
return this;
|
|
26890
27649
|
},
|
|
27650
|
+
/** @deprecated */
|
|
26891
27651
|
clear: function (opt) {
|
|
26892
27652
|
opt = assign({}, opt, {
|
|
26893
27653
|
clear: true
|
|
26894
27654
|
});
|
|
26895
|
-
|
|
26896
|
-
if (
|
|
27655
|
+
const cells = this.getCells();
|
|
27656
|
+
if (cells.length === 0) return this;
|
|
26897
27657
|
this.startBatch('clear', opt);
|
|
26898
|
-
|
|
26899
|
-
// The elements come after the links.
|
|
26900
|
-
var cells = collection.sortBy(function (cell) {
|
|
27658
|
+
const sortedCells = sortBy(cells, cell => {
|
|
26901
27659
|
return cell.isLink() ? 1 : 2;
|
|
26902
27660
|
});
|
|
26903
27661
|
do {
|
|
@@ -26905,43 +27663,56 @@ var joint = (function (exports) {
|
|
|
26905
27663
|
// Note that all the links are removed first, so it's
|
|
26906
27664
|
// safe to remove the elements without removing the connected
|
|
26907
27665
|
// links first.
|
|
26908
|
-
|
|
26909
|
-
} while (
|
|
27666
|
+
this.layerCollection.removeCell(sortedCells.shift(), opt);
|
|
27667
|
+
} while (sortedCells.length > 0);
|
|
26910
27668
|
this.stopBatch('clear');
|
|
26911
27669
|
return this;
|
|
26912
27670
|
},
|
|
26913
|
-
_prepareCell: function (
|
|
26914
|
-
let
|
|
26915
|
-
if (
|
|
26916
|
-
|
|
27671
|
+
_prepareCell: function (cellInit, opt) {
|
|
27672
|
+
let cellAttributes;
|
|
27673
|
+
if (cellInit[CELL_MARKER]) {
|
|
27674
|
+
cellAttributes = cellInit.attributes;
|
|
26917
27675
|
} else {
|
|
26918
|
-
|
|
27676
|
+
cellAttributes = cellInit;
|
|
26919
27677
|
}
|
|
26920
|
-
if (!isString(
|
|
27678
|
+
if (!isString(cellAttributes.type)) {
|
|
26921
27679
|
throw new TypeError('dia.Graph: cell type must be a string.');
|
|
26922
27680
|
}
|
|
26923
|
-
|
|
27681
|
+
|
|
27682
|
+
// Backward compatibility: prior v4.2, z-index was not set during reset.
|
|
27683
|
+
if (opt && opt.ensureZIndex) {
|
|
27684
|
+
if (cellAttributes.z === undefined) {
|
|
27685
|
+
const layerId = cellAttributes[config$3.layerAttribute] || this.defaultLayerId;
|
|
27686
|
+
const zIndex = this.maxZIndex(layerId) + 1;
|
|
27687
|
+
if (cellInit[CELL_MARKER]) {
|
|
27688
|
+
// Set with event in case there is a listener
|
|
27689
|
+
// directly on the cell instance
|
|
27690
|
+
// (the cell is not part of graph yet)
|
|
27691
|
+
cellInit.set('z', zIndex, opt);
|
|
27692
|
+
} else {
|
|
27693
|
+
cellAttributes.z = zIndex;
|
|
27694
|
+
}
|
|
27695
|
+
}
|
|
27696
|
+
}
|
|
27697
|
+
return cellInit;
|
|
26924
27698
|
},
|
|
26925
|
-
minZIndex: function () {
|
|
26926
|
-
|
|
26927
|
-
return
|
|
27699
|
+
minZIndex: function (layerId = this.defaultLayerId) {
|
|
27700
|
+
const layer = this.getLayer(layerId);
|
|
27701
|
+
return layer.cellCollection.minZIndex();
|
|
26928
27702
|
},
|
|
26929
|
-
maxZIndex: function () {
|
|
26930
|
-
|
|
26931
|
-
return
|
|
27703
|
+
maxZIndex: function (layerId = this.defaultLayerId) {
|
|
27704
|
+
const layer = this.getLayer(layerId);
|
|
27705
|
+
return layer.cellCollection.maxZIndex();
|
|
26932
27706
|
},
|
|
26933
|
-
addCell: function (
|
|
26934
|
-
if (Array.isArray(
|
|
26935
|
-
return this.addCells(
|
|
27707
|
+
addCell: function (cellInit, options) {
|
|
27708
|
+
if (Array.isArray(cellInit)) {
|
|
27709
|
+
return this.addCells(cellInit, options);
|
|
26936
27710
|
}
|
|
26937
|
-
|
|
26938
|
-
|
|
26939
|
-
|
|
26940
|
-
|
|
26941
|
-
|
|
26942
|
-
cell.z = this.maxZIndex() + 1;
|
|
26943
|
-
}
|
|
26944
|
-
this.get('cells').add(this._prepareCell(cell, opt), opt || {});
|
|
27711
|
+
this._prepareCell(cellInit, {
|
|
27712
|
+
...options,
|
|
27713
|
+
ensureZIndex: true
|
|
27714
|
+
});
|
|
27715
|
+
this.layerCollection.addCellToLayer(cellInit, this.getCellLayerId(cellInit), options);
|
|
26945
27716
|
return this;
|
|
26946
27717
|
},
|
|
26947
27718
|
addCells: function (cells, opt) {
|
|
@@ -26949,50 +27720,278 @@ var joint = (function (exports) {
|
|
|
26949
27720
|
cells = flattenDeep(cells);
|
|
26950
27721
|
opt.maxPosition = opt.position = cells.length - 1;
|
|
26951
27722
|
this.startBatch('add', opt);
|
|
26952
|
-
cells.forEach(
|
|
27723
|
+
cells.forEach(cell => {
|
|
26953
27724
|
this.addCell(cell, opt);
|
|
26954
27725
|
opt.position--;
|
|
26955
|
-
}
|
|
27726
|
+
});
|
|
26956
27727
|
this.stopBatch('add', opt);
|
|
26957
27728
|
return this;
|
|
26958
27729
|
},
|
|
26959
|
-
|
|
26960
|
-
|
|
26961
|
-
|
|
26962
|
-
|
|
26963
|
-
|
|
26964
|
-
|
|
26965
|
-
|
|
26966
|
-
|
|
27730
|
+
/**
|
|
27731
|
+
* @public
|
|
27732
|
+
* @description Reset the cells in the graph.
|
|
27733
|
+
* Useful for bulk operations and optimizations.
|
|
27734
|
+
*/
|
|
27735
|
+
resetCells: function (cellInits, options) {
|
|
27736
|
+
const {
|
|
27737
|
+
layerCollection
|
|
27738
|
+
} = this;
|
|
27739
|
+
// Note: `cellInits` is always an array and `options` is always an object.
|
|
27740
|
+
// See `wrappers.cells` at the end of this file.
|
|
27741
|
+
|
|
27742
|
+
// When resetting cells, do not set z-index if not provided.
|
|
27743
|
+
const prepareOptions = {
|
|
27744
|
+
...options,
|
|
27745
|
+
ensureZIndex: false
|
|
27746
|
+
};
|
|
27747
|
+
|
|
27748
|
+
// Initialize a map of layer IDs to arrays of cells
|
|
27749
|
+
const layerCellsMap = layerCollection.reduce((map, layer) => {
|
|
27750
|
+
map[layer.id] = [];
|
|
27751
|
+
return map;
|
|
27752
|
+
}, {});
|
|
27753
|
+
|
|
27754
|
+
// Distribute cells into their respective layers
|
|
27755
|
+
for (let i = 0; i < cellInits.length; i++) {
|
|
27756
|
+
const cellInit = cellInits[i];
|
|
27757
|
+
const layerId = this.getCellLayerId(cellInit);
|
|
27758
|
+
if (layerId in layerCellsMap) {
|
|
27759
|
+
this._prepareCell(cellInit, prepareOptions);
|
|
27760
|
+
layerCellsMap[layerId].push(cellInit);
|
|
27761
|
+
} else {
|
|
27762
|
+
throw new Error(`dia.Graph: Layer "${layerId}" does not exist.`);
|
|
27763
|
+
}
|
|
27764
|
+
}
|
|
27765
|
+
|
|
27766
|
+
// Reset each layer's cell collection with the corresponding cells.
|
|
27767
|
+
layerCollection.each(layer => {
|
|
27768
|
+
layer.cellCollection.reset(layerCellsMap[layer.id], options);
|
|
27769
|
+
});
|
|
27770
|
+
|
|
27771
|
+
// Trigger a single `reset` event on the graph
|
|
27772
|
+
// (while multiple `reset` events are triggered on layers).
|
|
27773
|
+
// Backwards compatibility: use default layer collection
|
|
27774
|
+
// The `collection` parameter is retained for backwards compatibility,
|
|
27775
|
+
// and it is subject to removal in future releases.
|
|
27776
|
+
this.trigger('reset', this.getDefaultLayer().cellCollection, options);
|
|
26967
27777
|
return this;
|
|
26968
27778
|
},
|
|
26969
|
-
|
|
26970
|
-
|
|
26971
|
-
|
|
26972
|
-
|
|
26973
|
-
|
|
27779
|
+
/**
|
|
27780
|
+
* @public
|
|
27781
|
+
* @description Get the layer ID in which the cell resides.
|
|
27782
|
+
* Cells without an explicit layer are assigned to the default layer.
|
|
27783
|
+
* @param {dia.Cell | Object} cellInit - Cell model or attributes.
|
|
27784
|
+
* @returns {string} - The layer ID.
|
|
27785
|
+
*/
|
|
27786
|
+
getCellLayerId: function (cellInit) {
|
|
27787
|
+
if (!cellInit) {
|
|
27788
|
+
throw new Error('dia.Graph: No cell provided.');
|
|
27789
|
+
}
|
|
27790
|
+
const cellAttributes = cellInit[CELL_MARKER] ? cellInit.attributes : cellInit;
|
|
27791
|
+
return cellAttributes[config$3.layerAttribute] || this.defaultLayerId;
|
|
27792
|
+
},
|
|
27793
|
+
/**
|
|
27794
|
+
* @protected
|
|
27795
|
+
* @description Reset the layers in the graph.
|
|
27796
|
+
* It assumes the existing cells have been removed beforehand
|
|
27797
|
+
* or can be discarded.
|
|
27798
|
+
*/
|
|
27799
|
+
_resetLayers: function (layers, defaultLayerId, options = {}) {
|
|
27800
|
+
if (!Array.isArray(layers) || layers.length === 0) {
|
|
27801
|
+
throw new Error('dia.Graph: At least one layer must be defined.');
|
|
27802
|
+
}
|
|
27803
|
+
|
|
27804
|
+
// Resetting layers disables legacy mode
|
|
27805
|
+
this.legacyMode = false;
|
|
27806
|
+
this.layerCollection.reset(layers, {
|
|
27807
|
+
...options,
|
|
27808
|
+
graph: this.cid
|
|
27809
|
+
});
|
|
27810
|
+
|
|
27811
|
+
// If no default layer is specified, use the first layer as default
|
|
27812
|
+
if (defaultLayerId) {
|
|
27813
|
+
// The default layer must be one of the defined layers
|
|
27814
|
+
if (!this.hasLayer(defaultLayerId)) {
|
|
27815
|
+
throw new Error(`dia.Graph: default layer "${defaultLayerId}" does not exist.`);
|
|
27816
|
+
}
|
|
27817
|
+
this.defaultLayerId = defaultLayerId;
|
|
27818
|
+
} else {
|
|
27819
|
+
this.defaultLayerId = this.layerCollection.at(0).id;
|
|
26974
27820
|
}
|
|
26975
27821
|
return this;
|
|
26976
27822
|
},
|
|
26977
|
-
|
|
26978
|
-
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
|
|
27823
|
+
/**
|
|
27824
|
+
* @public
|
|
27825
|
+
* @description Remove multiple cells from the graph.
|
|
27826
|
+
* @param {Array<dia.Cell | dia.Cell.ID>} cellRefs - Array of cell references (models or IDs) to remove.
|
|
27827
|
+
* @param {Object} [options] - Removal options. See {@link dia.Graph#removeCell}.
|
|
27828
|
+
*/
|
|
27829
|
+
removeCells: function (cellRefs, options) {
|
|
27830
|
+
if (!cellRefs.length) return this;
|
|
27831
|
+
// Remove multiple cells in a single batch
|
|
27832
|
+
this.startBatch('remove');
|
|
27833
|
+
for (const cellRef of cellRefs) {
|
|
27834
|
+
if (!cellRef) continue;
|
|
27835
|
+
let cell;
|
|
27836
|
+
if (cellRef[CELL_MARKER]) {
|
|
27837
|
+
cell = cellRef;
|
|
26985
27838
|
} else {
|
|
26986
|
-
this.
|
|
27839
|
+
cell = this.getCell(cellRef);
|
|
27840
|
+
if (!cell) {
|
|
27841
|
+
// The cell might have been already removed (embedded cell, connected link, etc.)
|
|
27842
|
+
continue;
|
|
27843
|
+
}
|
|
26987
27844
|
}
|
|
27845
|
+
this.layerCollection.removeCell(cell, options);
|
|
26988
27846
|
}
|
|
26989
|
-
|
|
26990
|
-
|
|
26991
|
-
|
|
26992
|
-
|
|
26993
|
-
|
|
26994
|
-
|
|
26995
|
-
|
|
27847
|
+
this.stopBatch('remove');
|
|
27848
|
+
return this;
|
|
27849
|
+
},
|
|
27850
|
+
/**
|
|
27851
|
+
* @protected
|
|
27852
|
+
* @description Replace an existing cell with a new cell.
|
|
27853
|
+
*/
|
|
27854
|
+
_replaceCell: function (currentCell, newCellInit, opt = {}) {
|
|
27855
|
+
const batchName = 'replace-cell';
|
|
27856
|
+
const replaceOptions = {
|
|
27857
|
+
...opt,
|
|
27858
|
+
replace: true
|
|
27859
|
+
};
|
|
27860
|
+
this.startBatch(batchName, opt);
|
|
27861
|
+
// 1. Remove the cell without removing connected links or embedded cells.
|
|
27862
|
+
this.layerCollection.removeCell(currentCell, replaceOptions);
|
|
27863
|
+
const newCellInitAttributes = newCellInit[CELL_MARKER] ? newCellInit.attributes : newCellInit;
|
|
27864
|
+
// 2. Combine the current cell attributes with the new cell attributes
|
|
27865
|
+
const replacementCellAttributes = Object.assign({}, currentCell.attributes, newCellInitAttributes);
|
|
27866
|
+
let replacement;
|
|
27867
|
+
if (newCellInit[CELL_MARKER]) {
|
|
27868
|
+
// If the new cell is a model, set the merged attributes on the model
|
|
27869
|
+
newCellInit.set(replacementCellAttributes, replaceOptions);
|
|
27870
|
+
replacement = newCellInit;
|
|
27871
|
+
} else {
|
|
27872
|
+
replacement = replacementCellAttributes;
|
|
27873
|
+
}
|
|
27874
|
+
|
|
27875
|
+
// 3. Add the replacement cell
|
|
27876
|
+
this.addCell(replacement, replaceOptions);
|
|
27877
|
+
this.stopBatch(batchName);
|
|
27878
|
+
},
|
|
27879
|
+
/**
|
|
27880
|
+
* @protected
|
|
27881
|
+
* @description Synchronize a single graph cell with the provided cell (model or attributes).
|
|
27882
|
+
* If the cell with the same `id` exists, it is updated. If the cell does not exist, it is added.
|
|
27883
|
+
* If the existing cell type is different from the incoming cell type, the existing cell is replaced.
|
|
27884
|
+
*/
|
|
27885
|
+
_syncCell: function (cellInit, opt = {}) {
|
|
27886
|
+
const cellAttributes = cellInit[CELL_MARKER] ? cellInit.attributes : cellInit;
|
|
27887
|
+
const currentCell = this.getCell(cellInit.id);
|
|
27888
|
+
if (currentCell) {
|
|
27889
|
+
// `cellInit` is either a model or attributes object
|
|
27890
|
+
if ('type' in cellAttributes && currentCell.get('type') !== cellAttributes.type) {
|
|
27891
|
+
// Replace the cell if the type has changed
|
|
27892
|
+
this._replaceCell(currentCell, cellInit, opt);
|
|
27893
|
+
} else {
|
|
27894
|
+
// Update existing cell
|
|
27895
|
+
// Note: the existing cell attributes are not removed,
|
|
27896
|
+
// if they're missing in `cellAttributes`.
|
|
27897
|
+
currentCell.set(cellAttributes, opt);
|
|
27898
|
+
}
|
|
27899
|
+
} else {
|
|
27900
|
+
// The cell does not exist yet, add it
|
|
27901
|
+
this.addCell(cellInit, opt);
|
|
27902
|
+
}
|
|
27903
|
+
},
|
|
27904
|
+
/**
|
|
27905
|
+
* @public
|
|
27906
|
+
* @description Synchronize the graph cells with the provided array of cells (models or attributes).
|
|
27907
|
+
*/
|
|
27908
|
+
syncCells: function (cellInits, opt = {}) {
|
|
27909
|
+
const batchName = 'sync-cells';
|
|
27910
|
+
const {
|
|
27911
|
+
remove = false,
|
|
27912
|
+
...setOpt
|
|
27913
|
+
} = opt;
|
|
27914
|
+
let currentCells, newCellsMap;
|
|
27915
|
+
if (remove) {
|
|
27916
|
+
// We need to track existing cells to remove the missing ones later
|
|
27917
|
+
currentCells = this.getCells();
|
|
27918
|
+
newCellsMap = new Map();
|
|
27919
|
+
}
|
|
27920
|
+
|
|
27921
|
+
// Observe changes to the graph cells
|
|
27922
|
+
let changeObserver, changedLayers;
|
|
27923
|
+
const shouldSort = opt.sort !== false;
|
|
27924
|
+
if (shouldSort) {
|
|
27925
|
+
changeObserver = new Listener();
|
|
27926
|
+
changedLayers = new Set();
|
|
27927
|
+
changeObserver.listenTo(this, {
|
|
27928
|
+
'add': cell => {
|
|
27929
|
+
changedLayers.add(this.getCellLayerId(cell));
|
|
27930
|
+
},
|
|
27931
|
+
'change': cell => {
|
|
27932
|
+
if (cell.hasChanged(config$3.layerAttribute) || cell.hasChanged('z')) {
|
|
27933
|
+
changedLayers.add(this.getCellLayerId(cell));
|
|
27934
|
+
}
|
|
27935
|
+
}
|
|
27936
|
+
});
|
|
27937
|
+
}
|
|
27938
|
+
this.startBatch(batchName, opt);
|
|
27939
|
+
|
|
27940
|
+
// Prevent multiple sorts during sync
|
|
27941
|
+
setOpt.sort = false;
|
|
27942
|
+
|
|
27943
|
+
// Add or update incoming cells
|
|
27944
|
+
for (const cellInit of cellInits) {
|
|
27945
|
+
if (remove) {
|
|
27946
|
+
// only track existence
|
|
27947
|
+
newCellsMap.set(cellInit.id, true);
|
|
27948
|
+
}
|
|
27949
|
+
this._syncCell(cellInit, setOpt);
|
|
27950
|
+
}
|
|
27951
|
+
if (remove) {
|
|
27952
|
+
// Remove cells not present in the incoming array
|
|
27953
|
+
for (const cell of currentCells) {
|
|
27954
|
+
if (!newCellsMap.has(cell.id)) {
|
|
27955
|
+
this.layerCollection.removeCell(cell, setOpt);
|
|
27956
|
+
}
|
|
27957
|
+
}
|
|
27958
|
+
}
|
|
27959
|
+
if (shouldSort) {
|
|
27960
|
+
// Sort layers that had changes affecting z-index or layer
|
|
27961
|
+
changeObserver.stopListening();
|
|
27962
|
+
for (const layerId of changedLayers) {
|
|
27963
|
+
this.getLayer(layerId).cellCollection.sort(opt);
|
|
27964
|
+
}
|
|
27965
|
+
}
|
|
27966
|
+
this.stopBatch(batchName);
|
|
27967
|
+
},
|
|
27968
|
+
/**
|
|
27969
|
+
* @public
|
|
27970
|
+
* @description Remove a cell from the graph.
|
|
27971
|
+
* @param {dia.Cell} cell
|
|
27972
|
+
* @param {Object} [options]
|
|
27973
|
+
* @param {boolean} [options.disconnectLinks=false] - If `true`, the connected links are
|
|
27974
|
+
* disconnected instead of removed.
|
|
27975
|
+
* @param {boolean} [options.clear=false] - If `true`, the connected links
|
|
27976
|
+
* are kept. @internal
|
|
27977
|
+
* @param {boolean} [options.replace=false] - If `true`, the connected links and
|
|
27978
|
+
* embedded cells are kept. @internal
|
|
27979
|
+
* @throws Will throw an error if no cell is provided
|
|
27980
|
+
* @throws Will throw an error if the ID of the cell to remove
|
|
27981
|
+
* does not exist in the graph
|
|
27982
|
+
**/
|
|
27983
|
+
removeCell: function (cellRef, options) {
|
|
27984
|
+
if (!cellRef) {
|
|
27985
|
+
throw new Error('dia.Graph: no cell provided.');
|
|
27986
|
+
}
|
|
27987
|
+
const cell = cellRef[CELL_MARKER] ? cellRef : this.getCell(cellRef);
|
|
27988
|
+
if (!cell) {
|
|
27989
|
+
throw new Error('dia.Graph: cell to remove does not exist in the graph.');
|
|
27990
|
+
}
|
|
27991
|
+
if (cell.graph !== this) return;
|
|
27992
|
+
this.startBatch('remove');
|
|
27993
|
+
cell.collection.remove(cell, options);
|
|
27994
|
+
this.stopBatch('remove');
|
|
26996
27995
|
},
|
|
26997
27996
|
transferCellEmbeds: function (sourceCell, targetCell, opt = {}) {
|
|
26998
27997
|
const batchName = 'transfer-embeds';
|
|
@@ -27022,24 +28021,248 @@ var joint = (function (exports) {
|
|
|
27022
28021
|
});
|
|
27023
28022
|
this.stopBatch(batchName);
|
|
27024
28023
|
},
|
|
27025
|
-
|
|
27026
|
-
|
|
27027
|
-
|
|
28024
|
+
/**
|
|
28025
|
+
* @private
|
|
28026
|
+
* Helper method for addLayer and moveLayer methods
|
|
28027
|
+
*/
|
|
28028
|
+
_getBeforeLayerIdFromOptions(options, layer = null) {
|
|
28029
|
+
let {
|
|
28030
|
+
before = null,
|
|
28031
|
+
index
|
|
28032
|
+
} = options;
|
|
28033
|
+
if (before && index !== undefined) {
|
|
28034
|
+
throw new Error('dia.Graph: Options "before" and "index" are mutually exclusive.');
|
|
28035
|
+
}
|
|
28036
|
+
let computedBefore;
|
|
28037
|
+
if (index !== undefined) {
|
|
28038
|
+
const layersArray = this.getLayers();
|
|
28039
|
+
if (index >= layersArray.length) {
|
|
28040
|
+
// If index is greater than the number of layers,
|
|
28041
|
+
// return before as null (move to the end).
|
|
28042
|
+
computedBefore = null;
|
|
28043
|
+
} else if (index < 0) {
|
|
28044
|
+
// If index is negative, move to the beginning.
|
|
28045
|
+
computedBefore = layersArray[0].id;
|
|
28046
|
+
} else {
|
|
28047
|
+
const originalIndex = layersArray.indexOf(layer);
|
|
28048
|
+
if (originalIndex !== -1 && index > originalIndex) {
|
|
28049
|
+
// If moving a layer upwards in the stack, we need to adjust the index
|
|
28050
|
+
// to account for the layer being removed from its original position.
|
|
28051
|
+
index += 1;
|
|
28052
|
+
}
|
|
28053
|
+
// Otherwise, get the layer ID at the specified index.
|
|
28054
|
+
computedBefore = layersArray[index]?.id || null;
|
|
28055
|
+
}
|
|
28056
|
+
} else {
|
|
28057
|
+
computedBefore = before;
|
|
28058
|
+
}
|
|
28059
|
+
return computedBefore;
|
|
28060
|
+
},
|
|
28061
|
+
/**
|
|
28062
|
+
* @public
|
|
28063
|
+
* Adds a new layer to the graph.
|
|
28064
|
+
* @param {GraphLayer | GraphLayerJSON} layerInit
|
|
28065
|
+
* @param {*} options
|
|
28066
|
+
* @param {string | null} [options.before] - ID of the layer
|
|
28067
|
+
* before which to insert the new layer. If `null`, the layer is added at the end.
|
|
28068
|
+
* @param {number} [options.index] - Zero-based index to which to add the layer.
|
|
28069
|
+
* @throws Will throw an error if the layer to add is invalid
|
|
28070
|
+
* @throws Will throw an error if a layer with the same ID already exists
|
|
28071
|
+
* @throws Will throw if `before` reference is invalid
|
|
28072
|
+
*/
|
|
28073
|
+
addLayer(layerInit, options = {}) {
|
|
28074
|
+
if (!layerInit || !layerInit.id) {
|
|
28075
|
+
throw new Error('dia.Graph: Layer to add is invalid.');
|
|
28076
|
+
}
|
|
28077
|
+
if (this.hasLayer(layerInit.id)) {
|
|
28078
|
+
throw new Error(`dia.Graph: Layer "${layerInit.id}" already exists.`);
|
|
28079
|
+
}
|
|
28080
|
+
const {
|
|
28081
|
+
before = null,
|
|
28082
|
+
index,
|
|
28083
|
+
...insertOptions
|
|
28084
|
+
} = options;
|
|
28085
|
+
insertOptions.graph = this.cid;
|
|
28086
|
+
|
|
28087
|
+
// Adding a new layer disables legacy mode
|
|
28088
|
+
this.legacyMode = false;
|
|
28089
|
+
const beforeId = this._getBeforeLayerIdFromOptions({
|
|
28090
|
+
before,
|
|
28091
|
+
index
|
|
28092
|
+
});
|
|
28093
|
+
this.layerCollection.insert(layerInit, beforeId, insertOptions);
|
|
28094
|
+
},
|
|
28095
|
+
/**
|
|
28096
|
+
* @public
|
|
28097
|
+
* Moves an existing layer to a new position in the layer stack.
|
|
28098
|
+
* @param {string | GraphLayer} layerRef - ID or reference of the layer to move.
|
|
28099
|
+
* @param {*} options
|
|
28100
|
+
* @param {string | null} [options.before] - ID of the layer
|
|
28101
|
+
* before which to insert the moved layer. If `null`, the layer is moved to the end.
|
|
28102
|
+
* @param {number} [options.index] - Zero-based index to which to move the layer.
|
|
28103
|
+
* @throws Will throw an error if the layer to move does not exist
|
|
28104
|
+
* @throws Will throw an error if `before` reference is invalid
|
|
28105
|
+
* @throws Will throw an error if both `before` and `index` options are provided
|
|
28106
|
+
*/
|
|
28107
|
+
moveLayer(layerRef, options = {}) {
|
|
28108
|
+
if (!layerRef || !this.hasLayer(layerRef)) {
|
|
28109
|
+
throw new Error('dia.Graph: Layer to move does not exist.');
|
|
28110
|
+
}
|
|
28111
|
+
const layer = this.getLayer(layerRef);
|
|
28112
|
+
const {
|
|
28113
|
+
before = null,
|
|
28114
|
+
index,
|
|
28115
|
+
...insertOptions
|
|
28116
|
+
} = options;
|
|
28117
|
+
insertOptions.graph = this.cid;
|
|
28118
|
+
|
|
28119
|
+
// Moving a layer disables legacy mode
|
|
28120
|
+
this.legacyMode = false;
|
|
28121
|
+
const beforeId = this._getBeforeLayerIdFromOptions({
|
|
28122
|
+
before,
|
|
28123
|
+
index
|
|
28124
|
+
}, layer);
|
|
28125
|
+
this.layerCollection.insert(layer, beforeId, insertOptions);
|
|
28126
|
+
},
|
|
28127
|
+
/**
|
|
28128
|
+
* @public
|
|
28129
|
+
* Removes an existing layer from the graph.
|
|
28130
|
+
* @param {string | GraphLayer} layerRef - ID or reference of the layer to remove.
|
|
28131
|
+
* @param {*} options
|
|
28132
|
+
* @throws Will throw an error if no layer is provided
|
|
28133
|
+
* @throws Will throw an error if the layer to remove does not exist
|
|
28134
|
+
*/
|
|
28135
|
+
removeLayer(layerRef, options = {}) {
|
|
28136
|
+
if (!layerRef) {
|
|
28137
|
+
throw new Error('dia.Graph: No layer provided.');
|
|
28138
|
+
}
|
|
28139
|
+
|
|
28140
|
+
// The layer must exist
|
|
28141
|
+
const layerId = layerRef.id ? layerRef.id : layerRef;
|
|
28142
|
+
const layer = this.getLayer(layerId);
|
|
28143
|
+
|
|
28144
|
+
// Prevent removing the default layer
|
|
28145
|
+
// Note: if there is only one layer, it is also the default layer.
|
|
28146
|
+
const {
|
|
28147
|
+
id: defaultLayerId
|
|
28148
|
+
} = this.getDefaultLayer();
|
|
28149
|
+
if (layerId === defaultLayerId) {
|
|
28150
|
+
throw new Error('dia.Graph: default layer cannot be removed.');
|
|
28151
|
+
}
|
|
28152
|
+
|
|
28153
|
+
// A layer with cells cannot be removed
|
|
28154
|
+
if (layer.cellCollection.length > 0) {
|
|
28155
|
+
throw new Error(`dia.Graph: Layer "${layerId}" cannot be removed because it is not empty.`);
|
|
28156
|
+
}
|
|
28157
|
+
this.layerCollection.remove(layerId, {
|
|
28158
|
+
...options,
|
|
28159
|
+
graph: this.cid
|
|
28160
|
+
});
|
|
28161
|
+
},
|
|
28162
|
+
getDefaultLayer() {
|
|
28163
|
+
return this.layerCollection.get(this.defaultLayerId);
|
|
28164
|
+
},
|
|
28165
|
+
setDefaultLayer(layerRef, options = {}) {
|
|
28166
|
+
if (!layerRef) {
|
|
28167
|
+
throw new Error('dia.Graph: No default layer ID provided.');
|
|
28168
|
+
}
|
|
28169
|
+
|
|
28170
|
+
// Make sure the layer exists
|
|
28171
|
+
const defaultLayerId = layerRef.id ? layerRef.id : layerRef;
|
|
28172
|
+
const defaultLayer = this.getLayer(defaultLayerId);
|
|
28173
|
+
|
|
28174
|
+
// If the default layer is not changing, do nothing
|
|
28175
|
+
const currentDefaultLayerId = this.defaultLayerId;
|
|
28176
|
+
if (defaultLayerId === currentDefaultLayerId) {
|
|
28177
|
+
// The default layer stays the same
|
|
28178
|
+
return;
|
|
28179
|
+
}
|
|
28180
|
+
|
|
28181
|
+
// Get all cells that belong to the current default layer implicitly
|
|
28182
|
+
const implicitLayerCells = this.getImplicitLayerCells();
|
|
28183
|
+
|
|
28184
|
+
// Set the new default layer ID
|
|
28185
|
+
this.defaultLayerId = defaultLayerId;
|
|
28186
|
+
const batchName = 'default-layer-change';
|
|
28187
|
+
this.startBatch(batchName, options);
|
|
28188
|
+
if (implicitLayerCells.length > 0) {
|
|
28189
|
+
// Reassign any cells lacking an explicit layer to the new default layer.
|
|
28190
|
+
// Do not sort yet, wait until all cells are moved.
|
|
28191
|
+
const moveOptions = {
|
|
28192
|
+
...options,
|
|
28193
|
+
sort: false
|
|
28194
|
+
};
|
|
28195
|
+
for (const cell of implicitLayerCells) {
|
|
28196
|
+
this.layerCollection.moveCellBetweenLayers(cell, defaultLayerId, moveOptions);
|
|
28197
|
+
}
|
|
28198
|
+
// Now sort the new default layer
|
|
28199
|
+
if (options.sort !== false) {
|
|
28200
|
+
defaultLayer.cellCollection.sort(options);
|
|
28201
|
+
}
|
|
28202
|
+
}
|
|
28203
|
+
|
|
28204
|
+
// Pretend to trigger the event on the layer itself.
|
|
28205
|
+
// It will bubble up as `layer:default` event on the graph.
|
|
28206
|
+
defaultLayer.trigger(defaultLayer.eventPrefix + 'default', defaultLayer, {
|
|
28207
|
+
...options,
|
|
28208
|
+
previousDefaultLayerId: currentDefaultLayerId
|
|
28209
|
+
});
|
|
28210
|
+
this.stopBatch(batchName, options);
|
|
28211
|
+
},
|
|
28212
|
+
/**
|
|
28213
|
+
* @protected
|
|
28214
|
+
* @description Get all cells that do not have an explicit layer assigned.
|
|
28215
|
+
* These cells belong to the default layer implicitly.
|
|
28216
|
+
* @return {Array<dia.Cell>} Array of cells without an explicit layer.
|
|
28217
|
+
*/
|
|
28218
|
+
getImplicitLayerCells() {
|
|
28219
|
+
return this.getDefaultLayer().cellCollection.filter(cell => {
|
|
28220
|
+
return cell.get(config$3.layerAttribute) == null;
|
|
28221
|
+
});
|
|
28222
|
+
},
|
|
28223
|
+
getLayer(layerId) {
|
|
28224
|
+
if (!this.hasLayer(layerId)) {
|
|
28225
|
+
throw new Error(`dia.Graph: Layer "${layerId}" does not exist.`);
|
|
28226
|
+
}
|
|
28227
|
+
return this.layerCollection.get(layerId);
|
|
28228
|
+
},
|
|
28229
|
+
hasLayer(layerRef) {
|
|
28230
|
+
return this.layerCollection.has(layerRef);
|
|
28231
|
+
},
|
|
28232
|
+
getLayers() {
|
|
28233
|
+
return this.layerCollection.toArray();
|
|
28234
|
+
},
|
|
28235
|
+
getCell: function (cellRef) {
|
|
28236
|
+
return this.layerCollection.getCell(cellRef);
|
|
27028
28237
|
},
|
|
27029
28238
|
getCells: function () {
|
|
27030
|
-
return this.
|
|
28239
|
+
return this.layerCollection.getCells();
|
|
27031
28240
|
},
|
|
27032
28241
|
getElements: function () {
|
|
27033
|
-
return this.
|
|
28242
|
+
return this.getCells().filter(cell => cell.isElement());
|
|
27034
28243
|
},
|
|
27035
28244
|
getLinks: function () {
|
|
27036
|
-
return this.
|
|
28245
|
+
return this.getCells().filter(cell => cell.isLink());
|
|
27037
28246
|
},
|
|
27038
|
-
getFirstCell: function () {
|
|
27039
|
-
|
|
28247
|
+
getFirstCell: function (layerId) {
|
|
28248
|
+
let layer;
|
|
28249
|
+
if (!layerId) {
|
|
28250
|
+
// Get the first cell from the bottom-most layer
|
|
28251
|
+
layer = this.getLayers().at(0);
|
|
28252
|
+
} else {
|
|
28253
|
+
layer = this.getLayer(layerId);
|
|
28254
|
+
}
|
|
28255
|
+
return layer.cellCollection.models.at(0);
|
|
27040
28256
|
},
|
|
27041
|
-
getLastCell: function () {
|
|
27042
|
-
|
|
28257
|
+
getLastCell: function (layerId) {
|
|
28258
|
+
let layer;
|
|
28259
|
+
if (!layerId) {
|
|
28260
|
+
// Get the last cell from the top-most layer
|
|
28261
|
+
layer = this.getLayers().at(-1);
|
|
28262
|
+
} else {
|
|
28263
|
+
layer = this.getLayer(layerId);
|
|
28264
|
+
}
|
|
28265
|
+
return layer.cellCollection.models.at(-1);
|
|
27043
28266
|
},
|
|
27044
28267
|
// Get all inbound and outbound links connected to the cell `model`.
|
|
27045
28268
|
getConnectedLinks: function (model, opt) {
|
|
@@ -27063,12 +28286,13 @@ var joint = (function (exports) {
|
|
|
27063
28286
|
addInbounds(this, model);
|
|
27064
28287
|
}
|
|
27065
28288
|
function addOutbounds(graph, model) {
|
|
27066
|
-
forIn(graph.getOutboundEdges(model.id), function (_, edge) {
|
|
28289
|
+
forIn(graph.topologyIndex.getOutboundEdges(model.id), function (_, edge) {
|
|
27067
28290
|
// skip links that were already added
|
|
27068
28291
|
// (those must be self-loop links)
|
|
27069
28292
|
// (because they are inbound and outbound edges of the same two elements)
|
|
27070
28293
|
if (edges[edge]) return;
|
|
27071
28294
|
var link = graph.getCell(edge);
|
|
28295
|
+
if (!link) return;
|
|
27072
28296
|
links.push(link);
|
|
27073
28297
|
edges[edge] = true;
|
|
27074
28298
|
if (indirect) {
|
|
@@ -27087,12 +28311,13 @@ var joint = (function (exports) {
|
|
|
27087
28311
|
}
|
|
27088
28312
|
}
|
|
27089
28313
|
function addInbounds(graph, model) {
|
|
27090
|
-
forIn(graph.getInboundEdges(model.id), function (_, edge) {
|
|
28314
|
+
forIn(graph.topologyIndex.getInboundEdges(model.id), function (_, edge) {
|
|
27091
28315
|
// skip links that were already added
|
|
27092
28316
|
// (those must be self-loop links)
|
|
27093
28317
|
// (because they are inbound and outbound edges of the same two elements)
|
|
27094
28318
|
if (edges[edge]) return;
|
|
27095
28319
|
var link = graph.getCell(edge);
|
|
28320
|
+
if (!link) return;
|
|
27096
28321
|
links.push(link);
|
|
27097
28322
|
edges[edge] = true;
|
|
27098
28323
|
if (indirect) {
|
|
@@ -27127,7 +28352,7 @@ var joint = (function (exports) {
|
|
|
27127
28352
|
embeddedCells.forEach(function (cell) {
|
|
27128
28353
|
if (cell.isLink()) return;
|
|
27129
28354
|
if (outbound) {
|
|
27130
|
-
forIn(this.getOutboundEdges(cell.id), function (exists, edge) {
|
|
28355
|
+
forIn(this.topologyIndex.getOutboundEdges(cell.id), function (exists, edge) {
|
|
27131
28356
|
if (!edges[edge]) {
|
|
27132
28357
|
var edgeCell = this.getCell(edge);
|
|
27133
28358
|
var {
|
|
@@ -27147,7 +28372,7 @@ var joint = (function (exports) {
|
|
|
27147
28372
|
}.bind(this));
|
|
27148
28373
|
}
|
|
27149
28374
|
if (inbound) {
|
|
27150
|
-
forIn(this.getInboundEdges(cell.id), function (exists, edge) {
|
|
28375
|
+
forIn(this.topologyIndex.getInboundEdges(cell.id), function (exists, edge) {
|
|
27151
28376
|
if (!edges[edge]) {
|
|
27152
28377
|
var edgeCell = this.getCell(edge);
|
|
27153
28378
|
var {
|
|
@@ -27426,31 +28651,19 @@ var joint = (function (exports) {
|
|
|
27426
28651
|
},
|
|
27427
28652
|
// Get all the roots of the graph. Time complexity: O(|V|).
|
|
27428
28653
|
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;
|
|
28654
|
+
return this.topologyIndex.getSourceNodes().map(nodeId => this.getCell(nodeId));
|
|
27436
28655
|
},
|
|
27437
28656
|
// Get all the leafs of the graph. Time complexity: O(|V|).
|
|
27438
28657
|
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;
|
|
28658
|
+
return this.topologyIndex.getSinkNodes().map(nodeId => this.getCell(nodeId));
|
|
27446
28659
|
},
|
|
27447
28660
|
// Return `true` if `element` is a root. Time complexity: O(1).
|
|
27448
28661
|
isSource: function (element) {
|
|
27449
|
-
return
|
|
28662
|
+
return this.topologyIndex.isSourceNode(element.id);
|
|
27450
28663
|
},
|
|
27451
28664
|
// Return `true` if `element` is a leaf. Time complexity: O(1).
|
|
27452
28665
|
isSink: function (element) {
|
|
27453
|
-
return
|
|
28666
|
+
return this.topologyIndex.isSinkNode(element.id);
|
|
27454
28667
|
},
|
|
27455
28668
|
// Return `true` is `elementB` is a successor of `elementA`. Return `false` otherwise.
|
|
27456
28669
|
isSuccessor: function (elementA, elementB) {
|
|
@@ -27521,8 +28734,10 @@ var joint = (function (exports) {
|
|
|
27521
28734
|
});
|
|
27522
28735
|
},
|
|
27523
28736
|
// Remove links connected to the cell `model` completely.
|
|
27524
|
-
removeLinks: function (
|
|
27525
|
-
|
|
28737
|
+
removeLinks: function (cell, opt) {
|
|
28738
|
+
this.getConnectedLinks(cell).forEach(link => {
|
|
28739
|
+
this.layerCollection.removeCell(link, opt);
|
|
28740
|
+
});
|
|
27526
28741
|
},
|
|
27527
28742
|
// Find all cells at given point
|
|
27528
28743
|
|
|
@@ -27713,85 +28928,6 @@ var joint = (function (exports) {
|
|
|
27713
28928
|
});
|
|
27714
28929
|
wrapWith(Graph.prototype, ['resetCells', 'addCells', 'removeCells'], wrappers.cells);
|
|
27715
28930
|
|
|
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
28931
|
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
28932
|
const positiveValueList = ['r', 'rx', 'ry', 'width', 'height', 'stroke-width', 'font-size'];
|
|
27797
28933
|
const calcAttributes = calcAttributesList.reduce((acc, attrName) => {
|
|
@@ -29033,7 +30169,6 @@ var joint = (function (exports) {
|
|
|
29033
30169
|
// Internal tag to identify this object as a cell view instance.
|
|
29034
30170
|
// Used instead of `instanceof` for performance and cross-frame safety.
|
|
29035
30171
|
|
|
29036
|
-
const CELL_VIEW_MARKER = Symbol('joint.cellViewMarker');
|
|
29037
30172
|
Object.defineProperty(CellView.prototype, CELL_VIEW_MARKER, {
|
|
29038
30173
|
value: true
|
|
29039
30174
|
});
|
|
@@ -31841,6 +32976,231 @@ var joint = (function (exports) {
|
|
|
31841
32976
|
}
|
|
31842
32977
|
});
|
|
31843
32978
|
|
|
32979
|
+
const LayerView = View.extend({
|
|
32980
|
+
tagName: 'g',
|
|
32981
|
+
svgElement: true,
|
|
32982
|
+
pivotNodes: null,
|
|
32983
|
+
defaultTheme: null,
|
|
32984
|
+
UPDATE_PRIORITY: 4,
|
|
32985
|
+
options: {
|
|
32986
|
+
id: ''
|
|
32987
|
+
},
|
|
32988
|
+
paper: null,
|
|
32989
|
+
init: function () {
|
|
32990
|
+
this.pivotNodes = {};
|
|
32991
|
+
this.id = this.options.id || this.cid;
|
|
32992
|
+
},
|
|
32993
|
+
setPaperReference: function (paper) {
|
|
32994
|
+
this.paper = paper;
|
|
32995
|
+
this.afterPaperReferenceSet(paper);
|
|
32996
|
+
},
|
|
32997
|
+
unsetPaperReference: function () {
|
|
32998
|
+
this.beforePaperReferenceUnset();
|
|
32999
|
+
this.paper = null;
|
|
33000
|
+
},
|
|
33001
|
+
assertPaperReference() {
|
|
33002
|
+
if (!this.paper) {
|
|
33003
|
+
throw new Error('LayerView: paper reference is not set.');
|
|
33004
|
+
}
|
|
33005
|
+
},
|
|
33006
|
+
afterPaperReferenceSet: function () {
|
|
33007
|
+
// Can be overridden in subclasses.
|
|
33008
|
+
},
|
|
33009
|
+
beforePaperReferenceUnset: function () {
|
|
33010
|
+
// Can be overridden in subclasses.
|
|
33011
|
+
},
|
|
33012
|
+
// prevents id to be set on the DOM element
|
|
33013
|
+
_setAttributes: function (attrs) {
|
|
33014
|
+
const newAttrs = clone$1(attrs);
|
|
33015
|
+
delete newAttrs.id;
|
|
33016
|
+
View.prototype._setAttributes.call(this, newAttrs);
|
|
33017
|
+
},
|
|
33018
|
+
className: function () {
|
|
33019
|
+
const {
|
|
33020
|
+
id
|
|
33021
|
+
} = this.options;
|
|
33022
|
+
return addClassNamePrefix(`${id}-layer`);
|
|
33023
|
+
},
|
|
33024
|
+
insertSortedNode: function (node, z) {
|
|
33025
|
+
this.el.insertBefore(node, this.insertPivot(z));
|
|
33026
|
+
},
|
|
33027
|
+
insertNode: function (node) {
|
|
33028
|
+
const {
|
|
33029
|
+
el
|
|
33030
|
+
} = this;
|
|
33031
|
+
if (node.parentNode !== el) {
|
|
33032
|
+
el.appendChild(node);
|
|
33033
|
+
}
|
|
33034
|
+
},
|
|
33035
|
+
insertPivot: function (z) {
|
|
33036
|
+
const {
|
|
33037
|
+
el,
|
|
33038
|
+
pivotNodes
|
|
33039
|
+
} = this;
|
|
33040
|
+
z = +z;
|
|
33041
|
+
z || (z = 0);
|
|
33042
|
+
let pivotNode = pivotNodes[z];
|
|
33043
|
+
if (pivotNode) return pivotNode;
|
|
33044
|
+
pivotNode = pivotNodes[z] = document.createComment('z-index:' + (z + 1));
|
|
33045
|
+
let neighborZ = -Infinity;
|
|
33046
|
+
for (let currentZ in pivotNodes) {
|
|
33047
|
+
currentZ = +currentZ;
|
|
33048
|
+
if (currentZ < z && currentZ > neighborZ) {
|
|
33049
|
+
neighborZ = currentZ;
|
|
33050
|
+
if (neighborZ === z - 1) continue;
|
|
33051
|
+
}
|
|
33052
|
+
}
|
|
33053
|
+
if (neighborZ !== -Infinity) {
|
|
33054
|
+
const neighborPivot = pivotNodes[neighborZ];
|
|
33055
|
+
// Insert After
|
|
33056
|
+
el.insertBefore(pivotNode, neighborPivot.nextSibling);
|
|
33057
|
+
} else {
|
|
33058
|
+
// First Child
|
|
33059
|
+
el.insertBefore(pivotNode, el.firstChild);
|
|
33060
|
+
}
|
|
33061
|
+
return pivotNode;
|
|
33062
|
+
},
|
|
33063
|
+
removePivots: function () {
|
|
33064
|
+
const {
|
|
33065
|
+
el,
|
|
33066
|
+
pivotNodes
|
|
33067
|
+
} = this;
|
|
33068
|
+
for (let z in pivotNodes) el.removeChild(pivotNodes[z]);
|
|
33069
|
+
this.pivotNodes = {};
|
|
33070
|
+
},
|
|
33071
|
+
isEmpty: function () {
|
|
33072
|
+
// Check if the layer has any child elements (pivot comments are not counted).
|
|
33073
|
+
return this.el.children.length === 0;
|
|
33074
|
+
},
|
|
33075
|
+
reset: function () {
|
|
33076
|
+
this.removePivots();
|
|
33077
|
+
}
|
|
33078
|
+
});
|
|
33079
|
+
Object.defineProperty(LayerView.prototype, LAYER_VIEW_MARKER, {
|
|
33080
|
+
value: true
|
|
33081
|
+
});
|
|
33082
|
+
|
|
33083
|
+
/**
|
|
33084
|
+
* @class GraphLayerView
|
|
33085
|
+
* @description A GraphLayerView is responsible for managing the rendering of cell views inside a layer.
|
|
33086
|
+
* It listens to the corresponding GraphLayer model and updates the DOM accordingly.
|
|
33087
|
+
* It uses dia.Paper sorting options to sort cell views in the DOM based on their `z` attribute.
|
|
33088
|
+
*/
|
|
33089
|
+
const GraphLayerView = LayerView.extend({
|
|
33090
|
+
SORT_DELAYING_BATCHES: ['add', 'to-front', 'to-back'],
|
|
33091
|
+
style: {
|
|
33092
|
+
webkitUserSelect: 'none',
|
|
33093
|
+
userSelect: 'none'
|
|
33094
|
+
},
|
|
33095
|
+
graph: null,
|
|
33096
|
+
init() {
|
|
33097
|
+
LayerView.prototype.init.apply(this, arguments);
|
|
33098
|
+
this.graph = this.model.graph;
|
|
33099
|
+
},
|
|
33100
|
+
className: function () {
|
|
33101
|
+
const {
|
|
33102
|
+
id
|
|
33103
|
+
} = this.options;
|
|
33104
|
+
return [addClassNamePrefix(`${id}-layer`), addClassNamePrefix('cells')].join(' ');
|
|
33105
|
+
},
|
|
33106
|
+
afterPaperReferenceSet(paper) {
|
|
33107
|
+
this.listenTo(this.model, 'sort', this.onCellCollectionSort);
|
|
33108
|
+
this.listenTo(this.model, 'change', this.onCellChange);
|
|
33109
|
+
this.listenTo(this.model, 'move', this.onCellMove);
|
|
33110
|
+
this.listenTo(this.graph, 'batch:stop', this.onGraphBatchStop);
|
|
33111
|
+
},
|
|
33112
|
+
beforePaperReferenceUnset() {
|
|
33113
|
+
this.stopListening(this.model);
|
|
33114
|
+
this.stopListening(this.graph);
|
|
33115
|
+
},
|
|
33116
|
+
onCellCollectionSort() {
|
|
33117
|
+
if (this.graph.hasActiveBatch(this.SORT_DELAYING_BATCHES)) return;
|
|
33118
|
+
this.sort();
|
|
33119
|
+
},
|
|
33120
|
+
onCellMove(cell, opt = {}) {
|
|
33121
|
+
// When a cell is moved from one layer to another,
|
|
33122
|
+
// request insertion of its view in the new layer.
|
|
33123
|
+
this.paper.requestCellViewInsertion(cell, opt);
|
|
33124
|
+
},
|
|
33125
|
+
onCellChange(cell, opt) {
|
|
33126
|
+
if (!cell.hasChanged('z')) return;
|
|
33127
|
+
// Re-insert the cell view to maintain correct z-ordering
|
|
33128
|
+
if (this.paper.options.sorting === sortingTypes.APPROX) {
|
|
33129
|
+
this.paper.requestCellViewInsertion(cell, opt);
|
|
33130
|
+
}
|
|
33131
|
+
},
|
|
33132
|
+
onGraphBatchStop(data) {
|
|
33133
|
+
const name = data && data.batchName;
|
|
33134
|
+
const sortDelayingBatches = this.SORT_DELAYING_BATCHES;
|
|
33135
|
+
// After certain batches, sorting may be required
|
|
33136
|
+
if (sortDelayingBatches.includes(name) && !this.graph.hasActiveBatch(sortDelayingBatches)) {
|
|
33137
|
+
this.sort();
|
|
33138
|
+
}
|
|
33139
|
+
},
|
|
33140
|
+
sort() {
|
|
33141
|
+
this.assertPaperReference();
|
|
33142
|
+
const {
|
|
33143
|
+
paper
|
|
33144
|
+
} = this;
|
|
33145
|
+
if (!paper.isExactSorting()) {
|
|
33146
|
+
// noop
|
|
33147
|
+
return;
|
|
33148
|
+
}
|
|
33149
|
+
if (paper.isFrozen()) {
|
|
33150
|
+
// sort views once unfrozen
|
|
33151
|
+
paper._updates.sort = true;
|
|
33152
|
+
return;
|
|
33153
|
+
}
|
|
33154
|
+
this.sortExact();
|
|
33155
|
+
},
|
|
33156
|
+
sortExact() {
|
|
33157
|
+
// Run insertion sort algorithm in order to efficiently sort DOM elements according to their
|
|
33158
|
+
// associated model `z` attribute.
|
|
33159
|
+
const cellNodes = Array.from(this.el.children).filter(node => node.getAttribute('model-id'));
|
|
33160
|
+
const cellCollection = this.model.cellCollection;
|
|
33161
|
+
sortElements(cellNodes, function (a, b) {
|
|
33162
|
+
const cellA = cellCollection.get(a.getAttribute('model-id'));
|
|
33163
|
+
const cellB = cellCollection.get(b.getAttribute('model-id'));
|
|
33164
|
+
const zA = cellA.attributes.z || 0;
|
|
33165
|
+
const zB = cellB.attributes.z || 0;
|
|
33166
|
+
return zA === zB ? 0 : zA < zB ? -1 : 1;
|
|
33167
|
+
});
|
|
33168
|
+
},
|
|
33169
|
+
insertCellView(cellView) {
|
|
33170
|
+
this.assertPaperReference();
|
|
33171
|
+
const {
|
|
33172
|
+
paper
|
|
33173
|
+
} = this;
|
|
33174
|
+
const {
|
|
33175
|
+
el,
|
|
33176
|
+
model
|
|
33177
|
+
} = cellView;
|
|
33178
|
+
switch (paper.options.sorting) {
|
|
33179
|
+
case sortingTypes.APPROX:
|
|
33180
|
+
this.insertSortedNode(el, model.get('z'));
|
|
33181
|
+
break;
|
|
33182
|
+
case sortingTypes.EXACT:
|
|
33183
|
+
default:
|
|
33184
|
+
this.insertNode(el);
|
|
33185
|
+
break;
|
|
33186
|
+
}
|
|
33187
|
+
}
|
|
33188
|
+
});
|
|
33189
|
+
Object.defineProperty(GraphLayerView.prototype, GRAPH_LAYER_VIEW_MARKER, {
|
|
33190
|
+
value: true
|
|
33191
|
+
});
|
|
33192
|
+
|
|
33193
|
+
/**
|
|
33194
|
+
* @class LegacyGraphLayerView
|
|
33195
|
+
* @description A legacy GraphLayerView with an additional class name for backward compatibility.
|
|
33196
|
+
*/
|
|
33197
|
+
const LegacyGraphLayerView = GraphLayerView.extend({
|
|
33198
|
+
className: function () {
|
|
33199
|
+
const className = GraphLayerView.prototype.className.apply(this, arguments);
|
|
33200
|
+
return className + ' ' + addClassNamePrefix('viewport');
|
|
33201
|
+
}
|
|
33202
|
+
});
|
|
33203
|
+
|
|
31844
33204
|
/**
|
|
31845
33205
|
* Deque implementation for managing a double-ended queue.
|
|
31846
33206
|
* This implementation uses a doubly linked list for efficient operations.
|
|
@@ -31963,23 +33323,24 @@ var joint = (function (exports) {
|
|
|
31963
33323
|
}
|
|
31964
33324
|
}
|
|
31965
33325
|
|
|
31966
|
-
const
|
|
33326
|
+
const GridLayerView = LayerView.extend({
|
|
31967
33327
|
style: {
|
|
31968
33328
|
'pointer-events': 'none'
|
|
31969
33329
|
},
|
|
31970
33330
|
_gridCache: null,
|
|
31971
33331
|
_gridSettings: null,
|
|
31972
33332
|
init() {
|
|
31973
|
-
|
|
31974
|
-
|
|
31975
|
-
options: {
|
|
31976
|
-
paper
|
|
31977
|
-
}
|
|
31978
|
-
} = this;
|
|
33333
|
+
LayerView.prototype.init.apply(this, arguments);
|
|
33334
|
+
this.paper = this.options.paper;
|
|
31979
33335
|
this._gridCache = null;
|
|
31980
33336
|
this._gridSettings = [];
|
|
33337
|
+
},
|
|
33338
|
+
afterPaperReferenceSet(paper) {
|
|
31981
33339
|
this.listenTo(paper, 'transform resize', this.updateGrid);
|
|
31982
33340
|
},
|
|
33341
|
+
beforePaperReferenceUnset(paper) {
|
|
33342
|
+
this.stopListening(paper);
|
|
33343
|
+
},
|
|
31983
33344
|
setGrid(drawGrid) {
|
|
31984
33345
|
this._gridSettings = this.getGridSettings(drawGrid);
|
|
31985
33346
|
this.renderGrid();
|
|
@@ -32004,9 +33365,7 @@ var joint = (function (exports) {
|
|
|
32004
33365
|
},
|
|
32005
33366
|
renderGrid() {
|
|
32006
33367
|
const {
|
|
32007
|
-
|
|
32008
|
-
paper
|
|
32009
|
-
}
|
|
33368
|
+
paper
|
|
32010
33369
|
} = this;
|
|
32011
33370
|
const {
|
|
32012
33371
|
_gridSettings: gridSettings
|
|
@@ -32051,9 +33410,7 @@ var joint = (function (exports) {
|
|
|
32051
33410
|
const {
|
|
32052
33411
|
_gridCache: grid,
|
|
32053
33412
|
_gridSettings: gridSettings,
|
|
32054
|
-
|
|
32055
|
-
paper
|
|
32056
|
-
}
|
|
33413
|
+
paper
|
|
32057
33414
|
} = this;
|
|
32058
33415
|
if (!grid) return;
|
|
32059
33416
|
const {
|
|
@@ -32087,7 +33444,7 @@ var joint = (function (exports) {
|
|
|
32087
33444
|
});
|
|
32088
33445
|
},
|
|
32089
33446
|
_getPatternId(index) {
|
|
32090
|
-
return `pattern_${this.
|
|
33447
|
+
return `pattern_${this.paper.cid}_${index}`;
|
|
32091
33448
|
},
|
|
32092
33449
|
_getGridRefs() {
|
|
32093
33450
|
let {
|
|
@@ -32122,27 +33479,27 @@ var joint = (function (exports) {
|
|
|
32122
33479
|
return grid;
|
|
32123
33480
|
},
|
|
32124
33481
|
_resolveDrawGridOption(opt) {
|
|
32125
|
-
|
|
33482
|
+
const namespace = this.options.patterns;
|
|
32126
33483
|
if (isString(opt) && Array.isArray(namespace[opt])) {
|
|
32127
33484
|
return namespace[opt].map(function (item) {
|
|
32128
33485
|
return assign({}, item);
|
|
32129
33486
|
});
|
|
32130
33487
|
}
|
|
32131
|
-
|
|
33488
|
+
const options = opt || {
|
|
32132
33489
|
args: [{}]
|
|
32133
33490
|
};
|
|
32134
|
-
|
|
32135
|
-
|
|
33491
|
+
const isArray = Array.isArray(options);
|
|
33492
|
+
let name = options.name;
|
|
32136
33493
|
if (!isArray && !name && !options.markup) {
|
|
32137
33494
|
name = 'dot';
|
|
32138
33495
|
}
|
|
32139
33496
|
if (name && Array.isArray(namespace[name])) {
|
|
32140
|
-
|
|
33497
|
+
const pattern = namespace[name].map(function (item) {
|
|
32141
33498
|
return assign({}, item);
|
|
32142
33499
|
});
|
|
32143
|
-
|
|
33500
|
+
const args = Array.isArray(options.args) ? options.args : [options.args || {}];
|
|
32144
33501
|
defaults(args[0], omit(opt, 'args'));
|
|
32145
|
-
for (
|
|
33502
|
+
for (let i = 0; i < args.length; i++) {
|
|
32146
33503
|
if (pattern[i]) {
|
|
32147
33504
|
assign(pattern[i], args[i]);
|
|
32148
33505
|
}
|
|
@@ -32159,6 +33516,15 @@ var joint = (function (exports) {
|
|
|
32159
33516
|
}
|
|
32160
33517
|
});
|
|
32161
33518
|
|
|
33519
|
+
const paperLayers = {
|
|
33520
|
+
GRID: 'grid',
|
|
33521
|
+
BACK: 'back',
|
|
33522
|
+
/** @deprecated */
|
|
33523
|
+
CELLS: 'cells',
|
|
33524
|
+
FRONT: 'front',
|
|
33525
|
+
TOOLS: 'tools',
|
|
33526
|
+
LABELS: 'labels'
|
|
33527
|
+
};
|
|
32162
33528
|
const sortingTypes = {
|
|
32163
33529
|
NONE: 'sorting-none',
|
|
32164
33530
|
APPROX: 'sorting-approximate',
|
|
@@ -32191,18 +33557,205 @@ var joint = (function (exports) {
|
|
|
32191
33557
|
}
|
|
32192
33558
|
}
|
|
32193
33559
|
};
|
|
32194
|
-
const
|
|
32195
|
-
|
|
32196
|
-
|
|
32197
|
-
|
|
33560
|
+
const gridPatterns = {
|
|
33561
|
+
dot: [{
|
|
33562
|
+
color: '#AAAAAA',
|
|
33563
|
+
thickness: 1,
|
|
33564
|
+
markup: 'rect',
|
|
33565
|
+
render: function (el, opt) {
|
|
33566
|
+
V(el).attr({
|
|
33567
|
+
width: opt.thickness,
|
|
33568
|
+
height: opt.thickness,
|
|
33569
|
+
fill: opt.color
|
|
33570
|
+
});
|
|
33571
|
+
}
|
|
33572
|
+
}],
|
|
33573
|
+
fixedDot: [{
|
|
33574
|
+
color: '#AAAAAA',
|
|
33575
|
+
thickness: 1,
|
|
33576
|
+
markup: 'rect',
|
|
33577
|
+
render: function (el, opt) {
|
|
33578
|
+
V(el).attr({
|
|
33579
|
+
fill: opt.color
|
|
33580
|
+
});
|
|
33581
|
+
},
|
|
33582
|
+
update: function (el, opt, paper) {
|
|
33583
|
+
const {
|
|
33584
|
+
sx,
|
|
33585
|
+
sy
|
|
33586
|
+
} = paper.scale();
|
|
33587
|
+
const width = sx <= 1 ? opt.thickness : opt.thickness / sx;
|
|
33588
|
+
const height = sy <= 1 ? opt.thickness : opt.thickness / sy;
|
|
33589
|
+
V(el).attr({
|
|
33590
|
+
width,
|
|
33591
|
+
height
|
|
33592
|
+
});
|
|
33593
|
+
}
|
|
33594
|
+
}],
|
|
33595
|
+
mesh: [{
|
|
33596
|
+
color: '#AAAAAA',
|
|
33597
|
+
thickness: 1,
|
|
33598
|
+
markup: 'path',
|
|
33599
|
+
render: function (el, opt) {
|
|
33600
|
+
var d;
|
|
33601
|
+
var width = opt.width;
|
|
33602
|
+
var height = opt.height;
|
|
33603
|
+
var thickness = opt.thickness;
|
|
33604
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33605
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33606
|
+
} else {
|
|
33607
|
+
d = 'M 0 0 0 0';
|
|
33608
|
+
}
|
|
33609
|
+
V(el).attr({
|
|
33610
|
+
'd': d,
|
|
33611
|
+
stroke: opt.color,
|
|
33612
|
+
'stroke-width': opt.thickness
|
|
33613
|
+
});
|
|
33614
|
+
}
|
|
33615
|
+
}],
|
|
33616
|
+
doubleMesh: [{
|
|
33617
|
+
color: '#AAAAAA',
|
|
33618
|
+
thickness: 1,
|
|
33619
|
+
markup: 'path',
|
|
33620
|
+
render: function (el, opt) {
|
|
33621
|
+
var d;
|
|
33622
|
+
var width = opt.width;
|
|
33623
|
+
var height = opt.height;
|
|
33624
|
+
var thickness = opt.thickness;
|
|
33625
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33626
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33627
|
+
} else {
|
|
33628
|
+
d = 'M 0 0 0 0';
|
|
33629
|
+
}
|
|
33630
|
+
V(el).attr({
|
|
33631
|
+
'd': d,
|
|
33632
|
+
stroke: opt.color,
|
|
33633
|
+
'stroke-width': opt.thickness
|
|
33634
|
+
});
|
|
33635
|
+
}
|
|
33636
|
+
}, {
|
|
33637
|
+
color: '#000000',
|
|
33638
|
+
thickness: 3,
|
|
33639
|
+
scaleFactor: 4,
|
|
33640
|
+
markup: 'path',
|
|
33641
|
+
render: function (el, opt) {
|
|
33642
|
+
var d;
|
|
33643
|
+
var width = opt.width;
|
|
33644
|
+
var height = opt.height;
|
|
33645
|
+
var thickness = opt.thickness;
|
|
33646
|
+
if (width - thickness >= 0 && height - thickness >= 0) {
|
|
33647
|
+
d = ['M', width, 0, 'H0 M0 0 V0', height].join(' ');
|
|
33648
|
+
} else {
|
|
33649
|
+
d = 'M 0 0 0 0';
|
|
33650
|
+
}
|
|
33651
|
+
V(el).attr({
|
|
33652
|
+
'd': d,
|
|
33653
|
+
stroke: opt.color,
|
|
33654
|
+
'stroke-width': opt.thickness
|
|
33655
|
+
});
|
|
33656
|
+
}
|
|
33657
|
+
}]
|
|
33658
|
+
};
|
|
33659
|
+
const backgroundPatterns = {
|
|
33660
|
+
flipXy: function (img) {
|
|
33661
|
+
// d b
|
|
33662
|
+
// q p
|
|
33663
|
+
|
|
33664
|
+
var canvas = document.createElement('canvas');
|
|
33665
|
+
var imgWidth = img.width;
|
|
33666
|
+
var imgHeight = img.height;
|
|
33667
|
+
canvas.width = 2 * imgWidth;
|
|
33668
|
+
canvas.height = 2 * imgHeight;
|
|
33669
|
+
var ctx = canvas.getContext('2d');
|
|
33670
|
+
// top-left image
|
|
33671
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33672
|
+
// xy-flipped bottom-right image
|
|
33673
|
+
ctx.setTransform(-1, 0, 0, -1, canvas.width, canvas.height);
|
|
33674
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33675
|
+
// x-flipped top-right image
|
|
33676
|
+
ctx.setTransform(-1, 0, 0, 1, canvas.width, 0);
|
|
33677
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33678
|
+
// y-flipped bottom-left image
|
|
33679
|
+
ctx.setTransform(1, 0, 0, -1, 0, canvas.height);
|
|
33680
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33681
|
+
return canvas;
|
|
33682
|
+
},
|
|
33683
|
+
flipX: function (img) {
|
|
33684
|
+
// d b
|
|
33685
|
+
// d b
|
|
33686
|
+
|
|
33687
|
+
var canvas = document.createElement('canvas');
|
|
33688
|
+
var imgWidth = img.width;
|
|
33689
|
+
var imgHeight = img.height;
|
|
33690
|
+
canvas.width = imgWidth * 2;
|
|
33691
|
+
canvas.height = imgHeight;
|
|
33692
|
+
var ctx = canvas.getContext('2d');
|
|
33693
|
+
// left image
|
|
33694
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33695
|
+
// flipped right image
|
|
33696
|
+
ctx.translate(2 * imgWidth, 0);
|
|
33697
|
+
ctx.scale(-1, 1);
|
|
33698
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33699
|
+
return canvas;
|
|
33700
|
+
},
|
|
33701
|
+
flipY: function (img) {
|
|
33702
|
+
// d d
|
|
33703
|
+
// q q
|
|
33704
|
+
|
|
33705
|
+
var canvas = document.createElement('canvas');
|
|
33706
|
+
var imgWidth = img.width;
|
|
33707
|
+
var imgHeight = img.height;
|
|
33708
|
+
canvas.width = imgWidth;
|
|
33709
|
+
canvas.height = imgHeight * 2;
|
|
33710
|
+
var ctx = canvas.getContext('2d');
|
|
33711
|
+
// top image
|
|
33712
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33713
|
+
// flipped bottom image
|
|
33714
|
+
ctx.translate(0, 2 * imgHeight);
|
|
33715
|
+
ctx.scale(1, -1);
|
|
33716
|
+
ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
|
|
33717
|
+
return canvas;
|
|
33718
|
+
},
|
|
33719
|
+
watermark: function (img, opt) {
|
|
33720
|
+
// d
|
|
33721
|
+
// d
|
|
33722
|
+
|
|
33723
|
+
opt = opt || {};
|
|
33724
|
+
var imgWidth = img.width;
|
|
33725
|
+
var imgHeight = img.height;
|
|
33726
|
+
var canvas = document.createElement('canvas');
|
|
33727
|
+
canvas.width = imgWidth * 3;
|
|
33728
|
+
canvas.height = imgHeight * 3;
|
|
33729
|
+
var ctx = canvas.getContext('2d');
|
|
33730
|
+
var angle = isNumber(opt.watermarkAngle) ? -opt.watermarkAngle : -20;
|
|
33731
|
+
var radians = toRad(angle);
|
|
33732
|
+
var stepX = canvas.width / 4;
|
|
33733
|
+
var stepY = canvas.height / 4;
|
|
33734
|
+
for (var i = 0; i < 4; i++) {
|
|
33735
|
+
for (var j = 0; j < 4; j++) {
|
|
33736
|
+
if ((i + j) % 2 > 0) {
|
|
33737
|
+
// reset the current transformations
|
|
33738
|
+
ctx.setTransform(1, 0, 0, 1, (2 * i - 1) * stepX, (2 * j - 1) * stepY);
|
|
33739
|
+
ctx.rotate(radians);
|
|
33740
|
+
ctx.drawImage(img, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight);
|
|
33741
|
+
}
|
|
33742
|
+
}
|
|
33743
|
+
}
|
|
33744
|
+
return canvas;
|
|
33745
|
+
}
|
|
33746
|
+
};
|
|
33747
|
+
const implicitLayers = [{
|
|
33748
|
+
id: paperLayers.GRID,
|
|
33749
|
+
type: 'GridLayerView',
|
|
33750
|
+
patterns: gridPatterns
|
|
32198
33751
|
}, {
|
|
32199
|
-
|
|
33752
|
+
id: paperLayers.BACK
|
|
32200
33753
|
}, {
|
|
32201
|
-
|
|
33754
|
+
id: paperLayers.LABELS
|
|
32202
33755
|
}, {
|
|
32203
|
-
|
|
33756
|
+
id: paperLayers.FRONT
|
|
32204
33757
|
}, {
|
|
32205
|
-
|
|
33758
|
+
id: paperLayers.TOOLS
|
|
32206
33759
|
}];
|
|
32207
33760
|
const CELL_VIEW_PLACEHOLDER_MARKER = Symbol('joint.cellViewPlaceholderMarker');
|
|
32208
33761
|
const Paper = View.extend({
|
|
@@ -32272,7 +33825,7 @@ var joint = (function (exports) {
|
|
|
32272
33825
|
// Do not create hard dependency on the joint.shapes.standard namespace (by importing the standard.Link model directly)
|
|
32273
33826
|
const {
|
|
32274
33827
|
cellNamespace
|
|
32275
|
-
} = this.model.
|
|
33828
|
+
} = this.model.layerCollection;
|
|
32276
33829
|
const ctor = getByPath(cellNamespace, ['standard', 'Link']);
|
|
32277
33830
|
if (!ctor) throw new Error('dia.Paper: no default link model found. Use `options.defaultLink` to specify a default link model.');
|
|
32278
33831
|
return new ctor();
|
|
@@ -32358,12 +33911,24 @@ var joint = (function (exports) {
|
|
|
32358
33911
|
viewManagement: false,
|
|
32359
33912
|
// no docs yet
|
|
32360
33913
|
onViewUpdate: function (view, flag, priority, opt, paper) {
|
|
32361
|
-
|
|
32362
|
-
|
|
32363
|
-
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
|
|
33914
|
+
if (opt.mounting || opt.isolate) {
|
|
33915
|
+
// Do not update connected links when:
|
|
33916
|
+
// - the view was just mounted (added back to the paper by viewport function)
|
|
33917
|
+
// - the change was marked as `isolate`.
|
|
33918
|
+
return;
|
|
33919
|
+
}
|
|
33920
|
+
// Always update connected links when the view model was replaced with another model
|
|
33921
|
+
// with the same id.
|
|
33922
|
+
// Note: the removal is done in 2 steps: remove the old model, add the new model.
|
|
33923
|
+
// We update connected links on the add step.
|
|
33924
|
+
if (!(opt.replace && opt.add)) {
|
|
33925
|
+
if (flag & (paper.FLAG_INSERT | paper.FLAG_REMOVE)) {
|
|
33926
|
+
// Do not update connected links when:
|
|
33927
|
+
// - the view was just inserted (added to the graph and rendered)
|
|
33928
|
+
// - the view model was just removed from the graph
|
|
33929
|
+
return;
|
|
33930
|
+
}
|
|
33931
|
+
}
|
|
32367
33932
|
paper.requestConnectedLinksUpdate(view, priority, opt);
|
|
32368
33933
|
},
|
|
32369
33934
|
// no docs yet
|
|
@@ -32380,6 +33945,7 @@ var joint = (function (exports) {
|
|
|
32380
33945
|
// Default namespaces
|
|
32381
33946
|
|
|
32382
33947
|
cellViewNamespace: null,
|
|
33948
|
+
layerViewNamespace: null,
|
|
32383
33949
|
routerNamespace: null,
|
|
32384
33950
|
connectorNamespace: null,
|
|
32385
33951
|
highlighterNamespace: highlighters,
|
|
@@ -32427,10 +33993,11 @@ var joint = (function (exports) {
|
|
|
32427
33993
|
}
|
|
32428
33994
|
`,
|
|
32429
33995
|
svg: null,
|
|
32430
|
-
viewport: null,
|
|
32431
33996
|
defs: null,
|
|
32432
33997
|
tools: null,
|
|
32433
33998
|
layers: null,
|
|
33999
|
+
// deprecated, use layers element instead
|
|
34000
|
+
viewport: null,
|
|
32434
34001
|
// For storing the current transformation matrix (CTM) of the paper's viewport.
|
|
32435
34002
|
_viewportMatrix: null,
|
|
32436
34003
|
// For verifying whether the CTM is up-to-date. The viewport transform attribute
|
|
@@ -32440,7 +34007,6 @@ var joint = (function (exports) {
|
|
|
32440
34007
|
_updates: null,
|
|
32441
34008
|
// Paper Layers
|
|
32442
34009
|
_layers: null,
|
|
32443
|
-
SORT_DELAYING_BATCHES: ['add', 'to-front', 'to-back'],
|
|
32444
34010
|
UPDATE_DELAYING_BATCHES: ['translate'],
|
|
32445
34011
|
// If you interact with these elements,
|
|
32446
34012
|
// the default interaction such as `element move` is prevented.
|
|
@@ -32460,12 +34026,13 @@ var joint = (function (exports) {
|
|
|
32460
34026
|
// The find buffer is used to extend the area of the search
|
|
32461
34027
|
// to mitigate the differences between the model and view geometry.
|
|
32462
34028
|
DEFAULT_FIND_BUFFER: 200,
|
|
32463
|
-
// Default layer to insert the cell views into.
|
|
32464
|
-
DEFAULT_CELL_LAYER: LayersNames.CELLS,
|
|
32465
|
-
// Update flags
|
|
32466
34029
|
FLAG_INSERT: 1 << 30,
|
|
32467
34030
|
FLAG_REMOVE: 1 << 29,
|
|
32468
34031
|
FLAG_INIT: 1 << 28,
|
|
34032
|
+
// Layers that are always present on the paper (e.g. grid, back, front, tools)
|
|
34033
|
+
implicitLayers,
|
|
34034
|
+
// Reference layer for inserting new graph layers.
|
|
34035
|
+
graphLayerRefId: paperLayers.LABELS,
|
|
32469
34036
|
init: function () {
|
|
32470
34037
|
const {
|
|
32471
34038
|
options
|
|
@@ -32475,6 +34042,12 @@ var joint = (function (exports) {
|
|
|
32475
34042
|
options.cellViewNamespace = typeof joint !== 'undefined' && has(joint, 'shapes') ? joint.shapes : null;
|
|
32476
34043
|
/* eslint-enable no-undef */
|
|
32477
34044
|
}
|
|
34045
|
+
const defaultLayerViewNamespace = {
|
|
34046
|
+
LayerView,
|
|
34047
|
+
GraphLayerView,
|
|
34048
|
+
GridLayerView
|
|
34049
|
+
};
|
|
34050
|
+
this.layerViewNamespace = defaultsDeep({}, options.layerViewNamespace || {}, defaultLayerViewNamespace);
|
|
32478
34051
|
const model = this.model = options.model || new Graph();
|
|
32479
34052
|
|
|
32480
34053
|
// This property tells us if we need to keep the compatibility
|
|
@@ -32484,18 +34057,17 @@ var joint = (function (exports) {
|
|
|
32484
34057
|
// Layers (SVGGroups)
|
|
32485
34058
|
this._layers = {
|
|
32486
34059
|
viewsMap: {},
|
|
32487
|
-
namesMap: {},
|
|
32488
34060
|
order: []
|
|
32489
34061
|
};
|
|
32490
|
-
this.cloneOptions();
|
|
32491
|
-
this.render();
|
|
32492
|
-
this._setDimensions();
|
|
32493
|
-
this.startListening();
|
|
32494
34062
|
|
|
32495
34063
|
// Hash of all cell views.
|
|
32496
34064
|
this._views = {};
|
|
32497
34065
|
this._viewPlaceholders = {};
|
|
32498
34066
|
this._idToCid = {};
|
|
34067
|
+
this.cloneOptions();
|
|
34068
|
+
this.render();
|
|
34069
|
+
this._setDimensions();
|
|
34070
|
+
this.startListening();
|
|
32499
34071
|
|
|
32500
34072
|
// Mouse wheel events buffer
|
|
32501
34073
|
this._mw_evt_buffer = {
|
|
@@ -32504,7 +34076,7 @@ var joint = (function (exports) {
|
|
|
32504
34076
|
};
|
|
32505
34077
|
|
|
32506
34078
|
// Render existing cells in the graph
|
|
32507
|
-
this.resetViews(model.
|
|
34079
|
+
this.resetViews(model.getCells());
|
|
32508
34080
|
},
|
|
32509
34081
|
_resetUpdates: function () {
|
|
32510
34082
|
if (this._updates && this._updates.id) cancelFrame(this._updates.id);
|
|
@@ -32524,7 +34096,8 @@ var joint = (function (exports) {
|
|
|
32524
34096
|
},
|
|
32525
34097
|
startListening: function () {
|
|
32526
34098
|
var model = this.model;
|
|
32527
|
-
this.listenTo(model, 'add', this.onCellAdded).listenTo(model, 'remove', this.onCellRemoved).listenTo(model, '
|
|
34099
|
+
this.listenTo(model, 'add', this.onCellAdded).listenTo(model, 'remove', this.onCellRemoved).listenTo(model, 'reset', this.onGraphReset).listenTo(model, 'batch:stop', this.onGraphBatchStop);
|
|
34100
|
+
this.listenTo(model, 'layer:add', this.onGraphLayerAdd).listenTo(model, 'layer:remove', this.onGraphLayerRemove).listenTo(model, 'layers:sort', this.onGraphLayerCollectionSort);
|
|
32528
34101
|
this.on('cell:highlight', this.onCellHighlight).on('cell:unhighlight', this.onCellUnhighlight).on('transform', this.update);
|
|
32529
34102
|
},
|
|
32530
34103
|
onCellAdded: function (cell, _, opt) {
|
|
@@ -32550,22 +34123,15 @@ var joint = (function (exports) {
|
|
|
32550
34123
|
this.requestViewUpdate(viewLike, this.FLAG_REMOVE, viewLike.UPDATE_PRIORITY, opt);
|
|
32551
34124
|
}
|
|
32552
34125
|
},
|
|
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();
|
|
34126
|
+
onGraphReset: function (_collection, opt) {
|
|
34127
|
+
// Re-render all graph layer views
|
|
34128
|
+
// but keep the implicit layer views.
|
|
34129
|
+
this.renderGraphLayerViews();
|
|
34130
|
+
this.resetLayerViews();
|
|
34131
|
+
// Backward compatibility: reassign the `cells` property
|
|
34132
|
+
// with the default layer view.
|
|
34133
|
+
this.assertLayerViews();
|
|
34134
|
+
this.resetViews(this.model.getCells(), opt);
|
|
32569
34135
|
},
|
|
32570
34136
|
onGraphBatchStop: function (data) {
|
|
32571
34137
|
if (this.isFrozen() || this.isIdle()) return;
|
|
@@ -32577,10 +34143,92 @@ var joint = (function (exports) {
|
|
|
32577
34143
|
this.updateViews(data);
|
|
32578
34144
|
}
|
|
32579
34145
|
}
|
|
32580
|
-
|
|
32581
|
-
|
|
32582
|
-
|
|
34146
|
+
},
|
|
34147
|
+
/**
|
|
34148
|
+
* @protected
|
|
34149
|
+
* @description When a new layer is added to the graph, we create a new layer view
|
|
34150
|
+
**/
|
|
34151
|
+
onGraphLayerAdd: function (layer, _, opt) {
|
|
34152
|
+
if (this.hasLayerView(layer.id)) return;
|
|
34153
|
+
const layerView = this.createLayerView({
|
|
34154
|
+
id: layer.id,
|
|
34155
|
+
model: layer
|
|
34156
|
+
});
|
|
34157
|
+
const layers = this.model.getLayers();
|
|
34158
|
+
let before;
|
|
34159
|
+
// Note: There is always at least one graph layer.
|
|
34160
|
+
if (layers[layers.length - 1] === layer) {
|
|
34161
|
+
// This is the last layer, so insert before the labels layer
|
|
34162
|
+
before = paperLayers.LABELS;
|
|
34163
|
+
} else {
|
|
34164
|
+
// There is a layer after the current one, so insert before that one
|
|
34165
|
+
const index = layers.indexOf(layer);
|
|
34166
|
+
before = layers[index + 1].id;
|
|
32583
34167
|
}
|
|
34168
|
+
this.addLayerView(layerView, {
|
|
34169
|
+
before
|
|
34170
|
+
});
|
|
34171
|
+
},
|
|
34172
|
+
/**
|
|
34173
|
+
* @protected
|
|
34174
|
+
* @description When a layer is removed from the graph, we remove the corresponding layer view
|
|
34175
|
+
**/
|
|
34176
|
+
onGraphLayerRemove: function (layer, _, opt) {
|
|
34177
|
+
if (!this.hasLayerView(layer)) return;
|
|
34178
|
+
|
|
34179
|
+
// Request layer removal. Since the UPDATE_PRIORITY is lower
|
|
34180
|
+
// than cells update priority, the cell views will be removed first.
|
|
34181
|
+
this.requestLayerViewRemoval(layer);
|
|
34182
|
+
},
|
|
34183
|
+
/**
|
|
34184
|
+
* @protected
|
|
34185
|
+
* @description When the graph layer collection is sorted,
|
|
34186
|
+
* we reorder all graph layer views.
|
|
34187
|
+
**/
|
|
34188
|
+
onGraphLayerCollectionSort: function (layerCollection) {
|
|
34189
|
+
layerCollection.each(layer => {
|
|
34190
|
+
if (!this.hasLayerView(layer)) return;
|
|
34191
|
+
this.moveLayerView(layer, {
|
|
34192
|
+
before: this.graphLayerRefId
|
|
34193
|
+
});
|
|
34194
|
+
});
|
|
34195
|
+
},
|
|
34196
|
+
/**
|
|
34197
|
+
* @protected
|
|
34198
|
+
* @description Resets all graph layer views.
|
|
34199
|
+
*/
|
|
34200
|
+
renderGraphLayerViews: function () {
|
|
34201
|
+
// Remove all existing graph layer views
|
|
34202
|
+
// Note: we don't use `getGraphLayerViews()` here because
|
|
34203
|
+
// rendered graph layer views could be different from the ones
|
|
34204
|
+
// in the graph layer collection (`onResetGraphLayerCollectionReset`).
|
|
34205
|
+
this.getLayerViews().forEach(layerView => {
|
|
34206
|
+
if (!layerView[GRAPH_LAYER_VIEW_MARKER]) return;
|
|
34207
|
+
this._removeLayerView(layerView);
|
|
34208
|
+
});
|
|
34209
|
+
// Create and insert new graph layer views
|
|
34210
|
+
this.model.getLayers().forEach(layer => {
|
|
34211
|
+
const layerView = this.createLayerView({
|
|
34212
|
+
id: layer.id,
|
|
34213
|
+
model: layer
|
|
34214
|
+
});
|
|
34215
|
+
// Insert the layer view into the paper layers, just before the labels layer.
|
|
34216
|
+
// All cell layers are positioned between the "back" and "labels" layers,
|
|
34217
|
+
// with the default "cells" layer originally occupying this position.
|
|
34218
|
+
this.addLayerView(layerView, {
|
|
34219
|
+
before: this.graphLayerRefId
|
|
34220
|
+
});
|
|
34221
|
+
});
|
|
34222
|
+
},
|
|
34223
|
+
/**
|
|
34224
|
+
* @protected
|
|
34225
|
+
* @description Renders all implicit layer views.
|
|
34226
|
+
*/
|
|
34227
|
+
renderImplicitLayerViews: function () {
|
|
34228
|
+
this.implicitLayers.forEach(layerInit => {
|
|
34229
|
+
const layerView = this.createLayerView(layerInit);
|
|
34230
|
+
this.addLayerView(layerView);
|
|
34231
|
+
});
|
|
32584
34232
|
},
|
|
32585
34233
|
cloneOptions: function () {
|
|
32586
34234
|
const {
|
|
@@ -32675,136 +34323,295 @@ var joint = (function (exports) {
|
|
|
32675
34323
|
}]
|
|
32676
34324
|
}];
|
|
32677
34325
|
},
|
|
32678
|
-
|
|
32679
|
-
|
|
34326
|
+
/**
|
|
34327
|
+
* @public
|
|
34328
|
+
* @description Checks whether the layer view exists by the given layer id or layer model.
|
|
34329
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34330
|
+
* @return {boolean} True if the layer view exists, false otherwise.
|
|
34331
|
+
*/
|
|
34332
|
+
hasLayerView(layerRef) {
|
|
34333
|
+
let layerId;
|
|
34334
|
+
if (isString(layerRef)) {
|
|
34335
|
+
layerId = layerRef;
|
|
34336
|
+
} else if (layerRef) {
|
|
34337
|
+
layerId = layerRef.id;
|
|
34338
|
+
} else {
|
|
34339
|
+
return false;
|
|
34340
|
+
}
|
|
34341
|
+
return layerId in this._layers.viewsMap;
|
|
32680
34342
|
},
|
|
32681
|
-
|
|
32682
|
-
|
|
32683
|
-
|
|
32684
|
-
|
|
32685
|
-
|
|
32686
|
-
|
|
32687
|
-
|
|
32688
|
-
|
|
34343
|
+
/**
|
|
34344
|
+
* @public
|
|
34345
|
+
* @description Returns the layer view by the given layer id or layer model.
|
|
34346
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34347
|
+
* @return {dia.LayerView} The layer view.
|
|
34348
|
+
* @throws {Error} if the layer view is not found
|
|
34349
|
+
*/
|
|
34350
|
+
getLayerView(layerRef) {
|
|
34351
|
+
let layerId;
|
|
34352
|
+
if (isString(layerRef)) {
|
|
34353
|
+
layerId = layerRef;
|
|
34354
|
+
} else if (layerRef) {
|
|
34355
|
+
layerId = layerRef.id;
|
|
34356
|
+
} else {
|
|
34357
|
+
throw new Error('dia.Paper: No layer provided.');
|
|
34358
|
+
}
|
|
34359
|
+
const layerView = this._layers.viewsMap[layerId];
|
|
34360
|
+
if (!layerView) {
|
|
34361
|
+
throw new Error(`dia.Paper: Unknown layer view "${layerId}".`);
|
|
34362
|
+
}
|
|
34363
|
+
return layerView;
|
|
32689
34364
|
},
|
|
32690
|
-
|
|
32691
|
-
|
|
34365
|
+
/**
|
|
34366
|
+
* @deprecated use `getLayerView(layerId).el` instead
|
|
34367
|
+
*/
|
|
34368
|
+
getLayerNode(layerId) {
|
|
34369
|
+
return this.getLayerView(layerId).el;
|
|
32692
34370
|
},
|
|
32693
|
-
|
|
32694
|
-
|
|
34371
|
+
/**
|
|
34372
|
+
* @protected
|
|
34373
|
+
* @description Removes the given layer view from the paper.
|
|
34374
|
+
* It does not check whether the layer view is empty.
|
|
34375
|
+
* @param {dia.LayerView} layerView - The layer view to remove.
|
|
34376
|
+
*/
|
|
34377
|
+
_removeLayerView(layerView) {
|
|
34378
|
+
this._unregisterLayerView(layerView);
|
|
32695
34379
|
layerView.remove();
|
|
32696
34380
|
},
|
|
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];
|
|
34381
|
+
/**
|
|
34382
|
+
* @protected
|
|
34383
|
+
* @description Removes all layer views from the paper.
|
|
34384
|
+
* It does not check whether the layer views are empty.
|
|
34385
|
+
*/
|
|
34386
|
+
_removeLayerViews: function () {
|
|
34387
|
+
Object.values(this._layers.viewsMap).forEach(layerView => {
|
|
34388
|
+
this._removeLayerView(layerView);
|
|
34389
|
+
});
|
|
32709
34390
|
},
|
|
32710
|
-
|
|
34391
|
+
/**
|
|
34392
|
+
* @protected
|
|
34393
|
+
* @description Unregisters the given layer view from the paper.
|
|
34394
|
+
* @param {dia.LayerView} layerView - The layer view to unregister.
|
|
34395
|
+
*/
|
|
34396
|
+
_unregisterLayerView(layerView) {
|
|
32711
34397
|
const {
|
|
32712
34398
|
_layers: {
|
|
32713
34399
|
viewsMap,
|
|
32714
|
-
namesMap,
|
|
32715
34400
|
order
|
|
32716
34401
|
}
|
|
32717
34402
|
} = this;
|
|
32718
|
-
|
|
32719
|
-
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
order.
|
|
34403
|
+
const layerId = layerView.id;
|
|
34404
|
+
// Remove the layer id from the order list.
|
|
34405
|
+
const layerIndex = order.indexOf(layerId);
|
|
34406
|
+
if (layerIndex !== -1) {
|
|
34407
|
+
order.splice(layerIndex, 1);
|
|
32723
34408
|
}
|
|
32724
|
-
|
|
32725
|
-
|
|
34409
|
+
// Unlink the layer view from the paper.
|
|
34410
|
+
layerView.unsetPaperReference();
|
|
34411
|
+
// Remove the layer view from the paper's registry.
|
|
34412
|
+
delete viewsMap[layerId];
|
|
32726
34413
|
},
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32735
|
-
|
|
32736
|
-
|
|
34414
|
+
/**
|
|
34415
|
+
* @protected
|
|
34416
|
+
* @description Registers the given layer view in the paper.
|
|
34417
|
+
* @param {dia.LayerView} layerView - The layer view to register.
|
|
34418
|
+
* @throws {Error} if the layer view is not an instance of dia.LayerView
|
|
34419
|
+
* @throws {Error} if the layer view already exists in the paper
|
|
34420
|
+
*/
|
|
34421
|
+
_registerLayerView(layerView) {
|
|
34422
|
+
if (!layerView || !layerView[LAYER_VIEW_MARKER]) {
|
|
34423
|
+
throw new Error('dia.Paper: The layer view must be an instance of dia.LayerView.');
|
|
32737
34424
|
}
|
|
32738
|
-
if (
|
|
32739
|
-
|
|
34425
|
+
if (this.hasLayerView(layerView.id)) {
|
|
34426
|
+
throw new Error(`dia.Paper: The layer view "${layerView.id}" already exists.`);
|
|
34427
|
+
}
|
|
34428
|
+
// Link the layer view back to the paper.
|
|
34429
|
+
layerView.setPaperReference(this);
|
|
34430
|
+
// Store the layer view in the paper's registry.
|
|
34431
|
+
this._layers.viewsMap[layerView.id] = layerView;
|
|
32740
34432
|
},
|
|
32741
|
-
|
|
34433
|
+
/**
|
|
34434
|
+
* @public
|
|
34435
|
+
* @description Removes the layer view by the given layer id or layer model.
|
|
34436
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34437
|
+
* @throws {Error} if the layer view is not empty
|
|
34438
|
+
*/
|
|
34439
|
+
removeLayerView(layerRef) {
|
|
34440
|
+
const layerView = this.getLayerView(layerRef);
|
|
34441
|
+
if (!layerView.isEmpty()) {
|
|
34442
|
+
throw new Error('dia.Paper: The layer view is not empty.');
|
|
34443
|
+
}
|
|
34444
|
+
this._removeLayerView(layerView);
|
|
34445
|
+
},
|
|
34446
|
+
/**
|
|
34447
|
+
* @protected
|
|
34448
|
+
* @description Schedules the layer view removal by the given layer id or layer model.
|
|
34449
|
+
* The actual removal will be performed during the paper update cycle.
|
|
34450
|
+
* @param {string|dia.GraphLayer} layerRef - Layer id or layer model.
|
|
34451
|
+
* @param {Object} [opt] - Update options.
|
|
34452
|
+
*/
|
|
34453
|
+
requestLayerViewRemoval(layerRef, opt) {
|
|
34454
|
+
const layerView = this.getLayerView(layerRef);
|
|
32742
34455
|
const {
|
|
32743
|
-
|
|
32744
|
-
namesMap
|
|
32745
|
-
}
|
|
34456
|
+
FLAG_REMOVE
|
|
32746
34457
|
} = this;
|
|
32747
|
-
|
|
34458
|
+
const {
|
|
34459
|
+
UPDATE_PRIORITY
|
|
34460
|
+
} = layerView;
|
|
34461
|
+
this.requestViewUpdate(layerView, FLAG_REMOVE, UPDATE_PRIORITY, opt);
|
|
32748
34462
|
},
|
|
32749
|
-
|
|
32750
|
-
|
|
32751
|
-
|
|
32752
|
-
|
|
32753
|
-
|
|
34463
|
+
/**
|
|
34464
|
+
* @public
|
|
34465
|
+
* @internal not documented
|
|
34466
|
+
* @description Schedules the cell view insertion into the appropriate layer view.
|
|
34467
|
+
* The actual insertion will be performed during the paper update cycle.
|
|
34468
|
+
* @param {dia.Cell} cell - The cell model whose view should be inserted.
|
|
34469
|
+
* @param {Object} [opt] - Update options.
|
|
34470
|
+
*/
|
|
34471
|
+
requestCellViewInsertion(cell, opt) {
|
|
34472
|
+
const viewLike = this._getCellViewLike(cell);
|
|
34473
|
+
if (!viewLike) return;
|
|
34474
|
+
this.requestViewUpdate(viewLike, this.FLAG_INSERT, viewLike.UPDATE_PRIORITY, opt);
|
|
34475
|
+
},
|
|
34476
|
+
/**
|
|
34477
|
+
* @private
|
|
34478
|
+
* Helper method for addLayerView and moveLayerView methods
|
|
34479
|
+
*/
|
|
34480
|
+
_getBeforeLayerViewFromOptions(layerView, options) {
|
|
34481
|
+
let {
|
|
34482
|
+
before = null,
|
|
34483
|
+
index
|
|
34484
|
+
} = options;
|
|
34485
|
+
if (before && index !== undefined) {
|
|
34486
|
+
throw new Error('dia.Paper: Options "before" and "index" are mutually exclusive.');
|
|
34487
|
+
}
|
|
34488
|
+
let computedBefore;
|
|
34489
|
+
if (index !== undefined) {
|
|
34490
|
+
const {
|
|
34491
|
+
_layers: {
|
|
34492
|
+
order
|
|
34493
|
+
}
|
|
34494
|
+
} = this;
|
|
34495
|
+
if (index >= order.length) {
|
|
34496
|
+
// If index is greater than the number of layers,
|
|
34497
|
+
// return before as null (move to the end).
|
|
34498
|
+
computedBefore = null;
|
|
34499
|
+
} else if (index < 0) {
|
|
34500
|
+
// If index is negative, move to the beginning.
|
|
34501
|
+
computedBefore = order[0];
|
|
32754
34502
|
} else {
|
|
32755
|
-
|
|
34503
|
+
const originalIndex = order.indexOf(layerView.id);
|
|
34504
|
+
if (originalIndex !== -1 && index > originalIndex) {
|
|
34505
|
+
// If moving a layer upwards in the stack, we need to adjust the index
|
|
34506
|
+
// to account for the layer being removed from its original position.
|
|
34507
|
+
index += 1;
|
|
34508
|
+
}
|
|
34509
|
+
// Otherwise, get the layer ID at the specified index.
|
|
34510
|
+
computedBefore = order[index] || null;
|
|
32756
34511
|
}
|
|
34512
|
+
} else {
|
|
34513
|
+
computedBefore = before;
|
|
32757
34514
|
}
|
|
32758
|
-
return
|
|
34515
|
+
return computedBefore ? this.getLayerView(computedBefore) : null;
|
|
32759
34516
|
},
|
|
32760
|
-
|
|
32761
|
-
|
|
34517
|
+
/**
|
|
34518
|
+
* @public
|
|
34519
|
+
* @description Adds the layer view to the paper.
|
|
34520
|
+
* @param {dia.LayerView} layerView - The layer view to add.
|
|
34521
|
+
* @param {Object} [options] - Adding options.
|
|
34522
|
+
* @param {string|dia.GraphLayer} [options.before] - Layer id or layer model before
|
|
34523
|
+
*/
|
|
34524
|
+
addLayerView(layerView, options = {}) {
|
|
34525
|
+
this._registerLayerView(layerView);
|
|
34526
|
+
const beforeLayerView = this._getBeforeLayerViewFromOptions(layerView, options);
|
|
34527
|
+
this.insertLayerView(layerView, beforeLayerView);
|
|
32762
34528
|
},
|
|
32763
|
-
|
|
32764
|
-
|
|
32765
|
-
|
|
32766
|
-
|
|
32767
|
-
|
|
32768
|
-
|
|
34529
|
+
/**
|
|
34530
|
+
* @public
|
|
34531
|
+
* @description Moves the layer view.
|
|
34532
|
+
* @param {Paper.LayerRef} layerRef - The layer view reference to move.
|
|
34533
|
+
* @param {Object} [options] - Moving options.
|
|
34534
|
+
* @param {Paper.LayerRef} [options.before] - Layer id or layer model before
|
|
34535
|
+
* @param {number} [options.index] - Zero-based index to which to move the layer view.
|
|
34536
|
+
*/
|
|
34537
|
+
moveLayerView(layerRef, options = {}) {
|
|
34538
|
+
const layerView = this.getLayerView(layerRef);
|
|
34539
|
+
const beforeLayerView = this._getBeforeLayerViewFromOptions(layerView, options);
|
|
34540
|
+
this.insertLayerView(layerView, beforeLayerView);
|
|
32769
34541
|
},
|
|
32770
|
-
|
|
32771
|
-
|
|
32772
|
-
|
|
32773
|
-
|
|
32774
|
-
|
|
32775
|
-
|
|
32776
|
-
|
|
32777
|
-
|
|
32778
|
-
|
|
32779
|
-
|
|
34542
|
+
/**
|
|
34543
|
+
* @protected
|
|
34544
|
+
* @description Inserts the layer view into the paper.
|
|
34545
|
+
* If the layer view already exists in the paper, it is moved to the new position.
|
|
34546
|
+
* @param {dia.LayerView} layerView - The layer view to insert.
|
|
34547
|
+
* @param {dia.LayerView} [before] - Layer view before
|
|
34548
|
+
* which the layer view should be inserted.
|
|
34549
|
+
*/
|
|
34550
|
+
insertLayerView(layerView, beforeLayerView) {
|
|
34551
|
+
const layerId = layerView.id;
|
|
32780
34552
|
const {
|
|
32781
|
-
|
|
32782
|
-
|
|
32783
|
-
|
|
32784
|
-
|
|
32785
|
-
|
|
32786
|
-
|
|
32787
|
-
|
|
32788
|
-
|
|
34553
|
+
_layers: {
|
|
34554
|
+
order
|
|
34555
|
+
}
|
|
34556
|
+
} = this;
|
|
34557
|
+
const currentLayerIndex = order.indexOf(layerId);
|
|
34558
|
+
|
|
34559
|
+
// Should the layer view be inserted before another layer view?
|
|
34560
|
+
if (beforeLayerView) {
|
|
34561
|
+
const beforeLayerViewId = beforeLayerView.id;
|
|
34562
|
+
if (layerId === beforeLayerViewId) {
|
|
34563
|
+
// The layer view is already in the right place.
|
|
34564
|
+
return;
|
|
34565
|
+
}
|
|
34566
|
+
let beforeLayerPosition = order.indexOf(beforeLayerViewId);
|
|
34567
|
+
// Remove from the `order` list if the layer view is already in the order.
|
|
34568
|
+
if (currentLayerIndex !== -1) {
|
|
34569
|
+
if (currentLayerIndex < beforeLayerPosition) {
|
|
34570
|
+
beforeLayerPosition -= 1;
|
|
34571
|
+
}
|
|
34572
|
+
order.splice(currentLayerIndex, 1);
|
|
34573
|
+
}
|
|
34574
|
+
order.splice(beforeLayerPosition, 0, layerId);
|
|
32789
34575
|
this.layers.insertBefore(layerView.el, beforeLayerView.el);
|
|
34576
|
+
return;
|
|
32790
34577
|
}
|
|
34578
|
+
|
|
34579
|
+
// Remove from the `order` list if the layer view is already in the order.
|
|
34580
|
+
// This is needed for the case when the layer view is inserted in the new position.
|
|
34581
|
+
if (currentLayerIndex !== -1) {
|
|
34582
|
+
order.splice(currentLayerIndex, 1);
|
|
34583
|
+
}
|
|
34584
|
+
order.push(layerId);
|
|
34585
|
+
this.layers.appendChild(layerView.el);
|
|
32791
34586
|
},
|
|
32792
|
-
|
|
32793
|
-
|
|
32794
|
-
|
|
32795
|
-
|
|
32796
|
-
|
|
32797
|
-
|
|
32798
|
-
insertBefore
|
|
32799
|
-
});
|
|
32800
|
-
},
|
|
32801
|
-
getLayerNames() {
|
|
32802
|
-
// Returns a sorted array of layer names.
|
|
34587
|
+
/**
|
|
34588
|
+
* @protected
|
|
34589
|
+
* @description Returns an array of layer view ids in the order they are rendered.
|
|
34590
|
+
* @returns {string[]} An array of layer view ids.
|
|
34591
|
+
*/
|
|
34592
|
+
getLayerViewOrder() {
|
|
32803
34593
|
return this._layers.order.slice();
|
|
32804
34594
|
},
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
34595
|
+
/**
|
|
34596
|
+
* @public
|
|
34597
|
+
* @description Returns an array of layer views in the order they are rendered.
|
|
34598
|
+
* @returns {dia.LayerView[]} An array of layer views.
|
|
34599
|
+
*/
|
|
34600
|
+
getLayerViews() {
|
|
34601
|
+
return this.getLayerViewOrder().map(id => this.getLayerView(id));
|
|
34602
|
+
},
|
|
34603
|
+
/**
|
|
34604
|
+
* @public
|
|
34605
|
+
* @description Returns an array of graph layer views in the order they are rendered.
|
|
34606
|
+
* @returns {dia.GraphLayerView[]} An array of graph layer views.
|
|
34607
|
+
*/
|
|
34608
|
+
getGraphLayerViews() {
|
|
34609
|
+
const {
|
|
34610
|
+
_layers: {
|
|
34611
|
+
viewsMap
|
|
34612
|
+
}
|
|
34613
|
+
} = this;
|
|
34614
|
+
return this.model.getLayers().map(layer => viewsMap[layer.id]);
|
|
32808
34615
|
},
|
|
32809
34616
|
render: function () {
|
|
32810
34617
|
this.renderChildren();
|
|
@@ -32824,7 +34631,7 @@ var joint = (function (exports) {
|
|
|
32824
34631
|
this.svg = svg;
|
|
32825
34632
|
this.defs = defs;
|
|
32826
34633
|
this.layers = layers;
|
|
32827
|
-
this.
|
|
34634
|
+
this.renderLayerViews();
|
|
32828
34635
|
V.ensureId(svg);
|
|
32829
34636
|
this.addStylesheet(stylesheet);
|
|
32830
34637
|
if (options.background) {
|
|
@@ -32839,60 +34646,79 @@ var joint = (function (exports) {
|
|
|
32839
34646
|
if (!css) return;
|
|
32840
34647
|
V(this.svg).prepend(V.createSVGStyle(css));
|
|
32841
34648
|
},
|
|
32842
|
-
|
|
32843
|
-
|
|
32844
|
-
|
|
32845
|
-
|
|
32846
|
-
|
|
32847
|
-
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
|
|
32853
|
-
|
|
34649
|
+
/**
|
|
34650
|
+
* @protected
|
|
34651
|
+
* @description Creates a layer view instance based on the provided options.
|
|
34652
|
+
* It finds the appropriate layer view constructor from the paper's
|
|
34653
|
+
* `layerViewNamespace` and instantiates it.
|
|
34654
|
+
* @param {*} options See `dia.LayerView` options.
|
|
34655
|
+
* @returns {dia.LayerView}
|
|
34656
|
+
*/
|
|
34657
|
+
createLayerView(options) {
|
|
34658
|
+
if (options == null) {
|
|
34659
|
+
throw new Error('dia.Paper: Layer view options are required.');
|
|
34660
|
+
}
|
|
34661
|
+
if (options.id == null) {
|
|
34662
|
+
throw new Error('dia.Paper: Layer view id is required.');
|
|
34663
|
+
}
|
|
34664
|
+
const viewOptions = clone$1(options);
|
|
34665
|
+
let viewConstructor;
|
|
34666
|
+
if (viewOptions.model) {
|
|
34667
|
+
const modelType = viewOptions.model.get('type') || viewOptions.model.constructor.name;
|
|
34668
|
+
const type = modelType + 'View';
|
|
34669
|
+
|
|
34670
|
+
// For backward compatibility we use the LegacyGraphLayerView for the default `cells` layer.
|
|
34671
|
+
if (this.model.layersController.legacyMode) {
|
|
34672
|
+
viewConstructor = LegacyGraphLayerView;
|
|
34673
|
+
} else {
|
|
34674
|
+
viewConstructor = this.layerViewNamespace[type] || LayerView;
|
|
34675
|
+
}
|
|
34676
|
+
} else {
|
|
34677
|
+
// Paper layers
|
|
34678
|
+
const type = viewOptions.type;
|
|
34679
|
+
viewConstructor = this.layerViewNamespace[type] || LayerView;
|
|
32854
34680
|
}
|
|
34681
|
+
return new viewConstructor(viewOptions);
|
|
32855
34682
|
},
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
|
|
32859
|
-
|
|
34683
|
+
/**
|
|
34684
|
+
* @protected
|
|
34685
|
+
* @description Renders all paper layer views and graph layer views.
|
|
34686
|
+
*/
|
|
34687
|
+
renderLayerViews: function () {
|
|
34688
|
+
this._removeLayerViews();
|
|
34689
|
+
// Render the paper layers.
|
|
34690
|
+
this.renderImplicitLayerViews();
|
|
34691
|
+
// Render the layers.
|
|
34692
|
+
this.renderGraphLayerViews();
|
|
34693
|
+
// Ensure that essential layer views are present.
|
|
34694
|
+
this.assertLayerViews();
|
|
32860
34695
|
},
|
|
32861
|
-
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
|
|
32868
|
-
const
|
|
32869
|
-
const
|
|
34696
|
+
/**
|
|
34697
|
+
* @protected
|
|
34698
|
+
* @description Ensures that essential layer views are present on the paper.
|
|
34699
|
+
* @throws {Error} if any of the essential layer views is missing
|
|
34700
|
+
*/
|
|
34701
|
+
assertLayerViews: function () {
|
|
34702
|
+
// Throws an exception if essential layer views are missing.
|
|
34703
|
+
const cellsLayerView = this.getLayerView(this.model.getDefaultLayer().id);
|
|
34704
|
+
const toolsLayerView = this.getLayerView(paperLayers.TOOLS);
|
|
34705
|
+
const labelsLayerView = this.getLayerView(paperLayers.LABELS);
|
|
34706
|
+
|
|
32870
34707
|
// backwards compatibility
|
|
32871
34708
|
this.tools = toolsLayerView.el;
|
|
32872
34709
|
this.cells = this.viewport = cellsLayerView.el;
|
|
32873
|
-
//
|
|
32874
|
-
|
|
34710
|
+
// Backwards compatibility: same as `LegacyGraphLayerView` we keep
|
|
34711
|
+
// the `viewport` class on the labels layer.
|
|
32875
34712
|
labelsLayerView.vel.addClass(addClassNamePrefix('viewport'));
|
|
32876
|
-
cellsLayerView.el.style.webkitUserSelect = 'none';
|
|
32877
|
-
cellsLayerView.el.style.userSelect = 'none';
|
|
32878
34713
|
labelsLayerView.el.style.webkitUserSelect = 'none';
|
|
32879
34714
|
labelsLayerView.el.style.userSelect = 'none';
|
|
32880
34715
|
},
|
|
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());
|
|
34716
|
+
/**
|
|
34717
|
+
* @protected
|
|
34718
|
+
* @description Resets all layer views.
|
|
34719
|
+
*/
|
|
34720
|
+
resetLayerViews: function () {
|
|
34721
|
+
this.getLayerViews().forEach(layerView => layerView.reset());
|
|
32896
34722
|
},
|
|
32897
34723
|
update: function () {
|
|
32898
34724
|
if (this._background) {
|
|
@@ -33008,26 +34834,25 @@ var joint = (function (exports) {
|
|
|
33008
34834
|
return this;
|
|
33009
34835
|
},
|
|
33010
34836
|
clientMatrix: function () {
|
|
33011
|
-
return V.createSVGMatrix(this.
|
|
34837
|
+
return V.createSVGMatrix(this.layers.getScreenCTM());
|
|
33012
34838
|
},
|
|
33013
34839
|
requestConnectedLinksUpdate: function (view, priority, opt) {
|
|
33014
|
-
if (view
|
|
33015
|
-
|
|
33016
|
-
|
|
33017
|
-
|
|
33018
|
-
|
|
33019
|
-
|
|
33020
|
-
|
|
33021
|
-
|
|
33022
|
-
|
|
33023
|
-
|
|
33024
|
-
|
|
33025
|
-
|
|
33026
|
-
}
|
|
34840
|
+
if (!view || !view[CELL_VIEW_MARKER]) return;
|
|
34841
|
+
var model = view.model;
|
|
34842
|
+
var links = this.model.getConnectedLinks(model);
|
|
34843
|
+
for (var j = 0, n = links.length; j < n; j++) {
|
|
34844
|
+
var link = links[j];
|
|
34845
|
+
var linkView = this._getCellViewLike(link);
|
|
34846
|
+
if (!linkView) continue;
|
|
34847
|
+
// We do not have to update placeholder views.
|
|
34848
|
+
// They will be updated on initial render.
|
|
34849
|
+
if (linkView[CELL_VIEW_PLACEHOLDER_MARKER]) continue;
|
|
34850
|
+
var nextPriority = Math.max(priority + 1, linkView.UPDATE_PRIORITY);
|
|
34851
|
+
this.scheduleViewUpdate(linkView, linkView.getFlag(LinkView.Flags.UPDATE), nextPriority, opt);
|
|
33027
34852
|
}
|
|
33028
34853
|
},
|
|
33029
34854
|
forcePostponedViewUpdate: function (view, flag) {
|
|
33030
|
-
if (!view || !
|
|
34855
|
+
if (!view || !view[CELL_VIEW_MARKER]) return false;
|
|
33031
34856
|
const model = view.model;
|
|
33032
34857
|
if (model.isElement()) return false;
|
|
33033
34858
|
const dumpOptions = {
|
|
@@ -33142,6 +34967,12 @@ var joint = (function (exports) {
|
|
|
33142
34967
|
const {
|
|
33143
34968
|
model
|
|
33144
34969
|
} = view;
|
|
34970
|
+
if (view[GRAPH_LAYER_VIEW_MARKER]) {
|
|
34971
|
+
if (flag & FLAG_REMOVE) {
|
|
34972
|
+
this.removeLayerView(view);
|
|
34973
|
+
return 0;
|
|
34974
|
+
}
|
|
34975
|
+
}
|
|
33145
34976
|
if (view[CELL_VIEW_MARKER]) {
|
|
33146
34977
|
if (flag & FLAG_REMOVE) {
|
|
33147
34978
|
this.removeView(model);
|
|
@@ -33741,7 +35572,7 @@ var joint = (function (exports) {
|
|
|
33741
35572
|
}
|
|
33742
35573
|
this.options.frozen = updates.keyFrozen = false;
|
|
33743
35574
|
if (updates.sort) {
|
|
33744
|
-
this.
|
|
35575
|
+
this.sortLayerViews();
|
|
33745
35576
|
updates.sort = false;
|
|
33746
35577
|
}
|
|
33747
35578
|
},
|
|
@@ -33769,8 +35600,8 @@ var joint = (function (exports) {
|
|
|
33769
35600
|
this.freeze();
|
|
33770
35601
|
this._updates.disabled = true;
|
|
33771
35602
|
//clean up all DOM elements/views to prevent memory leaks
|
|
33772
|
-
this.removeLayers();
|
|
33773
35603
|
this.removeViews();
|
|
35604
|
+
this._removeLayerViews();
|
|
33774
35605
|
},
|
|
33775
35606
|
getComputedSize: function () {
|
|
33776
35607
|
var options = this.options;
|
|
@@ -34008,7 +35839,17 @@ var joint = (function (exports) {
|
|
|
34008
35839
|
if (opt && opt.useModelGeometry) {
|
|
34009
35840
|
return this.model.getBBox() || new Rect();
|
|
34010
35841
|
}
|
|
34011
|
-
|
|
35842
|
+
const graphLayerViews = this.getGraphLayerViews();
|
|
35843
|
+
// Return an empty rectangle if there are no layers
|
|
35844
|
+
// should not happen in practice
|
|
35845
|
+
if (graphLayerViews.length === 0) {
|
|
35846
|
+
return new Rect();
|
|
35847
|
+
}
|
|
35848
|
+
|
|
35849
|
+
// Combine content area rectangles from all layers,
|
|
35850
|
+
// considering only graph layer views to exclude non-cell elements (e.g., grid, tools)
|
|
35851
|
+
const bbox = Rect.fromRectUnion(...graphLayerViews.map(view => view.vel.getBBox()));
|
|
35852
|
+
return bbox;
|
|
34012
35853
|
},
|
|
34013
35854
|
// Return the dimensions of the content bbox in the paper units (as it appears on screen).
|
|
34014
35855
|
getContentBBox: function (opt) {
|
|
@@ -34084,7 +35925,7 @@ var joint = (function (exports) {
|
|
|
34084
35925
|
cid,
|
|
34085
35926
|
model: cell,
|
|
34086
35927
|
interactive,
|
|
34087
|
-
labelsLayer: labelsLayer === true ?
|
|
35928
|
+
labelsLayer: labelsLayer === true ? paperLayers.LABELS : labelsLayer
|
|
34088
35929
|
});
|
|
34089
35930
|
},
|
|
34090
35931
|
_resolveCellViewClass: function (cell) {
|
|
@@ -34245,7 +36086,7 @@ var joint = (function (exports) {
|
|
|
34245
36086
|
this.unfreeze({
|
|
34246
36087
|
key
|
|
34247
36088
|
});
|
|
34248
|
-
this.
|
|
36089
|
+
this.sortLayerViews();
|
|
34249
36090
|
},
|
|
34250
36091
|
removeViews: function () {
|
|
34251
36092
|
// Remove all views and their references from the paper.
|
|
@@ -34259,7 +36100,7 @@ var joint = (function (exports) {
|
|
|
34259
36100
|
this._viewPlaceholders = {};
|
|
34260
36101
|
this._idToCid = {};
|
|
34261
36102
|
},
|
|
34262
|
-
|
|
36103
|
+
sortLayerViews: function () {
|
|
34263
36104
|
if (!this.isExactSorting()) {
|
|
34264
36105
|
// noop
|
|
34265
36106
|
return;
|
|
@@ -34269,38 +36110,16 @@ var joint = (function (exports) {
|
|
|
34269
36110
|
this._updates.sort = true;
|
|
34270
36111
|
return;
|
|
34271
36112
|
}
|
|
34272
|
-
this.
|
|
36113
|
+
this.sortLayerViewsExact();
|
|
34273
36114
|
},
|
|
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
|
-
});
|
|
36115
|
+
sortLayerViewsExact: function () {
|
|
36116
|
+
this.getGraphLayerViews().forEach(view => view.sortExact());
|
|
34287
36117
|
},
|
|
34288
36118
|
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
|
-
}
|
|
36119
|
+
// layer can be null if it is added to the graph with 'dry' option
|
|
36120
|
+
const layerId = this.model.getCellLayerId(view.model);
|
|
36121
|
+
const layerView = this.getLayerView(layerId);
|
|
36122
|
+
layerView.insertCellView(view);
|
|
34304
36123
|
view.onMount(isInitialInsert);
|
|
34305
36124
|
},
|
|
34306
36125
|
_hideView: function (viewLike) {
|
|
@@ -34355,7 +36174,7 @@ var joint = (function (exports) {
|
|
|
34355
36174
|
// Find the first view climbing up the DOM tree starting at element `el`. Note that `el` can also
|
|
34356
36175
|
// be a selector or a jQuery object.
|
|
34357
36176
|
findView: function ($el) {
|
|
34358
|
-
var el = isString($el) ? this.
|
|
36177
|
+
var el = isString($el) ? this.layers.querySelector($el) : $el instanceof $ ? $el[0] : $el;
|
|
34359
36178
|
var id = this.findAttribute('model-id', el);
|
|
34360
36179
|
if (id) return this._views[id];
|
|
34361
36180
|
return undefined;
|
|
@@ -34393,7 +36212,7 @@ var joint = (function (exports) {
|
|
|
34393
36212
|
var views = this.model.getElements().map(this.findViewByModel, this);
|
|
34394
36213
|
return views.filter(function (view) {
|
|
34395
36214
|
return view && view.vel.getBBox({
|
|
34396
|
-
target: this.
|
|
36215
|
+
target: this.layers
|
|
34397
36216
|
}).containsPoint(p);
|
|
34398
36217
|
}, this);
|
|
34399
36218
|
},
|
|
@@ -34407,7 +36226,7 @@ var joint = (function (exports) {
|
|
|
34407
36226
|
var method = opt.strict ? 'containsRect' : 'intersect';
|
|
34408
36227
|
return views.filter(function (view) {
|
|
34409
36228
|
return view && rect[method](view.vel.getBBox({
|
|
34410
|
-
target: this.
|
|
36229
|
+
target: this.layers
|
|
34411
36230
|
}));
|
|
34412
36231
|
}, this);
|
|
34413
36232
|
},
|
|
@@ -35191,7 +37010,7 @@ var joint = (function (exports) {
|
|
|
35191
37010
|
if (this.GUARDED_TAG_NAMES.includes(target.tagName)) {
|
|
35192
37011
|
return true;
|
|
35193
37012
|
}
|
|
35194
|
-
if (view && view.model && view.model
|
|
37013
|
+
if (view && view.model && view.model[CELL_MARKER]) {
|
|
35195
37014
|
return false;
|
|
35196
37015
|
}
|
|
35197
37016
|
if (this.el === target || this.svg.contains(target)) {
|
|
@@ -35206,12 +37025,12 @@ var joint = (function (exports) {
|
|
|
35206
37025
|
options.gridSize = gridSize;
|
|
35207
37026
|
if (options.drawGrid && !options.drawGridSize) {
|
|
35208
37027
|
// Do not redraw the grid if the `drawGridSize` is set.
|
|
35209
|
-
this.getLayerView(
|
|
37028
|
+
this.getLayerView(paperLayers.GRID).renderGrid();
|
|
35210
37029
|
}
|
|
35211
37030
|
return this;
|
|
35212
37031
|
},
|
|
35213
37032
|
setGrid: function (drawGrid) {
|
|
35214
|
-
this.getLayerView(
|
|
37033
|
+
this.getLayerView(paperLayers.GRID).setGrid(drawGrid);
|
|
35215
37034
|
return this;
|
|
35216
37035
|
},
|
|
35217
37036
|
updateBackgroundImage: function (opt) {
|
|
@@ -35536,194 +37355,9 @@ var joint = (function (exports) {
|
|
|
35536
37355
|
}
|
|
35537
37356
|
}, {
|
|
35538
37357
|
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
|
-
}
|
|
37358
|
+
Layers: paperLayers,
|
|
37359
|
+
backgroundPatterns,
|
|
37360
|
+
gridPatterns
|
|
35727
37361
|
});
|
|
35728
37362
|
|
|
35729
37363
|
const ToolView = View.extend({
|
|
@@ -35822,7 +37456,7 @@ var joint = (function (exports) {
|
|
|
35822
37456
|
tools: null,
|
|
35823
37457
|
relatedView: null,
|
|
35824
37458
|
name: null
|
|
35825
|
-
// layer?:
|
|
37459
|
+
// layer?: Paper.Layers.TOOLS
|
|
35826
37460
|
// z?: number
|
|
35827
37461
|
},
|
|
35828
37462
|
configure: function (options) {
|
|
@@ -35936,7 +37570,7 @@ var joint = (function (exports) {
|
|
|
35936
37570
|
},
|
|
35937
37571
|
getLayer() {
|
|
35938
37572
|
const {
|
|
35939
|
-
layer =
|
|
37573
|
+
layer = Paper.Layers.TOOLS
|
|
35940
37574
|
} = this.options;
|
|
35941
37575
|
return layer;
|
|
35942
37576
|
},
|
|
@@ -35965,21 +37599,26 @@ var joint = (function (exports) {
|
|
|
35965
37599
|
|
|
35966
37600
|
var index$2 = {
|
|
35967
37601
|
__proto__: null,
|
|
35968
|
-
CELL_VIEW_MARKER: CELL_VIEW_MARKER,
|
|
35969
37602
|
Cell: Cell,
|
|
37603
|
+
CellCollection: CellCollection,
|
|
35970
37604
|
CellView: CellView,
|
|
37605
|
+
DEFAULT_GRAPH_LAYER_TYPE: DEFAULT_GRAPH_LAYER_TYPE,
|
|
35971
37606
|
Element: Element$1,
|
|
35972
37607
|
ElementView: ElementView,
|
|
35973
37608
|
Graph: Graph,
|
|
37609
|
+
GraphLayer: GraphLayer,
|
|
37610
|
+
GraphLayerCollection: GraphLayerCollection,
|
|
37611
|
+
GraphLayerView: GraphLayerView,
|
|
37612
|
+
GridLayerView: GridLayerView,
|
|
35974
37613
|
HighlighterView: HighlighterView,
|
|
35975
|
-
|
|
37614
|
+
LayerView: LayerView,
|
|
35976
37615
|
Link: Link$1,
|
|
35977
37616
|
LinkView: LinkView,
|
|
35978
37617
|
Paper: Paper,
|
|
35979
|
-
PaperLayer: PaperLayer,
|
|
35980
37618
|
ToolView: ToolView,
|
|
35981
37619
|
ToolsView: ToolsView,
|
|
35982
|
-
attributes: attributes
|
|
37620
|
+
attributes: attributes,
|
|
37621
|
+
sortingTypes: sortingTypes
|
|
35983
37622
|
};
|
|
35984
37623
|
|
|
35985
37624
|
// Vertex Handles
|
|
@@ -37986,7 +39625,7 @@ var joint = (function (exports) {
|
|
|
37986
39625
|
Remove: Remove
|
|
37987
39626
|
};
|
|
37988
39627
|
|
|
37989
|
-
var version = "4.2.0-
|
|
39628
|
+
var version = "4.2.0-beta.1";
|
|
37990
39629
|
|
|
37991
39630
|
const Vectorizer = V;
|
|
37992
39631
|
const layout$1 = {
|