@plait/draw 0.59.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 (100) hide show
  1. package/constants/geometry.d.ts +115 -7
  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/activity-class.d.ts +2 -0
  8. package/engines/uml/assembly.d.ts +2 -0
  9. package/engines/uml/component-box.d.ts +2 -0
  10. package/engines/uml/component.d.ts +2 -0
  11. package/engines/uml/deletion.d.ts +2 -0
  12. package/engines/uml/note.d.ts +2 -0
  13. package/engines/uml/provided-interface.d.ts +2 -0
  14. package/engines/uml/required-interface.d.ts +2 -0
  15. package/engines/uml/template.d.ts +2 -0
  16. package/esm2022/constants/geometry.mjs +87 -15
  17. package/esm2022/constants/index.mjs +3 -2
  18. package/esm2022/constants/line.mjs +2 -1
  19. package/esm2022/constants/pointer.mjs +3 -3
  20. package/esm2022/constants/swimlane.mjs +25 -0
  21. package/esm2022/constants/text.mjs +2 -0
  22. package/esm2022/engines/index.mjs +27 -2
  23. package/esm2022/engines/table/table.mjs +10 -3
  24. package/esm2022/engines/uml/activity-class.mjs +47 -0
  25. package/esm2022/engines/uml/assembly.mjs +56 -0
  26. package/esm2022/engines/uml/component-box.mjs +61 -0
  27. package/esm2022/engines/uml/component.mjs +72 -0
  28. package/esm2022/engines/uml/deletion.mjs +31 -0
  29. package/esm2022/engines/uml/note.mjs +58 -0
  30. package/esm2022/engines/uml/provided-interface.mjs +47 -0
  31. package/esm2022/engines/uml/required-interface.mjs +36 -0
  32. package/esm2022/engines/uml/template.mjs +47 -0
  33. package/esm2022/generators/single-text.generator.mjs +3 -3
  34. package/esm2022/generators/table.generator.mjs +1 -1
  35. package/esm2022/generators/text.generator.mjs +10 -13
  36. package/esm2022/geometry.component.mjs +12 -14
  37. package/esm2022/image.component.mjs +6 -8
  38. package/esm2022/interfaces/geometry.mjs +17 -10
  39. package/esm2022/interfaces/index.mjs +19 -9
  40. package/esm2022/interfaces/swimlane.mjs +13 -0
  41. package/esm2022/interfaces/table.mjs +5 -1
  42. package/esm2022/line.component.mjs +12 -13
  43. package/esm2022/plugins/with-draw-fragment.mjs +6 -2
  44. package/esm2022/plugins/with-geometry-create.mjs +16 -13
  45. package/esm2022/plugins/with-line-text.mjs +7 -8
  46. package/esm2022/plugins/with-swimlane-create.mjs +4 -4
  47. package/esm2022/plugins/with-swimlane.mjs +21 -2
  48. package/esm2022/plugins/with-table-resize.mjs +6 -5
  49. package/esm2022/plugins/with-table.mjs +28 -10
  50. package/esm2022/table.component.mjs +31 -12
  51. package/esm2022/transforms/geometry-text.mjs +8 -6
  52. package/esm2022/transforms/image.mjs +3 -3
  53. package/esm2022/transforms/index.mjs +5 -3
  54. package/esm2022/transforms/line.mjs +1 -1
  55. package/esm2022/transforms/multi-text-geometry-text.mjs +1 -1
  56. package/esm2022/transforms/swimlane.mjs +142 -47
  57. package/esm2022/utils/clipboard.mjs +27 -21
  58. package/esm2022/utils/common.mjs +6 -7
  59. package/esm2022/utils/geometry.mjs +16 -10
  60. package/esm2022/utils/hit.mjs +2 -2
  61. package/esm2022/utils/index.mjs +5 -1
  62. package/esm2022/utils/multi-text-geometry.mjs +4 -4
  63. package/esm2022/utils/selected.mjs +3 -8
  64. package/esm2022/utils/swimlane.mjs +73 -78
  65. package/esm2022/utils/table-selected.mjs +26 -0
  66. package/esm2022/utils/table.mjs +26 -1
  67. package/esm2022/utils/uml.mjs +88 -0
  68. package/fesm2022/plait-draw.mjs +1215 -367
  69. package/fesm2022/plait-draw.mjs.map +1 -1
  70. package/generators/single-text.generator.d.ts +3 -4
  71. package/generators/table.generator.d.ts +2 -2
  72. package/generators/text.generator.d.ts +3 -6
  73. package/image.component.d.ts +0 -1
  74. package/interfaces/geometry.d.ts +25 -24
  75. package/interfaces/index.d.ts +11 -6
  76. package/interfaces/swimlane.d.ts +22 -0
  77. package/interfaces/table.d.ts +13 -4
  78. package/line.component.d.ts +1 -2
  79. package/package.json +1 -3
  80. package/plugins/with-geometry-create.d.ts +1 -1
  81. package/plugins/with-swimlane-create.d.ts +1 -1
  82. package/plugins/with-swimlane.d.ts +3 -2
  83. package/plugins/with-table-resize.d.ts +1 -1
  84. package/plugins/with-table.d.ts +1 -4
  85. package/transforms/geometry.d.ts +2 -2
  86. package/transforms/index.d.ts +9 -7
  87. package/transforms/swimlane.d.ts +8 -5
  88. package/utils/clipboard.d.ts +4 -3
  89. package/utils/common.d.ts +5 -5
  90. package/utils/geometry.d.ts +43 -2
  91. package/utils/index.d.ts +4 -0
  92. package/utils/multi-text-geometry.d.ts +1 -1
  93. package/utils/selected.d.ts +2 -4
  94. package/utils/shape.d.ts +1 -1
  95. package/utils/swimlane.d.ts +11 -26
  96. package/utils/table-selected.d.ts +9 -0
  97. package/utils/table.d.ts +10 -9
  98. package/utils/uml.d.ts +3 -0
  99. package/constants/draw.d.ts +0 -1
  100. 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,22 +56,29 @@ 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";
72
62
  UMLSymbols["useCase"] = "useCase";
73
63
  UMLSymbols["container"] = "container";
64
+ UMLSymbols["note"] = "note";
65
+ UMLSymbols["simpleClass"] = "simpleClass";
66
+ UMLSymbols["activityClass"] = "activityClass";
67
+ UMLSymbols["branchMerge"] = "branchMerge";
68
+ UMLSymbols["port"] = "port";
74
69
  UMLSymbols["package"] = "package";
75
70
  UMLSymbols["combinedFragment"] = "combinedFragment";
71
+ UMLSymbols["class"] = "class";
72
+ UMLSymbols["interface"] = "interface";
73
+ UMLSymbols["object"] = "object";
74
+ UMLSymbols["component"] = "component";
75
+ UMLSymbols["componentBox"] = "componentBox";
76
+ UMLSymbols["template"] = "template";
77
+ UMLSymbols["activation"] = "activation";
78
+ UMLSymbols["deletion"] = "deletion";
79
+ UMLSymbols["assembly"] = "assembly";
80
+ UMLSymbols["providedInterface"] = "providedInterface";
81
+ UMLSymbols["requiredInterface"] = "requiredInterface";
76
82
  })(UMLSymbols || (UMLSymbols = {}));
77
83
  var MultipleTextGeometryCommonTextKeys;
78
84
  (function (MultipleTextGeometryCommonTextKeys) {
@@ -81,6 +87,23 @@ var MultipleTextGeometryCommonTextKeys;
81
87
  })(MultipleTextGeometryCommonTextKeys || (MultipleTextGeometryCommonTextKeys = {}));
82
88
  const PlaitGeometry = {};
83
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 = {}));
84
107
  const PlaitTableElement = {
85
108
  isTable: (value) => {
86
109
  return value.type === 'table';
@@ -201,6 +224,38 @@ const DefaultPackageProperty = {
201
224
  }
202
225
  ]
203
226
  };
227
+ const DefaultActivationProperty = {
228
+ width: 18,
229
+ height: 80
230
+ };
231
+ const DefaultObjectProperty = {
232
+ width: 120,
233
+ height: 60
234
+ };
235
+ const DefaultComponentBoxProperty = {
236
+ width: 200,
237
+ height: 150
238
+ };
239
+ const DefaultDeletionProperty = {
240
+ width: 40,
241
+ height: 40
242
+ };
243
+ const DefaultPortProperty = {
244
+ width: 20,
245
+ height: 20
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
+ };
204
259
  const DefaultCombinedFragmentProperty = {
205
260
  width: 400,
206
261
  height: 280,
@@ -217,13 +272,31 @@ const DefaultCombinedFragmentProperty = {
217
272
  }
218
273
  ]
219
274
  };
