@plait/draw 0.60.0 → 0.62.0-next.0

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.
Files changed (92) hide show
  1. package/constants/geometry.d.ts +41 -13
  2. package/constants/index.d.ts +2 -1
  3. package/constants/line.d.ts +1 -0
  4. package/constants/pointer.d.ts +2 -2
  5. package/constants/swimlane.d.ts +21 -0
  6. package/constants/text.d.ts +1 -0
  7. package/engines/uml/assembly.d.ts +2 -0
  8. package/engines/uml/component-box.d.ts +2 -0
  9. package/engines/uml/component.d.ts +2 -0
  10. package/engines/uml/provided-interface.d.ts +2 -0
  11. package/engines/uml/required-interface.d.ts +2 -0
  12. package/engines/uml/template.d.ts +2 -0
  13. package/esm2022/constants/geometry.mjs +30 -17
  14. package/esm2022/constants/index.mjs +3 -2
  15. package/esm2022/constants/line.mjs +2 -1
  16. package/esm2022/constants/pointer.mjs +3 -3
  17. package/esm2022/constants/swimlane.mjs +25 -0
  18. package/esm2022/constants/text.mjs +2 -0
  19. package/esm2022/engines/index.mjs +14 -2
  20. package/esm2022/engines/table/table.mjs +9 -3
  21. package/esm2022/engines/uml/assembly.mjs +56 -0
  22. package/esm2022/engines/uml/component-box.mjs +61 -0
  23. package/esm2022/engines/uml/component.mjs +72 -0
  24. package/esm2022/engines/uml/provided-interface.mjs +47 -0
  25. package/esm2022/engines/uml/required-interface.mjs +36 -0
  26. package/esm2022/engines/uml/template.mjs +47 -0
  27. package/esm2022/generators/single-text.generator.mjs +3 -3
  28. package/esm2022/generators/table.generator.mjs +1 -1
  29. package/esm2022/generators/text.generator.mjs +10 -13
  30. package/esm2022/geometry.component.mjs +12 -14
  31. package/esm2022/image.component.mjs +6 -8
  32. package/esm2022/interfaces/geometry.mjs +7 -10
  33. package/esm2022/interfaces/index.mjs +18 -8
  34. package/esm2022/interfaces/swimlane.mjs +13 -0
  35. package/esm2022/interfaces/table.mjs +5 -1
  36. package/esm2022/line.component.mjs +12 -13
  37. package/esm2022/plugins/with-draw-fragment.mjs +5 -2
  38. package/esm2022/plugins/with-draw.mjs +1 -1
  39. package/esm2022/plugins/with-geometry-create.mjs +4 -10
  40. package/esm2022/plugins/with-line-text.mjs +7 -8
  41. package/esm2022/plugins/with-swimlane-create.mjs +4 -4
  42. package/esm2022/plugins/with-swimlane.mjs +21 -2
  43. package/esm2022/plugins/with-table-resize.mjs +6 -5
  44. package/esm2022/plugins/with-table.mjs +28 -10
  45. package/esm2022/table.component.mjs +31 -12
  46. package/esm2022/transforms/geometry-text.mjs +8 -6
  47. package/esm2022/transforms/image.mjs +3 -3
  48. package/esm2022/transforms/index.mjs +5 -3
  49. package/esm2022/transforms/line.mjs +1 -1
  50. package/esm2022/transforms/multi-text-geometry-text.mjs +1 -1
  51. package/esm2022/transforms/swimlane.mjs +129 -37
  52. package/esm2022/utils/clipboard.mjs +27 -21
  53. package/esm2022/utils/common.mjs +6 -7
  54. package/esm2022/utils/geometry.mjs +4 -4
  55. package/esm2022/utils/hit.mjs +2 -2
  56. package/esm2022/utils/index.mjs +4 -1
  57. package/esm2022/utils/multi-text-geometry.mjs +2 -2
  58. package/esm2022/utils/selected.mjs +3 -8
  59. package/esm2022/utils/swimlane.mjs +66 -77
  60. package/esm2022/utils/table-selected.mjs +26 -0
  61. package/esm2022/utils/table.mjs +26 -1
  62. package/esm2022/utils/uml.mjs +2 -2
  63. package/fesm2022/plait-draw.mjs +848 -309
  64. package/fesm2022/plait-draw.mjs.map +1 -1
  65. package/generators/single-text.generator.d.ts +3 -4
  66. package/generators/table.generator.d.ts +2 -2
  67. package/generators/text.generator.d.ts +3 -6
  68. package/image.component.d.ts +0 -1
  69. package/interfaces/geometry.d.ts +15 -24
  70. package/interfaces/index.d.ts +11 -6
  71. package/interfaces/swimlane.d.ts +22 -0
  72. package/interfaces/table.d.ts +13 -4
  73. package/line.component.d.ts +1 -2
  74. package/package.json +1 -3
  75. package/plugins/with-geometry-create.d.ts +1 -1
  76. package/plugins/with-swimlane-create.d.ts +1 -1
  77. package/plugins/with-swimlane.d.ts +3 -2
  78. package/plugins/with-table-resize.d.ts +1 -1
  79. package/plugins/with-table.d.ts +1 -4
  80. package/transforms/index.d.ts +7 -5
  81. package/transforms/swimlane.d.ts +8 -5
  82. package/utils/clipboard.d.ts +4 -3
  83. package/utils/common.d.ts +5 -5
  84. package/utils/geometry.d.ts +16 -1
  85. package/utils/index.d.ts +3 -0
  86. package/utils/selected.d.ts +2 -4
  87. package/utils/shape.d.ts +1 -1
  88. package/utils/swimlane.d.ts +11 -26
  89. package/utils/table-selected.d.ts +9 -0
  90. package/utils/table.d.ts +10 -9
  91. package/constants/draw.d.ts +0 -1
  92. package/esm2022/constants/draw.mjs +0 -2
@@ -1,9 +1,8 @@
1
- import { ACTIVE_STROKE_WIDTH, ThemeColorMode, RectangleClient, idCreator, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, rotatePointsByElement, isPolylineHitRectangle, rotateAntiPointsByElement, distanceBetweenPointAndPoint, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, createG, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, createDebugGenerator, Point, arrowPoints, createPath, drawLinearPath, rotate, catmullRomFitting, setStrokeLinecap, findElements, createMask, createRect, PlaitElement, getSelectedElements, getElementById, Path, Direction, PlaitNode, hasValidAngle, toViewBoxPoint, toHostPoint, rotatePoints, getRectangleByElements, getSelectionAngle, rotatedDataPoints, isAxisChangedByAngle, isSelectionMoving, drawRectangle, getRectangleByAngle, getSnapRectangles, getTripleAxis, getMinPointDelta, SNAP_TOLERANCE, drawPointSnapLines, drawSolidLines, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, getNearestPointBetweenPointAndEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRoundRectangle, isPointInRoundRectangle, setPathStrokeLinecap, getCrossingPointsBetweenEllipseAndSegment, drawLine as drawLine$1, RgbaToHEX, getHitElementByPoint, preventTouchMove, WritableClipboardOperationType, createClipboardContext, WritableClipboardType, addClipboardContext, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, normalizeAngle, degreesToRadians, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, isSelectedElement } from '@plait/core';
2
- import { WithTextPluginKey, ELEMENT_TO_TEXT_MANAGES, getMemorizedLatest, memorizeLatest, RESIZE_HANDLE_DIAMETER, getPointOnPolyline, TRANSPARENT, getTextEditorsByElement, Generator, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, getPointByVectorComponent, getFirstTextManage, ActiveGenerator, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, getDirectionByVector, normalizeShapePoints, getFirstTextEditor, resetPointsAfterResize, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, isCornerHandle, getIndexByResizeHandle, withResize, drawHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, getDirectionFactorByDirectionComponent, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByPointOfRectangle, getDirectionFactor, rotateVector, getOppositeDirection, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, PRIMARY_COLOR, CommonElementFlavour, canResize, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, getTextManages, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } from '@plait/common';
3
- import { Alignment, TextManage, buildText, DEFAULT_FONT_SIZE, getTextSize, AlignEditor } from '@plait/text';
1
+ import { ACTIVE_STROKE_WIDTH, ThemeColorMode, RectangleClient, idCreator, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, rotatePointsByElement, isPolylineHitRectangle, rotateAntiPointsByElement, distanceBetweenPointAndPoint, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, createG, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, createDebugGenerator, Point, arrowPoints, createPath, drawLinearPath, rotate, catmullRomFitting, setStrokeLinecap, findElements, createMask, createRect, PlaitElement, getSelectedElements, getElementById, Path, Direction, PlaitNode, hasValidAngle, toViewBoxPoint, toHostPoint, rotatePoints, getRectangleByElements, getSelectionAngle, rotatedDataPoints, isAxisChangedByAngle, isSelectionMoving, drawRectangle, getRectangleByAngle, getSnapRectangles, getTripleAxis, getMinPointDelta, SNAP_TOLERANCE, drawPointSnapLines, drawSolidLines, isPointInPolygon, getNearestPointBetweenPointAndSegments, isPointInEllipse, getNearestPointBetweenPointAndEllipse, getEllipseTangentSlope, getVectorFromPointAndSlope, drawRoundRectangle, isPointInRoundRectangle, setPathStrokeLinecap, getCrossingPointsBetweenEllipseAndSegment, drawLine as drawLine$1, RgbaToHEX, getHitElementByPoint, preventTouchMove, WritableClipboardOperationType, createClipboardContext, WritableClipboardType, addClipboardContext, setAngleForG, CursorClass, temporaryDisableSelection, PRESS_AND_MOVE_BUFFER, isMainPointer, throttleRAF, getAngleBetweenPoints, normalizeAngle, degreesToRadians, rotateElements, MERGING, ROTATE_HANDLE_CLASS_NAME, SELECTION_RECTANGLE_CLASS_NAME, isSelectedElement, isDragging } from '@plait/core';
2
+ import { Alignment, WithTextPluginKey, ELEMENT_TO_TEXT_MANAGES, TextManage, getMemorizedLatest, memorizeLatest, RESIZE_HANDLE_DIAMETER, getPointOnPolyline, buildText, TRANSPARENT, getTextEditorsByElement, Generator, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, getPointByVectorComponent, measureElement, DEFAULT_FONT_FAMILY, getFirstTextManage, ActiveGenerator, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, getDirectionByVector, normalizeShapePoints, getFirstTextEditor, resetPointsAfterResize, getRectangleResizeHandleRefs, getRotatedResizeCursorClassByAngle, ROTATE_HANDLE_DISTANCE_TO_ELEMENT, ROTATE_HANDLE_SIZE, isCornerHandle, getIndexByResizeHandle, withResize, drawHandle, getSymmetricHandleIndex, getResizeHandlePointByIndex, getDirectionFactorByDirectionComponent, getCrossingPointsBetweenPointAndSegment, isPointOnSegment, getDirectionByPointOfRectangle, getDirectionFactor, rotateVector, getOppositeDirection, rotateVectorAnti90, getSourceAndTargetOuterRectangle, getNextPoint, PRIMARY_COLOR, CommonElementFlavour, canResize, drawPrimaryHandle, drawFillPrimaryHandle, isVirtualKey, isDelete, isSpaceHotkey, isDndMode, isDrawingMode, getElementsText, acceptImageTypes, getElementOfFocusedImage, buildImage, isResizingByCondition, getRatioByPoint, getTextManages, ImageGenerator, ResizeHandle, addRotating, removeRotating, drawRotateHandle } from '@plait/common';
4
3
  import { pointsOnBezierCurves } from 'points-on-curve';
4
+ import { TEXT_DEFAULT_HEIGHT, DEFAULT_FONT_SIZE, AlignEditor } from '@plait/text-plugins';
5
5
  import { isKeyHotkey } from 'is-hotkey';
6
- import { NgZone } from '@angular/core';
7
6
  import { Node } from 'slate';
8
7
 
9
8
  var BasicShapes;
@@ -57,15 +56,6 @@ var FlowchartSymbols;
57
56
  FlowchartSymbols["noteSquare"] = "noteSquare";
58
57
  FlowchartSymbols["display"] = "display";
59
58
  })(FlowchartSymbols || (FlowchartSymbols = {}));
60
- var TableSymbols;
61
- (function (TableSymbols) {
62
- TableSymbols["table"] = "table";
63
- })(TableSymbols || (TableSymbols = {}));
64
- var SwimlaneSymbols;
65
- (function (SwimlaneSymbols) {
66
- SwimlaneSymbols["swimlaneVertical"] = "swimlaneVertical";
67
- SwimlaneSymbols["swimlaneHorizontal"] = "swimlaneHorizontal";
68
- })(SwimlaneSymbols || (SwimlaneSymbols = {}));
69
59
  var UMLSymbols;
70
60
  (function (UMLSymbols) {
71
61
  UMLSymbols["actor"] = "actor";
@@ -81,8 +71,14 @@ var UMLSymbols;
81
71
  UMLSymbols["class"] = "class";
82
72
  UMLSymbols["interface"] = "interface";
83
73
  UMLSymbols["object"] = "object";
74
+ UMLSymbols["component"] = "component";
75
+ UMLSymbols["componentBox"] = "componentBox";
76
+ UMLSymbols["template"] = "template";
84
77
  UMLSymbols["activation"] = "activation";
85
78
  UMLSymbols["deletion"] = "deletion";
79
+ UMLSymbols["assembly"] = "assembly";
80
+ UMLSymbols["providedInterface"] = "providedInterface";
81
+ UMLSymbols["requiredInterface"] = "requiredInterface";
86
82
  })(UMLSymbols || (UMLSymbols = {}));
