orcasvn-react-diagrams 0.2.8 → 0.2.10

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.
@@ -1144,6 +1144,163 @@ var selectionDemoConfig = ({
1144
1144
  ],
1145
1145
  });
1146
1146
 
1147
+ var createElementVisibilitySelectionState = function () { return ({
1148
+ elements: [
1149
+ {
1150
+ id: 'policy-normal',
1151
+ position: { x: 120, y: 160 },
1152
+ size: { width: 180, height: 120 },
1153
+ shapeId: 'default',
1154
+ style: { fill: '#dbeafe', stroke: '#1d4ed8', strokeWidth: 2 },
1155
+ },
1156
+ {
1157
+ id: 'policy-unselectable',
1158
+ position: { x: 410, y: 160 },
1159
+ size: { width: 180, height: 120 },
1160
+ shapeId: 'default',
1161
+ selectable: false,
1162
+ style: { fill: '#e2e8f0', stroke: '#334155', strokeWidth: 2 },
1163
+ },
1164
+ {
1165
+ id: 'policy-hidden-parent',
1166
+ position: { x: 660, y: 110 },
1167
+ size: { width: 220, height: 170 },
1168
+ shapeId: 'default',
1169
+ visible: false,
1170
+ style: { fill: '#fee2e2', stroke: '#dc2626', strokeWidth: 2 },
1171
+ },
1172
+ {
1173
+ id: 'policy-hidden-child',
1174
+ parentId: 'policy-hidden-parent',
1175
+ position: { x: 50, y: 58 },
1176
+ size: { width: 120, height: 72 },
1177
+ shapeId: 'default',
1178
+ style: { fill: '#dcfce7', stroke: '#16a34a', strokeWidth: 2 },
1179
+ },
1180
+ ],
1181
+ ports: [
1182
+ {
1183
+ id: 'policy-normal-port',
1184
+ elementId: 'policy-normal',
1185
+ position: { x: 180, y: 60 },
1186
+ shapeId: 'port-circle',
1187
+ },
1188
+ {
1189
+ id: 'policy-unselectable-port',
1190
+ elementId: 'policy-unselectable',
1191
+ position: { x: 0, y: 60 },
1192
+ shapeId: 'port-circle',
1193
+ },
1194
+ {
1195
+ id: 'policy-hidden-parent-port',
1196
+ elementId: 'policy-hidden-parent',
1197
+ position: { x: 0, y: 85 },
1198
+ shapeId: 'port-circle',
1199
+ },
1200
+ {
1201
+ id: 'policy-hidden-child-port',
1202
+ elementId: 'policy-hidden-child',
1203
+ position: { x: 120, y: 36 },
1204
+ shapeId: 'port-circle',
1205
+ },
1206
+ ],
1207
+ links: [
1208
+ {
1209
+ id: 'policy-visible-link',
1210
+ sourcePortId: 'policy-normal-port',
1211
+ targetPortId: 'policy-unselectable-port',
1212
+ points: [
1213
+ { x: 300, y: 220 },
1214
+ { x: 410, y: 220 },
1215
+ ],
1216
+ style: { stroke: '#2563eb', strokeWidth: 3 },
1217
+ },
1218
+ {
1219
+ id: 'policy-hidden-parent-link',
1220
+ sourcePortId: 'policy-normal-port',
1221
+ targetPortId: 'policy-hidden-parent-port',
1222
+ points: [
1223
+ { x: 300, y: 220 },
1224
+ { x: 660, y: 195 },
1225
+ ],
1226
+ style: { stroke: '#dc2626', strokeWidth: 3 },
1227
+ },
1228
+ {
1229
+ id: 'policy-visible-child-link',
1230
+ sourcePortId: 'policy-normal-port',
1231
+ targetPortId: 'policy-hidden-child-port',
1232
+ points: [
1233
+ { x: 300, y: 220 },
1234
+ { x: 830, y: 204 },
1235
+ ],
1236
+ style: { stroke: '#16a34a', strokeWidth: 3 },
1237
+ },
1238
+ ],
1239
+ texts: [
1240
+ {
1241
+ id: 'policy-tip',
1242
+ content: 'Blue node is normal. Slate node is visible but its body ignores click and marquee. Its port stays interactive. Red parent container is hidden, but its green child stays visible and interactive. Parent-owned port/text and the red parent link stay suppressed, while the green child link remains in scene, selection, zoom-to-fit, and fit-to-content export.',
1243
+ position: { x: 80, y: 72 },
1244
+ size: { width: 810, height: 60 },
1245
+ style: { fontSize: 14, fill: '#0f172a' },
1246
+ },
1247
+ {
1248
+ id: 'policy-normal-label',
1249
+ content: 'Normal selectable element',
1250
+ position: { x: 16, y: 14 },
1251
+ ownerId: 'policy-normal',
1252
+ },
1253
+ {
1254
+ id: 'policy-unselectable-label',
1255
+ content: 'Visible but body is unselectable',
1256
+ position: { x: 16, y: 14 },
1257
+ ownerId: 'policy-unselectable',
1258
+ },
1259
+ {
1260
+ id: 'policy-hidden-label',
1261
+ content: 'Hidden parent body',
1262
+ position: { x: 16, y: 14 },
1263
+ ownerId: 'policy-hidden-parent',
1264
+ },
1265
+ {
1266
+ id: 'policy-hidden-child-label',
1267
+ content: 'Visible child inside hidden parent',
1268
+ position: { x: 10, y: 12 },
1269
+ ownerId: 'policy-hidden-child',
1270
+ },
1271
+ ],
1272
+ }); };
1273
+ var elementVisibilitySelectionDemoConfig = {
1274
+ id: 'element-visibility-selection',
1275
+ title: 'Element Visibility + Selectability',
1276
+ description: 'QA scene for visible-but-unselectable bodies, hidden parent containers, and visible descendants that survive hidden ancestors. Shift + drag marquee to confirm only eligible items are collected.',
1277
+ createState: createElementVisibilitySelectionState,
1278
+ elementShapes: baseElementShapes,
1279
+ portShapes: basePortShapes,
1280
+ defaultElementShapeId: 'default',
1281
+ defaultPortShapeId: 'port-circle',
1282
+ actions: [
1283
+ {
1284
+ id: 'policy-filtered-selection',
1285
+ label: 'Try filtered API selection',
1286
+ run: function (editor) {
1287
+ editor.setSelection([
1288
+ 'policy-normal',
1289
+ 'policy-unselectable',
1290
+ 'policy-hidden-parent',
1291
+ 'policy-hidden-child',
1292
+ 'policy-unselectable-port',
1293
+ 'policy-hidden-parent-port',
1294
+ 'policy-hidden-child-port',
1295
+ 'policy-hidden-parent-link',
1296
+ 'policy-visible-child-link',
1297
+ 'policy-hidden-child-label',
1298
+ ]);
1299
+ },
1300
+ },
1301
+ ],
1302
+ };
1303
+
1147
1304
  var createEventHandlersState = function () { return ({
1148
1305
  elements: [
1149
1306
  {
@@ -4610,6 +4767,8 @@ var ElementModel = /** @class */ (function () {
4610
4767
  this.style = data.style;
4611
4768
  this.portIds = data.portIds ? __spreadArray([], data.portIds, true) : [];
4612
4769
  this.textIds = data.textIds ? __spreadArray([], data.textIds, true) : [];
4770
+ this.visible = data.visible;
4771
+ this.selectable = data.selectable;
4613
4772
  this.parentId = (_a = data.parentId) !== null && _a !== void 0 ? _a : null;
4614
4773
  this.moveMode = data.moveMode;
4615
4774
  this.anchorCenter = data.anchorCenter;
@@ -4648,6 +4807,8 @@ var ElementModel = /** @class */ (function () {
4648
4807
  style: this.style,
4649
4808
  portIds: __spreadArray([], this.portIds, true),
4650
4809
  textIds: __spreadArray([], this.textIds, true),
4810
+ visible: this.visible,
4811
+ selectable: this.selectable,
4651
4812
  parentId: this.parentId,
4652
4813
  moveMode: this.moveMode,
4653
4814
  anchorCenter: this.anchorCenter,
@@ -5051,6 +5212,18 @@ var DiagramModel = /** @class */ (function () {
5051
5212
  DiagramModel.prototype.getElement = function (id) {
5052
5213
  return this.elements.get(id);
5053
5214
  };
5215
+ DiagramModel.prototype.isElementVisible = function (id) {
5216
+ var element = this.elements.get(id);
5217
+ if (!element)
5218
+ return false;
5219
+ return element.visible !== false;
5220
+ };
5221
+ DiagramModel.prototype.isElementSelectable = function (id) {
5222
+ var element = this.elements.get(id);
5223
+ if (!element)
5224
+ return false;
5225
+ return this.isElementVisible(id) && element.selectable !== false;
5226
+ };
5054
5227
  DiagramModel.prototype.setElementLayout = function (id, layout) {
5055
5228
  var element = this.elements.get(id);
5056
5229
  if (!element)
@@ -5069,6 +5242,12 @@ var DiagramModel = /** @class */ (function () {
5069
5242
  DiagramModel.prototype.getPort = function (id) {
5070
5243
  return this.ports.get(id);
5071
5244
  };
5245
+ DiagramModel.prototype.isPortVisible = function (id) {
5246
+ var port = this.ports.get(id);
5247
+ if (!port)
5248
+ return false;
5249
+ return this.isElementVisible(port.elementId);
5250
+ };
5072
5251
  DiagramModel.prototype.getPortWorldPosition = function (id) {
5073
5252
  var port = this.ports.get(id);
5074
5253
  if (!port)
@@ -5084,6 +5263,16 @@ var DiagramModel = /** @class */ (function () {
5084
5263
  DiagramModel.prototype.getLink = function (id) {
5085
5264
  return this.links.get(id);
5086
5265
  };
5266
+ DiagramModel.prototype.isLinkVisible = function (id) {
5267
+ var link = this.links.get(id);
5268
+ if (!link)
5269
+ return false;
5270
+ var sourcePort = this.ports.get(link.sourcePortId);
5271
+ var targetPort = this.ports.get(link.targetPortId);
5272
+ var sourceVisible = sourcePort ? this.isPortVisible(sourcePort.id) : true;
5273
+ var targetVisible = targetPort ? this.isPortVisible(targetPort.id) : true;
5274
+ return sourceVisible && targetVisible;
5275
+ };
5087
5276
  DiagramModel.prototype.getLinkMidpoint = function (id) {
5088
5277
  var link = this.links.get(id);
5089
5278
  if (!link)
@@ -5093,6 +5282,23 @@ var DiagramModel = /** @class */ (function () {
5093
5282
  DiagramModel.prototype.getText = function (id) {
5094
5283
  return this.texts.get(id);
5095
5284
  };
5285
+ DiagramModel.prototype.isTextVisible = function (id) {
5286
+ var text = this.texts.get(id);
5287
+ if (!text)
5288
+ return false;
5289
+ if (!text.ownerId)
5290
+ return true;
5291
+ if (this.elements.has(text.ownerId)) {
5292
+ return this.isElementVisible(text.ownerId);
5293
+ }
5294
+ if (this.ports.has(text.ownerId)) {
5295
+ return this.isPortVisible(text.ownerId);
5296
+ }
5297
+ if (this.links.has(text.ownerId)) {
5298
+ return this.isLinkVisible(text.ownerId);
5299
+ }
5300
+ return true;
5301
+ };
5096
5302
  DiagramModel.prototype.getTextWorldPosition = function (id) {
5097
5303
  var text = this.texts.get(id);
5098
5304
  if (!text)
@@ -8407,16 +8613,38 @@ var DiagramEngine = /** @class */ (function () {
8407
8613
  this.emitEntityDeletionEvents(removal.removed);
8408
8614
  };
8409
8615
  DiagramEngine.prototype.setSelection = function (ids) {
8410
- this.selection.set(ids);
8616
+ this.selection.set(this.normalizeSelectionIds(ids));
8411
8617
  this.emitSelection();
8412
8618
  };
8413
8619
  DiagramEngine.prototype.toggleSelection = function (id) {
8414
- this.selection.toggle(id);
8620
+ var current = new Set(this.selection.get());
8621
+ if (current.has(id)) {
8622
+ current.delete(id);
8623
+ }
8624
+ else if (this.isSelectableId(id)) {
8625
+ current.add(id);
8626
+ }
8627
+ this.selection.set(Array.from(current));
8415
8628
  this.emitSelection();
8416
8629
  };
8417
8630
  DiagramEngine.prototype.getSelection = function () {
8418
8631
  return this.selection.get();
8419
8632
  };
8633
+ DiagramEngine.prototype.isElementVisible = function (id) {
8634
+ return this.model.isElementVisible(id);
8635
+ };
8636
+ DiagramEngine.prototype.isElementSelectable = function (id) {
8637
+ return this.model.isElementSelectable(id);
8638
+ };
8639
+ DiagramEngine.prototype.isPortVisible = function (id) {
8640
+ return this.model.isPortVisible(id);
8641
+ };
8642
+ DiagramEngine.prototype.isLinkVisible = function (id) {
8643
+ return this.model.isLinkVisible(id);
8644
+ };
8645
+ DiagramEngine.prototype.isTextVisible = function (id) {
8646
+ return this.model.isTextVisible(id);
8647
+ };
8420
8648
  DiagramEngine.prototype.getElementWorldPosition = function (id) {
8421
8649
  return this.model.getElementWorldPosition(id);
8422
8650
  };
@@ -8678,11 +8906,15 @@ var DiagramEngine = /** @class */ (function () {
8678
8906
  var _this = this;
8679
8907
  var _a;
8680
8908
  var allPatches = this.appendTextLayoutPatches(patches, (_a = options === null || options === void 0 ? void 0 : options.emitTextUpdated) !== null && _a !== void 0 ? _a : true);
8909
+ var selectionChanged = this.syncSelectionToPolicies();
8681
8910
  var state = this.model.toState();
8682
8911
  this.events.emit('change', { patches: allPatches, state: state });
8683
- if ((options === null || options === void 0 ? void 0 : options.render) === false)
8684
- return;
8685
- this.scheduler.requestRender(function () { return _this.renderer.render(_this.model); });
8912
+ if ((options === null || options === void 0 ? void 0 : options.render) !== false) {
8913
+ this.scheduler.requestRender(function () { return _this.renderer.render(_this.model); });
8914
+ }
8915
+ if (selectionChanged) {
8916
+ this.emitSelection();
8917
+ }
8686
8918
  };
8687
8919
  DiagramEngine.prototype.appendTextLayoutPatches = function (patches, emitTextUpdated) {
8688
8920
  var _this = this;
@@ -9128,6 +9360,31 @@ var DiagramEngine = /** @class */ (function () {
9128
9360
  });
9129
9361
  this.renderer.renderSelection(selectedIds);
9130
9362
  };
9363
+ DiagramEngine.prototype.normalizeSelectionIds = function (ids) {
9364
+ var _this = this;
9365
+ return ids.filter(function (id, index) { return ids.indexOf(id) === index && _this.isSelectableId(id); });
9366
+ };
9367
+ DiagramEngine.prototype.isSelectableId = function (id) {
9368
+ if (this.model.getElement(id))
9369
+ return this.model.isElementSelectable(id);
9370
+ if (this.model.getPort(id))
9371
+ return this.model.isPortVisible(id);
9372
+ if (this.model.getLink(id))
9373
+ return this.model.isLinkVisible(id);
9374
+ if (this.model.getText(id))
9375
+ return this.model.isTextVisible(id);
9376
+ return false;
9377
+ };
9378
+ DiagramEngine.prototype.syncSelectionToPolicies = function () {
9379
+ var current = this.selection.get();
9380
+ var normalized = this.normalizeSelectionIds(current);
9381
+ if (current.length === normalized.length &&
9382
+ current.every(function (id, index) { return id === normalized[index]; })) {
9383
+ return false;
9384
+ }
9385
+ this.selection.set(normalized);
9386
+ return true;
9387
+ };
9131
9388
  DiagramEngine.prototype.applyLayoutForParent = function (parentId, options) {
9132
9389
  return this.autoLayoutService.applyLayoutForParent(parentId, options);
9133
9390
  };
@@ -10045,7 +10302,9 @@ var KonvaRenderer = /** @class */ (function () {
10045
10302
  };
10046
10303
  KonvaRenderer.prototype.syncElements = function (model) {
10047
10304
  var _this = this;
10048
- var elements = Array.from(model.elements.values()).map(function (element, index) { return ({
10305
+ var elements = Array.from(model.elements.values())
10306
+ .filter(function (element) { return model.isElementVisible(element.id); })
10307
+ .map(function (element, index) { return ({
10049
10308
  element: element,
10050
10309
  depth: _this.getElementDepth(model, element),
10051
10310
  order: index,
@@ -10078,6 +10337,10 @@ var KonvaRenderer = /** @class */ (function () {
10078
10337
  node.setAttrs({ __depth: depth });
10079
10338
  }
10080
10339
  });
10340
+ var visibleElementIds = new Set(elements.map(function (_a) {
10341
+ var element = _a.element;
10342
+ return element.id;
10343
+ }));
10081
10344
  elements.forEach(function (_a) {
10082
10345
  var _b;
10083
10346
  var element = _a.element;
@@ -10086,7 +10349,7 @@ var KonvaRenderer = /** @class */ (function () {
10086
10349
  });
10087
10350
  Array.from(this.elementNodes.keys()).forEach(function (id) {
10088
10351
  var _a;
10089
- if (!model.elements.has(id)) {
10352
+ if (!visibleElementIds.has(id)) {
10090
10353
  var node = _this.elementNodes.get(id);
10091
10354
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
10092
10355
  _this.elementNodes.delete(id);
@@ -10109,7 +10372,7 @@ var KonvaRenderer = /** @class */ (function () {
10109
10372
  };
10110
10373
  KonvaRenderer.prototype.syncPorts = function (model) {
10111
10374
  var _this = this;
10112
- var ports = Array.from(model.ports.values());
10375
+ var ports = Array.from(model.ports.values()).filter(function (port) { return model.isPortVisible(port.id); });
10113
10376
  ports.forEach(function (port) {
10114
10377
  var _a, _b, _c, _d, _e;
10115
10378
  var data = port.toData();
@@ -10127,9 +10390,10 @@ var KonvaRenderer = /** @class */ (function () {
10127
10390
  _this.updatePosition(node, position);
10128
10391
  _this.applyPortOrientation(node, data, position, model);
10129
10392
  });
10393
+ var visiblePortIds = new Set(ports.map(function (port) { return port.id; }));
10130
10394
  Array.from(this.portNodes.keys()).forEach(function (id) {
10131
10395
  var _a;
10132
- if (!model.ports.has(id)) {
10396
+ if (!visiblePortIds.has(id)) {
10133
10397
  var node = _this.portNodes.get(id);
10134
10398
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
10135
10399
  _this.portNodes.delete(id);
@@ -10140,7 +10404,7 @@ var KonvaRenderer = /** @class */ (function () {
10140
10404
  };
10141
10405
  KonvaRenderer.prototype.syncLinks = function (model) {
10142
10406
  var _this = this;
10143
- var links = Array.from(model.links.values());
10407
+ var links = Array.from(model.links.values()).filter(function (link) { return model.isLinkVisible(link.id); });
10144
10408
  links.forEach(function (link) {
10145
10409
  var _a, _b;
10146
10410
  var node = _this.linkNodes.get(link.id);
@@ -10151,9 +10415,10 @@ var KonvaRenderer = /** @class */ (function () {
10151
10415
  }
10152
10416
  _this.updateLine(node, link.toData());
10153
10417
  });
10418
+ var visibleLinkIds = new Set(links.map(function (link) { return link.id; }));
10154
10419
  Array.from(this.linkNodes.keys()).forEach(function (id) {
10155
10420
  var _a;
10156
- if (!model.links.has(id)) {
10421
+ if (!visibleLinkIds.has(id)) {
10157
10422
  var node = _this.linkNodes.get(id);
10158
10423
  (_a = node === null || node === void 0 ? void 0 : node.destroy) === null || _a === void 0 ? void 0 : _a.call(node);
10159
10424
  _this.linkNodes.delete(id);
@@ -10164,7 +10429,7 @@ var KonvaRenderer = /** @class */ (function () {
10164
10429
  };
10165
10430
  KonvaRenderer.prototype.syncTexts = function (model) {
10166
10431
  var _this = this;
10167
- var texts = Array.from(model.texts.values());
10432
+ var texts = Array.from(model.texts.values()).filter(function (text) { return model.isTextVisible(text.id); });
10168
10433
  texts.forEach(function (text) {
10169
10434
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
10170
10435
  var node = _this.textNodes.get(text.id);
@@ -10253,9 +10518,10 @@ var KonvaRenderer = /** @class */ (function () {
10253
10518
  _this.textBackgroundNodes.delete(text.id);
10254
10519
  }
10255
10520
  });
10521
+ var visibleTextIds = new Set(texts.map(function (text) { return text.id; }));
10256
10522
  Array.from(this.textNodes.keys()).forEach(function (id) {
10257
10523
  var _a, _b;
10258
- if (!model.texts.has(id)) {
10524
+ if (!visibleTextIds.has(id)) {
10259
10525
  var backgroundNode = _this.textBackgroundNodes.get(id);
10260
10526
  (_a = backgroundNode === null || backgroundNode === void 0 ? void 0 : backgroundNode.destroy) === null || _a === void 0 ? void 0 : _a.call(backgroundNode);
10261
10527
  _this.textBackgroundNodes.delete(id);
@@ -11247,15 +11513,21 @@ var KonvaInteraction = /** @class */ (function () {
11247
11513
  KonvaInteraction.prototype.normalizeHit = function (hit) {
11248
11514
  if (!hit || hit.type === 'none')
11249
11515
  return null;
11250
- if (hit.type === 'port' ||
11251
- hit.type === 'link' ||
11252
- hit.type === 'text' ||
11253
- hit.type === 'resize-handle' ||
11516
+ if (hit.type === 'port') {
11517
+ return this.engine.isPortVisible(hit.id) ? hit : null;
11518
+ }
11519
+ if (hit.type === 'link') {
11520
+ return this.engine.isLinkVisible(hit.id) ? hit : null;
11521
+ }
11522
+ if (hit.type === 'text') {
11523
+ return this.engine.isTextVisible(hit.id) ? hit : null;
11524
+ }
11525
+ if (hit.type === 'resize-handle' ||
11254
11526
  hit.type === 'link-handle' ||
11255
11527
  hit.type === 'shape-hover-control') {
11256
11528
  return hit;
11257
11529
  }
11258
- return __assign(__assign({}, hit), { type: 'element' });
11530
+ return this.engine.isElementSelectable(hit.id) ? __assign(__assign({}, hit), { type: 'element' }) : null;
11259
11531
  };
11260
11532
  KonvaInteraction.prototype.resolveHit = function (point) {
11261
11533
  var _this = this;
@@ -11321,6 +11593,8 @@ var KonvaInteraction = /** @class */ (function () {
11321
11593
  var best = null;
11322
11594
  state.elements.forEach(function (element) {
11323
11595
  var _a, _b, _c;
11596
+ if (!_this.engine.isElementSelectable(element.id))
11597
+ return;
11324
11598
  var world = (_a = _this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
11325
11599
  var rotation = _this.engine.getElementRotation(element.id);
11326
11600
  if (!pointInRotatedRect(point, world, element.size, rotation, (_b = element.anchorCenter) !== null && _b !== void 0 ? _b : false))
@@ -11350,6 +11624,8 @@ var KonvaInteraction = /** @class */ (function () {
11350
11624
  var bestDistance = Number.POSITIVE_INFINITY;
11351
11625
  links.forEach(function (link) {
11352
11626
  var _a, _b;
11627
+ if (!_this.engine.isLinkVisible(link.id))
11628
+ return;
11353
11629
  if (link.points.length < 2)
11354
11630
  return;
11355
11631
  var tolerance = ((_b = (_a = link.style) === null || _a === void 0 ? void 0 : _a.hitStrokeWidth) !== null && _b !== void 0 ? _b : 15) / 2;
@@ -12364,6 +12640,8 @@ var KonvaInteraction = /** @class */ (function () {
12364
12640
  };
12365
12641
  state.elements.forEach(function (element) {
12366
12642
  var _a, _b;
12643
+ if (!_this.engine.isElementSelectable(element.id))
12644
+ return;
12367
12645
  var position = (_a = _this.engine.getElementWorldPosition(element.id)) !== null && _a !== void 0 ? _a : element.position;
12368
12646
  var rotation = _this.engine.getElementRotation(element.id);
12369
12647
  var anchorCenter = (_b = element.anchorCenter) !== null && _b !== void 0 ? _b : false;
@@ -12381,6 +12659,8 @@ var KonvaInteraction = /** @class */ (function () {
12381
12659
  });
12382
12660
  state.ports.forEach(function (port) {
12383
12661
  var _a;
12662
+ if (!_this.engine.isPortVisible(port.id))
12663
+ return;
12384
12664
  var position = (_a = _this.engine.getPortWorldPosition(port.id)) !== null && _a !== void 0 ? _a : port.position;
12385
12665
  if (containsPoint(position)) {
12386
12666
  selected.add(port.id);
@@ -12388,6 +12668,8 @@ var KonvaInteraction = /** @class */ (function () {
12388
12668
  });
12389
12669
  state.texts.forEach(function (text) {
12390
12670
  var _a, _b, _c, _d, _e;
12671
+ if (!_this.engine.isTextVisible(text.id))
12672
+ return;
12391
12673
  var position = (_a = _this.engine.getTextWorldPosition(text.id)) !== null && _a !== void 0 ? _a : text.position;
12392
12674
  var width = (_c = (_b = text.size) === null || _b === void 0 ? void 0 : _b.width) !== null && _c !== void 0 ? _c : 0;
12393
12675
  var height = (_e = (_d = text.size) === null || _d === void 0 ? void 0 : _d.height) !== null && _e !== void 0 ? _e : 0;
@@ -12397,6 +12679,8 @@ var KonvaInteraction = /** @class */ (function () {
12397
12679
  }
12398
12680
  });
12399
12681
  state.links.forEach(function (link) {
12682
+ if (!_this.engine.isLinkVisible(link.id))
12683
+ return;
12400
12684
  if (link.points.length === 0)
12401
12685
  return;
12402
12686
  var xs = link.points.map(function (point) { return point.x; });
@@ -13328,32 +13612,180 @@ var resolveViewportFitOptions = function (options) {
13328
13612
  return { padding: padding, minZoom: minZoom, maxZoom: maxZoom };
13329
13613
  };
13330
13614
  var clamp = function (value, min, max) { return Math.max(min, Math.min(max, value)); };
13615
+ var isElementVisibleInState = function (elementId, elementsById) {
13616
+ var element = elementsById.get(elementId);
13617
+ if (!element)
13618
+ return false;
13619
+ return element.visible !== false;
13620
+ };
13621
+ var isPortVisibleInState = function (portId, portsById, elementsById) {
13622
+ var port = portsById.get(portId);
13623
+ if (!port)
13624
+ return false;
13625
+ return isElementVisibleInState(port.elementId, elementsById);
13626
+ };
13627
+ var isLinkVisibleInState = function (linkId, linksById, portsById, elementsById) {
13628
+ var link = linksById.get(linkId);
13629
+ if (!link)
13630
+ return false;
13631
+ var sourcePort = portsById.get(link.sourcePortId);
13632
+ var targetPort = portsById.get(link.targetPortId);
13633
+ var sourceVisible = sourcePort ? isPortVisibleInState(sourcePort.id, portsById, elementsById) : true;
13634
+ var targetVisible = targetPort ? isPortVisibleInState(targetPort.id, portsById, elementsById) : true;
13635
+ return sourceVisible && targetVisible;
13636
+ };
13637
+ var isTextVisibleInState = function (text, elementsById, portsById, linksById) {
13638
+ if (!text.ownerId)
13639
+ return true;
13640
+ if (elementsById.has(text.ownerId))
13641
+ return isElementVisibleInState(text.ownerId, elementsById);
13642
+ if (portsById.has(text.ownerId))
13643
+ return isPortVisibleInState(text.ownerId, portsById, elementsById);
13644
+ if (linksById.has(text.ownerId))
13645
+ return isLinkVisibleInState(text.ownerId, linksById, portsById, elementsById);
13646
+ return true;
13647
+ };
13648
+ var resolveElementWorldPositionInState = function (elementId, elementsById) {
13649
+ var element = elementsById.get(elementId);
13650
+ if (!element)
13651
+ return null;
13652
+ var x = element.position.x;
13653
+ var y = element.position.y;
13654
+ if (element.anchorCenter) {
13655
+ x -= element.size.width / 2;
13656
+ y -= element.size.height / 2;
13657
+ }
13658
+ var current = element;
13659
+ while (current.parentId) {
13660
+ var parent_1 = elementsById.get(current.parentId);
13661
+ if (!parent_1)
13662
+ break;
13663
+ var parentX = parent_1.position.x;
13664
+ var parentY = parent_1.position.y;
13665
+ if (parent_1.anchorCenter) {
13666
+ parentX -= parent_1.size.width / 2;
13667
+ parentY -= parent_1.size.height / 2;
13668
+ }
13669
+ x += parentX;
13670
+ y += parentY;
13671
+ current = parent_1;
13672
+ }
13673
+ return { x: x, y: y };
13674
+ };
13675
+ var resolvePortWorldPositionInState = function (portId, portsById, elementsById) {
13676
+ var port = portsById.get(portId);
13677
+ if (!port)
13678
+ return null;
13679
+ var elementPosition = resolveElementWorldPositionInState(port.elementId, elementsById);
13680
+ if (!elementPosition)
13681
+ return __assign({}, port.position);
13682
+ return {
13683
+ x: elementPosition.x + port.position.x,
13684
+ y: elementPosition.y + port.position.y,
13685
+ };
13686
+ };
13687
+ var resolveLinkMidpointInState = function (link) {
13688
+ var points = link.points;
13689
+ if (points.length === 0)
13690
+ return { x: 0, y: 0 };
13691
+ if (points.length === 1)
13692
+ return __assign({}, points[0]);
13693
+ var total = 0;
13694
+ for (var i = 1; i < points.length; i += 1) {
13695
+ total += distance(points[i - 1], points[i]);
13696
+ }
13697
+ var halfway = total / 2;
13698
+ var traveled = 0;
13699
+ for (var i = 1; i < points.length; i += 1) {
13700
+ var segment = distance(points[i - 1], points[i]);
13701
+ if (traveled + segment >= halfway) {
13702
+ var ratio = segment === 0 ? 0 : (halfway - traveled) / segment;
13703
+ return {
13704
+ x: points[i - 1].x + (points[i].x - points[i - 1].x) * ratio,
13705
+ y: points[i - 1].y + (points[i].y - points[i - 1].y) * ratio,
13706
+ };
13707
+ }
13708
+ traveled += segment;
13709
+ }
13710
+ return __assign({}, points[points.length - 1]);
13711
+ };
13712
+ var resolveTextWorldPositionInState = function (text, elementsById, portsById, linksById) {
13713
+ if (!text.ownerId)
13714
+ return __assign({}, text.position);
13715
+ if (elementsById.has(text.ownerId)) {
13716
+ var elementPosition = resolveElementWorldPositionInState(text.ownerId, elementsById);
13717
+ if (!elementPosition)
13718
+ return __assign({}, text.position);
13719
+ return {
13720
+ x: elementPosition.x + text.position.x,
13721
+ y: elementPosition.y + text.position.y,
13722
+ };
13723
+ }
13724
+ if (portsById.has(text.ownerId)) {
13725
+ var portPosition = resolvePortWorldPositionInState(text.ownerId, portsById, elementsById);
13726
+ if (!portPosition)
13727
+ return __assign({}, text.position);
13728
+ return {
13729
+ x: portPosition.x + text.position.x,
13730
+ y: portPosition.y + text.position.y,
13731
+ };
13732
+ }
13733
+ if (linksById.has(text.ownerId)) {
13734
+ var link = linksById.get(text.ownerId);
13735
+ if (!link)
13736
+ return __assign({}, text.position);
13737
+ var midpoint = resolveLinkMidpointInState(link);
13738
+ return {
13739
+ x: midpoint.x + text.position.x,
13740
+ y: midpoint.y + text.position.y,
13741
+ };
13742
+ }
13743
+ return __assign({}, text.position);
13744
+ };
13331
13745
  var resolveStateWorldBounds = function (state) {
13332
13746
  var bounds = createBounds();
13747
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
13748
+ var portsById = new Map(state.ports.map(function (port) { return [port.id, port]; }));
13749
+ var linksById = new Map(state.links.map(function (link) { return [link.id, link]; }));
13333
13750
  state.elements.forEach(function (element) {
13334
- includeRect(bounds, element.position.x, element.position.y, element.size.width, element.size.height);
13751
+ if (!isElementVisibleInState(element.id, elementsById))
13752
+ return;
13753
+ var position = resolveElementWorldPositionInState(element.id, elementsById);
13754
+ if (!position)
13755
+ return;
13756
+ includeRect(bounds, position.x, position.y, element.size.width, element.size.height);
13335
13757
  });
13336
13758
  state.ports.forEach(function (port) {
13337
13759
  var _a;
13760
+ if (!isPortVisibleInState(port.id, portsById, elementsById))
13761
+ return;
13762
+ var position = resolvePortWorldPositionInState(port.id, portsById, elementsById);
13763
+ if (!position)
13764
+ return;
13338
13765
  var size = port.size;
13339
13766
  if (!size) {
13340
- expandBounds(bounds, port.position.x, port.position.y);
13767
+ expandBounds(bounds, position.x, position.y);
13341
13768
  return;
13342
13769
  }
13343
13770
  var anchorCenter = (_a = port.anchorCenter) !== null && _a !== void 0 ? _a : true;
13344
- var x = anchorCenter ? port.position.x - size.width / 2 : port.position.x;
13345
- var y = anchorCenter ? port.position.y - size.height / 2 : port.position.y;
13771
+ var x = anchorCenter ? position.x - size.width / 2 : position.x;
13772
+ var y = anchorCenter ? position.y - size.height / 2 : position.y;
13346
13773
  includeRect(bounds, x, y, size.width, size.height);
13347
13774
  });
13348
13775
  state.links.forEach(function (link) {
13776
+ if (!isLinkVisibleInState(link.id, linksById, portsById, elementsById))
13777
+ return;
13349
13778
  link.points.forEach(function (point) {
13350
13779
  expandBounds(bounds, point.x, point.y);
13351
13780
  });
13352
13781
  });
13353
13782
  state.texts.forEach(function (text) {
13354
13783
  var _a;
13784
+ if (!isTextVisibleInState(text, elementsById, portsById, linksById))
13785
+ return;
13355
13786
  var offset = (_a = text.displayOffset) !== null && _a !== void 0 ? _a : { x: 0, y: 0 };
13356
- var position = { x: text.position.x + offset.x, y: text.position.y + offset.y };
13787
+ var worldPosition = resolveTextWorldPositionInState(text, elementsById, portsById, linksById);
13788
+ var position = { x: worldPosition.x + offset.x, y: worldPosition.y + offset.y };
13357
13789
  var clipSize = text.displayClipSize;
13358
13790
  var size = clipSize !== null && clipSize !== void 0 ? clipSize : text.size;
13359
13791
  if (size) {
@@ -13366,8 +13798,14 @@ var resolveStateWorldBounds = function (state) {
13366
13798
  };
13367
13799
  var resolveElementWorldBounds = function (state) {
13368
13800
  var bounds = createBounds();
13801
+ var elementsById = new Map(state.elements.map(function (element) { return [element.id, element]; }));
13369
13802
  state.elements.forEach(function (element) {
13370
- includeRect(bounds, element.position.x, element.position.y, element.size.width, element.size.height);
13803
+ if (!isElementVisibleInState(element.id, elementsById))
13804
+ return;
13805
+ var position = resolveElementWorldPositionInState(element.id, elementsById);
13806
+ if (!position)
13807
+ return;
13808
+ includeRect(bounds, position.x, position.y, element.size.width, element.size.height);
13371
13809
  });
13372
13810
  return hasBounds(bounds) ? bounds : null;
13373
13811
  };
@@ -16518,6 +16956,12 @@ var demoTabs = [
16518
16956
  description: selectionDemoConfig.description,
16519
16957
  Component: wrapSimpleDemo(selectionDemoConfig),
16520
16958
  },
16959
+ {
16960
+ id: elementVisibilitySelectionDemoConfig.id,
16961
+ title: elementVisibilitySelectionDemoConfig.title,
16962
+ description: elementVisibilitySelectionDemoConfig.description,
16963
+ Component: wrapSimpleDemo(elementVisibilitySelectionDemoConfig),
16964
+ },
16521
16965
  {
16522
16966
  id: eventHandlersDemoConfig.id,
16523
16967
  title: eventHandlersDemoConfig.title,