220
- const DefaultSwimlaneVerticalProperty = {
221
- width: 450,
222
- height: 500
275
+ const DefaultClassProperty = {
276
+ width: 230,
277
+ height: 180,
278
+ texts: [
279
+ { text: 'Class', align: Alignment.center },
280
+ {
281
+ text: '+ attribute1:type defaultValue\n+ attribute2:type\n- attribute3:type',
282
+ align: Alignment.left
283
+ },
284
+ {
285
+ text: '+ operation1(params):returnType\n- operation2(params)\n- operation3()',
286
+ align: Alignment.left
287
+ }
288
+ ]
223
289
  };
224
- const DefaultSwimlaneHorizontalProperty = {
225
- width: 500,
226
- height: 450
290
+ const DefaultInterfaceProperty = {
291
+ width: 230,
292
+ height: 140,
293
+ texts: [
294
+ { text: '<<interface>>\nInterface', align: Alignment.center },
295
+ {
296
+ text: '+ operation1(params):returnType\n- operation2(params)\n- operation3()',
297
+ align: Alignment.left
298
+ }
299
+ ]
227
300
  };
228
301
  const DefaultBasicShapePropertyMap = {
229
302
  [BasicShapes.pentagonArrow]: DefaultPentagonArrowProperty,
@@ -263,28 +336,50 @@ const DefaultUMLPropertyMap = {
263
336
  [UMLSymbols.actor]: DefaultActorProperty,
264
337
  [UMLSymbols.useCase]: DefaultDocumentProperty,
265
338
  [UMLSymbols.container]: DefaultContainerProperty,
339
+ [UMLSymbols.note]: DefaultObjectProperty,
266
340
  [UMLSymbols.package]: DefaultPackageProperty,
267
- [UMLSymbols.combinedFragment]: DefaultCombinedFragmentProperty
341
+ [UMLSymbols.combinedFragment]: DefaultCombinedFragmentProperty,
342
+ [UMLSymbols.class]: DefaultClassProperty,
343
+ [UMLSymbols.interface]: DefaultInterfaceProperty,
344
+ [UMLSymbols.activation]: DefaultActivationProperty,
345
+ [UMLSymbols.object]: DefaultObjectProperty,
346
+ [UMLSymbols.deletion]: DefaultDeletionProperty,
347
+ [UMLSymbols.activityClass]: DefaultObjectProperty,
348
+ [UMLSymbols.simpleClass]: DefaultObjectProperty,
349
+ [UMLSymbols.component]: DefaultMultiDocumentProperty,
350
+ [UMLSymbols.template]: DefaultMultiDocumentProperty,
351
+ [UMLSymbols.componentBox]: DefaultComponentBoxProperty,
352
+ [UMLSymbols.port]: DefaultPortProperty,
353
+ [UMLSymbols.branchMerge]: DefaultDeletionProperty,
354
+ [UMLSymbols.assembly]: DefaultAssemblyProperty,
355
+ [UMLSymbols.providedInterface]: DefaultProvidedInterfaceProperty,
356
+ [UMLSymbols.requiredInterface]: DefaultRequiredInterfaceProperty
268
357
  };
269
358
  const MultipleTextGeometryTextKeys = {
270
359
  [UMLSymbols.package]: Object.keys(MultipleTextGeometryCommonTextKeys),
271
360
  [UMLSymbols.combinedFragment]: Object.keys(MultipleTextGeometryCommonTextKeys)
272
361
  };
273
- const DefaultSwimlanePropertyMap = {
274
- [SwimlaneSymbols.swimlaneHorizontal]: DefaultSwimlaneHorizontalProperty,
275
- [SwimlaneSymbols.swimlaneVertical]: DefaultSwimlaneVerticalProperty
276
- };
277
362
  const LINE_HIT_GEOMETRY_BUFFER = 10;
278
363
  const LINE_SNAPPING_BUFFER = 6;
279
364
  const LINE_SNAPPING_CONNECTOR_BUFFER = 8;
280
- const GEOMETRY_WITHOUT_TEXT = [FlowchartSymbols.or, FlowchartSymbols.summingJunction];
365
+ const GEOMETRY_WITHOUT_TEXT = [
366
+ FlowchartSymbols.or,
367
+ FlowchartSymbols.summingJunction,
368
+ UMLSymbols.activation,
369
+ UMLSymbols.deletion,
370
+ UMLSymbols.port,
371
+ UMLSymbols.branchMerge,
372
+ UMLSymbols.assembly,
373
+ UMLSymbols.providedInterface,
374
+ UMLSymbols.requiredInterface
375
+ ];
281
376
  const GEOMETRY_WITH_MULTIPLE_TEXT = [UMLSymbols.package, UMLSymbols.combinedFragment];
282
377
 
283
378
  const getGeometryPointers = () => {
284
379
  return [...Object.keys(BasicShapes), ...Object.keys(FlowchartSymbols), ...Object.keys(UMLSymbols)];
285
380
  };
286
381
  const getSwimlanePointers = () => {
287
- return Object.keys(SwimlaneSymbols);
382
+ return Object.keys(SwimlaneDrawSymbols);
288
383
  };
289
384
  const getBasicPointers = () => {
290
385
  return Object.keys(BasicShapes);
@@ -328,7 +423,31 @@ const DrawThemeColors = {
328
423
  }
329
424
  };
330
425
 
331
- 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;
332
451
 
333
452
  const getElementShape = (value) => {
334
453
  if (PlaitDrawElement.isImage(value)) {
@@ -354,15 +473,15 @@ class TextGenerator {
354
473
  get shape() {
355
474
  return this.element.shape || this.element.type;
356
475
  }
357
- constructor(board, element, texts, viewContainerRef, options) {
476
+ constructor(board, element, texts, options) {
358
477
  this.board = board;
359
478
  this.texts = texts;
360
479
  this.element = element;
361
- this.viewContainerRef = viewContainerRef;
362
480
  this.options = options;
363
481
  }
364
482
  initialize() {
365
- const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
483
+ const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {})
484
+ .textPlugins;
366
485
  this.textManages = this.texts.map(text => {
367
486
  const textManage = this.createTextManage(text, textPlugins);
368
487
  setTextManage(getTextKey(this.element, text), textManage);
@@ -385,7 +504,8 @@ class TextGenerator {
385
504
  this.element = element;
386
505
  ELEMENT_TO_TEXT_MANAGES.set(this.element, this.textManages);
387
506
  const centerPoint = RectangleClient.getCenterPoint(this.board.getRectangle(this.element));
388
- const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
507
+ const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {})
508
+ .textPlugins;
389
509
  const removedTexts = previousDrawShapeTexts.filter(value => {
390
510
  return !currentDrawShapeTexts.find(item => item.key === value.key);
391
511
  });
@@ -419,12 +539,12 @@ class TextGenerator {
419
539
  });
420
540
  }
421
541
  createTextManage(text, textPlugins) {
422
- const textManage = new TextManage(this.board, this.viewContainerRef, {
542
+ const textManage = new TextManage(this.board, {
423
543
  getRectangle: () => {
424
544
  return this.getRectangle(text);
425
545
  },
426
- onValueChangeHandle: (textManageRef) => {
427
- return this.onValueChangeHandle(textManageRef, text);
546
+ onChange: (data) => {
547
+ return this.options.onChange(this.element, data, text);
428
548
  },
429
549
  getMaxWidth: () => {
430
550
  return this.getMaxWidth(text);
@@ -443,9 +563,6 @@ class TextGenerator {
443
563
  }
444
564
  return getTextRectangle(this.element);
445
565
  }
446
- onValueChangeHandle(textManageRef, text) {
447
- return this.options.onValueChangeHandle(this.element, textManageRef, text);
448
- }
449
566
  getMaxWidth(text) {
450
567
  return this.options.getMaxWidth ? this.options.getMaxWidth() : this.getRectangle(text).width;
451
568
  }
@@ -582,6 +699,29 @@ function updateCellIds(cells) {
582
699
  function isCellIncludeText(cell) {
583
700
  return cell.text && cell.textHeight;
584
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
+ };
585
725
 
586
726
  const SHAPE_MAX_LENGTH = 6;
587
727
  const memorizedShape = new WeakMap();
@@ -749,7 +889,7 @@ const getMultipleTextGeometryTextKeys = (shape) => {
749
889
  };
750
890
  const createMultipleTextGeometryElement = (shape, points, options = {}) => {
751
891
  const id = idCreator();
752
- const drawShapeTexts = buildDefaultTextsByShape(shape, id);
892
+ const drawShapeTexts = buildDefaultTextsByShape(shape);
753
893
  return {
754
894
  id,
755
895
  type: 'geometry',
@@ -761,7 +901,7 @@ const createMultipleTextGeometryElement = (shape, points, options = {}) => {
761
901
  ...options
762
902
  };
763
903
  };
764
- const buildDefaultTextsByShape = (shape, elementId) => {
904
+ const buildDefaultTextsByShape = (shape) => {
765
905
  const memorizedLatest = getMemorizedLatestByPointer(shape);
766
906
  const textProperties = { ...memorizedLatest.textProperties };
767
907
  const alignment = textProperties?.align;
@@ -914,7 +1054,7 @@ const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
914
1054
  const isHitElementInside = (board, element, point) => {
915
1055
  const rectangle = board.getRectangle(element);
916
1056
  point = rotateAntiPointsByElement(point, element) || point;
917
- if (PlaitDrawElement.isGeometry(element)) {
1057
+ if (PlaitDrawElement.isGeometry(element) && !PlaitDrawElement.isGeometryByTable(element)) {
918
1058
  const engine = getEngine(getElementShape(element));
919
1059
  const isHitInside = engine.isInsidePoint(rectangle, point);
920
1060
  if (isHitInside) {
@@ -977,7 +1117,7 @@ const isDrawElementIncludeText = (element) => {
977
1117
  const editors = getTextEditorsByElement(element);
978
1118
  return editors.length > 0;
979
1119
  }
980
- if (PlaitDrawElement.isTable(element)) {
1120
+ if (PlaitDrawElement.isElementByTable(element)) {
981
1121
  return element.cells.some(cell => isCellIncludeText(cell));
982
1122
  }
983
1123
  return true;
@@ -1029,7 +1169,7 @@ const drawBoundReaction = (board, element, roughOptions = { hasMask: true, hasCo
1029
1169
  const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
1030
1170
  const shape = getElementShape(element);
1031
1171
  let drawOptions = {};
1032
- if (PlaitDrawElement.isTable(element)) {
1172
+ if (PlaitDrawElement.isElementByTable(element)) {
1033
1173
  drawOptions = { element };
1034
1174
  }
1035
1175
  const strokeG = drawShape(board, activeRectangle, shape, {
@@ -1068,7 +1208,7 @@ const getTextKey = (element, text) => {
1068
1208
  return text.key;
1069
1209
  }
1070
1210
  };
1071
- const getGeometryAlign = (element) => {
1211
+ const getGeometryAlign = (board, element) => {
1072
1212
  if (isMultipleTextGeometry(element)) {
1073
1213
  const drawShapeText = element.texts.find(item => item.key.includes(MultipleTextGeometryCommonTextKeys.content));
1074
1214
  return drawShapeText?.text.align || Alignment.center;
@@ -1076,7 +1216,7 @@ const getGeometryAlign = (element) => {
1076
1216
  if (isSingleTextGeometry(element)) {
1077
1217
  return element.text?.align || Alignment.center;
1078
1218
  }
1079
- if (PlaitDrawElement.isTable(element)) {
1219
+ if (PlaitDrawElement.isElementByTable(element)) {
1080
1220
  const firstTextCell = element.cells.find(item => item.text);
1081
1221
  return firstTextCell?.text?.align || Alignment.center;
1082
1222
  }
@@ -1119,6 +1259,7 @@ const LINE_AUTO_COMPLETE_OPACITY = 0.6;
1119
1259
  const LINE_AUTO_COMPLETE_HOVERED_OPACITY = 0.8;
1120
1260
  const LINE_AUTO_COMPLETE_HOVERED_DIAMETER = 10;
1121
1261
  const LINE_ALIGN_TOLERANCE = 3;
1262
+ const LINE_TEXT = '文本';
1122
1263
 
1123
1264
  class LineShapeGenerator extends Generator {
1124
1265
  canDraw(element, data) {
@@ -1796,6 +1937,89 @@ function drawMask(board, element, id) {
1796
1937
  return { mask, maskTargetFillRect };
1797
1938
  }
1798
1939
 
1940
+ const createUMLClassOrInterfaceGeometryElement = (board, shape, points) => {
1941
+ const memorizedLatest = getMemorizedLatestByPointer(shape);
1942
+ const element = {
1943
+ id: idCreator(),
1944
+ type: 'geometry',
1945
+ angle: 0,
1946
+ opacity: 1,
1947
+ points,
1948
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth,
1949
+ ...memorizedLatest.geometryProperties
1950
+ };
1951
+ let rows;
1952
+ let columns;
1953
+ if (shape === UMLSymbols.class) {
1954
+ rows = [
1955
+ {
1956
+ id: idCreator(),
1957
+ height: 30
1958
+ },
1959
+ {
1960
+ id: idCreator()
1961
+ },
1962
+ {
1963
+ id: idCreator()
1964
+ }
1965
+ ];
1966
+ columns = [
1967
+ {
1968
+ id: idCreator()
1969
+ }
1970
+ ];
1971
+ }
1972
+ else {
1973
+ rows = [
1974
+ {
1975
+ id: idCreator(),
1976
+ height: 50
1977
+ },
1978
+ {
1979
+ id: idCreator()
1980
+ }
1981
+ ];
1982
+ columns = [
1983
+ {
1984
+ id: idCreator()
1985
+ }
1986
+ ];
1987
+ }
1988
+ return {
1989
+ ...element,
1990
+ shape,
1991
+ rows,
1992
+ columns,
1993
+ cells: buildTableCellsForGeometry(board, rows, columns, shape)
1994
+ };
1995
+ };
1996
+ const buildTableCellsForGeometry = (board, rows, columns, shape) => {
1997
+ const memorizedLatest = getMemorizedLatestByPointer(shape);
1998
+ const cellCount = rows.length * columns.length;
1999
+ const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
2000
+ const testHeights = defaultTexts.map((textItem) => {
2001
+ return getTextShapeProperty(board, textItem.text || DefaultTextProperty.text, memorizedLatest.textProperties['font-size']).height;
2002
+ });
2003
+ return new Array(cellCount).fill('').map((item, index) => {
2004
+ const rowIndex = Math.floor(index / columns.length);
2005
+ const columnIndex = index % columns.length;
2006
+ return {
2007
+ id: idCreator(),
2008
+ rowId: rows[rowIndex].id,
2009
+ columnId: columns[columnIndex].id,
2010
+ textHeight: testHeights[index],
2011
+ text: {
2012
+ children: [
2013
+ {
2014
+ text: defaultTexts[index].text
2015
+ }
2016
+ ],
2017
+ align: defaultTexts[index].align
2018
+ }
2019
+ };
2020
+ });
2021
+ };
2022
+
1799
2023
  const createGeometryElement = (shape, points, text, options = {}, textProperties = {}) => {
1800
2024
  if (GEOMETRY_WITHOUT_TEXT.includes(shape)) {
1801
2025
  return createGeometryElementWithoutText(shape, points, options);
@@ -1943,7 +2167,7 @@ const getFlowchartDefaultFill = (theme) => {
1943
2167
  };
1944
2168
  const getTextShapeProperty = (board, text = DefaultTextProperty.text, fontSize) => {
1945
2169
  fontSize = fontSize ? Number(fontSize) : DEFAULT_FONT_SIZE;
1946
- const textSize = getTextSize(board, text, Infinity, { fontSize });
2170
+ const textSize = measureElement(buildText(text), { fontSize, fontFamily: DEFAULT_FONT_FAMILY });
1947
2171
  return {
1948
2172
  width: textSize.width + ShapeDefaultSpace.rectangleAndText * 2,
1949
2173
  height: textSize.height
@@ -1981,6 +2205,9 @@ const createTextElement = (board, points, text = DefaultTextProperty.text, textH
1981
2205
  const createDefaultGeometry = (board, points, shape) => {
1982
2206
  const memorizedLatest = getMemorizedLatestByPointer(shape);
1983
2207
  const textHeight = getTextShapeProperty(board, DefaultTextProperty.text, memorizedLatest.textProperties['font-size']).height;
2208
+ if (PlaitDrawElement.isUMLClassOrInterface({ shape })) {
2209
+ return createUMLClassOrInterfaceGeometryElement(board, shape, points);
2210
+ }
1984
2211
  if (isMultipleTextShape(shape)) {
1985
2212
  return createMultipleTextGeometryElement(shape, points, {
1986
2213
  strokeWidth: DefaultBasicShapeProperty.strokeWidth,
@@ -1996,12 +2223,14 @@ const createDefaultGeometry = (board, points, shape) => {
1996
2223
  };
1997
2224
  const editText = (board, element, text) => {
1998
2225
  const textManage = text ? getTextManage(`${element.id}-${text.key}`) : getFirstTextManage(element);
1999
- textManage.edit(() => {
2000
- // delay to avoid blinking
2001
- setTimeout(() => {
2002
- rerenderGeometryActive(board, element);
2003
- }, 200);
2004
- });
2226
+ if (textManage) {
2227
+ textManage.edit(() => {
2228
+ // delay to avoid blinking
2229
+ setTimeout(() => {
2230
+ rerenderGeometryActive(board, element);
2231
+ }, 200);
2232
+ });
2233
+ }
2005
2234
  rerenderGeometryActive(board, element);
2006
2235
  };
2007
2236
  const rerenderGeometryActive = (board, element) => {
@@ -2147,13 +2376,9 @@ const isSingleSelectSwimlane = (board) => {
2147
2376
  const selectedElements = getSelectedElements(board);
2148
2377
  return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isSwimlane(selectedElements[0]);
2149
2378
  };
2150
- const isSingleSelectTable = (board) => {
2379
+ const getSelectedSwimlane = (board) => {
2151
2380
  const selectedElements = getSelectedElements(board);
2152
- return selectedElements && selectedElements.length === 1 && PlaitTableElement.isTable(selectedElements[0]);
2153
- };
2154
- const getSelectedTableElements = (board, elements) => {
2155
- const selectedElements = elements?.length ? elements : getSelectedElements(board);
2156
- return selectedElements.filter(value => PlaitTableElement.isTable(value));
2381
+ return selectedElements.find(item => PlaitDrawElement.isSwimlane(item));
2157
2382
  };
2158
2383
 
2159
2384
  const resizeLine = (board, options, path) => {
@@ -2315,23 +2540,24 @@ const normalizePoints = (board, element, width, textHeight) => {
2315
2540
  let autoSize = element.autoSize;
2316
2541
  const defaultSpace = ShapeDefaultSpace.rectangleAndText;
2317
2542
  if (autoSize) {
2543
+ const newWidth = width < MIN_TEXT_WIDTH ? MIN_TEXT_WIDTH : width;
2318
2544
  const editor = getFirstTextEditor(element);
2319
2545
  if (AlignEditor.isActive(editor, Alignment.right)) {
2320
2546
  points = [
2321
- [points[1][0] - (width + defaultSpace * 2), points[0][1]],
2547
+ [points[1][0] - (newWidth + defaultSpace * 2), points[0][1]],
2322
2548
  [points[1][0], points[0][1] + textHeight]
2323
2549
  ];
2324
2550
  }
2325
2551
  else if (AlignEditor.isActive(editor, Alignment.center)) {
2326
2552
  const oldWidth = Math.abs(points[0][0] - points[1][0]);
2327
- const offset = (width - oldWidth) / 2;
2553
+ const offset = (newWidth - oldWidth) / 2;
2328
2554
  points = [
2329
2555
  [points[0][0] - offset - defaultSpace, points[0][1]],
2330
2556
  [points[1][0] + offset + defaultSpace, points[0][1] + textHeight]
2331
2557
  ];
2332
2558
  }
2333
2559
  else {
2334
- 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]];
2335
2561
  }
2336
2562
  if (hasValidAngle(element)) {
2337
2563
  points = resetPointsAfterResize(RectangleClient.getRectangleByPoints(element.points), RectangleClient.getRectangleByPoints(points), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(element.points)), RectangleClient.getCenterPoint(RectangleClient.getRectangleByPoints(points)), element.angle);
@@ -2365,8 +2591,8 @@ const setTextSize = (board, element, textWidth, textHeight) => {
2365
2591
 
2366
2592
  const insertImage = (board, imageItem, startPoint) => {
2367
2593
  const { width, height, url } = imageItem;
2368
- const viewportWidth = PlaitBoard.getComponent(board).nativeElement.clientWidth;
2369
- const viewportHeight = PlaitBoard.getComponent(board).nativeElement.clientHeight;
2594
+ const viewportWidth = PlaitBoard.getBoardContainer(board).clientWidth;
2595
+ const viewportHeight = PlaitBoard.getBoardContainer(board).clientHeight;
2370
2596
  const point = toViewBoxPoint(board, toHostPoint(board, viewportWidth / 2, viewportHeight / 2));
2371
2597
  const points = startPoint
2372
2598
  ? [startPoint, [startPoint[0] + width, startPoint[1] + height]]
@@ -2384,89 +2610,265 @@ const insertImage = (board, imageItem, startPoint) => {
2384
2610
  Transforms.addSelectionWithTemporaryElements(board, [imageElement]);
2385
2611
  };
2386
2612
 
2387
- const addSwimlaneRow = (board, swimlane, index) => {
2388
- 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)) {
2389
2749
  const newRows = [...swimlane.rows];
2390
- const newRowId = idCreator();
2391
- newRows.splice(index, 0, { id: newRowId });
2392
- let newCells = createNewRowCells(swimlane, newRowId);
2393
- newCells.shift();
2394
- newCells = [...swimlane.cells, ...newCells];
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
+ });
2395
2759
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2396
2760
  const lastRowHeight = RectangleClient.getRectangleByPoints(lastCellPoints).height;
2397
- 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]];
2398
2762
  updateSwimlane(board, swimlane, swimlane.columns, newRows, newCells, newPoints);
2399
2763
  }
2400
2764
  };
2401
- const addSwimlaneColumn = (board, swimlane, index) => {
2402
- if (PlaitDrawElement.isSwimlane(swimlane) && swimlane.shape === SwimlaneSymbols.swimlaneVertical) {
2765
+ const addSwimlaneColumn = (board, swimlane, index, count = 1) => {
2766
+ if (PlaitDrawElement.isVerticalSwimlane(swimlane)) {
2403
2767
  const newColumns = [...swimlane.columns];
2404
- const newColumnId = idCreator();
2405
- newColumns.splice(index, 0, { id: newColumnId });
2406
- let newCells = createNewColumnCells(swimlane, newColumnId);
2407
- newCells.shift();
2408
- newCells = [...swimlane.cells, ...newCells];
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
+ });
2409
2777
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2410
2778
  const lastColumnWidth = RectangleClient.getRectangleByPoints(lastCellPoints).width;
2411
- 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]]];
2412
2780
  updateSwimlane(board, swimlane, newColumns, swimlane.rows, newCells, newPoints);
2413
2781
  }
2414
2782
  };
2415
- const removeSwimlaneRow = (board, swimlane, index) => {
2416
- 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
+ }
2417
2788
  const newRows = [...swimlane.rows];
2418
- newRows.splice(index, 1);
2789
+ newRows.splice(index, count);
2419
2790
  if (newRows.length === 0) {
2420
2791
  const path = PlaitBoard.findPath(board, swimlane);
2421
2792
  Transforms.removeNode(board, path);
2422
2793
  }
2423
2794
  else {
2424
- const removeRow = swimlane.rows[index];
2425
- const newCells = swimlane.cells.filter(item => item.rowId !== removeRow.id);
2426
- let removeRowHeight = removeRow.height;
2427
- if (!removeRowHeight) {
2428
- const cellPoints = getCellWithPoints(board, swimlane, swimlane.cells[index].id).points;
2429
- 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);
2430
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
+ });
2431
2813
  const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] - removeRowHeight]];
2432
2814
  updateSwimlane(board, swimlane, swimlane.columns, newRows, newCells, newPoints);
2433
2815
  }
2434
2816
  }
2435
2817
  };
2436
- const removeSwimlaneColumn = (board, swimlane, index) => {
2437
- 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
+ }
2438
2823
  const newColumns = [...swimlane.columns];
2439
- newColumns.splice(index, 1);
2824
+ newColumns.splice(index, count);
2440
2825
  if (newColumns.length === 0) {
2441
2826
  const path = PlaitBoard.findPath(board, swimlane);
2442
2827
  Transforms.removeNode(board, path);
2443
2828
  }
2444
2829
  else {
2445
- const removeColumn = swimlane.columns[index];
2446
- const newCells = swimlane.cells.filter(item => item.columnId !== removeColumn.id);
2447
- let removeColumnWidth = removeColumn.width;
2448
- if (!removeColumnWidth) {
2449
- const cellPoints = getCellWithPoints(board, swimlane, swimlane.cells[index].id).points;
2450
- 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);
2451
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
+ });
2452
2848
  const newPoints = [swimlane.points[0], [swimlane.points[1][0] - removeColumnWidth, swimlane.points[1][1]]];
2453
2849
  updateSwimlane(board, swimlane, newColumns, swimlane.rows, newCells, newPoints);
2454
2850
  }
2455
2851
  }
2456
2852
  };
2457
- const createNewColumnCells = (swimlane, newColumnId) => {
2458
- return swimlane.rows.map(row => ({
2459
- id: idCreator(),
2460
- rowId: row.id,
2461
- columnId: newColumnId
2462
- }));
2463
- };
2464
- const createNewRowCells = (swimlane, newRowId) => {
2465
- return swimlane.columns.map(column => ({
2853
+ const createNewSwimlaneCells = (swimlane, newId, type) => {
2854
+ const cells = swimlane[`${type}s`].map(item => ({
2466
2855
  id: idCreator(),
2467
- rowId: newRowId,
2468
- columnId: column.id
2856
+ rowId: type === 'row' ? item.id : newId,
2857
+ columnId: type === 'row' ? newId : item.id
2469
2858
  }));
2859
+ if (swimlane.header) {
2860
+ cells.shift();
2861
+ }
2862
+ cells[0] = {
2863
+ ...cells[0],
2864
+ text: {
2865
+ children: [{ text: swimlane.header ? 'Lane' : 'New Swimlane' }],
2866
+ align: Alignment.center,
2867
+ direction: type === 'row' ? undefined : 'vertical'
2868
+ },
2869
+ textHeight: 20
2870
+ };
2871
+ return cells;
2470
2872
  };
2471
2873
  const updateSwimlane = (board, swimlane, newColumns, newRows, newCells, newPoints) => {
2472
2874
  const path = PlaitBoard.findPath(board, swimlane);
@@ -2477,6 +2879,33 @@ const updateSwimlane = (board, swimlane, newColumns, newRows, newCells, newPoint
2477
2879
  points: newPoints
2478
2880
  }, path);
2479
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
+ };
2480
2909
 
2481
2910
  const setDrawShapeText = (board, element, text) => {
2482
2911
  const newTexts = element.texts?.map(item => {
@@ -2552,7 +2981,9 @@ const DrawTransforms = {
2552
2981
  addSwimlaneRow,
2553
2982
  addSwimlaneColumn,
2554
2983
  removeSwimlaneRow,
2555
- removeSwimlaneColumn
2984
+ removeSwimlaneColumn,
2985
+ setSwimlaneFill,
2986
+ updateSwimlaneCount
2556
2987
  };
2557
2988
 
2558
2989
  const getHitRectangleResizeHandleRef = (board, rectangle, point, angle = 0) => {
@@ -3009,6 +3440,29 @@ function drawIsometricSnapLines(board, activePoints, snapRectangles, resizeSnapO
3009
3440
  return drawSolidLines(board, isometricLines);
3010
3441
  }
3011
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
+
3012
3466
  const getCenterPointsOnPolygon = (points) => {
3013
3467
  const centerPoints = [];
3014
3468
  for (let i = 0; i < points.length; i++) {
@@ -4777,10 +5231,17 @@ const TableEngine = {
4777
5231
  pointCells.forEach(cell => {
4778
5232
  const rectangle = RectangleClient.getRectangleByPoints(cell.points);
4779
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 });
4780
5240
  const cellRightBorder = drawLine$1(rs, [x + width, y], [x + width, y + height], roughOptions);
4781
5241
  const cellBottomBorder = drawLine$1(rs, [x, y + height], [x + width, y + height], roughOptions);
4782
- g.append(cellRightBorder, cellBottomBorder);
5242
+ g.append(cellRectangle, cellRightBorder, cellBottomBorder);
4783
5243
  });
5244
+ setStrokeLinecap(g, 'round');
4784
5245
  return g;
4785
5246
  },
4786
5247
  isInsidePoint(rectangle, point) {
@@ -5098,36 +5559,454 @@ const CombinedFragmentEngine = {
5098
5559
  }
5099
5560
  };
5100
5561
 
5101
- const ShapeEngineMap = {
5102
- [BasicShapes.rectangle]: RectangleEngine,
5103
- [BasicShapes.diamond]: DiamondEngine,
5104
- [BasicShapes.ellipse]: EllipseEngine,
5105
- [BasicShapes.parallelogram]: ParallelogramEngine,
5106
- [BasicShapes.roundRectangle]: RoundRectangleEngine,
5107
- [BasicShapes.text]: RectangleEngine,
5108
- [BasicShapes.triangle]: TriangleEngine,
5109
- [BasicShapes.leftArrow]: LeftArrowEngine,
5110
- [BasicShapes.trapezoid]: TrapezoidEngine,
5111
- [BasicShapes.rightArrow]: RightArrowEngine,
5112
- [BasicShapes.cross]: CrossEngine,
5113
- [BasicShapes.star]: StarEngine,
5114
- [BasicShapes.pentagon]: PentagonEngine,
5115
- [BasicShapes.hexagon]: HexagonEngine,
5116
- [BasicShapes.octagon]: OctagonEngine,
5117
- [BasicShapes.pentagonArrow]: PentagonArrowEngine,
5118
- [BasicShapes.processArrow]: ProcessArrowEngine,
5119
- [BasicShapes.twoWayArrow]: TwoWayArrowEngine,
5120
- [BasicShapes.comment]: CommentEngine,
5121
- [BasicShapes.roundComment]: RoundCommentEngine,
5122
- [BasicShapes.cloud]: CloudEngine,
5123
- [FlowchartSymbols.process]: RectangleEngine,
5124
- [FlowchartSymbols.decision]: DiamondEngine,
5125
- [FlowchartSymbols.connector]: EllipseEngine,
5126
- [FlowchartSymbols.data]: ParallelogramEngine,
5127
- [FlowchartSymbols.terminal]: TerminalEngine,
5128
- [FlowchartSymbols.database]: DatabaseEngine,
5129
- [FlowchartSymbols.hardDisk]: HardDiskEngine,
5130
- [FlowchartSymbols.internalStorage]: InternalStorageEngine,
5562
+ const DeletionEngine = {
5563
+ draw(board, rectangle, options) {
5564
+ const rs = PlaitBoard.getRoughSVG(board);
5565
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y} L${rectangle.x + rectangle.width} ${rectangle.y + rectangle.height}
5566
+ M${rectangle.x + rectangle.width} ${rectangle.y} L${rectangle.x} ${rectangle.y + rectangle.height}
5567
+ `, { ...options, fillStyle: 'solid', strokeWidth: 4 });
5568
+ return shape;
5569
+ },
5570
+ isInsidePoint(rectangle, point) {
5571
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5572
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5573
+ },
5574
+ getCornerPoints(rectangle) {
5575
+ return RectangleClient.getCornerPoints(rectangle);
5576
+ },
5577
+ getNearestPoint(rectangle, point) {
5578
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5579
+ },
5580
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5581
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5582
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5583
+ return getPolygonEdgeByConnectionPoint(corners, point);
5584
+ },
5585
+ getConnectorPoints(rectangle) {
5586
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5587
+ }
5588
+ };
5589
+
5590
+ const ActiveClassEngine = {
5591
+ draw(board, rectangle, options) {
5592
+ const rs = PlaitBoard.getRoughSVG(board);
5593
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y} H${rectangle.x + rectangle.width} V${rectangle.y + rectangle.height} H${rectangle.x} Z M${rectangle.x + rectangle.width * 0.125} ${rectangle.y} L${rectangle.x + rectangle.width * 0.125} ${rectangle.y +
5594
+ rectangle.height} M${rectangle.x + rectangle.width - rectangle.width * 0.125} ${rectangle.y} L${rectangle.x +
5595
+ rectangle.width -
5596
+ rectangle.width * 0.125} ${rectangle.y + rectangle.height}`, { ...options, fillStyle: 'solid' });
5597
+ setStrokeLinecap(shape, 'round');
5598
+ return shape;
5599
+ },
5600
+ isInsidePoint(rectangle, point) {
5601
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5602
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5603
+ },
5604
+ getCornerPoints(rectangle) {
5605
+ return RectangleClient.getCornerPoints(rectangle);
5606
+ },
5607
+ getNearestPoint(rectangle, point) {
5608
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5609
+ },
5610
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5611
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5612
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5613
+ return getPolygonEdgeByConnectionPoint(corners, point);
5614
+ },
5615
+ getConnectorPoints(rectangle) {
5616
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5617
+ },
5618
+ getTextRectangle: (element) => {
5619
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5620
+ const strokeWidth = getStrokeWidthByElement(element);
5621
+ const height = element.textHeight;
5622
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2 - elementRectangle.width * 0.125 * 2;
5623
+ return {
5624
+ height,
5625
+ width: width > 0 ? width : 0,
5626
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + elementRectangle.width * 0.125,
5627
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5628
+ };
5629
+ }
5630
+ };
5631
+
5632
+ const NoteEngine = {
5633
+ draw(board, rectangle, options) {
5634
+ const rs = PlaitBoard.getRoughSVG(board);
5635
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y}
5636
+ h${rectangle.width - 16}
5637
+ v16
5638
+ h16
5639
+ v${rectangle.height - 16}
5640
+ h${-rectangle.width}
5641
+ Z
5642
+ M${rectangle.x + rectangle.width - 16} ${rectangle.y}
5643
+ A16 16, 0,0,1, ${rectangle.x + rectangle.width} ${rectangle.y + 16}
5644
+ `, { ...options, fillStyle: 'solid' });
5645
+ setStrokeLinecap(shape, 'round');
5646
+ return shape;
5647
+ },
5648
+ isInsidePoint(rectangle, point) {
5649
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5650
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5651
+ },
5652
+ getCornerPoints(rectangle) {
5653
+ return RectangleClient.getCornerPoints(rectangle);
5654
+ },
5655
+ getNearestPoint(rectangle, point) {
5656
+ const nearestPoint = getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5657
+ if (nearestPoint[0] > rectangle.x + rectangle.width - 16 && nearestPoint[1] < rectangle.y + 16) {
5658
+ return getNearestPointBetweenPointAndEllipse(point, [rectangle.x + rectangle.width - 16, rectangle.y + 16], 16, 16);
5659
+ }
5660
+ return nearestPoint;
5661
+ },
5662
+ getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
5663
+ const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5664
+ const centerPoint = [rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height / 2];
5665
+ const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
5666
+ const slope = getEllipseTangentSlope(point[0], point[1], 16, 16);
5667
+ return getVectorFromPointAndSlope(point[0], point[1], slope);
5668
+ },
5669
+ getConnectorPoints(rectangle) {
5670
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5671
+ },
5672
+ getTextRectangle: (element) => {
5673
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5674
+ const strokeWidth = getStrokeWidthByElement(element);
5675
+ const height = element.textHeight;
5676
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth - 15;
5677
+ return {
5678
+ height,
5679
+ width: width > 0 ? width : 0,
5680
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
5681
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5682
+ };
5683
+ }
5684
+ };
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
+
5980
+ const ShapeEngineMap = {
5981
+ [BasicShapes.rectangle]: RectangleEngine,
5982
+ [BasicShapes.diamond]: DiamondEngine,
5983
+ [BasicShapes.ellipse]: EllipseEngine,
5984
+ [BasicShapes.parallelogram]: ParallelogramEngine,
5985
+ [BasicShapes.roundRectangle]: RoundRectangleEngine,
5986
+ [BasicShapes.text]: RectangleEngine,
5987
+ [BasicShapes.triangle]: TriangleEngine,
5988
+ [BasicShapes.leftArrow]: LeftArrowEngine,
5989
+ [BasicShapes.trapezoid]: TrapezoidEngine,
5990
+ [BasicShapes.rightArrow]: RightArrowEngine,
5991
+ [BasicShapes.cross]: CrossEngine,
5992
+ [BasicShapes.star]: StarEngine,
5993
+ [BasicShapes.pentagon]: PentagonEngine,
5994
+ [BasicShapes.hexagon]: HexagonEngine,
5995
+ [BasicShapes.octagon]: OctagonEngine,
5996
+ [BasicShapes.pentagonArrow]: PentagonArrowEngine,
5997
+ [BasicShapes.processArrow]: ProcessArrowEngine,
5998
+ [BasicShapes.twoWayArrow]: TwoWayArrowEngine,
5999
+ [BasicShapes.comment]: CommentEngine,
6000
+ [BasicShapes.roundComment]: RoundCommentEngine,
6001
+ [BasicShapes.cloud]: CloudEngine,
6002
+ [FlowchartSymbols.process]: RectangleEngine,
6003
+ [FlowchartSymbols.decision]: DiamondEngine,
6004
+ [FlowchartSymbols.connector]: EllipseEngine,
6005
+ [FlowchartSymbols.data]: ParallelogramEngine,
6006
+ [FlowchartSymbols.terminal]: TerminalEngine,
6007
+ [FlowchartSymbols.database]: DatabaseEngine,
6008
+ [FlowchartSymbols.hardDisk]: HardDiskEngine,
6009
+ [FlowchartSymbols.internalStorage]: InternalStorageEngine,
5131
6010
  [FlowchartSymbols.manualInput]: ManualInputEngine,
5132
6011
  [FlowchartSymbols.preparation]: PreparationEngine,
5133
6012
  [FlowchartSymbols.manualLoop]: ManualLoopEngine,
@@ -5150,8 +6029,24 @@ const ShapeEngineMap = {
5150
6029
  [UMLSymbols.actor]: ActorEngine,
5151
6030
  [UMLSymbols.useCase]: EllipseEngine,
5152
6031
  [UMLSymbols.container]: ContainerEngine,
6032
+ [UMLSymbols.note]: NoteEngine,
5153
6033
  [UMLSymbols.package]: PackageEngine,
5154
- [UMLSymbols.combinedFragment]: CombinedFragmentEngine
6034
+ [UMLSymbols.combinedFragment]: CombinedFragmentEngine,
6035
+ [UMLSymbols.class]: TableEngine,
6036
+ [UMLSymbols.interface]: TableEngine,
6037
+ [UMLSymbols.activation]: RectangleEngine,
6038
+ [UMLSymbols.object]: RectangleEngine,
6039
+ [UMLSymbols.deletion]: DeletionEngine,
6040
+ [UMLSymbols.activityClass]: ActiveClassEngine,
6041
+ [UMLSymbols.simpleClass]: RectangleEngine,
6042
+ [UMLSymbols.component]: ComponentEngine,
6043
+ [UMLSymbols.componentBox]: ComponentBoxEngine,
6044
+ [UMLSymbols.template]: TemplateEngine,
6045
+ [UMLSymbols.port]: RectangleEngine,
6046
+ [UMLSymbols.branchMerge]: DiamondEngine,
6047
+ [UMLSymbols.assembly]: AssemblyEngine,
6048
+ [UMLSymbols.requiredInterface]: RequiredInterfaceEngine,
6049
+ [UMLSymbols.providedInterface]: ProvidedInterfaceEngine
5155
6050
  };
5156
6051
  const getEngine = (shape) => {
5157
6052
  return ShapeEngineMap[shape];
@@ -5376,7 +6271,8 @@ const PlaitDrawElement = {
5376
6271
  if (PlaitDrawElement.isGeometry(value) ||
5377
6272
  PlaitDrawElement.isLine(value) ||
5378
6273
  PlaitDrawElement.isImage(value) ||
5379
- PlaitTableElement.isTable(value)) {
6274
+ PlaitDrawElement.isTable(value) ||
6275
+ PlaitDrawElement.isSwimlane(value)) {
5380
6276
  return true;
5381
6277
  }
5382
6278
  else {
@@ -5384,7 +6280,7 @@ const PlaitDrawElement = {
5384
6280
  }
5385
6281
  },
5386
6282
  isShapeElement: (value) => {
5387
- return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isTable(value);
6283
+ return PlaitDrawElement.isImage(value) || PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isTable(value) || PlaitDrawElement.isSwimlane(value);
5388
6284
  },
5389
6285
  isBasicShape: (value) => {
5390
6286
  return Object.keys(BasicShapes).includes(value.shape);
@@ -5396,17 +6292,23 @@ const PlaitDrawElement = {
5396
6292
  return Object.keys(UMLSymbols).includes(value.shape);
5397
6293
  },
5398
6294
  isSwimlane: (value) => {
5399
- return Object.keys(SwimlaneSymbols).includes(value.shape);
6295
+ return value.type === 'swimlane';
5400
6296
  },
5401
6297
  isVerticalSwimlane: (value) => {
5402
- return Object.keys(SwimlaneSymbols).includes(value.shape) && value.shape === SwimlaneSymbols.swimlaneVertical;
6298
+ return PlaitDrawElement.isSwimlane(value) && value.shape === SwimlaneSymbols.swimlaneVertical;
5403
6299
  },
5404
6300
  isHorizontalSwimlane: (value) => {
5405
- return Object.keys(SwimlaneSymbols).includes(value.shape) && value.shape === SwimlaneSymbols.swimlaneHorizontal;
6301
+ return PlaitDrawElement.isSwimlane(value) && value.shape === SwimlaneSymbols.swimlaneHorizontal;
5406
6302
  },
5407
6303
  isUMLClassOrInterface: (value) => {
5408
- return false;
5409
- }
6304
+ return Object.keys(UMLSymbols).includes(value.shape) && [UMLSymbols.class, UMLSymbols.interface].includes(value.shape);
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
+ },
5410
6312
  };
5411
6313
 
5412
6314
  class GeometryShapeGenerator extends Generator {
@@ -5478,8 +6380,8 @@ class SingleTextGenerator extends TextGenerator {
5478
6380
  get textManage() {
5479
6381
  return this.textManages[0];
5480
6382
  }
5481
- constructor(board, element, text, viewContainerRef, options) {
5482
- 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);
5483
6385
  }
5484
6386
  update(element, previousText, currentText, elementG) {
5485
6387
  if (!isMultipleTextGeometry(element)) {
@@ -5569,34 +6471,32 @@ class GeometryComponent extends CommonElementFlavour {
5569
6471
  }
5570
6472
  }
5571
6473
  initializeTextManage() {
5572
- const onTextValueChangeHandle = (element, textManageRef, text) => {
5573
- const height = textManageRef.height / this.board.viewport.zoom;
5574
- const width = textManageRef.width / this.board.viewport.zoom;
5575
- if (textManageRef.newValue) {
6474
+ const onTextChange = (element, textManageChangeData, text) => {
6475
+ if (textManageChangeData.newText) {
5576
6476
  if (isMultipleTextGeometry(element)) {
5577
6477
  DrawTransforms.setDrawShapeText(this.board, element, {
5578
6478
  key: text.key,
5579
- text: textManageRef.newValue,
5580
- textHeight: height
6479
+ text: textManageChangeData.newText,
6480
+ textHeight: textManageChangeData.height
5581
6481
  });
5582
6482
  }
5583
6483
  else {
5584
- DrawTransforms.setText(this.board, element, textManageRef.newValue, width, height);
6484
+ DrawTransforms.setText(this.board, element, textManageChangeData.newText, textManageChangeData.width, textManageChangeData.height);
5585
6485
  }
5586
6486
  }
5587
6487
  else {
5588
- DrawTransforms.setTextSize(this.board, element, width, height);
6488
+ DrawTransforms.setTextSize(this.board, element, textManageChangeData.width, textManageChangeData.height);
5589
6489
  }
5590
- textManageRef.operations && memorizeLatestText(element, textManageRef.operations);
6490
+ textManageChangeData.operations && memorizeLatestText(element, textManageChangeData.operations);
5591
6491
  };
5592
6492
  if (isMultipleTextGeometry(this.element)) {
5593
- this.textGenerator = new TextGenerator(this.board, this.element, this.element.texts, PlaitBoard.getViewContainerRef(this.board), {
5594
- onValueChangeHandle: onTextValueChangeHandle
6493
+ this.textGenerator = new TextGenerator(this.board, this.element, this.element.texts, {
6494
+ onChange: onTextChange
5595
6495
  });
5596
6496
  }
5597
6497
  else {
5598
- this.textGenerator = new SingleTextGenerator(this.board, this.element, this.element.text, PlaitBoard.getViewContainerRef(this.board), {
5599
- onValueChangeHandle: onTextValueChangeHandle,
6498
+ this.textGenerator = new SingleTextGenerator(this.board, this.element, this.element.text, {
6499
+ onChange: onTextChange,
5600
6500
  getMaxWidth: () => {
5601
6501
  let width = getTextRectangle(this.element).width;
5602
6502
  const getRectangle = getEngine(this.element.shape).getTextRectangle;
@@ -5785,24 +6685,24 @@ class LineComponent extends CommonElementFlavour {
5785
6685
  }
5786
6686
  }
5787
6687
  createTextManage(text, index) {
5788
- return new TextManage(this.board, PlaitBoard.getViewContainerRef(this.board), {
6688
+ return new TextManage(this.board, {
5789
6689
  getRectangle: () => {
5790
6690
  return getLineTextRectangle(this.board, this.element, index);
5791
6691
  },
5792
- onValueChangeHandle: (textManageRef) => {
5793
- const height = textManageRef.height / this.board.viewport.zoom;
5794
- const width = textManageRef.width / this.board.viewport.zoom;
6692
+ onChange: (textManageChangeData) => {
5795
6693
  const texts = [...this.element.texts];
6694
+ const newWidth = textManageChangeData.width < MIN_TEXT_WIDTH ? MIN_TEXT_WIDTH : textManageChangeData.width;
5796
6695
  texts.splice(index, 1, {
5797
- text: textManageRef.newValue ? textManageRef.newValue : this.element.texts[index].text,
6696
+ text: textManageChangeData.newText ? textManageChangeData.newText : this.element.texts[index].text,
5798
6697
  position: this.element.texts[index].position,
5799
- width,
5800
- height
6698
+ width: newWidth,
6699
+ height: textManageChangeData.height
5801
6700
  });
5802
6701
  DrawTransforms.setLineTexts(this.board, this.element, texts);
5803
- textManageRef.operations && memorizeLatestText(this.element, textManageRef.operations);
6702
+ textManageChangeData.operations && memorizeLatestText(this.element, textManageChangeData.operations);
5804
6703
  },
5805
- getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth
6704
+ getMaxWidth: () => GeometryThreshold.defaultTextMaxWidth,
6705
+ textPlugins: []
5806
6706
  });
5807
6707
  }
5808
6708
  updateText(previousTexts, currentTexts) {
@@ -5877,6 +6777,21 @@ const withDrawHotkey = (board) => {
5877
6777
  return board;
5878
6778
  };
5879
6779
 
6780
+ class TableGenerator extends Generator {
6781
+ canDraw(element, data) {
6782
+ return true;
6783
+ }
6784
+ draw(element, data) {
6785
+ const rectangle = RectangleClient.getRectangleByPoints(element.points);
6786
+ return getEngine(TableSymbols.table).draw(this.board, rectangle, {
6787
+ strokeWidth: 2,
6788
+ stroke: getDrawDefaultStrokeColor(this.board.theme.themeColorMode),
6789
+ }, {
6790
+ element: element
6791
+ });
6792
+ }
6793
+ }
6794
+
5880
6795
  const isGeometryDndMode = (board) => {
5881
6796
  const geometryPointers = getGeometryPointers();
5882
6797
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
@@ -5889,6 +6804,14 @@ const isGeometryDrawingMode = (board) => {
5889
6804
  const drawingMode = isGeometryPointer && isDrawingMode(board);
5890
6805
  return drawingMode;
5891
6806
  };
6807
+ const getGeometryGeneratorByShape = (board, shape) => {
6808
+ if (PlaitDrawElement.isUMLClassOrInterface({ shape: shape })) {
6809
+ return new TableGenerator(board);
6810
+ }
6811
+ else {
6812
+ return new GeometryShapeGenerator(board);
6813
+ }
6814
+ };
5892
6815
  const withGeometryCreateByDrag = (board) => {
5893
6816
  const { pointerMove, globalPointerUp, pointerUp } = board;
5894
6817
  let geometryShapeG = null;
@@ -5897,12 +6820,12 @@ const withGeometryCreateByDrag = (board) => {
5897
6820
  board.pointerMove = (event) => {
5898
6821
  geometryShapeG?.remove();
5899
6822
  geometryShapeG = createG();
5900
- const geometryGenerator = new GeometryShapeGenerator(board);
5901
6823
  const geometryPointers = getGeometryPointers();
5902
6824
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
5903
6825
  const dragMode = isGeometryPointer && isDndMode(board);
5904
6826
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
5905
6827
  const pointer = PlaitBoard.getPointer(board);
6828
+ const geometryGenerator = getGeometryGeneratorByShape(board, pointer);
5906
6829
  if (dragMode) {
5907
6830
  const memorizedLatest = getMemorizedLatestByPointer(pointer);
5908
6831
  if (pointer === BasicShapes.text) {
@@ -5910,16 +6833,12 @@ const withGeometryCreateByDrag = (board) => {
5910
6833
  const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(movingPoint, property.width, property.height));
5911
6834
  temporaryElement = createTextElement(board, points);
5912
6835
  if (!fakeCreateTextRef) {
5913
- const textManage = new TextManage(board, PlaitBoard.getComponent(board).viewContainerRef, {
6836
+ const textManage = new TextManage(board, {
5914
6837
  getRectangle: () => {
5915
6838
  return getTextRectangle(temporaryElement);
5916
6839
  }
5917
6840
  });
5918
- PlaitBoard.getComponent(board)
5919
- .viewContainerRef.injector.get(NgZone)
5920
- .run(() => {
5921
- textManage.draw(temporaryElement.text);
5922
- });
6841
+ textManage.draw(temporaryElement.text);
5923
6842
  fakeCreateTextRef = {
5924
6843
  g: createG(),
5925
6844
  textManage
@@ -5997,9 +6916,9 @@ const withGeometryCreateByDrawing = (board) => {
5997
6916
  board.pointerMove = (event) => {
5998
6917
  geometryShapeG?.remove();
5999
6918
  geometryShapeG = createG();
6000
- const geometryGenerator = new GeometryShapeGenerator(board);
6001
6919
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
6002
6920
  const pointer = PlaitBoard.getPointer(board);
6921
+ const geometryGenerator = getGeometryGeneratorByShape(board, pointer);
6003
6922
  snapG?.remove();
6004
6923
  if (start && isGeometryDrawingMode(board)) {
6005
6924
  let points = normalizeShapePoints([start, movingPoint], isShift);
@@ -6051,7 +6970,7 @@ const withGeometryCreateByDrawing = (board) => {
6051
6970
 
6052
6971
  const buildClipboardData = (board, elements, startPoint) => {
6053
6972
  return elements.map(element => {
6054
- if (PlaitDrawElement.isGeometry(element) || PlaitDrawElement.isImage(element) || PlaitDrawElement.isTable(element)) {
6973
+ if (PlaitDrawElement.isShapeElement(element)) {
6055
6974
  const points = element.points.map(point => [point[0] - startPoint[0], point[1] - startPoint[1]]);
6056
6975
  return { ...element, points };
6057
6976
  }
@@ -6081,37 +7000,28 @@ const buildClipboardData = (board, elements, startPoint) => {
6081
7000
  };
6082
7001
  const insertClipboardData = (board, elements, startPoint) => {
6083
7002
  const lines = elements.filter(value => PlaitDrawElement.isLine(value));
6084
- const geometries = elements.filter(value => PlaitDrawElement.isGeometry(value) || PlaitDrawElement.isImage(value));
6085
- 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));
6086
7005
  geometries.forEach(element => {
6087
- const sourceLines = [];
6088
- const targetLines = [];
6089
- lines.forEach(line => {
6090
- if (PlaitLine.isBoundElementOfSource(line, element)) {
6091
- sourceLines.push(line);
6092
- }
6093
- if (PlaitLine.isBoundElementOfTarget(line, element)) {
6094
- targetLines.push(line);
6095
- }
6096
- });
6097
- element.id = idCreator();
6098
- // update lines
6099
- sourceLines.forEach(sourceLine => (sourceLine.source.boundId = element.id));
6100
- targetLines.forEach(targetLine => (targetLine.target.boundId = element.id));
7006
+ const newId = idCreator();
7007
+ updateBoundLinesId(element, lines, newId);
7008
+ element.id = newId;
6101
7009
  element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
6102
7010
  Transforms.insertNode(board, element, [board.children.length]);
6103
7011
  });
7012
+ insertClipboardTableData(board, tables, startPoint, lines);
6104
7013
  lines.forEach(element => {
6105
7014
  element.id = idCreator();
6106
7015
  element.points = element.points.map(point => [startPoint[0] + point[0], startPoint[1] + point[1]]);
6107
7016
  Transforms.insertNode(board, element, [board.children.length]);
6108
7017
  });
6109
- insertClipboardTableData(board, tables, startPoint);
6110
7018
  Transforms.addSelectionWithTemporaryElements(board, elements);
6111
7019
  };
6112
- const insertClipboardTableData = (board, elements, startPoint) => {
7020
+ const insertClipboardTableData = (board, elements, startPoint, lines) => {
6113
7021
  elements.forEach(element => {
6114
- element.id = idCreator();
7022
+ const newId = idCreator();
7023
+ updateBoundLinesId(element, lines, newId);
7024
+ element.id = newId;
6115
7025
  updateRowOrColumnIds(element, 'row');
6116
7026
  updateRowOrColumnIds(element, 'column');
6117
7027
  updateCellIds(element.cells);
@@ -6119,6 +7029,21 @@ const insertClipboardTableData = (board, elements, startPoint) => {
6119
7029
  Transforms.insertNode(board, element, [board.children.length]);
6120
7030
  });
6121
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
+ };
6122
7047
 
6123
7048
  const withDrawFragment = (baseBoard) => {
6124
7049
  const board = baseBoard;
@@ -6130,15 +7055,19 @@ const withDrawFragment = (baseBoard) => {
6130
7055
  const lineElements = drawElements.filter(value => PlaitDrawElement.isLine(value));
6131
7056
  const imageElements = drawElements.filter(value => PlaitDrawElement.isImage(value));
6132
7057
  const tableElements = drawElements.filter(value => PlaitDrawElement.isTable(value));
7058
+ const swimlaneElements = drawElements.filter(value => PlaitDrawElement.isSwimlane(value));
6133
7059
  const boundLineElements = [
6134
7060
  ...getBoundedLineElements(board, geometryElements),
6135
- ...getBoundedLineElements(board, imageElements)
7061
+ ...getBoundedLineElements(board, imageElements),
7062
+ ...getBoundedLineElements(board, tableElements),
7063
+ ...getBoundedLineElements(board, swimlaneElements)
6136
7064
  ].filter(line => !lineElements.includes(line));
6137
7065
  data.push(...[
6138
7066
  ...geometryElements,
6139
7067
  ...lineElements,
6140
7068
  ...imageElements,
6141
7069
  ...tableElements,
7070
+ ...swimlaneElements,
6142
7071
  ...boundLineElements.filter(line => !lineElements.includes(line))
6143
7072
  ]);
6144
7073
  }
@@ -6533,7 +7462,7 @@ const withLineText = (board) => {
6533
7462
  else {
6534
7463
  const ratio = getRatioByPoint(points, point);
6535
7464
  texts.push({
6536
- text: buildText('文本'),
7465
+ text: buildText(LINE_TEXT),
6537
7466
  position: ratio,
6538
7467
  width: 28,
6539
7468
  height: 20
@@ -6556,10 +7485,9 @@ const withLineText = (board) => {
6556
7485
  function editHandle(board, element, manageIndex, isFirstEdit = false) {
6557
7486
  const textManages = getTextManages(element);
6558
7487
  const textManage = textManages[manageIndex];
6559
- const originText = textManage.componentRef.instance.children;
6560
- textManage.edit((origin, descendant) => {
6561
- const text = Node.string(descendant[0]);
6562
- const shouldRemove = (isFirstEdit && originText === descendant) || !text;
7488
+ textManage.edit(() => {
7489
+ const text = Node.string(textManage.getText());
7490
+ const shouldRemove = !text || (isFirstEdit && text === LINE_TEXT);
6563
7491
  if (shouldRemove) {
6564
7492
  DrawTransforms.removeLineText(board, element, manageIndex);
6565
7493
  }
@@ -6567,9 +7495,6 @@ function editHandle(board, element, manageIndex, isFirstEdit = false) {
6567
7495
  }
6568
7496
 
6569
7497
  class ImageComponent extends CommonElementFlavour {
6570
- get activeGenerator() {
6571
- return this.imageGenerator.componentRef.instance.activeGenerator;
6572
- }
6573
7498
  constructor() {
6574
7499
  super();
6575
7500
  }
@@ -6597,7 +7522,7 @@ class ImageComponent extends CommonElementFlavour {
6597
7522
  initialize() {
6598
7523
  super.initialize();
6599
7524
  this.initializeGenerator();
6600
- this.imageGenerator.processDrawing(this.element, this.getElementG(), PlaitBoard.getViewContainerRef(this.board));
7525
+ this.imageGenerator.processDrawing(this.element, this.getElementG());
6601
7526
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6602
7527
  selected: this.selected
6603
7528
  });
@@ -6605,16 +7530,17 @@ class ImageComponent extends CommonElementFlavour {
6605
7530
  onContextChanged(value, previous) {
6606
7531
  if (value.element !== previous.element) {
6607
7532
  this.imageGenerator.updateImage(this.getElementG(), previous.element, value.element);
6608
- this.imageGenerator.componentRef.instance.isFocus = this.selected;
7533
+ this.imageGenerator.setFocus(this.element, this.selected);
6609
7534
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6610
7535
  selected: this.selected
6611
7536
  });
6612
7537
  }
6613
7538
  else {
6614
7539
  const hasSameSelected = value.selected === previous.selected;
6615
- 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;
6616
7542
  if (!hasSameSelected || !hasSameHandleState) {
6617
- this.imageGenerator.componentRef.instance.isFocus = this.selected;
7543
+ this.imageGenerator.setFocus(this.element, this.selected);
6618
7544
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
6619
7545
  selected: this.selected
6620
7546
  });
@@ -6900,21 +7826,6 @@ const withDrawRotate = (board) => {
6900
7826
  return board;
6901
7827
  };
6902
7828
 
6903
- class TableGenerator extends Generator {
6904
- canDraw(element, data) {
6905
- return true;
6906
- }
6907
- draw(element, data) {
6908
- const rectangle = RectangleClient.getRectangleByPoints(element.points);
6909
- return getEngine(TableSymbols.table).draw(this.board, rectangle, {
6910
- strokeWidth: 2,
6911
- stroke: getDrawDefaultStrokeColor(this.board.theme.themeColorMode),
6912
- }, {
6913
- element: element
6914
- });
6915
- }
6916
- }
6917
-
6918
7829
  class TableComponent extends CommonElementFlavour {
6919
7830
  constructor() {
6920
7831
  super();
@@ -6928,9 +7839,17 @@ class TableComponent extends CommonElementFlavour {
6928
7839
  return 1;
6929
7840
  },
6930
7841
  getRectangle: (value) => {
7842
+ const cells = getSelectedCells(value);
7843
+ if (cells?.length) {
7844
+ return getCellsRectangle(this.board, this.element, cells);
7845
+ }
6931
7846
  return RectangleClient.getRectangleByPoints(value.points);
6932
7847
  },
6933
7848
  hasResizeHandle: () => {
7849
+ const cells = getSelectedCells(this.element);
7850
+ if (cells?.length) {
7851
+ return false;
7852
+ }
6934
7853
  return canResize(this.board, this.element);
6935
7854
  }
6936
7855
  });
@@ -6953,7 +7872,8 @@ class TableComponent extends CommonElementFlavour {
6953
7872
  });
6954
7873
  }
6955
7874
  rotateVerticalText() {
6956
- this.element.cells.forEach(item => {
7875
+ const table = this.board.buildTable(this.element);
7876
+ table.cells.forEach(item => {
6957
7877
  if (PlaitTableElement.isVerticalText(item)) {
6958
7878
  const textManage = getTextManage(item.id);
6959
7879
  if (textManage) {
@@ -6979,14 +7899,14 @@ class TableComponent extends CommonElementFlavour {
6979
7899
  }
6980
7900
  initializeTextManage() {
6981
7901
  const texts = this.getDrawShapeTexts(this.element.cells);
6982
- this.textGenerator = new TextGenerator(this.board, this.element, texts, PlaitBoard.getViewContainerRef(this.board), {
6983
- onValueChangeHandle: (value, textManageRef, text) => {
6984
- const height = textManageRef.height / this.board.viewport.zoom;
6985
- const width = textManageRef.width / this.board.viewport.zoom;
6986
- if (textManageRef.newValue) {
6987
- 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);
6988
7908
  }
6989
- textManageRef.operations && memorizeLatestText(value, textManageRef.operations);
7909
+ data.operations && memorizeLatestText(value, data.operations);
6990
7910
  },
6991
7911
  getRenderRectangle: (value, text) => {
6992
7912
  const cell = getCellWithPoints(this.board, value, text.key);
@@ -7010,7 +7930,13 @@ class TableComponent extends CommonElementFlavour {
7010
7930
  this.textGenerator.initialize();
7011
7931
  }
7012
7932
  onContextChanged(value, previous) {
7013
- 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
+ }
7014
7940
  this.tableGenerator.processDrawing(value.element, this.getElementG());
7015
7941
  this.activeGenerator.processDrawing(value.element, PlaitBoard.getElementActiveHost(this.board), { selected: this.selected });
7016
7942
  const previousTexts = this.getDrawShapeTexts(previous.element.cells);
@@ -7021,11 +7947,15 @@ class TableComponent extends CommonElementFlavour {
7021
7947
  else {
7022
7948
  const hasSameSelected = value.selected === previous.selected;
7023
7949
  const hasSameHandleState = this.activeGenerator.options.hasResizeHandle() === this.activeGenerator.hasResizeHandle;
7024
- if (!hasSameSelected || !hasSameHandleState) {
7950
+ const currentSelectedCells = getSelectedCells(value.element);
7951
+ if (!hasSameSelected || !hasSameHandleState || currentSelectedCells?.length) {
7025
7952
  this.activeGenerator.processDrawing(value.element, PlaitBoard.getElementActiveHost(this.board), {
7026
7953
  selected: this.selected
7027
7954
  });
7028
7955
  }
7956
+ if (!this.selected) {
7957
+ clearSelectedCells(value.element);
7958
+ }
7029
7959
  }
7030
7960
  this.lineAutoCompleteGenerator.processDrawing(this.element, PlaitBoard.getElementActiveHost(this.board), {
7031
7961
  selected: this.selected
@@ -7050,12 +7980,13 @@ function withTableResize(board) {
7050
7980
  },
7051
7981
  hitTest: (point) => {
7052
7982
  const hitElement = getHitElementByPoint(board, point);
7053
- if (hitElement && PlaitTableElement.isTable(hitElement)) {
7983
+ if (hitElement && PlaitDrawElement.isElementByTable(hitElement)) {
7054
7984
  let rectangle = board.getRectangle(hitElement);
7055
7985
  let handleRef = getHitRectangleResizeHandleRef(board, rectangle, point, hitElement.angle);
7056
7986
  if (handleRef) {
7057
7987
  const selectElement = isSelectedElement(board, hitElement);
7058
- if ((selectElement && isSingleSelectTable(board)) || (!selectElement && !isCornerHandle(board, handleRef.handle))) {
7988
+ if ((selectElement && isSingleSelectElementByTable(board)) ||
7989
+ (!selectElement && !isCornerHandle(board, handleRef.handle))) {
7059
7990
  return {
7060
7991
  element: hitElement,
7061
7992
  handle: handleRef.handle,
@@ -7164,48 +8095,65 @@ function withTableResize(board) {
7164
8095
 
7165
8096
  const withTable = (board) => {
7166
8097
  const tableBoard = board;
7167
- const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, dblClick } = tableBoard;
8098
+ const { drawElement, getRectangle, isRectangleHit, isHit, isMovable, dblClick, keyDown } = tableBoard;
7168
8099
  tableBoard.drawElement = (context) => {
7169
- if (PlaitTableElement.isTable(context.element)) {
8100
+ if (PlaitDrawElement.isElementByTable(context.element)) {
7170
8101
  return TableComponent;
7171
8102
  }
7172
8103
  return drawElement(context);
7173
8104
  };
7174
8105
  tableBoard.isHit = (element, point) => {
7175
- if (PlaitTableElement.isTable(element)) {
8106
+ if (PlaitDrawElement.isElementByTable(element)) {
7176
8107
  const client = RectangleClient.getRectangleByPoints(element.points);
7177
8108
  return RectangleClient.isPointInRectangle(client, point);
7178
8109
  }
7179
8110
  return isHit(element, point);
7180
8111
  };
7181
8112
  tableBoard.getRectangle = (element) => {
7182
- if (PlaitTableElement.isTable(element)) {
8113
+ if (PlaitDrawElement.isElementByTable(element)) {
7183
8114
  return RectangleClient.getRectangleByPoints(element.points);
7184
8115
  }
7185
8116
  return getRectangle(element);
7186
8117
  };
7187
8118
  tableBoard.isMovable = (element) => {
7188
- if (PlaitTableElement.isTable(element)) {
8119
+ if (PlaitDrawElement.isElementByTable(element)) {
7189
8120
  return true;
7190
8121
  }
7191
8122
  return isMovable(element);
7192
8123
  };
7193
8124
  tableBoard.isRectangleHit = (element, selection) => {
7194
- if (PlaitTableElement.isTable(element)) {
8125
+ if (PlaitDrawElement.isElementByTable(element)) {
7195
8126
  const rangeRectangle = RectangleClient.getRectangleByPoints([selection.anchor, selection.focus]);
7196
8127
  return isPolylineHitRectangle(element.points, rangeRectangle);
7197
8128
  }
7198
8129
  return isRectangleHit(element, selection);
7199
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
+ };
7200
8147
  tableBoard.dblClick = (event) => {
7201
8148
  event.preventDefault();
7202
8149
  if (!PlaitBoard.isReadonly(board)) {
7203
8150
  const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7204
8151
  const hitElement = getHitElementByPoint(board, point);
7205
- if (hitElement && PlaitTableElement.isTable(hitElement)) {
8152
+ if (hitElement && PlaitDrawElement.isElementByTable(hitElement)) {
7206
8153
  const hitCell = getHitCell(tableBoard, hitElement, point);
7207
8154
  if (hitCell && hitCell.text && hitCell.textHeight) {
7208
8155
  editCell(hitCell);
8156
+ return;
7209
8157
  }
7210
8158
  }
7211
8159
  }
@@ -7217,123 +8165,6 @@ const withTable = (board) => {
7217
8165
  return withTableResize(tableBoard);
7218
8166
  };
7219
8167
 
7220
- function buildSwimlaneTable(element) {
7221
- const swimlaneElement = { ...element };
7222
- if (PlaitDrawElement.isHorizontalSwimlane(element)) {
7223
- swimlaneElement.cells = element.cells.map((item, index) => {
7224
- if (index === 0) {
7225
- item = {
7226
- ...element.cells[0],
7227
- rowspan: element.rows.length
7228
- };
7229
- }
7230
- if (item.text && item.textHeight && !item.text.direction) {
7231
- item.text.direction = 'vertical';
7232
- }
7233
- return item;
7234
- });
7235
- return swimlaneElement;
7236
- }
7237
- swimlaneElement.cells = [
7238
- {
7239
- ...element.cells[0],
7240
- colspan: element.columns.length
7241
- },
7242
- ...element.cells.slice(1, element.cells.length)
7243
- ];
7244
- return swimlaneElement;
7245
- }
7246
- const getDefaultSWimlanePoints = (pointer, centerPoint) => {
7247
- const property = DefaultSwimlanePropertyMap[pointer];
7248
- return RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(centerPoint, property.width, property.height));
7249
- };
7250
- const createDefaultSwimlane = (shape, points) => {
7251
- const rows = createDefaultRowsOrColumns(shape, 'row');
7252
- const columns = createDefaultRowsOrColumns(shape, 'column');
7253
- const swimlane = {
7254
- id: idCreator(),
7255
- type: 'table',
7256
- shape,
7257
- points,
7258
- rows,
7259
- columns,
7260
- cells: createDefaultCells(shape, rows, columns)
7261
- };
7262
- return buildSwimlaneTable(swimlane);
7263
- };
7264
- const createDefaultRowsOrColumns = (shape, type) => {
7265
- let data = new Array(3).fill('').map(item => {
7266
- return { id: idCreator() };
7267
- });
7268
- if (type === 'row' && shape === SwimlaneSymbols.swimlaneVertical) {
7269
- data = data.map((item, index) => {
7270
- if (index === 0 || index === 1) {
7271
- return {
7272
- ...item,
7273
- height: 30
7274
- };
7275
- }
7276
- return item;
7277
- });
7278
- }
7279
- if (type === 'column' && shape === SwimlaneSymbols.swimlaneHorizontal) {
7280
- data = data.map((item, index) => {
7281
- if (index === 0 || index === 1) {
7282
- return {
7283
- ...item,
7284
- width: 30
7285
- };
7286
- }
7287
- return item;
7288
- });
7289
- }
7290
- return data;
7291
- };
7292
- const createDefaultCells = (shape, rows, columns) => {
7293
- return new Array(7).fill('').map((item, index) => {
7294
- if (index === 0) {
7295
- item = {
7296
- id: idCreator(),
7297
- rowId: rows[0].id,
7298
- columnId: columns[0].id,
7299
- textHeight: DEFAULT_TEXT_HEIGHT,
7300
- text: {
7301
- children: [
7302
- {
7303
- text: 'New Swimlane'
7304
- }
7305
- ],
7306
- align: 'center'
7307
- }
7308
- };
7309
- }
7310
- if ([1, 2, 3].includes(index)) {
7311
- item = {
7312
- id: idCreator(),
7313
- rowId: shape === SwimlaneSymbols.swimlaneVertical ? rows[1].id : rows[index - 1].id,
7314
- columnId: shape === SwimlaneSymbols.swimlaneVertical ? columns[index - 1].id : columns[1].id,
7315
- textHeight: DEFAULT_TEXT_HEIGHT,
7316
- text: {
7317
- children: [
7318
- {
7319
- text: 'Lane'
7320
- }
7321
- ],
7322
- align: 'center'
7323
- }
7324
- };
7325
- }
7326
- if ([4, 5, 6].includes(index)) {
7327
- item = {
7328
- id: idCreator(),
7329
- rowId: shape === SwimlaneSymbols.swimlaneVertical ? rows[2].id : rows[index - 4].id,
7330
- columnId: shape === SwimlaneSymbols.swimlaneVertical ? columns[index - 4].id : columns[2].id
7331
- };
7332
- }
7333
- return item;
7334
- });
7335
- };
7336
-
7337
8168
  const isSwimlaneDndMode = (board) => {
7338
8169
  const swimlanePointers = getSwimlanePointers();
7339
8170
  const isSwimlanePointer = PlaitBoard.isInPointer(board, swimlanePointers);
@@ -7358,7 +8189,7 @@ const withSwimlaneCreateByDrag = (board) => {
7358
8189
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
7359
8190
  const pointer = PlaitBoard.getPointer(board);
7360
8191
  if (dragMode) {
7361
- const points = getDefaultSWimlanePoints(pointer, movingPoint);
8192
+ const points = getDefaultSwimlanePoints(pointer, movingPoint);
7362
8193
  temporaryElement = createDefaultSwimlane(pointer, points);
7363
8194
  tableGenerator.processDrawing(temporaryElement, swimlaneG);
7364
8195
  PlaitBoard.getElementActiveHost(board).append(swimlaneG);
@@ -7439,7 +8270,7 @@ const withSwimlaneCreateByDrawing = (board) => {
7439
8270
  const { width, height } = RectangleClient.getRectangleByPoints([start, targetPoint]);
7440
8271
  if (Math.hypot(width, height) < 8) {
7441
8272
  const pointer = PlaitBoard.getPointer(board);
7442
- const points = getDefaultSWimlanePoints(pointer, targetPoint);
8273
+ const points = getDefaultSwimlanePoints(pointer, targetPoint);
7443
8274
  temporaryElement = createDefaultSwimlane(pointer, points);
7444
8275
  }
7445
8276
  if (temporaryElement) {
@@ -7459,7 +8290,7 @@ const withSwimlaneCreateByDrawing = (board) => {
7459
8290
  };
7460
8291
 
7461
8292
  const withSwimlane = (board) => {
7462
- const { drawElement, buildTable } = board;
8293
+ const { drawElement, buildTable, pointerUp } = board;
7463
8294
  board.drawElement = (context) => {
7464
8295
  if (PlaitDrawElement.isSwimlane(context.element)) {
7465
8296
  return TableComponent;
@@ -7472,6 +8303,23 @@ const withSwimlane = (board) => {
7472
8303
  }
7473
8304
  return buildTable(element);
7474
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
+ };
7475
8323
  return withSwimlaneCreateByDrawing(withSwimlaneCreateByDrag(board));
7476
8324
  };
7477
8325
 
@@ -7580,5 +8428,5 @@ const withDraw = (board) => {
7580
8428
  * Generated bundle index. Do not edit.
7581
8429
  */
7582
8430
 
7583
- export { BasicShapes, DEFAULT_IMAGE_WIDTH, DEFAULT_TEXT_HEIGHT, DefaultActorProperty, DefaultArrowProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInternalStorageProperty, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, 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, 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 };
7584
8432
  //# sourceMappingURL=plait-draw.mjs.map