87
83
  var MultipleTextGeometryCommonTextKeys;
88
84
  (function (MultipleTextGeometryCommonTextKeys) {
@@ -91,6 +87,23 @@ var MultipleTextGeometryCommonTextKeys;
91
87
  })(MultipleTextGeometryCommonTextKeys || (MultipleTextGeometryCommonTextKeys = {}));
92
88
  const PlaitGeometry = {};
93
89
 
90
+ var SwimlaneSymbols;
91
+ (function (SwimlaneSymbols) {
92
+ SwimlaneSymbols["swimlaneVertical"] = "swimlaneVertical";
93
+ SwimlaneSymbols["swimlaneHorizontal"] = "swimlaneHorizontal";
94
+ })(SwimlaneSymbols || (SwimlaneSymbols = {}));
95
+ var SwimlaneDrawSymbols;
96
+ (function (SwimlaneDrawSymbols) {
97
+ SwimlaneDrawSymbols["swimlaneVertical"] = "swimlaneVertical";
98
+ SwimlaneDrawSymbols["swimlaneHorizontal"] = "swimlaneHorizontal";
99
+ SwimlaneDrawSymbols["swimlaneVerticalWithHeader"] = "swimlaneVerticalWithHeader";
100
+ SwimlaneDrawSymbols["swimlaneHorizontalWithHeader"] = "swimlaneHorizontalWithHeader";
101
+ })(SwimlaneDrawSymbols || (SwimlaneDrawSymbols = {}));
102
+
103
+ var TableSymbols;
104
+ (function (TableSymbols) {
105
+ TableSymbols["table"] = "table";
106
+ })(TableSymbols || (TableSymbols = {}));
94
107
  const PlaitTableElement = {
95
108
  isTable: (value) => {
96
109
  return value.type === 'table';
@@ -219,6 +232,10 @@ const DefaultObjectProperty = {
219
232
  width: 120,
220
233
  height: 60
221
234
  };
235
+ const DefaultComponentBoxProperty = {
236
+ width: 200,
237
+ height: 150
238
+ };
222
239
  const DefaultDeletionProperty = {
223
240
  width: 40,
224
241
  height: 40
@@ -227,6 +244,18 @@ const DefaultPortProperty = {
227
244
  width: 20,
228
245
  height: 20
229
246
  };
247
+ const DefaultRequiredInterfaceProperty = {
248
+ width: 70,
249
+ height: 56
250
+ };
251
+ const DefaultAssemblyProperty = {
252
+ width: 120,
253
+ height: 56
254
+ };
255
+ const DefaultProvidedInterfaceProperty = {
256
+ width: 70,
257
+ height: 34
258
+ };
230
259
  const DefaultCombinedFragmentProperty = {
231
260
  width: 400,
232
261
  height: 280,
@@ -269,14 +298,6 @@ const DefaultInterfaceProperty = {
269
298
  }
270
299
  ]
271
300
  };
272
- const DefaultSwimlaneVerticalProperty = {
273
- width: 450,
274
- height: 500
275
- };
276
- const DefaultSwimlaneHorizontalProperty = {
277
- width: 500,
278
- height: 450
279
- };
280
301
  const DefaultBasicShapePropertyMap = {
281
302
  [BasicShapes.pentagonArrow]: DefaultPentagonArrowProperty,
282
303
  [BasicShapes.processArrow]: DefaultPentagonArrowProperty,
@@ -325,17 +346,19 @@ const DefaultUMLPropertyMap = {
325
346
  [UMLSymbols.deletion]: DefaultDeletionProperty,
326
347
  [UMLSymbols.activityClass]: DefaultObjectProperty,
327
348
  [UMLSymbols.simpleClass]: DefaultObjectProperty,
349
+ [UMLSymbols.component]: DefaultMultiDocumentProperty,
350
+ [UMLSymbols.template]: DefaultMultiDocumentProperty,
351
+ [UMLSymbols.componentBox]: DefaultComponentBoxProperty,
328
352
  [UMLSymbols.port]: DefaultPortProperty,
329
- [UMLSymbols.branchMerge]: DefaultDeletionProperty
353
+ [UMLSymbols.branchMerge]: DefaultDeletionProperty,
354
+ [UMLSymbols.assembly]: DefaultAssemblyProperty,
355
+ [UMLSymbols.providedInterface]: DefaultProvidedInterfaceProperty,
356
+ [UMLSymbols.requiredInterface]: DefaultRequiredInterfaceProperty
330
357
  };
331
358
  const MultipleTextGeometryTextKeys = {
332
359
  [UMLSymbols.package]: Object.keys(MultipleTextGeometryCommonTextKeys),
333
360
  [UMLSymbols.combinedFragment]: Object.keys(MultipleTextGeometryCommonTextKeys)
334
361
  };
335
- const DefaultSwimlanePropertyMap = {
336
- [SwimlaneSymbols.swimlaneHorizontal]: DefaultSwimlaneHorizontalProperty,
337
- [SwimlaneSymbols.swimlaneVertical]: DefaultSwimlaneVerticalProperty
338
- };
339
362
  const LINE_HIT_GEOMETRY_BUFFER = 10;
340
363
  const LINE_SNAPPING_BUFFER = 6;
341
364
  const LINE_SNAPPING_CONNECTOR_BUFFER = 8;
@@ -345,7 +368,10 @@ const GEOMETRY_WITHOUT_TEXT = [
345
368
  UMLSymbols.activation,
346
369
  UMLSymbols.deletion,
347
370
  UMLSymbols.port,
348
- UMLSymbols.branchMerge
371
+ UMLSymbols.branchMerge,
372
+ UMLSymbols.assembly,
373
+ UMLSymbols.providedInterface,
374
+ UMLSymbols.requiredInterface
349
375
  ];
350
376
  const GEOMETRY_WITH_MULTIPLE_TEXT = [UMLSymbols.package, UMLSymbols.combinedFragment];
351
377
 
@@ -353,7 +379,7 @@ const getGeometryPointers = () => {
353
379
  return [...Object.keys(BasicShapes), ...Object.keys(FlowchartSymbols), ...Object.keys(UMLSymbols)];
354
380
  };
355
381
  const getSwimlanePointers = () => {
356
- return Object.keys(SwimlaneSymbols);
382
+ return Object.keys(SwimlaneDrawSymbols);
357
383
  };
358
384
  const getBasicPointers = () => {
359
385
  return Object.keys(BasicShapes);
@@ -397,7 +423,31 @@ const DrawThemeColors = {
397
423
  }
398
424
  };
399
425
 
400
- const DEFAULT_TEXT_HEIGHT = 20;
426
+ const SWIMLANE_HEADER_SIZE = 42;
427
+ const DefaultSwimlaneVerticalWithHeaderProperty = {
428
+ width: 580,
429
+ height: 524
430
+ };
431
+ const DefaultSwimlaneHorizontalWithHeaderProperty = {
432
+ width: 524,
433
+ height: 580
434
+ };
435
+ const DefaultSwimlaneVerticalProperty = {
436
+ width: 580,
437
+ height: 524
438
+ };
439
+ const DefaultSwimlaneHorizontalProperty = {
440
+ width: 524,
441
+ height: 580
442
+ };
443
+ const DefaultSwimlanePropertyMap = {
444
+ [SwimlaneDrawSymbols.swimlaneHorizontal]: DefaultSwimlaneHorizontalProperty,
445
+ [SwimlaneDrawSymbols.swimlaneVertical]: DefaultSwimlaneVerticalProperty,
446
+ [SwimlaneDrawSymbols.swimlaneHorizontalWithHeader]: DefaultSwimlaneHorizontalWithHeaderProperty,
447
+ [SwimlaneDrawSymbols.swimlaneVerticalWithHeader]: DefaultSwimlaneVerticalWithHeaderProperty
448
+ };
449
+
450
+ const MIN_TEXT_WIDTH = 5;
401
451
 
402
452
  const getElementShape = (value) => {
403
453
  if (PlaitDrawElement.isImage(value)) {
@@ -423,15 +473,15 @@ class TextGenerator {
423
473
  get shape() {
424
474
  return this.element.shape || this.element.type;
425
475
  }
426
- constructor(board, element, texts, viewContainerRef, options) {
476
+ constructor(board, element, texts, options) {
427
477
  this.board = board;
428
478
  this.texts = texts;
429
479
  this.element = element;
430
- this.viewContainerRef = viewContainerRef;
431
480
  this.options = options;
432
481
  }
433
482
  initialize() {
434
- const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
483
+ const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {})
484
+ .textPlugins;
435
485
  this.textManages = this.texts.map(text => {
436
486
  const textManage = this.createTextManage(text, textPlugins);
437
487
  setTextManage(getTextKey(this.element, text), textManage);
@@ -454,7 +504,8 @@ class TextGenerator {
454
504
  this.element = element;
455
505
  ELEMENT_TO_TEXT_MANAGES.set(this.element, this.textManages);
456
506
  const centerPoint = RectangleClient.getCenterPoint(this.board.getRectangle(this.element));
457
- const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
507
+ const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {})
508
+ .textPlugins;
458
509
  const removedTexts = previousDrawShapeTexts.filter(value => {
459
510
  return !currentDrawShapeTexts.find(item => item.key === value.key);
460
511
  });
@@ -488,12 +539,12 @@ class TextGenerator {
488
539
  });
489
540
  }
490
541
  createTextManage(text, textPlugins) {
491
- const textManage = new TextManage(this.board, this.viewContainerRef, {
542
+ const textManage = new TextManage(this.board, {
492
543
  getRectangle: () => {
493
544
  return this.getRectangle(text);
494
545
  },
495
- onValueChangeHandle: (textManageRef) => {
496
- return this.onValueChangeHandle(textManageRef, text);
546
+ onChange: (data) => {
547
+ return this.options.onChange(this.element, data, text);
497
548
  },
498
549
  getMaxWidth: () => {
499
550
  return this.getMaxWidth(text);
@@ -512,9 +563,6 @@ class TextGenerator {
512
563
  }
513
564
  return getTextRectangle(this.element);
514
565
  }
515
- onValueChangeHandle(textManageRef, text) {
516
- return this.options.onValueChangeHandle(this.element, textManageRef, text);
517
- }
518
566
  getMaxWidth(text) {
519
567
  return this.options.getMaxWidth ? this.options.getMaxWidth() : this.getRectangle(text).width;
520
568
  }
@@ -651,6 +699,29 @@ function updateCellIds(cells) {
651
699
  function isCellIncludeText(cell) {
652
700
  return cell.text && cell.textHeight;
653
701
  }
702
+ function getCellsRectangle(board, element, cells) {
703
+ const cellsWithPoints = getCellsWithPoints(board, element);
704
+ const points = cells.map(cell => {
705
+ const cellWithPoints = cellsWithPoints.find(item => item.id === cell.id);
706
+ return cellWithPoints.points;
707
+ });
708
+ return RectangleClient.getRectangleByPoints(points);
709
+ }
710
+ const createCell = (rowId, columnId, text = null) => {
711
+ const cell = {
712
+ id: idCreator(),
713
+ rowId,
714
+ columnId
715
+ };
716
+ if (text !== null) {
717
+ cell['textHeight'] = TEXT_DEFAULT_HEIGHT;
718
+ cell['text'] = {
719
+ children: [{ text }],
720
+ align: Alignment.center
721
+ };
722
+ }
723
+ return cell;
724
+ };
654
725
 
655
726
  const SHAPE_MAX_LENGTH = 6;
656
727
  const memorizedShape = new WeakMap();
@@ -983,7 +1054,7 @@ const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
983
1054
  const isHitElementInside = (board, element, point) => {
984
1055
  const rectangle = board.getRectangle(element);
985
1056
  point = rotateAntiPointsByElement(point, element) || point;
986
- if (PlaitDrawElement.isGeometry(element)) {
1057
+ if (PlaitDrawElement.isGeometry(element) && !PlaitDrawElement.isGeometryByTable(element)) {
987
1058
  const engine = getEngine(getElementShape(element));
988
1059
  const isHitInside = engine.isInsidePoint(rectangle, point);
989
1060
  if (isHitInside) {
@@ -1046,7 +1117,7 @@ const isDrawElementIncludeText = (element) => {
1046
1117
  const editors = getTextEditorsByElement(element);
1047
1118
  return editors.length > 0;
1048
1119
  }
1049
- if (PlaitDrawElement.isTable(element)) {
1120
+ if (PlaitDrawElement.isElementByTable(element)) {
1050
1121
  return element.cells.some(cell => isCellIncludeText(cell));
1051
1122
  }
1052
1123
  return true;
@@ -1098,7 +1169,7 @@ const drawBoundReaction = (board, element, roughOptions = { hasMask: true, hasCo
1098
1169
  const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
1099
1170
  const shape = getElementShape(element);
1100
1171
  let drawOptions = {};
1101
- if (PlaitDrawElement.isTable(element)) {
1172
+ if (PlaitDrawElement.isElementByTable(element)) {
1102
1173
  drawOptions = { element };
1103
1174
  }
1104
1175
  const strokeG = drawShape(board, activeRectangle, shape, {
@@ -1137,7 +1208,7 @@ const getTextKey = (element, text) => {
1137
1208
  return text.key;
1138
1209
  }
1139
1210
  };
1140
- const getGeometryAlign = (element) => {
1211
+ const getGeometryAlign = (board, element) => {
1141
1212
  if (isMultipleTextGeometry(element)) {
1142
1213
  const drawShapeText = element.texts.find(item => item.key.includes(MultipleTextGeometryCommonTextKeys.content));
1143
1214
  return drawShapeText?.text.align || Alignment.center;
@@ -1145,7 +1216,7 @@ const getGeometryAlign = (element) => {
1145
1216
  if (isSingleTextGeometry(element)) {
1146
1217
  return element.text?.align || Alignment.center;
1147
1218
  }
1148
- if (PlaitDrawElement.isTable(element)) {
1219
+ if (PlaitDrawElement.isElementByTable(element)) {
1149
1220
  const firstTextCell = element.cells.find(item => item.text);
1150
1221
  return firstTextCell?.text?.align || Alignment.center;
1151
1222
  }
@@ -1188,6 +1259,7 @@ const LINE_AUTO_COMPLETE_OPACITY = 0.6;
1188
1259
  const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
1189
1260
  const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
1190
1261
  const LINE_ALIGN_TOLERANCE = 3;
1262
+ const LINE_TEXT = '文本';
1191
1263
 
1192
1264
  class LineShapeGenerator extends Generator {
1193
1265
  canDraw(element, data) {
@@ -1869,7 +1941,7 @@ const createUMLClassOrInterfaceGeometryElement = (board, shape, points) => {
1869
1941
  const memorizedLatest = getMemorizedLatestByPointer(shape);
1870
1942
  const element = {
1871
1943
  id: idCreator(),
1872
- type: 'table',
1944
+ type: 'geometry',
1873
1945
  angle: 0,
1874
1946
  opacity: 1,
1875
1947
  points,
@@ -2095,7 +2167,7 @@ const getFlowchartDefaultFill = (theme) => {
2095
2167
  };
2096
2168
  const getTextShapeProperty = (board, text = DefaultTextProperty.text, fontSize) => {
2097
2169
  fontSize = fontSize ? Number(fontSize) : DEFAULT_FONT_SIZE;
2098
- const textSize = getTextSize(board, text, Infinity, { fontSize });
2170
+ const textSize = measureElement(buildText(text), { fontSize, fontFamily: DEFAULT_FONT_FAMILY });
2099
2171
  return {
2100
2172
  width: textSize.width + ShapeDefaultSpace.rectangleAndText * 2,
2101
2173
  height: textSize.height
@@ -2304,13 +2376,9 @@ const isSingleSelectSwimlane = (board) => {
2304
2376
  const selectedElements = getSelectedElements(board);
2305
2377
  return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isSwimlane(selectedElements[0]);
2306
2378
  };
2307
- const isSingleSelectTable = (board) => {
2379
+ const getSelectedSwimlane = (board) => {
2308
2380
  const selectedElements = getSelectedElements(board);
2309
- return selectedElements && selectedElements.length === 1 && PlaitTableElement.isTable(selectedElements[0]);
2310
- };
2311
- const getSelectedTableElements = (board, elements) => {
2312
- const selectedElements = elements?.length ? elements : getSelectedElements(board);
2313
- return selectedElements.filter(value => PlaitTableElement.isTable(value));
2381
+ return selectedElements.find(item => PlaitDrawElement.isSwimlane(item));
2314
2382
  };
2315
2383
 
2316
2384
  const resizeLine = (board, options, path) => {
@@ -2472,23 +2540,24 @@ const normalizePoints = (board, element, width, textHeight) => {
2472
2540
  let autoSize = element.autoSize;
2473
2541
  const defaultSpace = ShapeDefaultSpace.rectangleAndText;
2474
2542
  if (autoSize) {
2543
+ const newWidth = width < MIN_TEXT_WIDTH ? MIN_TEXT_WIDTH : width;
2475
2544
  const editor = getFirstTextEditor(element);
2476
2545
  if (AlignEditor.isActive(editor, Alignment.right)) {
2477
2546
  points = [
2478
- [points[1][0] - (width + defaultSpace * 2), points[0][1]],
2547
+ [points[1][0] - (newWidth + defaultSpace * 2), points[0][1]],
2479
2548
  [points[1][0], points[0][1] + textHeight]
2480
2549
  ];
2481
2550
  }
2482
2551
  else if (AlignEditor.isActive(editor, Alignment.center)) {
2483
2552
  const oldWidth = Math.abs(points[0][0] - points[1][0]);
2484
- const offset = (width - oldWidth) / 2;
2553
+ const offset = (newWidth - oldWidth) / 2;
2485
2554
  points = [
2486
2555
  [points[0][0] - offset - defaultSpace, points[0][1]],
2487
2556
  [points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
2488
2557
  ];
2489
2558
  }
2490
2559
  else {
2491
- points = [points[0], [points[0][0] + width + defaultSpace * 2, points[0][1] + textHeight]];
2560
+ points = [points[0], [points[0][0] + newWidth + defaultSpace * 2, points[0][1] + textHeight]];
2492
2561
  }
2493
2562
  if (hasValidAngle(element)) {
2494
2563
  points = resetPointsAfterResize(RectangleClient.getRectangleByPoints(element.points), RectangleClient.getRectangleByPoints(points), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(element.points)), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(points)), element.angle);
@@ -2522,8 +2591,8 @@ const setTextSize = (board, element, textWidth, textHeight) => {
2522
2591
 
2523
2592
  const insertImage = (board, imageItem, startPoint) => {
2524
2593
  const { width, height, url } = imageItem;
2525
- const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
2526
- const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
2594
+ const viewportWidth = PlaitBoard.getBoardContainer(board).clientWidth;
2595
+ const viewportHeight = PlaitBoard.getBoardContainer(board).clientHeight;
2527
2596
  const point = toViewBoxPoint(board, toHostPoint(board, viewportWidth / 2, viewportHeight / 2));
2528
2597
  const points = startPoint
2529
2598
  ? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
@@ -2541,69 +2610,241 @@ const insertImage = (board, imageItem, startPoint) => {
2541
2610
  Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
2542
2611
  };
2543
2612
 
2544
- const addSwimlaneRow = (board, swimlane, index) => {
2545
- if (PlaitDrawElement.isSwimlane(swimlane) && swimlane.shape === SwimlaneSymbols.swimlaneHorizontal) {
2613
+ function buildSwimlaneTable(element) {
2614
+ const swimlaneElement = { ...element };
2615
+ if (PlaitDrawElement.isHorizontalSwimlane(element)) {
2616
+ swimlaneElement.cells = element.cells.map((item, index) => {
2617
+ if (index === 0 && element.header) {
2618
+ item = {
2619
+ ...element.cells[0],
2620
+ rowspan: element.rows.length
2621
+ };
2622
+ }
2623
+ if (item.text && item.textHeight && !item.text.direction) {
2624
+ item = {
2625
+ ...item,
2626
+ text: {
2627
+ ...item.text,
2628
+ direction: 'vertical'
2629
+ }
2630
+ };
2631
+ }
2632
+ return item;
2633
+ });
2634
+ return swimlaneElement;
2635
+ }
2636
+ if (element.header) {
2637
+ swimlaneElement.cells = [
2638
+ {
2639
+ ...element.cells[0],
2640
+ colspan: element.columns.length
2641
+ },
2642
+ ...element.cells.slice(1, element.cells.length)
2643
+ ];
2644
+ }
2645
+ return swimlaneElement;
2646
+ }
2647
+ const getDefaultSwimlanePoints = (pointer, centerPoint) => {
2648
+ const property = DefaultSwimlanePropertyMap[pointer];
2649
+ return RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(centerPoint, property.width, property.height));
2650
+ };
2651
+ const createDefaultSwimlane = (shape, points) => {
2652
+ const header = isSwimlaneWithHeader(shape);
2653
+ const dataShape = adjustSwimlaneShape(shape);
2654
+ const rows = createDefaultRowsOrColumns(dataShape, 'row', header);
2655
+ const columns = createDefaultRowsOrColumns(dataShape, 'column', header);
2656
+ const swimlane = {
2657
+ id: idCreator(),
2658
+ type: 'swimlane',
2659
+ shape: dataShape,
2660
+ points,
2661
+ rows,
2662
+ columns,
2663
+ header,
2664
+ cells: createDefaultCells(dataShape, rows, columns, header)
2665
+ };
2666
+ return swimlane;
2667
+ };
2668
+ const createDefaultRowsOrColumns = (shape, type, header) => {
2669
+ const createItems = (count) => new Array(count).fill('').map(() => ({ id: idCreator() }));
2670
+ let data = createItems(3);
2671
+ if ((type === 'row' && shape === SwimlaneSymbols.swimlaneVertical) ||
2672
+ (type === 'column' && shape === SwimlaneSymbols.swimlaneHorizontal)) {
2673
+ data = header ? data : createItems(2);
2674
+ const dimension = type === 'row' ? 'height' : 'width';
2675
+ data = data.map((item, index) => {
2676
+ if (index === 0 || (index === 1 && header)) {
2677
+ return {
2678
+ ...item,
2679
+ [dimension]: SWIMLANE_HEADER_SIZE
2680
+ };
2681
+ }
2682
+ return item;
2683
+ });
2684
+ }
2685
+ return data;
2686
+ };
2687
+ const createDefaultCells = (shape, rows, columns, header) => {
2688
+ let headerCell = [];
2689
+ let startIndex = 0;
2690
+ if (header) {
2691
+ headerCell = [createCell(rows[0].id, columns[0].id, 'New Swimlane')];
2692
+ startIndex = 1;
2693
+ }
2694
+ const cells = new Array(6).fill('').map((_, index) => {
2695
+ if (index < 3) {
2696
+ const rowId = shape === SwimlaneSymbols.swimlaneVertical ? rows[startIndex].id : rows[index].id;
2697
+ const columnId = shape === SwimlaneSymbols.swimlaneVertical ? columns[index].id : columns[startIndex].id;
2698
+ return createCell(rowId, columnId, 'Lane');
2699
+ }
2700
+ const rowId = shape === SwimlaneSymbols.swimlaneVertical ? rows[startIndex + 1].id : rows[index - 3].id;
2701
+ const columnId = shape === SwimlaneSymbols.swimlaneVertical ? columns[index - 3].id : columns[startIndex + 1].id;
2702
+ return createCell(rowId, columnId);
2703
+ });
2704
+ return [...headerCell, ...cells];
2705
+ };
2706
+ const getSwimlaneCount = (swimlane) => {
2707
+ if (PlaitDrawElement.isHorizontalSwimlane(swimlane)) {
2708
+ return swimlane.rows.length;
2709
+ }
2710
+ if (PlaitDrawElement.isVerticalSwimlane(swimlane)) {
2711
+ return swimlane.columns.length;
2712
+ }
2713
+ return 0;
2714
+ };
2715
+ const isSwimlaneWithHeader = (shape) => {
2716
+ return [SwimlaneDrawSymbols.swimlaneHorizontalWithHeader, SwimlaneDrawSymbols.swimlaneVerticalWithHeader].includes(shape);
2717
+ };
2718
+ const adjustSwimlaneShape = (shape) => {
2719
+ return [SwimlaneDrawSymbols.swimlaneHorizontalWithHeader, SwimlaneDrawSymbols.swimlaneHorizontal].includes(shape)
2720
+ ? SwimlaneSymbols.swimlaneHorizontal
2721
+ : SwimlaneSymbols.swimlaneVertical;
2722
+ };
2723
+
2724
+ const updateSwimlaneCount = (board, swimlane, count) => {
2725
+ if (count > 0 && PlaitDrawElement.isSwimlane(swimlane)) {
2726
+ const currentCount = getSwimlaneCount(swimlane);
2727
+ if (PlaitDrawElement.isHorizontalSwimlane(swimlane)) {
2728
+ if (count > currentCount) {
2729
+ addSwimlaneRow(board, swimlane, swimlane.rows.length, count - currentCount);
2730
+ }
2731
+ else {
2732
+ const deleteIndex = swimlane.rows.length - (currentCount - count);
2733
+ removeSwimlaneRow(board, swimlane, deleteIndex, currentCount - count);
2734
+ }
2735
+ }
2736
+ if (PlaitDrawElement.isVerticalSwimlane(swimlane)) {
2737
+ if (count > currentCount) {
2738
+ addSwimlaneColumn(board, swimlane, swimlane.columns.length, count - currentCount);
2739
+ }
2740
+ else {
2741
+ const deleteIndex = swimlane.columns.length - (currentCount - count);
2742
+ removeSwimlaneColumn(board, swimlane, deleteIndex, currentCount - count);
2743
+ }
2744
+ }
2745
+ }
2746
+ };
2747
+ const addSwimlaneRow = (board, swimlane, index, count = 1) => {
2748
+ if (PlaitDrawElement.isHorizontalSwimlane(swimlane)) {
2546
2749
  const newRows = [...swimlane.rows];
2547
- const newRowId = idCreator();
2548
- newRows.splice(index, 0, { id: newRowId });
2549
- const newCells = [...swimlane.cells, ...createNewSwimlaneCells(swimlane, newRowId, 'column')];
2750
+ const addRows = [];
2751
+ for (let i = 0; i < count; i++) {
2752
+ addRows.push({ id: idCreator() });
2753
+ }
2754
+ newRows.splice(index, 0, ...addRows);
2755
+ const newCells = [...swimlane.cells];
2756
+ addRows.forEach(item => {
2757
+ newCells.push(...createNewSwimlaneCells(swimlane, item.id, 'column'));
2758
+ });
2550
2759
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2551
2760
  const lastRowHeight = RectangleClient.getRectangleByPoints(lastCellPoints).height;
2552
- const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] + lastRowHeight]];
2761
+ const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] + lastRowHeight * count]];
2553
2762
  updateSwimlane(board, swimlane, swimlane.columns, newRows, newCells, newPoints);
2554
2763
  }
2555
2764
  };
2556
- const addSwimlaneColumn = (board, swimlane, index) => {
2557
- if (PlaitDrawElement.isSwimlane(swimlane) && swimlane.shape === SwimlaneSymbols.swimlaneVertical) {
2765
+ const addSwimlaneColumn = (board, swimlane, index, count = 1) => {
2766
+ if (PlaitDrawElement.isVerticalSwimlane(swimlane)) {
2558
2767
  const newColumns = [...swimlane.columns];
2559
- const newColumnId = idCreator();
2560
- newColumns.splice(index, 0, { id: newColumnId });
2561
- const newCells = [...swimlane.cells, ...createNewSwimlaneCells(swimlane, newColumnId, 'row')];
2768
+ const addColumns = [];
2769
+ for (let i = 0; i < count; i++) {
2770
+ addColumns.push({ id: idCreator() });
2771
+ }
2772
+ newColumns.splice(index, 0, ...addColumns);
2773
+ const newCells = [...swimlane.cells];
2774
+ addColumns.forEach(item => {
2775
+ newCells.push(...createNewSwimlaneCells(swimlane, item.id, 'row'));
2776
+ });
2562
2777
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2563
2778
  const lastColumnWidth = RectangleClient.getRectangleByPoints(lastCellPoints).width;
2564
- const newPoints = [swimlane.points[0], [swimlane.points[1][0] + lastColumnWidth, swimlane.points[1][1]]];
2779
+ const newPoints = [swimlane.points[0], [swimlane.points[1][0] + lastColumnWidth * count, swimlane.points[1][1]]];
2565
2780
  updateSwimlane(board, swimlane, newColumns, swimlane.rows, newCells, newPoints);
2566
2781
  }
2567
2782
  };
2568
- const removeSwimlaneRow = (board, swimlane, index) => {
2569
- if (PlaitDrawElement.isSwimlane(swimlane) && swimlane.shape === SwimlaneSymbols.swimlaneHorizontal) {
2783
+ const removeSwimlaneRow = (board, swimlane, index, count = 1) => {
2784
+ if (PlaitDrawElement.isHorizontalSwimlane(swimlane)) {
2785
+ if (count > swimlane.rows.length) {
2786
+ return;
2787
+ }
2570
2788
  const newRows = [...swimlane.rows];
2571
- newRows.splice(index, 1);
2789
+ newRows.splice(index, count);
2572
2790
  if (newRows.length === 0) {
2573
2791
  const path = PlaitBoard.findPath(board, swimlane);
2574
2792
  Transforms.removeNode(board, path);
2575
2793
  }
2576
2794
  else {
2577
- const removeRow = swimlane.rows[index];
2578
- const newCells = swimlane.cells.filter(item => item.rowId !== removeRow.id);
2579
- let removeRowHeight = removeRow.height;
2580
- if (!removeRowHeight) {
2581
- const rowCell = swimlane.cells.find(item => item.rowId === removeRow.id);
2582
- const cellPoints = getCellWithPoints(board, swimlane, rowCell.id).points;
2583
- removeRowHeight = RectangleClient.getRectangleByPoints(cellPoints).height;
2795
+ let newCells = [...swimlane.cells];
2796
+ const removeRows = [];
2797
+ for (let i = index; i < count + index; i++) {
2798
+ const removeRow = swimlane.rows[i];
2799
+ removeRows.push(removeRow);
2800
+ newCells = newCells.filter(item => item.rowId !== removeRow.id);
2584
2801
  }
2802
+ let removeRowHeight = 0;
2803
+ removeRows.forEach(row => {
2804
+ if (!row.height) {
2805
+ const rowCell = swimlane.cells.find(item => item.rowId === row.id);
2806
+ const cellPoints = getCellWithPoints(board, swimlane, rowCell.id).points;
2807
+ removeRowHeight += RectangleClient.getRectangleByPoints(cellPoints).height;
2808
+ }
2809
+ else {
2810
+ removeRowHeight += row.height;
2811
+ }
2812
+ });
2585
2813
  const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] - removeRowHeight]];
2586
2814
  updateSwimlane(board, swimlane, swimlane.columns, newRows, newCells, newPoints);
2587
2815
  }
2588
2816
  }
2589
2817
  };
2590
- const removeSwimlaneColumn = (board, swimlane, index) => {
2591
- if (PlaitDrawElement.isSwimlane(swimlane) && swimlane.shape === SwimlaneSymbols.swimlaneVertical) {
2818
+ const removeSwimlaneColumn = (board, swimlane, index, count = 1) => {
2819
+ if (PlaitDrawElement.isVerticalSwimlane(swimlane)) {
2820
+ if (count > swimlane.columns.length) {
2821
+ return;
2822
+ }
2592
2823
  const newColumns = [...swimlane.columns];
2593
- newColumns.splice(index, 1);
2824
+ newColumns.splice(index, count);
2594
2825
  if (newColumns.length === 0) {
2595
2826
  const path = PlaitBoard.findPath(board, swimlane);
2596
2827
  Transforms.removeNode(board, path);
2597
2828
  }
2598
2829
  else {
2599
- const removeColumn = swimlane.columns[index];
2600
- const newCells = swimlane.cells.filter(item => item.columnId !== removeColumn.id);
2601
- let removeColumnWidth = removeColumn.width;
2602
- if (!removeColumnWidth) {
2603
- const columnCell = swimlane.cells.find(item => item.columnId === removeColumn.id);
2604
- const cellPoints = getCellWithPoints(board, swimlane, columnCell.id).points;
2605
- removeColumnWidth = RectangleClient.getRectangleByPoints(cellPoints).width;
2830
+ let newCells = [...swimlane.cells];
2831
+ const removeColumns = [];
2832
+ for (let i = index; i < count + index; i++) {
2833
+ const removeColumn = swimlane.columns[i];
2834
+ removeColumns.push(removeColumn);
2835
+ newCells = newCells.filter(item => item.columnId !== removeColumn.id);
2606
2836
  }
2837
+ let removeColumnWidth = 0;
2838
+ removeColumns.forEach(column => {
2839
+ if (!column.width) {
2840
+ const rowCell = swimlane.cells.find(item => item.columnId === column.id);
2841
+ const cellPoints = getCellWithPoints(board, swimlane, rowCell.id).points;
2842
+ removeColumnWidth += RectangleClient.getRectangleByPoints(cellPoints).width;
2843
+ }
2844
+ else {
2845
+ removeColumnWidth += column.width;
2846
+ }
2847
+ });
2607
2848
  const newPoints = [swimlane.points[0], [swimlane.points[1][0] - removeColumnWidth, swimlane.points[1][1]]];
2608
2849
  updateSwimlane(board, swimlane, newColumns, swimlane.rows, newCells, newPoints);
2609
2850
  }
@@ -2615,11 +2856,13 @@ const createNewSwimlaneCells = (swimlane, newId, type) => {
2615
2856
  rowId: type === 'row' ? item.id : newId,
2616
2857
  columnId: type === 'row' ? newId : item.id
2617
2858
  }));
2618
- cells.shift();
2859
+ if (swimlane.header) {
2860
+ cells.shift();
2861
+ }
2619
2862
  cells[0] = {
2620
2863
  ...cells[0],
2621
2864
  text: {
2622
- children: [{ text: 'Lane' }],
2865
+ children: [{ text: swimlane.header ? 'Lane' : 'New Swimlane' }],
2623
2866
  align: Alignment.center,
2624
2867
  direction: type === 'row' ? undefined : 'vertical'
2625
2868
  },
@@ -2636,6 +2879,33 @@ const updateSwimlane = (board, swimlane, newColumns, newRows, newCells, newPoint
2636
2879
  points: newPoints
2637
2880
  }, path);
2638
2881
  };
2882
+ const setSwimlaneFill = (board, element, fill, path) => {
2883
+ const selectedCells = getSelectedCells(element);
2884
+ let newCells = element.cells;
2885
+ if (selectedCells?.length) {
2886
+ newCells = element.cells.map(cell => {
2887
+ if (selectedCells.map(item => item.id).includes(cell.id)) {
2888
+ return {
2889
+ ...cell,
2890
+ fill
2891
+ };
2892
+ }
2893
+ return cell;
2894
+ });
2895
+ }
2896
+ else {
2897
+ newCells = element.cells.map(cell => {
2898
+ if (cell.text && cell.textHeight) {
2899
+ return {
2900
+ ...cell,
2901
+ fill
2902
+ };
2903
+ }
2904
+ return cell;
2905
+ });
2906
+ }
2907
+ Transforms.setNode(board, { cells: newCells }, path);
2908
+ };
2639
2909
 
2640
2910
  const setDrawShapeText = (board, element, text) => {
2641
2911
  const newTexts = element.texts?.map(item => {
@@ -2711,7 +2981,9 @@ const DrawTransforms = {
2711
2981
  addSwimlaneRow,
2712
2982
  addSwimlaneColumn,
2713
2983
  removeSwimlaneRow,
2714
- removeSwimlaneColumn
2984
+ removeSwimlaneColumn,
2985
+ setSwimlaneFill,
2986
+ updateSwimlaneCount
2715
2987
  };
2716
2988
 
2717
2989
  const getHitRectangleResizeHandleRef = (board, rectangle, point, angle = 0) => {
@@ -3168,6 +3440,29 @@ function drawIsometricSnapLines(board, activePoints, snapRectangles, resizeSnapO
3168
3440
  return drawSolidLines(board, isometricLines);
3169
3441
  }
3170
3442
 
3443
+ const isSingleSelectTable = (board) => {
3444
+ const selectedElements = getSelectedElements(board);
3445
+ return selectedElements && selectedElements.length === 1 && PlaitTableElement.isTable(selectedElements[0]);
3446
+ };
3447
+ const isSingleSelectElementByTable = (board) => {
3448
+ const selectedElements = getSelectedElements(board);
3449
+ return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isElementByTable(selectedElements[0]);
3450
+ };
3451
+ const getSelectedTableElements = (board, elements) => {
3452
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
3453
+ return selectedElements.filter(value => PlaitTableElement.isTable(value));
3454
+ };
3455
+ const SELECTED_CELLS = new WeakMap();
3456
+ function getSelectedCells(element) {
3457
+ return SELECTED_CELLS.get(element);
3458
+ }
3459
+ function setSelectedCells(element, cells) {
3460
+ return SELECTED_CELLS.set(element, cells);
3461
+ }
3462
+ function clearSelectedCells(element) {
3463
+ return SELECTED_CELLS.delete(element);
3464
+ }
3465
+
3171
3466
  const getCenterPointsOnPolygon = (points) => {
3172
3467
  const centerPoints = [];
3173
3468
  for (let i = 0; i < points.length; i++) {
@@ -4936,9 +5231,15 @@ const TableEngine = {
4936
5231
  pointCells.forEach(cell => {
4937
5232
  const rectangle = RectangleClient.getRectangleByPoints(cell.points);
4938
5233
  const { x, y, width, height } = rectangle;
5234
+ const cellRectangle = drawRectangle(board, {
5235
+ x: x + ACTIVE_STROKE_WIDTH,
5236
+ y: y + ACTIVE_STROKE_WIDTH,
5237
+ width: width - ACTIVE_STROKE_WIDTH * 2,
5238
+ height: height - ACTIVE_STROKE_WIDTH * 2
5239
+ }, { fill: cell.fill, fillStyle: 'solid', strokeWidth: 0 });
4939
5240
  const cellRightBorder = drawLine$1(rs, [x + width, y], [x + width, y + height], roughOptions);
4940
5241
  const cellBottomBorder = drawLine$1(rs, [x, y + height], [x + width, y + height], roughOptions);
4941
- g.append(cellRightBorder, cellBottomBorder);
5242
+ g.append(cellRectangle, cellRightBorder, cellBottomBorder);
4942
5243
  });
4943
5244
  setStrokeLinecap(g, 'round');
4944
5245
  return g;
@@ -5382,6 +5683,300 @@ const NoteEngine = {
5382
5683
  }
5383
5684
  };
5384
5685
 
5686
+ const AssemblyEngine = {
5687
+ draw(board, rectangle, options) {
5688
+ const rs = PlaitBoard.getRoughSVG(board);
5689
+ const shape = rs.path(`
5690
+ M${rectangle.x} ${rectangle.y + rectangle.height / 2}
5691
+ H${rectangle.x + rectangle.width * 0.3}
5692
+ A${rectangle.width * 0.13} ${rectangle.height * 0.285}, 0, 1, 1 ${rectangle.x +
5693
+ rectangle.width * 0.3 +
5694
+ rectangle.width * 0.26} ${rectangle.y + rectangle.height / 2}
5695
+ A${rectangle.width * 0.13} ${rectangle.height * 0.285}, 0, 1, 1 ${rectangle.x + rectangle.width * 0.3} ${rectangle.y +
5696
+ rectangle.height / 2}
5697
+ M${rectangle.x + rectangle.width * 0.3 + rectangle.width * 0.13} ${rectangle.y}
5698
+ A${rectangle.width * 0.233} ${rectangle.height / 2}, 0, 0, 1 ${rectangle.x +
5699
+ rectangle.width * 0.3 +
5700
+ rectangle.width * 0.13} ${rectangle.y + rectangle.height}
5701
+ M${rectangle.x + rectangle.width * 0.3 + rectangle.width * 0.13 + rectangle.width * 0.233} ${rectangle.y +
5702
+ rectangle.height / 2} H${rectangle.x + rectangle.width}
5703
+ `, {
5704
+ ...options,
5705
+ fillStyle: 'solid'
5706
+ });
5707
+ setStrokeLinecap(shape, 'round');
5708
+ return shape;
5709
+ },
5710
+ isInsidePoint(rectangle, point) {
5711
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5712
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5713
+ },
5714
+ getCornerPoints(rectangle) {
5715
+ return RectangleClient.getCornerPoints(rectangle);
5716
+ },
5717
+ getConnectorPoints(rectangle) {
5718
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5719
+ },
5720
+ getNearestPoint(rectangle, point) {
5721
+ const nearestPoint = getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5722
+ if (nearestPoint[0] === rectangle.x + rectangle.width / 2) {
5723
+ return getNearestPointBetweenPointAndEllipse(point, [rectangle.x + rectangle.width * 0.43, rectangle.y + rectangle.height / 2], rectangle.width * 0.223, rectangle.height / 2);
5724
+ }
5725
+ return nearestPoint;
5726
+ },
5727
+ getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
5728
+ const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5729
+ if (connectionPoint[0] > rectangle.x + rectangle.width * 0.43 && connectionPoint[1] < rectangle.y + rectangle.height / 2) {
5730
+ return rotateVector(getUnitVectorByPointAndPoint(connectionPoint, [rectangle.x, rectangle.y + rectangle.height / 2]), -Math.PI);
5731
+ }
5732
+ if (connectionPoint[0] > rectangle.x + rectangle.width * 0.43 && connectionPoint[1] > rectangle.y + rectangle.height / 2) {
5733
+ return getUnitVectorByPointAndPoint(connectionPoint, [rectangle.x, rectangle.y + rectangle.height / 2]);
5734
+ }
5735
+ return getUnitVectorByPointAndPoint(connectionPoint, [rectangle.x, rectangle.y + rectangle.height / 2]);
5736
+ }
5737
+ };
5738
+
5739
+ const RequiredInterfaceEngine = {
5740
+ draw(board, rectangle, options) {
5741
+ const rs = PlaitBoard.getRoughSVG(board);
5742
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y}
5743
+ A${rectangle.width * 0.39} ${rectangle.height / 2}, 0, 0, 1 ${rectangle.x} ${rectangle.y + rectangle.height}
5744
+ M${rectangle.x + rectangle.width * 0.41} ${rectangle.y + rectangle.height / 2} H${rectangle.x + rectangle.width}
5745
+ `, {
5746
+ ...options,
5747
+ fillStyle: 'solid'
5748
+ });
5749
+ setStrokeLinecap(shape, 'round');
5750
+ return shape;
5751
+ },
5752
+ isInsidePoint(rectangle, point) {
5753
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5754
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5755
+ },
5756
+ getCornerPoints(rectangle) {
5757
+ return RectangleClient.getCornerPoints(rectangle);
5758
+ },
5759
+ getNearestPoint(rectangle, point) {
5760
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5761
+ },
5762
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5763
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5764
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5765
+ return getPolygonEdgeByConnectionPoint(corners, point);
5766
+ },
5767
+ getConnectorPoints(rectangle) {
5768
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5769
+ }
5770
+ };
5771
+
5772
+ const ProvidedInterfaceEngine = {
5773
+ draw(board, rectangle, options) {
5774
+ const rs = PlaitBoard.getRoughSVG(board);
5775
+ const shape = rs.path(` M${rectangle.x} ${rectangle.y + rectangle.height / 2}
5776
+ H${rectangle.x + rectangle.width * 0.54}
5777
+ A${(rectangle.width * 0.46) / 2} ${rectangle.height / 2}, 0, 1, 1 ${rectangle.x + rectangle.width} ${rectangle.y +
5778
+ rectangle.height / 2}
5779
+ A${(rectangle.width * 0.46) / 2} ${rectangle.height / 2}, 0, 1, 1 ${rectangle.x + rectangle.width * 0.54} ${rectangle.y +
5780
+ rectangle.height / 2}
5781
+ `, {
5782
+ ...options,
5783
+ fillStyle: 'solid'
5784
+ });
5785
+ setStrokeLinecap(shape, 'round');
5786
+ return shape;
5787
+ },
5788
+ isInsidePoint(rectangle, point) {
5789
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5790
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5791
+ },
5792
+ getCornerPoints(rectangle) {
5793
+ return RectangleClient.getCornerPoints(rectangle);
5794
+ },
5795
+ getConnectorPoints(rectangle) {
5796
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5797
+ },
5798
+ getNearestPoint(rectangle, point) {
5799
+ const nearestPoint = getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5800
+ return nearestPoint;
5801
+ },
5802
+ getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
5803
+ const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5804
+ const centerPoint = [rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height / 2];
5805
+ if (connectionPoint[0] > rectangle.x + rectangle.width * 0.54) {
5806
+ const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
5807
+ const rx = (rectangle.width * 0.46) / 2;
5808
+ const ry = rectangle.height / 2;
5809
+ const slope = getEllipseTangentSlope(point[0], point[1], rx, ry);
5810
+ return getVectorFromPointAndSlope(point[0], point[1], slope);
5811
+ }
5812
+ return getUnitVectorByPointAndPoint(connectionPoint, [rectangle.x, rectangle.y + rectangle.height / 2]);
5813
+ }
5814
+ };
5815
+
5816
+ const ComponentEngine = {
5817
+ draw(board, rectangle, options) {
5818
+ const rs = PlaitBoard.getRoughSVG(board);
5819
+ const boxSize = {
5820
+ with: rectangle.width > 70 ? 24 : rectangle.width * 0.2,
5821
+ height: rectangle.height - 28 - rectangle.height * 0.35 > 1 ? 14 : rectangle.height * 0.175
5822
+ };
5823
+ const shape = rs.path(`M${rectangle.x + 12} ${rectangle.y}
5824
+ v${rectangle.height * 0.175}
5825
+ h${boxSize.with / 2} v${boxSize.height} h${-boxSize.with} v${-boxSize.height} h${boxSize.with / 2}
5826
+
5827
+ M${rectangle.x + 12} ${rectangle.y + rectangle.height * 0.175 + boxSize.height}
5828
+
5829
+ v${rectangle.height - rectangle.height * 0.35 - boxSize.height * 2}
5830
+ h${boxSize.with / 2} v${boxSize.height} h${-boxSize.with} v${-boxSize.height} h${boxSize.with / 2}
5831
+ M${rectangle.x + 12} ${rectangle.y + rectangle.height - rectangle.height * 0.175}
5832
+ V${rectangle.y + rectangle.height}
5833
+ H${rectangle.x + rectangle.width}
5834
+ v${-rectangle.height}
5835
+ h${-(rectangle.width - 12)}
5836
+ `, { ...options, fillStyle: 'solid' });
5837
+ setStrokeLinecap(shape, 'round');
5838
+ return shape;
5839
+ },
5840
+ isInsidePoint(rectangle, point) {
5841
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5842
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5843
+ },
5844
+ getCornerPoints(rectangle) {
5845
+ return RectangleClient.getCornerPoints(rectangle);
5846
+ },
5847
+ getNearestPoint(rectangle, point) {
5848
+ let nearestPoint = getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5849
+ if (nearestPoint[1] === rectangle.y + rectangle.height / 2) {
5850
+ nearestPoint = getNearestPointBetweenPointAndSegments(point, [
5851
+ [rectangle.x + 12, rectangle.y + rectangle.height * 0.175 + 14],
5852
+ [rectangle.x + 12, rectangle.y + rectangle.height - rectangle.height * 0.175 - 14]
5853
+ ], false);
5854
+ }
5855
+ return nearestPoint;
5856
+ },
5857
+ getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
5858
+ const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5859
+ return getUnitVectorByPointAndPoint([rectangle.x + 12, rectangle.y + rectangle.height - rectangle.height * 0.175 - 14], connectionPoint);
5860
+ },
5861
+ getConnectorPoints(rectangle) {
5862
+ return [
5863
+ [rectangle.x + rectangle.width / 2, rectangle.y],
5864
+ [rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2],
5865
+ [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height],
5866
+ [rectangle.x + 12, rectangle.y + rectangle.height / 2]
5867
+ ];
5868
+ },
5869
+ getTextRectangle(element) {
5870
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5871
+ const strokeWidth = getStrokeWidthByElement(element);
5872
+ const height = element.textHeight;
5873
+ const width = elementRectangle.width - 24 - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
5874
+ return {
5875
+ height,
5876
+ width: width > 0 ? width : 0,
5877
+ x: elementRectangle.x + 24 + ShapeDefaultSpace.rectangleAndText + strokeWidth,
5878
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5879
+ };
5880
+ }
5881
+ };
5882
+
5883
+ const ComponentBoxEngine = {
5884
+ draw(board, rectangle, options) {
5885
+ const rs = PlaitBoard.getRoughSVG(board);
5886
+ const componentWidth = rectangle.width - 45 * 2 - 18 > 1 ? 45 : rectangle.width * 0.25;
5887
+ const componentHeight = rectangle.height - 30 - 8 * 2 > 1 ? 30 : rectangle.height * 0.2;
5888
+ const componentRectangle = {
5889
+ x: rectangle.x + rectangle.width - 18 - componentWidth,
5890
+ y: rectangle.y + 8,
5891
+ width: componentWidth,
5892
+ height: componentHeight
5893
+ };
5894
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y}
5895
+ H${rectangle.x + rectangle.width}
5896
+ V${rectangle.y + rectangle.height}
5897
+ H${rectangle.x} Z
5898
+
5899
+ `, { ...options, fillStyle: 'solid' });
5900
+ const componentShape = ComponentEngine.draw(board, componentRectangle, options);
5901
+ shape.append(componentShape);
5902
+ setStrokeLinecap(shape, 'round');
5903
+ return shape;
5904
+ },
5905
+ isInsidePoint(rectangle, point) {
5906
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5907
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5908
+ },
5909
+ getCornerPoints(rectangle) {
5910
+ return RectangleClient.getCornerPoints(rectangle);
5911
+ },
5912
+ getNearestPoint(rectangle, point) {
5913
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5914
+ },
5915
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5916
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5917
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5918
+ return getPolygonEdgeByConnectionPoint(corners, point);
5919
+ },
5920
+ getConnectorPoints(rectangle) {
5921
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5922
+ },
5923
+ getTextRectangle(element) {
5924
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5925
+ const strokeWidth = getStrokeWidthByElement(element);
5926
+ const height = element.textHeight;
5927
+ const componentWidth = elementRectangle.width - 45 * 2 - 18 > 1 ? 45 : elementRectangle.width * 0.25;
5928
+ const width = elementRectangle.width - 18 - componentWidth - ShapeDefaultSpace.rectangleAndText - strokeWidth * 2;
5929
+ return {
5930
+ height,
5931
+ width: width > 0 ? width : 0,
5932
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
5933
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5934
+ };
5935
+ }
5936
+ };
5937
+
5938
+ const TemplateEngine = {
5939
+ draw(board, rectangle, options) {
5940
+ const rs = PlaitBoard.getRoughSVG(board);
5941
+ return drawRoundRectangle(rs, rectangle.x, rectangle.y, rectangle.x + rectangle.width, rectangle.y + rectangle.height, {
5942
+ ...options,
5943
+ fillStyle: 'solid',
5944
+ dashGap: 10,
5945
+ strokeLineDash: [10, 10]
5946
+ }, false, 4);
5947
+ },
5948
+ isInsidePoint(rectangle, point) {
5949
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5950
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5951
+ },
5952
+ getCornerPoints(rectangle) {
5953
+ return RectangleClient.getCornerPoints(rectangle);
5954
+ },
5955
+ getNearestPoint(rectangle, point) {
5956
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5957
+ },
5958
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5959
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5960
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5961
+ return getPolygonEdgeByConnectionPoint(corners, point);
5962
+ },
5963
+ getConnectorPoints(rectangle) {
5964
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5965
+ },
5966
+ getTextRectangle(element) {
5967
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5968
+ const strokeWidth = getStrokeWidthByElement(element);
5969
+ const height = element.textHeight;
5970
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
5971
+ return {
5972
+ height,
5973
+ width: width > 0 ? width : 0,
5974
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
5975
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5976
+ };
5977
+ }
5978
+ };
5979
+
5385
5980
  const ShapeEngineMap = {
5386
5981
  [BasicShapes.rectangle]: RectangleEngine,
5387
5982
  [BasicShapes.diamond]: DiamondEngine,
@@ -5444,8 +6039,14 @@ const ShapeEngineMap = {
5444
6039
  [UMLSymbols.deletion]: DeletionEngine,
5445
6040
  [UMLSymbols.activityClass]: ActiveClassEngine,
5446
6041
  [UMLSymbols.simpleClass]: RectangleEngine,
6042
+ [UMLSymbols.component]: ComponentEngine,
6043
+ [UMLSymbols.componentBox]: ComponentBoxEngine,
6044
+ [UMLSymbols.template]: TemplateEngine,
5447
6045
  [UMLSymbols.port]: RectangleEngine,
5448
- [UMLSymbols.branchMerge]: DiamondEngine
6046
+ [UMLSymbols.branchMerge]: DiamondEngine,
6047
+ [UMLSymbols.assembly]: AssemblyEngine,
6048
+ [UMLSymbols.requiredInterface]: RequiredInterfaceEngine,
6049
+ [UMLSymbols.providedInterface]: ProvidedInterfaceEngine
5449
6050
  };
5450
6051
  const getEngine = (shape) => {
5451
6052
  return ShapeEngineMap[shape];
@@ -5670,7 +6271,8 @@ const PlaitDrawElement = {
5670
6271
  if (PlaitDrawElement.isGeometry(value) ||
5671
6272
  PlaitDrawElement.isLine(value) ||
5672
6273
  PlaitDrawElement.isImage(value) ||
5673
- PlaitTableElement.isTable(value)) {
6274
+ PlaitDrawElement.isTable(value) ||
6275
+ PlaitDrawElement.isSwimlane(value)) {
5674
6276
  return true;
5675
6277
  }
5676
6278
  else {
@@ -5678,7 +6280,7 @@ const PlaitDrawElement = {
5678
6280
  }
5679
6281
  },
5680
6282
  isShapeElement: (value) => {
5681
- return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isTable(value);
6283
+ return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isTable(value) || PlaitDrawElement.isSwimlane(value);
5682
6284
  },
5683
6285
  isBasicShape: (value) => {
5684
6286
  return Object.keys(BasicShapes).includes(value.shape);
@@ -5690,17 +6292,23 @@ const PlaitDrawElement = {
5690
6292
  return Object.keys(UMLSymbols).includes(value.shape);
5691
6293
  },
5692
6294
  isSwimlane: (value) => {
5693
- return Object.keys(SwimlaneSymbols).includes(value.shape);
6295
+ return value.type === 'swimlane';
5694
6296
  },
5695
6297
  isVerticalSwimlane: (value) => {
5696
- return Object.keys(SwimlaneSymbols).includes(value.shape) && value.shape === SwimlaneSymbols.swimlaneVertical;
6298
+ return PlaitDrawElement.isSwimlane(value) && value.shape === SwimlaneSymbols.swimlaneVertical;
5697
6299
  },
5698
6300
  isHorizontalSwimlane: (value) => {
5699
- return Object.keys(SwimlaneSymbols).includes(value.shape) && value.shape === SwimlaneSymbols.swimlaneHorizontal;
6301
+ return PlaitDrawElement.isSwimlane(value) && value.shape === SwimlaneSymbols.swimlaneHorizontal;
5700
6302
  },
5701
6303
  isUMLClassOrInterface: (value) => {
5702
6304
  return Object.keys(UMLSymbols).includes(value.shape) && [UMLSymbols.class, UMLSymbols.interface].includes(value.shape);
5703
- }
6305
+ },
6306
+ isGeometryByTable: (value) => {
6307
+ return PlaitDrawElement.isUMLClassOrInterface(value);
6308
+ },
6309
+ isElementByTable: (value) => {
6310
+ return PlaitDrawElement.isTable(value) || PlaitDrawElement.isSwimlane(value) || PlaitDrawElement.isGeometryByTable(value);
6311
+ },
5704
6312
  };
5705
6313
 
5706
6314
  class GeometryShapeGenerator extends Generator {
@@ -5772,8 +6380,8 @@ class SingleTextGenerator extends TextGenerator {
5772
6380
  get textManage() {
5773
6381
  return this.textManages[0];
5774
6382
  }
5775
- constructor(board, element, text, viewContainerRef, options) {
5776
- super(board, element, [{ key: element.id, text: text, textHeight: element.textHeight }], viewContainerRef, options);
6383
+ constructor(board, element, text, options) {
6384
+ super(board, element, [{ key: element.id, text: text, textHeight: element.textHeight }], options);
5777
6385
  }
5778
6386
  update(element, previousText, currentText, elementG) {
5779
6387
  if (!isMultipleTextGeometry(element)) {
@@ -5863,34 +6471,32 @@ class GeometryComponent extends CommonElementFlavour {
5863
6471
  }
5864
6472
  }
5865
6473
  initializeTextManage() {
5866
- const onTextValueChangeHandle = (element, textManageRef, text) => {
5867
- const height = textManageRef.height / this.board.viewport.zoom;
5868
- const width = textManageRef.width / this.board.viewport.zoom;
5869
- if (textManageRef.newValue) {
6474
+ const onTextChange = (element, textManageChangeData, text) => {
6475
+ if (textManageChangeData.newText) {
5870
6476
  if (isMultipleTextGeometry(element)) {
5871
6477
  DrawTransforms.setDrawShapeText(this.board, element, {
5872
6478
  key: text.key,
5873
- text: textManageRef.newValue,
5874
- textHeight: height
6479
+ text: textManageChangeData.newText,
6480
+ textHeight: textManageChangeData.height
5875
6481
  });
5876
6482
  }
5877
6483
  else {
5878
- DrawTransforms.setText(this.board, element, textManageRef.newValue, width, height);
6484
+ DrawTransforms.setText(this.board, element, textManageChangeData.newText, textManageChangeData.width, textManageChangeData.height);
5879
6485
  }
5880
6486
  }
5881
6487
  else {
5882
- DrawTransforms.setTextSize(this.board, element, width, height);
6488
+ DrawTransforms.setTextSize(this.board, element, textManageChangeData.width, textManageChangeData.height);
5883
6489
  }
5884
- textManageRef.operations && memorizeLatestText(element, textManageRef.operations);
6490
+ textManageChangeData.operations && memorizeLatestText(element, textManageChangeData.operations);
5885
6491
  };
5886
6492
  if (isMultipleTextGeometry(this.element)) {
5887
- this.textGenerator = new TextGenerator(this.board, this.element, this.element.texts, PlaitBoard.getViewContainerRef(this.board), {
5888
- onValueChangeHandle: onTextValueChangeHandle
6493
+ this.textGenerator = new TextGenerator(this.board, this.element, this.element.texts, {
6494
+ onChange: onTextChange
5889
6495
  });
5890
6496
  }
5891
6497
  else {
5892
- this.textGenerator = new SingleTextGenerator(this.board, this.element, this.element.text, PlaitBoard.getViewContainerRef(this.board), {
5893
- onValueChangeHandle: onTextValueChangeHandle,
6498
+ this.textGenerator = new SingleTextGenerator(this.board, this.element, this.element.text, {
6499
+ onChange: onTextChange,
5894
6500
  getMaxWidth: () => {
5895
6501
  let width = getTextRectangle(this.element).width;
5896
6502
  const getRectangle = getEngine(this.element.shape).getTextRectangle;
@@ -6079,24 +6685,24 @@ class LineComponent extends CommonElementFlavour {
6079
6685
  }
6080
6686
  }
6081
6687
  createTextManage(text, index) {
6082
- return new TextManage(this.board, PlaitBoard.getViewContainerRef(this.board), {
6688
+ return new TextManage(this.board, {
6083
6689
  getRectangle: () => {
6084
6690
  return getLineTextRectangle(this.board, this.element, index);
6085
6691
  },
6086
- onValueChangeHandle: (textManageRef) => {
6087
- const height = textManageRef.height / this.board.viewport.zoom;
6088
- const width = textManageRef.width / this.board.viewport.zoom;
6692
+ onChange: (textManageChangeData) => {
6089
6693
  const texts = [...this.element.texts];
6694
+ const newWidth = textManageChangeData.width < MIN_TEXT_WIDTH ? MIN_TEXT_WIDTH : textManageChangeData.width;
6090
6695
  texts.splice(index, 1, {
6091
- text: textManageRef.newValue ? textManageRef.newValue : this.element.texts[index].text,
6696
+ text: textManageChangeData.newText ? textManageChangeData.newText : this.element.texts[index].text,
6092
6697
  position: this.element.texts[index].position,
6093
- width,
6094
- height
6698
+ width: newWidth,
6699
+ height: textManageChangeData.height
6095
6700
  });
6096
6701
  DrawTransforms.setLineTexts(this.board, this.element, texts);
6097
- textManageRef.operations && memorizeLatestText(this.element, textManageRef.operations);
6702
+ textManageChangeData.operations && memorizeLatestText(this.element, textManageChangeData.operations);
6098
6703
  },
6099
- getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth
6704
+ getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth,
6705
+ textPlugins: []
6100
6706
  });
6101
6707
  }
6102
6708
  updateText(previousTexts, currentTexts) {
@@ -6227,16 +6833,12 @@ const withGeometryCreateByDrag = (board) => {
6227
6833
  const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(movingPoint, property.width, property.height));
6228
6834
  temporaryElement = createTextElement(board, points);
6229
6835
  if (!fakeCreateTextRef) {
6230
- const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
6836
+ const textManage = new TextManage(board, {
6231
6837
  getRectangle: () => {
6232
6838
  return getTextRectangle(temporaryElement);
6233
6839
  }
6234
6840
  });
6235
- PlaitBoard.getComponent(board)
6236
- .viewContainerRef.injector.get(NgZone)
6237
- .run(() => {
6238
- textManage.draw(temporaryElement.text);
6239
- });
6841
+ textManage.draw(temporaryElement.text);
6240
6842
  fakeCreateTextRef = {
6241
6843
  g: createG(),
6242
6844
  textManage
@@ -6368,7 +6970,7 @@ const withGeometryCreateByDrawing = (board) => {
6368
6970
 
6369
6971
  const buildClipboardData = (board, elements, startPoint) => {
6370
6972
  return elements.map(element => {
6371
- if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element) || PlaitDrawElement.isTable(element)) {
6973
+ if (PlaitDrawElement.isShapeElement(element)) {
6372
6974
  const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
6373
6975
  return { ...element, points };
6374
6976
  }
@@ -6398,37 +7000,28 @@ const buildClipboardData = (board, elements, startPoint) => {
6398
7000
  };
6399
7001
  const insertClipboardData = (board, elements, startPoint) => {
6400
7002
  const lines = elements.filter(value => PlaitDrawElement.isLine(value));
6401
- const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isImage(value));
6402
- const tables = elements.filter(value => PlaitDrawElement.isTable(value));
7003
+ const geometries = elements.filter(value => (PlaitDrawElement.isGeometry(value) && !PlaitDrawElement.isGeometryByTable(value)) || PlaitDrawElement.isImage(value));
7004
+ const tables = elements.filter(value => PlaitDrawElement.isElementByTable(value));
6403
7005
  geometries.forEach(element => {
6404
- const sourceLines = [];
6405
- const targetLines = [];
6406
- lines.forEach(line => {
6407
- if (PlaitLine.isBoundElementOfSource(line, element)) {
6408
- sourceLines.push(line);
6409
- }
6410
- if (PlaitLine.isBoundElementOfTarget(line, element)) {
6411
- targetLines.push(line);
6412
- }
6413
- });
6414
- element.id = idCreator();
6415
- // update lines
6416
- sourceLines.forEach(sourceLine => (sourceLine.source.boundId = element.id));
6417
- targetLines.forEach(targetLine => (targetLine.target.boundId = element.id));
7006
+ const newId = idCreator();
7007
+ updateBoundLinesId(element, lines, newId);
7008
+ element.id = newId;
6418
7009
  element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
6419
7010
  Transforms.insertNode(board, element, [board.children.length]);
6420
7011
  });
7012
+ insertClipboardTableData(board, tables, startPoint, lines);
6421
7013
  lines.forEach(element => {
6422
7014
  element.id = idCreator();
6423
7015
  element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
6424
7016
  Transforms.insertNode(board, element, [board.children.length]);
6425
7017
  });
6426
- insertClipboardTableData(board, tables, startPoint);
6427
7018
  Transforms.addSelectionWithTemporaryElements(board, elements);
6428
7019
  };
6429
- const insertClipboardTableData = (board, elements, startPoint) => {
7020
+ const insertClipboardTableData = (board, elements, startPoint, lines) => {
6430
7021
  elements.forEach(element => {
6431
- element.id = idCreator();
7022
+ const newId = idCreator();
7023
+ updateBoundLinesId(element, lines, newId);
7024
+ element.id = newId;
6432
7025
  updateRowOrColumnIds(element, 'row');
6433
7026
  updateRowOrColumnIds(element, 'column');
6434
7027
  updateCellIds(element.cells);
@@ -6436,6 +7029,21 @@ const insertClipboardTableData = (board, elements, startPoint) => {
6436
7029
  Transforms.insertNode(board, element, [board.children.length]);
6437
7030
  });
6438
7031
  };
7032
+ const updateBoundLinesId = (element, lines, newId) => {
7033
+ const sourceLines = [];
7034
+ const targetLines = [];
7035
+ lines.forEach(line => {
7036
+ if (PlaitLine.isBoundElementOfSource(line, element)) {
7037
+ sourceLines.push(line);
7038
+ }
7039
+ if (PlaitLine.isBoundElementOfTarget(line, element)) {
7040
+ targetLines.push(line);
7041
+ }
7042
+ });
7043
+ // update lines
7044
+ sourceLines.forEach(sourceLine => (sourceLine.source.boundId = newId));
7045
+ targetLines.forEach(targetLine => (targetLine.target.boundId = newId));
7046
+ };
6439
7047
 
6440
7048
  const withDrawFragment = (baseBoard) => {
6441
7049
  const board = baseBoard;
@@ -6447,16 +7055,19 @@ const withDrawFragment = (baseBoard) => {
6447
7055
  const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
6448
7056
  const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
6449
7057
  const tableElements = drawElements.filter(value => PlaitDrawElement.isTable(value));
7058
+ const swimlaneElements = drawElements.filter(value => PlaitDrawElement.isSwimlane(value));
6450
7059
  const boundLineElements = [
6451
7060
  ...getBoundedLineElements(board, geometryElements),
6452
7061
  ...getBoundedLineElements(board, imageElements),
6453
- ...getBoundedLineElements(board, tableElements)
7062
+ ...getBoundedLineElements(board, tableElements),
7063
+ ...getBoundedLineElements(board, swimlaneElements)
6454
7064
  ].filter(line => !lineElements.includes(line));
6455
7065
  data.push(...[
6456
7066
  ...geometryElements,
6457
7067
  ...lineElements,
6458
7068
  ...imageElements,
6459
7069
  ...tableElements,
7070
+ ...swimlaneElements,
6460
7071
  ...boundLineElements.filter(line => !lineElements.includes(line))
6461
7072
  ]);
6462
7073
  }
@@ -6851,7 +7462,7 @@ const withLineText = (board) => {
6851
7462
  else {
6852
7463
  const ratio = getRatioByPoint(points, point);
6853
7464
  texts.push({
6854
- text: buildText('文本'),
7465
+ text: buildText(LINE_TEXT),
6855
7466
  position: ratio,
6856
7467
  width: 28,
6857
7468
  height: 20
@@ -6874,10 +7485,9 @@ const withLineText = (board) => {
6874
7485
  function editHandle(board, element, manageIndex, isFirstEdit = false) {
6875
7486
  const textManages = getTextManages(element);
6876
7487
  const textManage = textManages[manageIndex];
6877
- const originText = textManage.componentRef.instance.children;
6878
- textManage.edit((origin, descendant) => {
6879
- const text = Node.string(descendant[0]);
6880
- const shouldRemove = (isFirstEdit && originText === descendant) || !text;
7488
+ textManage.edit(() => {
7489
+ const text = Node.string(textManage.getText());
7490
+ const shouldRemove = !text || (isFirstEdit && text === LINE_TEXT);
6881
7491
  if (shouldRemove) {
6882
7492
  DrawTransforms.removeLineText(board, element, manageIndex);
6883
7493
  }
@@ -6885,9 +7495,6 @@ function editHandle(board, element, manageIndex, isFirstEdit = false) {
6885
7495
  }
6886
7496
 
6887
7497
  class ImageComponent extends CommonElementFlavour {
6888
- get activeGenerator() {
6889
- return this.imageGenerator.componentRef.instance.activeGenerator;
6890
- }
6891
7498
  constructor() {
6892
7499
  super();
6893
7500
  }
@@ -6915,7 +7522,7 @@ class ImageComponent extends CommonElementFlavour {
6915
7522
  initialize() {
6916
7523
  super.initialize();
6917
7524
  this.initializeGenerator();
6918
- this.imageGenerator.processDrawing(this.element, this.getElementG(), PlaitBoard.getViewContainerRef(this.board));
7525
+ this.imageGenerator.processDrawing(this.element, this.getElementG());
6919
7526
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6920
7527
  selected: this.selected
6921
7528
  });
@@ -6923,16 +7530,17 @@ class ImageComponent extends CommonElementFlavour {
6923
7530
  onContextChanged(value, previous) {
6924
7531
  if (value.element !== previous.element) {
6925
7532
  this.imageGenerator.updateImage(this.getElementG(), previous.element, value.element);
6926
- this.imageGenerator.componentRef.instance.isFocus = this.selected;
7533
+ this.imageGenerator.setFocus(this.element, this.selected);
6927
7534
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6928
7535
  selected: this.selected
6929
7536
  });
6930
7537
  }
6931
7538
  else {
6932
7539
  const hasSameSelected = value.selected === previous.selected;
6933
- const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
7540
+ const hasSameHandleState = this.imageGenerator.activeGenerator &&
7541
+ this.imageGenerator.activeGenerator.options.hasResizeHandle() === this.imageGenerator.activeGenerator.hasResizeHandle;
6934
7542
  if (!hasSameSelected || !hasSameHandleState) {
6935
- this.imageGenerator.componentRef.instance.isFocus = this.selected;
7543
+ this.imageGenerator.setFocus(this.element, this.selected);
6936
7544
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6937
7545
  selected: this.selected
6938
7546
  });
@@ -7231,9 +7839,17 @@ class TableComponent extends CommonElementFlavour {
7231
7839
  return 1;
7232
7840
  },
7233
7841
  getRectangle: (value) => {
7842
+ const cells = getSelectedCells(value);
7843
+ if (cells?.length) {
7844
+ return getCellsRectangle(this.board, this.element, cells);
7845
+ }
7234
7846
  return RectangleClient.getRectangleByPoints(value.points);
7235
7847
  },
7236
7848
  hasResizeHandle: () => {
7849
+ const cells = getSelectedCells(this.element);
7850
+ if (cells?.length) {
7851
+ return false;
7852
+ }
7237
7853
  return canResize(this.board, this.element);
7238
7854
  }
7239
7855
  });
@@ -7256,7 +7872,8 @@ class TableComponent extends CommonElementFlavour {
7256
7872
  });
7257
7873
  }
7258
7874
  rotateVerticalText() {
7259
- this.element.cells.forEach(item => {
7875
+ const table = this.board.buildTable(this.element);
7876
+ table.cells.forEach(item => {
7260
7877
  if (PlaitTableElement.isVerticalText(item)) {
7261
7878
  const textManage = getTextManage(item.id);
7262
7879
  if (textManage) {
@@ -7282,14 +7899,14 @@ class TableComponent extends CommonElementFlavour {
7282
7899
  }
7283
7900
  initializeTextManage() {
7284
7901
  const texts = this.getDrawShapeTexts(this.element.cells);
7285
- this.textGenerator = new TextGenerator(this.board, this.element, texts, PlaitBoard.getViewContainerRef(this.board), {
7286
- onValueChangeHandle: (value, textManageRef, text) => {
7287
- const height = textManageRef.height / this.board.viewport.zoom;
7288
- const width = textManageRef.width / this.board.viewport.zoom;
7289
- if (textManageRef.newValue) {
7290
- DrawTransforms.setTableText(this.board, value, text.key, textManageRef.newValue, width, height);
7902
+ this.textGenerator = new TextGenerator(this.board, this.element, texts, {
7903
+ onChange: (value, data, text) => {
7904
+ const height = data.height / this.board.viewport.zoom;
7905
+ const width = data.width / this.board.viewport.zoom;
7906
+ if (data.newText) {
7907
+ DrawTransforms.setTableText(this.board, value, text.key, data.newText, width, height);
7291
7908
  }
7292
- textManageRef.operations && memorizeLatestText(value, textManageRef.operations);
7909
+ data.operations && memorizeLatestText(value, data.operations);
7293
7910
  },
7294
7911
  getRenderRectangle: (value, text) => {
7295
7912
  const cell = getCellWithPoints(this.board, value, text.key);
@@ -7313,7 +7930,13 @@ class TableComponent extends CommonElementFlavour {
7313
7930
  this.textGenerator.initialize();
7314
7931
  }
7315
7932
  onContextChanged(value, previous) {
7316
- if (value.element !== previous.element) {
7933
+ const isChangeTheme = this.board.operations.find(op => op.type === 'set_theme');
7934
+ if (value.element !== previous.element || isChangeTheme) {
7935
+ const previousSelectedCells = getSelectedCells(previous.element);
7936
+ if (previousSelectedCells?.length) {
7937
+ clearSelectedCells(previous.element);
7938
+ setSelectedCells(value.element, previousSelectedCells);
7939
+ }
7317
7940
  this.tableGenerator.processDrawing(value.element, this.getElementG());
7318
7941
  this.activeGenerator.processDrawing(value.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
7319
7942
  const previousTexts = this.getDrawShapeTexts(previous.element.cells);
@@ -7324,11 +7947,15 @@ class TableComponent extends CommonElementFlavour {
7324
7947
  else {
7325
7948
  const hasSameSelected = value.selected === previous.selected;
7326
7949
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
7327
- if (!hasSameSelected || !hasSameHandleState) {
7950
+ const currentSelectedCells = getSelectedCells(value.element);
7951
+ if (!hasSameSelected || !hasSameHandleState || currentSelectedCells?.length) {
7328
7952
  this.activeGenerator.processDrawing(value.element, PlaitBoard.getElementActiveHost(this.board), {
7329
7953
  selected: this.selected
7330
7954
  });
7331
7955
  }
7956
+ if (!this.selected) {
7957
+ clearSelectedCells(value.element);
7958
+ }
7332
7959
  }
7333
7960
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7334
7961
  selected: this.selected
@@ -7353,12 +7980,13 @@ function withTableResize(board) {
7353
7980
  },
7354
7981
  hitTest: (point) => {
7355
7982
  const hitElement = getHitElementByPoint(board, point);
7356
- if (hitElement && PlaitTableElement.isTable(hitElement)) {
7983
+ if (hitElement && PlaitDrawElement.isElementByTable(hitElement)) {
7357
7984
  let rectangle = board.getRectangle(hitElement);
7358
7985
  let handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, hitElement.angle);
7359
7986
  if (handleRef) {
7360
7987
  const selectElement = isSelectedElement(board, hitElement);
7361
- if ((selectElement && isSingleSelectTable(board)) || (!selectElement && !isCornerHandle(board, handleRef.handle))) {
7988
+ if ((selectElement && isSingleSelectElementByTable(board)) ||
7989
+ (!selectElement && !isCornerHandle(board, handleRef.handle))) {
7362
7990
  return {
7363
7991
  element: hitElement,
7364
7992
  handle: handleRef.handle,
@@ -7467,48 +8095,65 @@ function withTableResize(board) {
7467
8095
 
7468
8096
  const withTable = (board) => {
7469
8097
  const tableBoard = board;
7470
- const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, dblClick } = tableBoard;
8098
+ const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, dblClick, keyDown } = tableBoard;
7471
8099
  tableBoard.drawElement = (context) => {
7472
- if (PlaitTableElement.isTable(context.element)) {
8100
+ if (PlaitDrawElement.isElementByTable(context.element)) {
7473
8101
  return TableComponent;
7474
8102
  }
7475
8103
  return drawElement(context);
7476
8104
  };
7477
8105
  tableBoard.isHit = (element, point) => {
7478
- if (PlaitTableElement.isTable(element)) {
8106
+ if (PlaitDrawElement.isElementByTable(element)) {
7479
8107
  const client = RectangleClient.getRectangleByPoints(element.points);
7480
8108
  return RectangleClient.isPointInRectangle(client, point);
7481
8109
  }
7482
8110
  return isHit(element, point);
7483
8111
  };
7484
8112
  tableBoard.getRectangle = (element) => {
7485
- if (PlaitTableElement.isTable(element)) {
8113
+ if (PlaitDrawElement.isElementByTable(element)) {
7486
8114
  return RectangleClient.getRectangleByPoints(element.points);
7487
8115
  }
7488
8116
  return getRectangle(element);
7489
8117
  };
7490
8118
  tableBoard.isMovable = (element) => {
7491
- if (PlaitTableElement.isTable(element)) {
8119
+ if (PlaitDrawElement.isElementByTable(element)) {
7492
8120
  return true;
7493
8121
  }
7494
8122
  return isMovable(element);
7495
8123
  };
7496
8124
  tableBoard.isRectangleHit = (element, selection) => {
7497
- if (PlaitTableElement.isTable(element)) {
8125
+ if (PlaitDrawElement.isElementByTable(element)) {
7498
8126
  const rangeRectangle = RectangleClient.getRectangleByPoints([selection.anchor, selection.focus]);
7499
8127
  return isPolylineHitRectangle(element.points, rangeRectangle);
7500
8128
  }
7501
8129
  return isRectangleHit(element, selection);
7502
8130
  };
8131
+ tableBoard.keyDown = (event) => {
8132
+ const selectedElements = getSelectedElements(board);
8133
+ const isSingleSelection = selectedElements.length === 1;
8134
+ const targetElement = selectedElements[0];
8135
+ if (!PlaitBoard.isReadonly(board) && !isVirtualKey(event) && !isDelete(event) && !isSpaceHotkey(event) && isSingleSelection) {
8136
+ event.preventDefault();
8137
+ if (PlaitDrawElement.isElementByTable(targetElement)) {
8138
+ const firstTextCell = targetElement.cells.find(item => item.text && item.textHeight);
8139
+ if (firstTextCell) {
8140
+ editCell(firstTextCell);
8141
+ return;
8142
+ }
8143
+ }
8144
+ }
8145
+ keyDown(event);
8146
+ };
7503
8147
  tableBoard.dblClick = (event) => {
7504
8148
  event.preventDefault();
7505
8149
  if (!PlaitBoard.isReadonly(board)) {
7506
8150
  const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7507
8151
  const hitElement = getHitElementByPoint(board, point);
7508
- if (hitElement && PlaitTableElement.isTable(hitElement)) {
8152
+ if (hitElement && PlaitDrawElement.isElementByTable(hitElement)) {
7509
8153
  const hitCell = getHitCell(tableBoard, hitElement, point);
7510
8154
  if (hitCell && hitCell.text && hitCell.textHeight) {
7511
8155
  editCell(hitCell);
8156
+ return;
7512
8157
  }
7513
8158
  }
7514
8159
  }
@@ -7520,129 +8165,6 @@ const withTable = (board) => {
7520
8165
  return withTableResize(tableBoard);
7521
8166
  };
7522
8167
 
7523
- function buildSwimlaneTable(element) {
7524
- const swimlaneElement = { ...element };
7525
- if (PlaitDrawElement.isHorizontalSwimlane(element)) {
7526
- swimlaneElement.cells = element.cells.map((item, index) => {
7527
- if (index === 0) {
7528
- item = {
7529
- ...element.cells[0],
7530
- rowspan: element.rows.length
7531
- };
7532
- }
7533
- if (item.text && item.textHeight && !item.text.direction) {
7534
- item = {
7535
- ...item,
7536
- text: {
7537
- ...item.text,
7538
- direction: 'vertical'
7539
- }
7540
- };
7541
- }
7542
- return item;
7543
- });
7544
- return swimlaneElement;
7545
- }
7546
- swimlaneElement.cells = [
7547
- {
7548
- ...element.cells[0],
7549
- colspan: element.columns.length
7550
- },
7551
- ...element.cells.slice(1, element.cells.length)
7552
- ];
7553
- return swimlaneElement;
7554
- }
7555
- const getDefaultSWimlanePoints = (pointer, centerPoint) => {
7556
- const property = DefaultSwimlanePropertyMap[pointer];
7557
- return RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(centerPoint, property.width, property.height));
7558
- };
7559
- const createDefaultSwimlane = (shape, points) => {
7560
- const rows = createDefaultRowsOrColumns(shape, 'row');
7561
- const columns = createDefaultRowsOrColumns(shape, 'column');
7562
- const swimlane = {
7563
- id: idCreator(),
7564
- type: 'table',
7565
- shape,
7566
- points,
7567
- rows,
7568
- columns,
7569
- cells: createDefaultCells(shape, rows, columns)
7570
- };
7571
- return buildSwimlaneTable(swimlane);
7572
- };
7573
- const createDefaultRowsOrColumns = (shape, type) => {
7574
- let data = new Array(3).fill('').map(item => {
7575
- return { id: idCreator() };
7576
- });
7577
- if (type === 'row' && shape === SwimlaneSymbols.swimlaneVertical) {
7578
- data = data.map((item, index) => {
7579
- if (index === 0 || index === 1) {
7580
- return {
7581
- ...item,
7582
- height: 30
7583
- };
7584
- }
7585
- return item;
7586
- });
7587
- }
7588
- if (type === 'column' && shape === SwimlaneSymbols.swimlaneHorizontal) {
7589
- data = data.map((item, index) => {
7590
- if (index === 0 || index === 1) {
7591
- return {
7592
- ...item,
7593
- width: 30
7594
- };
7595
- }
7596
- return item;
7597
- });
7598
- }
7599
- return data;
7600
- };
7601
- const createDefaultCells = (shape, rows, columns) => {
7602
- return new Array(7).fill('').map((item, index) => {
7603
- if (index === 0) {
7604
- item = {
7605
- id: idCreator(),
7606
- rowId: rows[0].id,
7607
- columnId: columns[0].id,
7608
- textHeight: DEFAULT_TEXT_HEIGHT,
7609
- text: {
7610
- children: [
7611
- {
7612
- text: 'New Swimlane'
7613
- }
7614
- ],
7615
- align: 'center'
7616
- }
7617
- };
7618
- }
7619
- if ([1, 2, 3].includes(index)) {
7620
- item = {
7621
- id: idCreator(),
7622
- rowId: shape === SwimlaneSymbols.swimlaneVertical ? rows[1].id : rows[index - 1].id,
7623
- columnId: shape === SwimlaneSymbols.swimlaneVertical ? columns[index - 1].id : columns[1].id,
7624
- textHeight: DEFAULT_TEXT_HEIGHT,
7625
- text: {
7626
- children: [
7627
- {
7628
- text: 'Lane'
7629
- }
7630
- ],
7631
- align: 'center'
7632
- }
7633
- };
7634
- }
7635
- if ([4, 5, 6].includes(index)) {
7636
- item = {
7637
- id: idCreator(),
7638
- rowId: shape === SwimlaneSymbols.swimlaneVertical ? rows[2].id : rows[index - 4].id,
7639
- columnId: shape === SwimlaneSymbols.swimlaneVertical ? columns[index - 4].id : columns[2].id
7640
- };
7641
- }
7642
- return item;
7643
- });
7644
- };
7645
-
7646
8168
  const isSwimlaneDndMode = (board) => {
7647
8169
  const swimlanePointers = getSwimlanePointers();
7648
8170
  const isSwimlanePointer = PlaitBoard.isInPointer(board, swimlanePointers);
@@ -7667,7 +8189,7 @@ const withSwimlaneCreateByDrag = (board) => {
7667
8189
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7668
8190
  const pointer = PlaitBoard.getPointer(board);
7669
8191
  if (dragMode) {
7670
- const points = getDefaultSWimlanePoints(pointer, movingPoint);
8192
+ const points = getDefaultSwimlanePoints(pointer, movingPoint);
7671
8193
  temporaryElement = createDefaultSwimlane(pointer, points);
7672
8194
  tableGenerator.processDrawing(temporaryElement, swimlaneG);
7673
8195
  PlaitBoard.getElementActiveHost(board).append(swimlaneG);
@@ -7748,7 +8270,7 @@ const withSwimlaneCreateByDrawing = (board) => {
7748
8270
  const { width, height } = RectangleClient.getRectangleByPoints([start, targetPoint]);
7749
8271
  if (Math.hypot(width, height) < 8) {
7750
8272
  const pointer = PlaitBoard.getPointer(board);
7751
- const points = getDefaultSWimlanePoints(pointer, targetPoint);
8273
+ const points = getDefaultSwimlanePoints(pointer, targetPoint);
7752
8274
  temporaryElement = createDefaultSwimlane(pointer, points);
7753
8275
  }
7754
8276
  if (temporaryElement) {
@@ -7768,7 +8290,7 @@ const withSwimlaneCreateByDrawing = (board) => {
7768
8290
  };
7769
8291
 
7770
8292
  const withSwimlane = (board) => {
7771
- const { drawElement, buildTable } = board;
8293
+ const { drawElement, buildTable, pointerUp } = board;
7772
8294
  board.drawElement = (context) => {
7773
8295
  if (PlaitDrawElement.isSwimlane(context.element)) {
7774
8296
  return TableComponent;
@@ -7781,6 +8303,23 @@ const withSwimlane = (board) => {
7781
8303
  }
7782
8304
  return buildTable(element);
7783
8305
  };
8306
+ board.pointerUp = (event) => {
8307
+ const isSetSelectionPointer = PlaitBoard.isPointer(board, PlaitPointerType.selection) || PlaitBoard.isPointer(board, PlaitPointerType.hand);
8308
+ const isSkip = !isMainPointer(event) || isDragging(board) || !isSetSelectionPointer;
8309
+ if (isSkip) {
8310
+ pointerUp(event);
8311
+ return;
8312
+ }
8313
+ if (isSingleSelectSwimlane(board)) {
8314
+ const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
8315
+ const element = getSelectedSwimlane(board);
8316
+ const hitCell = getHitCell(board, element, point);
8317
+ if (hitCell && hitCell.text && hitCell.textHeight) {
8318
+ setSelectedCells(element, [hitCell]);
8319
+ }
8320
+ }
8321
+ pointerUp(event);
8322
+ };
7784
8323
  return withSwimlaneCreateByDrawing(withSwimlaneCreateByDrag(board));
7785
8324
  };
7786
8325
 
@@ -7889,5 +8428,5 @@ const withDraw = (board) => {
7889
8428
  * Generated bundle index. Do not edit.
7890
8429
  */
7891
8430
 
7892
- export { BasicShapes, DEFAULT_IMAGE_WIDTH, DEFAULT_TEXT_HEIGHT, DefaultActivationProperty, DefaultActorProperty, DefaultArrowProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultClassProperty, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDeletionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInterfaceProperty, DefaultInternalStorageProperty, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultObjectProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, DefaultPortProperty, DefaultSwimlaneHorizontalProperty, DefaultSwimlanePropertyMap, DefaultSwimlaneVerticalProperty, DefaultTextProperty, DefaultTwoWayArrowProperty, DefaultUMLPropertyMap, DrawThemeColors, DrawTransforms, FlowchartSymbols, GEOMETRY_WITHOUT_TEXT, GEOMETRY_WITH_MULTIPLE_TEXT, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineActiveGenerator, LineAutoCompleteGenerator, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, MultipleTextGeometryCommonTextKeys, MultipleTextGeometryTextKeys, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, SingleTextGenerator, StrokeStyle, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, WithLineAutoCompletePluginKey, alignElbowSegment, alignPoints, buildDefaultTextsByShape, createDefaultFlowchart, createDefaultGeometry, createGeometryElement, createGeometryElementWithText, createGeometryElementWithoutText, createLineElement, createMultipleTextGeometryElement, createTextElement, createUMLClassOrInterfaceGeometryElement, debugGenerator$1 as debugGenerator, deleteTextManage, drawBoundReaction, drawGeometry, drawLine, drawLineArrow, drawShape, editText, getAutoCompletePoints, getBasicPointers, getCenterPointsOnPolygon$1 as getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getLines, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getSelectedTableElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlanePointers, getTextKey, getTextManage, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isDrawElementIncludeText, isDrawElementsIncludeText, isGeometryIncludeText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setTextManage, traverseDrawShapes, withDraw, withLineAutoComplete };
8431
+ export { BasicShapes, DEFAULT_IMAGE_WIDTH, DefaultActivationProperty, DefaultActorProperty, DefaultArrowProperty, DefaultAssemblyProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultClassProperty, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultComponentBoxProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDeletionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInterfaceProperty, DefaultInternalStorageProperty, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultObjectProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, DefaultPortProperty, DefaultProvidedInterfaceProperty, DefaultRequiredInterfaceProperty, DefaultSwimlaneHorizontalProperty, DefaultSwimlaneHorizontalWithHeaderProperty, DefaultSwimlanePropertyMap, DefaultSwimlaneVerticalProperty, DefaultSwimlaneVerticalWithHeaderProperty, DefaultTextProperty, DefaultTwoWayArrowProperty, DefaultUMLPropertyMap, DrawThemeColors, DrawTransforms, FlowchartSymbols, GEOMETRY_WITHOUT_TEXT, GEOMETRY_WITH_MULTIPLE_TEXT, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineActiveGenerator, LineAutoCompleteGenerator, LineComponent, LineHandleKey, LineMarkerType, LineShape, MIN_TEXT_WIDTH, MemorizeKey, MultipleTextGeometryCommonTextKeys, MultipleTextGeometryTextKeys, PlaitDrawElement, PlaitGeometry, PlaitLine, PlaitTableElement, Q2C, SELECTED_CELLS, SWIMLANE_HEADER_SIZE, ShapeDefaultSpace, SingleTextGenerator, StrokeStyle, SwimlaneDrawSymbols, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, WithLineAutoCompletePluginKey, adjustSwimlaneShape, alignElbowSegment, alignPoints, buildDefaultTextsByShape, buildSwimlaneTable, clearSelectedCells, createCell, createDefaultCells, createDefaultFlowchart, createDefaultGeometry, createDefaultRowsOrColumns, createDefaultSwimlane, createGeometryElement, createGeometryElementWithText, createGeometryElementWithoutText, createLineElement, createMultipleTextGeometryElement, createTextElement, createUMLClassOrInterfaceGeometryElement, debugGenerator$1 as debugGenerator, deleteTextManage, drawBoundReaction, drawGeometry, drawLine, drawLineArrow, drawShape, editCell, editText, getAutoCompletePoints, getBasicPointers, getCellWithPoints, getCellsRectangle, getCellsWithPoints, getCenterPointsOnPolygon$1 as getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultSwimlanePoints, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitCell, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getLines, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedCells, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getSelectedSwimlane, getSelectedTableElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlaneCount, getSwimlanePointers, getTextKey, getTextManage, getTextManageByCell, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isCellIncludeText, isDrawElementIncludeText, isDrawElementsIncludeText, isGeometryIncludeText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectElementByTable, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isSwimlaneWithHeader, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setSelectedCells, setTextManage, traverseDrawShapes, updateCellIds, updateCellIdsByRowOrColumn, updateColumns, updateRowOrColumnIds, updateRows, withDraw, withLineAutoComplete };
7893
8432
  //# sourceMappingURL=plait-draw.mjs.map