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