@plait/draw 0.58.0 → 0.60.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 (39) hide show
  1. package/constants/geometry.d.ts +82 -1
  2. package/engines/uml/activity-class.d.ts +2 -0
  3. package/engines/uml/deletion.d.ts +2 -0
  4. package/engines/uml/note.d.ts +2 -0
  5. package/esm2022/constants/geometry.mjs +64 -4
  6. package/esm2022/engines/index.mjs +15 -2
  7. package/esm2022/engines/table/table.mjs +3 -2
  8. package/esm2022/engines/uml/activity-class.mjs +47 -0
  9. package/esm2022/engines/uml/deletion.mjs +31 -0
  10. package/esm2022/engines/uml/note.mjs +58 -0
  11. package/esm2022/generators/text.generator.mjs +5 -13
  12. package/esm2022/interfaces/geometry.mjs +11 -1
  13. package/esm2022/interfaces/index.mjs +2 -2
  14. package/esm2022/plugins/with-draw-fragment.mjs +3 -2
  15. package/esm2022/plugins/with-draw-hotkey.mjs +3 -3
  16. package/esm2022/plugins/with-draw.mjs +1 -1
  17. package/esm2022/plugins/with-geometry-create.mjs +13 -4
  18. package/esm2022/plugins/with-geometry-resize.mjs +3 -2
  19. package/esm2022/table.component.mjs +5 -3
  20. package/esm2022/transforms/swimlane.mjs +23 -20
  21. package/esm2022/utils/common.mjs +50 -21
  22. package/esm2022/utils/geometry.mjs +21 -9
  23. package/esm2022/utils/index.mjs +2 -1
  24. package/esm2022/utils/multi-text-geometry.mjs +8 -8
  25. package/esm2022/utils/swimlane.mjs +8 -2
  26. package/esm2022/utils/table.mjs +1 -1
  27. package/esm2022/utils/uml.mjs +88 -0
  28. package/fesm2022/plait-draw.mjs +861 -526
  29. package/fesm2022/plait-draw.mjs.map +1 -1
  30. package/generators/text.generator.d.ts +0 -1
  31. package/interfaces/geometry.d.ts +11 -1
  32. package/package.json +1 -1
  33. package/transforms/geometry.d.ts +2 -2
  34. package/transforms/index.d.ts +2 -2
  35. package/utils/common.d.ts +5 -0
  36. package/utils/geometry.d.ts +30 -2
  37. package/utils/index.d.ts +1 -0
  38. package/utils/multi-text-geometry.d.ts +2 -2
  39. package/utils/uml.d.ts +3 -0
@@ -1,5 +1,5 @@
1
- import { ACTIVE_STROKE_WIDTH, ThemeColorMode, RectangleClient, idCreator, Transforms, clearSelectedElement, addSelectedElement, BoardTransforms, PlaitPointerType, rotateAntiPointsByElement, depthFirstRecursion, PlaitBoard, getIsRecursionFunc, createG, SNAPPING_STROKE_WIDTH, SELECTION_BORDER_COLOR, SELECTION_FILL_COLOR, drawCircle, createDebugGenerator, Point, arrowPoints, createPath, distanceBetweenPointAndPoint, drawLinearPath, rotate, catmullRomFitting, setStrokeLinecap, findElements, createMask, createRect, PlaitElement, getSelectedElements, getElementById, rotatePointsByElement, distanceBetweenPointAndSegments, HIT_DISTANCE_BUFFER, isPolylineHitRectangle, 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, getTextEditors, Generator, removeDuplicatePoints, generateElbowLineRoute, simplifyOrthogonalPoints, getExtendPoint, getUnitVectorByPointAndPoint, getPointByVectorComponent, getPointOnPolyline, RESIZE_HANDLE_DIAMETER, getFirstTextManage, ActiveGenerator, isSourceAndTargetIntersect, getPoints, DEFAULT_ROUTE_MARGIN, TRANSPARENT, 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';
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
3
  import { Alignment, TextManage, buildText, DEFAULT_FONT_SIZE, getTextSize, AlignEditor } from '@plait/text';
4
4
  import { pointsOnBezierCurves } from 'points-on-curve';
5
5
  import { isKeyHotkey } from 'is-hotkey';
@@ -71,8 +71,18 @@ var UMLSymbols;
71
71
  UMLSymbols["actor"] = "actor";
72
72
  UMLSymbols["useCase"] = "useCase";
73
73
  UMLSymbols["container"] = "container";
74
+ UMLSymbols["note"] = "note";
75
+ UMLSymbols["simpleClass"] = "simpleClass";
76
+ UMLSymbols["activityClass"] = "activityClass";
77
+ UMLSymbols["branchMerge"] = "branchMerge";
78
+ UMLSymbols["port"] = "port";
74
79
  UMLSymbols["package"] = "package";
75
80
  UMLSymbols["combinedFragment"] = "combinedFragment";
81
+ UMLSymbols["class"] = "class";
82
+ UMLSymbols["interface"] = "interface";
83
+ UMLSymbols["object"] = "object";
84
+ UMLSymbols["activation"] = "activation";
85
+ UMLSymbols["deletion"] = "deletion";
76
86
  })(UMLSymbols || (UMLSymbols = {}));
77
87
  var MultipleTextGeometryCommonTextKeys;
78
88
  (function (MultipleTextGeometryCommonTextKeys) {
@@ -201,6 +211,22 @@ const DefaultPackageProperty = {
201
211
  }
202
212
  ]
203
213
  };
214
+ const DefaultActivationProperty = {
215
+ width: 18,
216
+ height: 80
217
+ };
218
+ const DefaultObjectProperty = {
219
+ width: 120,
220
+ height: 60
221
+ };
222
+ const DefaultDeletionProperty = {
223
+ width: 40,
224
+ height: 40
225
+ };
226
+ const DefaultPortProperty = {
227
+ width: 20,
228
+ height: 20
229
+ };
204
230
  const DefaultCombinedFragmentProperty = {
205
231
  width: 400,
206
232
  height: 280,
@@ -217,6 +243,32 @@ const DefaultCombinedFragmentProperty = {
217
243
  }
218
244
  ]
219
245
  };
246
+ const DefaultClassProperty = {
247
+ width: 230,
248
+ height: 180,
249
+ texts: [
250
+ { text: 'Class', align: Alignment.center },
251
+ {
252
+ text: '+ attribute1:type defaultValue\n+ attribute2:type\n- attribute3:type',
253
+ align: Alignment.left
254
+ },
255
+ {
256
+ text: '+ operation1(params):returnType\n- operation2(params)\n- operation3()',
257
+ align: Alignment.left
258
+ }
259
+ ]
260
+ };
261
+ const DefaultInterfaceProperty = {
262
+ width: 230,
263
+ height: 140,
264
+ texts: [
265
+ { text: '<<interface>>\nInterface', align: Alignment.center },
266
+ {
267
+ text: '+ operation1(params):returnType\n- operation2(params)\n- operation3()',
268
+ align: Alignment.left
269
+ }
270
+ ]
271
+ };
220
272
  const DefaultSwimlaneVerticalProperty = {
221
273
  width: 450,
222
274
  height: 500
@@ -263,8 +315,18 @@ const DefaultUMLPropertyMap = {
263
315
  [UMLSymbols.actor]: DefaultActorProperty,
264
316
  [UMLSymbols.useCase]: DefaultDocumentProperty,
265
317
  [UMLSymbols.container]: DefaultContainerProperty,
318
+ [UMLSymbols.note]: DefaultObjectProperty,
266
319
  [UMLSymbols.package]: DefaultPackageProperty,
267
- [UMLSymbols.combinedFragment]: DefaultCombinedFragmentProperty
320
+ [UMLSymbols.combinedFragment]: DefaultCombinedFragmentProperty,
321
+ [UMLSymbols.class]: DefaultClassProperty,
322
+ [UMLSymbols.interface]: DefaultInterfaceProperty,
323
+ [UMLSymbols.activation]: DefaultActivationProperty,
324
+ [UMLSymbols.object]: DefaultObjectProperty,
325
+ [UMLSymbols.deletion]: DefaultDeletionProperty,
326
+ [UMLSymbols.activityClass]: DefaultObjectProperty,
327
+ [UMLSymbols.simpleClass]: DefaultObjectProperty,
328
+ [UMLSymbols.port]: DefaultPortProperty,
329
+ [UMLSymbols.branchMerge]: DefaultDeletionProperty
268
330
  };
269
331
  const MultipleTextGeometryTextKeys = {
270
332
  [UMLSymbols.package]: Object.keys(MultipleTextGeometryCommonTextKeys),
@@ -272,12 +334,20 @@ const MultipleTextGeometryTextKeys = {
272
334
  };
273
335
  const DefaultSwimlanePropertyMap = {
274
336
  [SwimlaneSymbols.swimlaneHorizontal]: DefaultSwimlaneHorizontalProperty,
275
- [SwimlaneSymbols.swimlaneVertical]: DefaultSwimlaneVerticalProperty,
337
+ [SwimlaneSymbols.swimlaneVertical]: DefaultSwimlaneVerticalProperty
276
338
  };
277
339
  const LINE_HIT_GEOMETRY_BUFFER = 10;
278
340
  const LINE_SNAPPING_BUFFER = 6;
279
341
  const LINE_SNAPPING_CONNECTOR_BUFFER = 8;
280
- const GEOMETRY_WITHOUT_TEXT = [FlowchartSymbols.or, FlowchartSymbols.summingJunction];
342
+ const GEOMETRY_WITHOUT_TEXT = [
343
+ FlowchartSymbols.or,
344
+ FlowchartSymbols.summingJunction,
345
+ UMLSymbols.activation,
346
+ UMLSymbols.deletion,
347
+ UMLSymbols.port,
348
+ UMLSymbols.branchMerge
349
+ ];
350
+ const GEOMETRY_WITH_MULTIPLE_TEXT = [UMLSymbols.package, UMLSymbols.combinedFragment];
281
351
 
282
352
  const getGeometryPointers = () => {
283
353
  return [...Object.keys(BasicShapes), ...Object.keys(FlowchartSymbols), ...Object.keys(UMLSymbols)];
@@ -364,23 +434,15 @@ class TextGenerator {
364
434
  const textPlugins = (this.board.getPluginOptions(WithTextPluginKey) || {}).textPlugins;
365
435
  this.textManages = this.texts.map(text => {
366
436
  const textManage = this.createTextManage(text, textPlugins);
367
- setTextManage(this.getTextKey(text), textManage);
437
+ setTextManage(getTextKey(this.element, text), textManage);
368
438
  return textManage;
369
439
  });
370
440
  ELEMENT_TO_TEXT_MANAGES.set(this.element, this.textManages);
371
441
  }
372
- getTextKey(text) {
373
- if (isMultipleTextGeometry(this.element)) {
374
- return `${this.element.id}-${text.key}`;
375
- }
376
- else {
377
- return text.key;
378
- }
379
- }
380
442
  draw(elementG) {
381
443
  const centerPoint = RectangleClient.getCenterPoint(this.board.getRectangle(this.element));
382
444
  this.texts.forEach(drawShapeText => {
383
- const textManage = getTextManage(this.getTextKey(drawShapeText));
445
+ const textManage = getTextManage(getTextKey(this.element, drawShapeText));
384
446
  if (drawShapeText.text && textManage) {
385
447
  textManage.draw(drawShapeText.text);
386
448
  elementG.append(textManage.g);
@@ -409,7 +471,7 @@ class TextGenerator {
409
471
  }
410
472
  currentDrawShapeTexts.forEach(drawShapeText => {
411
473
  if (drawShapeText.text) {
412
- let textManage = getTextManage(this.getTextKey(drawShapeText));
474
+ let textManage = getTextManage(getTextKey(this.element, drawShapeText));
413
475
  if (!textManage) {
414
476
  textManage = this.createTextManage(drawShapeText, textPlugins);
415
477
  setTextManage(drawShapeText.key, textManage);
@@ -682,156 +744,443 @@ const getMemorizedLatestShape = (board) => {
682
744
  return memorizedShape.get(board);
683
745
  };
684
746
 
685
- const getTextRectangle = (element) => {
686
- const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
687
- const strokeWidth = getStrokeWidthByElement(element);
688
- const height = element.textHeight;
689
- const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
690
- return {
691
- height,
692
- width: width > 0 ? width : 0,
693
- x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
694
- y: elementRectangle.y + (elementRectangle.height - height) / 2
695
- };
696
- };
697
- const getStrokeWidthByElement = (element) => {
698
- if (PlaitDrawElement.isText(element)) {
699
- return 0;
700
- }
701
- const strokeWidth = element.strokeWidth || DefaultDrawStyle.strokeWidth;
702
- return strokeWidth;
703
- };
704
- const insertElement = (board, element) => {
705
- memorizeLatestShape(board, element.shape);
706
- Transforms.insertNode(board, element, [board.children.length]);
707
- clearSelectedElement(board);
708
- addSelectedElement(board, element);
709
- BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
710
- };
711
- const isDrawElementsIncludeText = (elements) => {
712
- return elements.some(item => {
713
- if (PlaitDrawElement.isText(item)) {
714
- return true;
715
- }
716
- if (PlaitDrawElement.isImage(item)) {
717
- return false;
718
- }
719
- if (PlaitDrawElement.isGeometry(item)) {
720
- return isGeometryIncludeText(item);
747
+ var LineResizeHandle;
748
+ (function (LineResizeHandle) {
749
+ LineResizeHandle["source"] = "source";
750
+ LineResizeHandle["target"] = "target";
751
+ LineResizeHandle["addHandle"] = "addHandle";
752
+ })(LineResizeHandle || (LineResizeHandle = {}));
753
+ const getHitLineResizeHandleRef = (board, element, point) => {
754
+ let dataPoints = PlaitLine.getPoints(board, element);
755
+ const index = getHitPointIndex(dataPoints, point);
756
+ if (index !== -1) {
757
+ const handleIndex = index;
758
+ if (index === 0) {
759
+ return { handle: LineResizeHandle.source, handleIndex };
721
760
  }
722
- if (PlaitDrawElement.isLine(item)) {
723
- const editors = getTextEditors(item);
724
- return editors.length > 0;
761
+ if (index === dataPoints.length - 1) {
762
+ return { handle: LineResizeHandle.target, handleIndex };
725
763
  }
726
- if (PlaitDrawElement.isTable(item)) {
727
- return item.cells.some(cell => isCellIncludeText(cell));
764
+ // elbow line, data points only verify source connection point and target connection point
765
+ if (element.shape !== LineShape.elbow) {
766
+ return { handleIndex };
728
767
  }
729
- return true;
768
+ }
769
+ const middlePoints = getMiddlePoints(board, element);
770
+ const indexOfMiddlePoints = getHitPointIndex(middlePoints, point);
771
+ if (indexOfMiddlePoints !== -1) {
772
+ return {
773
+ handle: LineResizeHandle.addHandle,
774
+ handleIndex: indexOfMiddlePoints
775
+ };
776
+ }
777
+ return undefined;
778
+ };
779
+ function getHitPointIndex(points, movingPoint) {
780
+ const rectangles = points.map(point => {
781
+ return {
782
+ x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
783
+ y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
784
+ width: RESIZE_HANDLE_DIAMETER,
785
+ height: RESIZE_HANDLE_DIAMETER
786
+ };
787
+ });
788
+ const rectangle = rectangles.find(rectangle => {
789
+ return RectangleClient.isHit(RectangleClient.getRectangleByPoints([movingPoint, movingPoint]), rectangle);
790
+ });
791
+ return rectangle ? rectangles.indexOf(rectangle) : -1;
792
+ }
793
+ const getHitLineTextIndex = (board, element, point) => {
794
+ const texts = element.texts;
795
+ if (!texts.length)
796
+ return -1;
797
+ const points = getLinePoints(board, element);
798
+ return texts.findIndex(text => {
799
+ const center = getPointOnPolyline(points, text.position);
800
+ const rectangle = {
801
+ x: center[0] - text.width / 2,
802
+ y: center[1] - text.height / 2,
803
+ width: text.width,
804
+ height: text.height
805
+ };
806
+ return RectangleClient.isHit(rectangle, RectangleClient.getRectangleByPoints([point, point]));
730
807
  });
731
808
  };
732
- const getSnappingShape = (board, point) => {
733
- let hitElement = getHitShape(board, point);
734
- if (hitElement) {
735
- const ref = getSnappingRef(board, hitElement, point);
736
- if (ref.isHitConnector || ref.isHitEdge) {
737
- return hitElement;
738
- }
739
- }
740
- return null;
809
+
810
+ const isMultipleTextShape = (shape) => {
811
+ return GEOMETRY_WITH_MULTIPLE_TEXT.includes(shape);
741
812
  };
742
- const getSnappingRef = (board, hitElement, point) => {
743
- const rotatedPoint = rotateAntiPointsByElement(point, hitElement) || point;
744
- const connectorPoint = getHitConnectorPoint(rotatedPoint, hitElement);
745
- const edgePoint = getNearestPoint(hitElement, rotatedPoint);
746
- const isHitEdge = isHitEdgeOfShape(board, hitElement, rotatedPoint, LINE_SNAPPING_BUFFER);
747
- return { isHitEdge, isHitConnector: !!connectorPoint, connectorPoint, edgePoint };
813
+ const isMultipleTextGeometry = (geometry) => {
814
+ return PlaitDrawElement.isGeometry(geometry) && isMultipleTextShape(geometry.shape);
748
815
  };
749
- const getHitShape = (board, point, offset = LINE_HIT_GEOMETRY_BUFFER) => {
750
- let hitShape = null;
751
- traverseDrawShapes(board, (element) => {
752
- if (hitShape === null && isInsideOfShape(board, element, rotateAntiPointsByElement(point, element) || point, offset * 2)) {
753
- hitShape = element;
754
- }
755
- });
756
- return hitShape;
816
+ const getMultipleTextGeometryTextKeys = (shape) => {
817
+ return MultipleTextGeometryTextKeys[shape];
757
818
  };
758
- const traverseDrawShapes = (board, callback) => {
759
- depthFirstRecursion(board, node => {
760
- if (!PlaitBoard.isBoard(node) && PlaitDrawElement.isShapeElement(node)) {
761
- callback(node);
762
- }
763
- }, getIsRecursionFunc(board), true);
819
+ const createMultipleTextGeometryElement = (shape, points, options = {}) => {
820
+ const id = idCreator();
821
+ const drawShapeTexts = buildDefaultTextsByShape(shape);
822
+ return {
823
+ id,
824
+ type: 'geometry',
825
+ shape,
826
+ angle: 0,
827
+ opacity: 1,
828
+ texts: drawShapeTexts,
829
+ points,
830
+ ...options
831
+ };
764
832
  };
765
- const drawShape = (board, outerRectangle, shape, roughOptions, drawOptions) => {
766
- return getEngine(shape).draw(board, outerRectangle, roughOptions, drawOptions);
833
+ const buildDefaultTextsByShape = (shape) => {
834
+ const memorizedLatest = getMemorizedLatestByPointer(shape);
835
+ const textProperties = { ...memorizedLatest.textProperties };
836
+ const alignment = textProperties?.align;
837
+ const textHeight = textProperties?.textHeight || DefaultTextProperty.height;
838
+ delete textProperties?.align;
839
+ delete textProperties?.textHeight;
840
+ const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
841
+ const textKeys = getMultipleTextGeometryTextKeys(shape);
842
+ return (textKeys || []).map((textKey) => {
843
+ const text = defaultTexts?.find((item) => item?.key === textKey);
844
+ return {
845
+ key: textKey,
846
+ text: buildText(text?.text || '', alignment || text?.align || Alignment.center, textProperties),
847
+ textHeight: textHeight
848
+ };
849
+ });
767
850
  };
768
- const drawBoundReaction = (board, element, roughOptions = { hasMask: true, hasConnector: true }) => {
769
- const g = createG();
770
- const rectangle = RectangleClient.getRectangleByPoints(element.points);
771
- const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
772
- const shape = getElementShape(element);
773
- let drawOptions = {};
774
- if (PlaitDrawElement.isTable(element)) {
775
- drawOptions = { element };
776
- }
777
- const strokeG = drawShape(board, activeRectangle, shape, {
778
- stroke: SELECTION_BORDER_COLOR,
779
- strokeWidth: SNAPPING_STROKE_WIDTH
780
- }, drawOptions);
781
- g.appendChild(strokeG);
782
- if (roughOptions.hasMask) {
783
- const maskG = drawShape(board, activeRectangle, shape, {
784
- stroke: SELECTION_BORDER_COLOR,
785
- strokeWidth: 0,
786
- fill: SELECTION_FILL_COLOR,
787
- fillStyle: 'solid'
788
- }, drawOptions);
789
- g.appendChild(maskG);
790
- }
791
- if (roughOptions.hasConnector) {
792
- const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
793
- connectorPoints.forEach(point => {
794
- const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 8, {
795
- stroke: SELECTION_BORDER_COLOR,
796
- strokeWidth: ACTIVE_STROKE_WIDTH,
797
- fill: '#FFF',
798
- fillStyle: 'solid'
799
- });
800
- g.appendChild(circleG);
851
+ const getHitMultipleGeometryText = (element, point) => {
852
+ const engine = getEngine(element.shape);
853
+ const rectangle = RectangleClient.getRectangleByPoints([point, point]);
854
+ let hitText;
855
+ if (engine.getTextRectangle) {
856
+ hitText = element.texts.find(text => {
857
+ const textRectangle = engine.getTextRectangle(element, { key: text.key });
858
+ return RectangleClient.isHit(rectangle, textRectangle);
801
859
  });
802
860
  }
803
- return g;
861
+ return hitText;
804
862
  };
805
863
 
806
- const getStrokeColorByElement = (board, element) => {
807
- const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode);
808
- const strokeColor = element.strokeColor || defaultColor;
809
- return strokeColor;
810
- };
811
- const getFillByElement = (board, element) => {
812
- const defaultFill = PlaitDrawElement.isFlowchart(element)
813
- ? getFlowchartDefaultFill(board.theme.themeColorMode)
814
- : DefaultDrawStyle.fill;
815
- const fill = element.fill || defaultFill;
816
- return fill;
817
- };
818
- const getLineDashByElement = (element) => {
819
- switch (element.strokeStyle) {
820
- case StrokeStyle.dashed:
821
- return [8, 8 + getStrokeWidthByElement(element)];
822
- case StrokeStyle.dotted:
823
- return [0, 4 + getStrokeWidthByElement(element)];
824
- default:
825
- return undefined;
864
+ const isTextExceedingBounds = (geometry) => {
865
+ const client = RectangleClient.getRectangleByPoints(geometry.points);
866
+ if (geometry.textHeight && geometry.textHeight > client.height) {
867
+ return true;
826
868
  }
869
+ return false;
827
870
  };
828
- const getStrokeStyleByElement = (element) => {
829
- return element.strokeStyle || StrokeStyle.solid;
871
+ const isHitLineText = (board, element, point) => {
872
+ return getHitLineTextIndex(board, element, point) !== -1;
830
873
  };
831
-
832
- const DefaultLineStyle = {
833
- strokeWidth: 2,
834
- strokeColor: '#000'
874
+ const isHitPolyLine = (pathPoints, point) => {
875
+ const distance = distanceBetweenPointAndSegments(pathPoints, point);
876
+ return distance <= HIT_DISTANCE_BUFFER;
877
+ };
878
+ const isHitLine = (board, element, point) => {
879
+ const points = getLinePoints(board, element);
880
+ const isHitText = isHitLineText(board, element, point);
881
+ return isHitText || isHitPolyLine(points, point);
882
+ };
883
+ const isHitElementText = (element, point) => {
884
+ const engine = getEngine(element.shape);
885
+ if (isMultipleTextGeometry(element)) {
886
+ const texts = element.texts;
887
+ return texts.some(item => {
888
+ const textClient = engine.getTextRectangle(element, { key: item.key });
889
+ return RectangleClient.isPointInRectangle(textClient, point);
890
+ });
891
+ }
892
+ else {
893
+ const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
894
+ return RectangleClient.isPointInRectangle(textClient, point);
895
+ }
896
+ };
897
+ const isRectangleHitElementText = (element, rectangle) => {
898
+ const engine = getEngine(element.shape);
899
+ if (isMultipleTextGeometry(element)) {
900
+ const texts = element.texts;
901
+ return texts.some(item => {
902
+ const textClient = engine.getTextRectangle(element, { key: item.key });
903
+ const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(textClient), element) || RectangleClient.getCornerPoints(textClient);
904
+ return isPolylineHitRectangle(rotatedCornerPoints, rectangle);
905
+ });
906
+ }
907
+ else {
908
+ const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
909
+ const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(textClient), element) || RectangleClient.getCornerPoints(textClient);
910
+ return isPolylineHitRectangle(rotatedCornerPoints, rectangle);
911
+ }
912
+ };
913
+ const isRectangleHitDrawElement = (board, element, selection) => {
914
+ const rangeRectangle = RectangleClient.getRectangleByPoints([selection.anchor, selection.focus]);
915
+ if (PlaitDrawElement.isGeometry(element)) {
916
+ const client = RectangleClient.getRectangleByPoints(element.points);
917
+ let rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(client), element) || RectangleClient.getCornerPoints(client);
918
+ const isHitElement = isPolylineHitRectangle(rotatedCornerPoints, rangeRectangle);
919
+ if (isHitElement) {
920
+ return isHitElement;
921
+ }
922
+ return isRectangleHitElementText(element, rangeRectangle);
923
+ }
924
+ if (PlaitDrawElement.isImage(element)) {
925
+ const client = RectangleClient.getRectangleByPoints(element.points);
926
+ const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(client), element) || RectangleClient.getCornerPoints(client);
927
+ return isPolylineHitRectangle(rotatedCornerPoints, rangeRectangle);
928
+ }
929
+ if (PlaitDrawElement.isLine(element)) {
930
+ const points = getLinePoints(board, element);
931
+ return isPolylineHitRectangle(points, rangeRectangle);
932
+ }
933
+ return null;
934
+ };
935
+ const isHitDrawElement = (board, element, point) => {
936
+ const rectangle = board.getRectangle(element);
937
+ point = rotateAntiPointsByElement(point, element) || point;
938
+ if (PlaitDrawElement.isGeometry(element)) {
939
+ const fill = getFillByElement(board, element);
940
+ if (isHitEdgeOfShape(board, element, point, HIT_DISTANCE_BUFFER)) {
941
+ return true;
942
+ }
943
+ const engine = getEngine(getElementShape(element));
944
+ // when shape equals text, fill is not allowed
945
+ if (fill !== DefaultDrawStyle.fill && fill !== TRANSPARENT && !PlaitDrawElement.isText(element)) {
946
+ const isHitInside = engine.isInsidePoint(rectangle, point);
947
+ if (isHitInside) {
948
+ return isHitInside;
949
+ }
950
+ }
951
+ else {
952
+ // if shape equals text, only check text rectangle
953
+ if (PlaitDrawElement.isText(element)) {
954
+ const textClient = getTextRectangle(element);
955
+ let isHitText = RectangleClient.isPointInRectangle(textClient, point);
956
+ return isHitText;
957
+ }
958
+ // check textRectangle of element
959
+ const isHitText = isHitElementText(element, point);
960
+ if (isHitText) {
961
+ return isHitText;
962
+ }
963
+ }
964
+ }
965
+ if (PlaitDrawElement.isImage(element)) {
966
+ const client = RectangleClient.getRectangleByPoints(element.points);
967
+ return RectangleClient.isPointInRectangle(client, point);
968
+ }
969
+ if (PlaitDrawElement.isLine(element)) {
970
+ return isHitLine(board, element, point);
971
+ }
972
+ return null;
973
+ };
974
+ const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
975
+ const nearestPoint = getNearestPoint(element, point);
976
+ const distance = distanceBetweenPointAndPoint(nearestPoint[0], nearestPoint[1], point[0], point[1]);
977
+ return distance <= hitDistanceBuffer;
978
+ };
979
+ const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
980
+ const client = RectangleClient.inflate(RectangleClient.getRectangleByPoints(element.points), hitDistanceBuffer);
981
+ return getEngine(getElementShape(element)).isInsidePoint(client, point);
982
+ };
983
+ const isHitElementInside = (board, element, point) => {
984
+ const rectangle = board.getRectangle(element);
985
+ point = rotateAntiPointsByElement(point, element) || point;
986
+ if (PlaitDrawElement.isGeometry(element)) {
987
+ const engine = getEngine(getElementShape(element));
988
+ const isHitInside = engine.isInsidePoint(rectangle, point);
989
+ if (isHitInside) {
990
+ return isHitInside;
991
+ }
992
+ if (engine.getTextRectangle) {
993
+ const isHitText = isHitElementText(element, point);
994
+ if (isHitText) {
995
+ return isHitText;
996
+ }
997
+ }
998
+ }
999
+ if (PlaitDrawElement.isImage(element)) {
1000
+ const client = RectangleClient.getRectangleByPoints(element.points);
1001
+ return RectangleClient.isPointInRectangle(client, point);
1002
+ }
1003
+ if (PlaitDrawElement.isLine(element)) {
1004
+ return isHitLine(board, element, point);
1005
+ }
1006
+ return null;
1007
+ };
1008
+
1009
+ const getTextRectangle = (element) => {
1010
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
1011
+ const strokeWidth = getStrokeWidthByElement(element);
1012
+ const height = element.textHeight;
1013
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2;
1014
+ return {
1015
+ height,
1016
+ width: width > 0 ? width : 0,
1017
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
1018
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
1019
+ };
1020
+ };
1021
+ const getStrokeWidthByElement = (element) => {
1022
+ if (PlaitDrawElement.isText(element)) {
1023
+ return 0;
1024
+ }
1025
+ const strokeWidth = element.strokeWidth || DefaultDrawStyle.strokeWidth;
1026
+ return strokeWidth;
1027
+ };
1028
+ const insertElement = (board, element) => {
1029
+ memorizeLatestShape(board, element.shape);
1030
+ Transforms.insertNode(board, element, [board.children.length]);
1031
+ clearSelectedElement(board);
1032
+ addSelectedElement(board, element);
1033
+ BoardTransforms.updatePointerType(board, PlaitPointerType.selection);
1034
+ };
1035
+ const isDrawElementIncludeText = (element) => {
1036
+ if (PlaitDrawElement.isText(element)) {
1037
+ return true;
1038
+ }
1039
+ if (PlaitDrawElement.isImage(element)) {
1040
+ return false;
1041
+ }
1042
+ if (PlaitDrawElement.isGeometry(element)) {
1043
+ return isGeometryIncludeText(element);
1044
+ }
1045
+ if (PlaitDrawElement.isLine(element)) {
1046
+ const editors = getTextEditorsByElement(element);
1047
+ return editors.length > 0;
1048
+ }
1049
+ if (PlaitDrawElement.isTable(element)) {
1050
+ return element.cells.some(cell => isCellIncludeText(cell));
1051
+ }
1052
+ return true;
1053
+ };
1054
+ const isDrawElementsIncludeText = (elements) => {
1055
+ return elements.some(item => {
1056
+ return isDrawElementIncludeText(item);
1057
+ });
1058
+ };
1059
+ const getSnappingShape = (board, point) => {
1060
+ let hitElement = getHitShape(board, point);
1061
+ if (hitElement) {
1062
+ const ref = getSnappingRef(board, hitElement, point);
1063
+ if (ref.isHitConnector || ref.isHitEdge) {
1064
+ return hitElement;
1065
+ }
1066
+ }
1067
+ return null;
1068
+ };
1069
+ const getSnappingRef = (board, hitElement, point) => {
1070
+ const rotatedPoint = rotateAntiPointsByElement(point, hitElement) || point;
1071
+ const connectorPoint = getHitConnectorPoint(rotatedPoint, hitElement);
1072
+ const edgePoint = getNearestPoint(hitElement, rotatedPoint);
1073
+ const isHitEdge = isHitEdgeOfShape(board, hitElement, rotatedPoint, LINE_SNAPPING_BUFFER);
1074
+ return { isHitEdge, isHitConnector: !!connectorPoint, connectorPoint, edgePoint };
1075
+ };
1076
+ const getHitShape = (board, point, offset = LINE_HIT_GEOMETRY_BUFFER) => {
1077
+ let hitShape = null;
1078
+ traverseDrawShapes(board, (element) => {
1079
+ if (hitShape === null && isInsideOfShape(board, element, rotateAntiPointsByElement(point, element) || point, offset * 2)) {
1080
+ hitShape = element;
1081
+ }
1082
+ });
1083
+ return hitShape;
1084
+ };
1085
+ const traverseDrawShapes = (board, callback) => {
1086
+ depthFirstRecursion(board, node => {
1087
+ if (!PlaitBoard.isBoard(node) && PlaitDrawElement.isShapeElement(node)) {
1088
+ callback(node);
1089
+ }
1090
+ }, getIsRecursionFunc(board), true);
1091
+ };
1092
+ const drawShape = (board, outerRectangle, shape, roughOptions, drawOptions) => {
1093
+ return getEngine(shape).draw(board, outerRectangle, roughOptions, drawOptions);
1094
+ };
1095
+ const drawBoundReaction = (board, element, roughOptions = { hasMask: true, hasConnector: true }) => {
1096
+ const g = createG();
1097
+ const rectangle = RectangleClient.getRectangleByPoints(element.points);
1098
+ const activeRectangle = RectangleClient.inflate(rectangle, SNAPPING_STROKE_WIDTH);
1099
+ const shape = getElementShape(element);
1100
+ let drawOptions = {};
1101
+ if (PlaitDrawElement.isTable(element)) {
1102
+ drawOptions = { element };
1103
+ }
1104
+ const strokeG = drawShape(board, activeRectangle, shape, {
1105
+ stroke: SELECTION_BORDER_COLOR,
1106
+ strokeWidth: SNAPPING_STROKE_WIDTH
1107
+ }, drawOptions);
1108
+ g.appendChild(strokeG);
1109
+ if (roughOptions.hasMask) {
1110
+ const maskG = drawShape(board, activeRectangle, shape, {
1111
+ stroke: SELECTION_BORDER_COLOR,
1112
+ strokeWidth: 0,
1113
+ fill: SELECTION_FILL_COLOR,
1114
+ fillStyle: 'solid'
1115
+ }, drawOptions);
1116
+ g.appendChild(maskG);
1117
+ }
1118
+ if (roughOptions.hasConnector) {
1119
+ const connectorPoints = getEngine(shape).getConnectorPoints(rectangle);
1120
+ connectorPoints.forEach(point => {
1121
+ const circleG = drawCircle(PlaitBoard.getRoughSVG(board), point, 8, {
1122
+ stroke: SELECTION_BORDER_COLOR,
1123
+ strokeWidth: ACTIVE_STROKE_WIDTH,
1124
+ fill: '#FFF',
1125
+ fillStyle: 'solid'
1126
+ });
1127
+ g.appendChild(circleG);
1128
+ });
1129
+ }
1130
+ return g;
1131
+ };
1132
+ const getTextKey = (element, text) => {
1133
+ if (isMultipleTextGeometry(element)) {
1134
+ return `${element.id}-${text.key}`;
1135
+ }
1136
+ else {
1137
+ return text.key;
1138
+ }
1139
+ };
1140
+ const getGeometryAlign = (element) => {
1141
+ if (isMultipleTextGeometry(element)) {
1142
+ const drawShapeText = element.texts.find(item => item.key.includes(MultipleTextGeometryCommonTextKeys.content));
1143
+ return drawShapeText?.text.align || Alignment.center;
1144
+ }
1145
+ if (isSingleTextGeometry(element)) {
1146
+ return element.text?.align || Alignment.center;
1147
+ }
1148
+ if (PlaitDrawElement.isTable(element)) {
1149
+ const firstTextCell = element.cells.find(item => item.text);
1150
+ return firstTextCell?.text?.align || Alignment.center;
1151
+ }
1152
+ return Alignment.center;
1153
+ };
1154
+
1155
+ const getStrokeColorByElement = (board, element) => {
1156
+ const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode);
1157
+ const strokeColor = element.strokeColor || defaultColor;
1158
+ return strokeColor;
1159
+ };
1160
+ const getFillByElement = (board, element) => {
1161
+ const defaultFill = PlaitDrawElement.isFlowchart(element)
1162
+ ? getFlowchartDefaultFill(board.theme.themeColorMode)
1163
+ : DefaultDrawStyle.fill;
1164
+ const fill = element.fill || defaultFill;
1165
+ return fill;
1166
+ };
1167
+ const getLineDashByElement = (element) => {
1168
+ switch (element.strokeStyle) {
1169
+ case StrokeStyle.dashed:
1170
+ return [8, 8 + getStrokeWidthByElement(element)];
1171
+ case StrokeStyle.dotted:
1172
+ return [0, 4 + getStrokeWidthByElement(element)];
1173
+ default:
1174
+ return undefined;
1175
+ }
1176
+ };
1177
+ const getStrokeStyleByElement = (element) => {
1178
+ return element.strokeStyle || StrokeStyle.solid;
1179
+ };
1180
+
1181
+ const DefaultLineStyle = {
1182
+ strokeWidth: 2,
1183
+ strokeColor: '#000'
835
1184
  };
836
1185
  const LINE_TEXT_SPACE = 4;
837
1186
  const LINE_AUTO_COMPLETE_DIAMETER = 6;
@@ -1516,58 +1865,87 @@ function drawMask(board, element, id) {
1516
1865
  return { mask, maskTargetFillRect };
1517
1866
  }
1518
1867
 
1519
- const isMultipleTextShape = (shape) => {
1520
- return [UMLSymbols.package, UMLSymbols.combinedFragment].includes(shape);
1521
- };
1522
- const isMultipleTextGeometry = (geometry) => {
1523
- return !!geometry.texts;
1524
- };
1525
- const getMultipleTextGeometryTextKeys = (shape) => {
1526
- return MultipleTextGeometryTextKeys[shape];
1527
- };
1528
- const createMultipleTextGeometryElement = (shape, points, options = {}) => {
1529
- const id = idCreator();
1530
- const drawShapeTexts = buildDefaultTextsByShape(shape, id);
1531
- return {
1532
- id,
1533
- type: 'geometry',
1534
- shape,
1868
+ const createUMLClassOrInterfaceGeometryElement = (board, shape, points) => {
1869
+ const memorizedLatest = getMemorizedLatestByPointer(shape);
1870
+ const element = {
1871
+ id: idCreator(),
1872
+ type: 'table',
1535
1873
  angle: 0,
1536
1874
  opacity: 1,
1537
- texts: drawShapeTexts,
1538
1875
  points,
1539
- ...options
1876
+ strokeWidth: DefaultBasicShapeProperty.strokeWidth,
1877
+ ...memorizedLatest.geometryProperties
1878
+ };
1879
+ let rows;
1880
+ let columns;
1881
+ if (shape === UMLSymbols.class) {
1882
+ rows = [
1883
+ {
1884
+ id: idCreator(),
1885
+ height: 30
1886
+ },
1887
+ {
1888
+ id: idCreator()
1889
+ },
1890
+ {
1891
+ id: idCreator()
1892
+ }
1893
+ ];
1894
+ columns = [
1895
+ {
1896
+ id: idCreator()
1897
+ }
1898
+ ];
1899
+ }
1900
+ else {
1901
+ rows = [
1902
+ {
1903
+ id: idCreator(),
1904
+ height: 50
1905
+ },
1906
+ {
1907
+ id: idCreator()
1908
+ }
1909
+ ];
1910
+ columns = [
1911
+ {
1912
+ id: idCreator()
1913
+ }
1914
+ ];
1915
+ }
1916
+ return {
1917
+ ...element,
1918
+ shape,
1919
+ rows,
1920
+ columns,
1921
+ cells: buildTableCellsForGeometry(board, rows, columns, shape)
1540
1922
  };
1541
1923
  };
1542
- const buildDefaultTextsByShape = (shape, elementId) => {
1924
+ const buildTableCellsForGeometry = (board, rows, columns, shape) => {
1543
1925
  const memorizedLatest = getMemorizedLatestByPointer(shape);
1544
- const textProperties = { ...memorizedLatest.textProperties };
1545
- const alignment = textProperties?.align;
1546
- const textHeight = textProperties?.textHeight || DefaultTextProperty.height;
1547
- delete textProperties?.align;
1548
- delete textProperties?.textHeight;
1549
- const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
1550
- const textKeys = getMultipleTextGeometryTextKeys(shape);
1551
- return (textKeys || []).map((textKey) => {
1552
- const text = defaultTexts?.find((item) => item?.key === textKey);
1553
- return {
1554
- key: textKey,
1555
- text: buildText(text?.text || '', alignment || text?.align || Alignment.center, textProperties),
1556
- textHeight: textHeight
1557
- };
1558
- });
1559
- };
1560
- const getHitText = (element, point) => {
1561
- const engine = getEngine(element.shape);
1562
- const rectangle = RectangleClient.getRectangleByPoints([point, point]);
1563
- let hitText;
1564
- if (engine.getTextRectangle) {
1565
- hitText = element.texts.find(text => {
1566
- const textRectangle = engine.getTextRectangle(element, { key: text.key });
1567
- return RectangleClient.isHit(rectangle, textRectangle);
1568
- });
1569
- }
1570
- return hitText;
1926
+ const cellCount = rows.length * columns.length;
1927
+ const defaultTexts = getDefaultGeometryProperty(shape)?.texts || [];
1928
+ const testHeights = defaultTexts.map((textItem) => {
1929
+ return getTextShapeProperty(board, textItem.text || DefaultTextProperty.text, memorizedLatest.textProperties['font-size']).height;
1930
+ });
1931
+ return new Array(cellCount).fill('').map((item, index) => {
1932
+ const rowIndex = Math.floor(index / columns.length);
1933
+ const columnIndex = index % columns.length;
1934
+ return {
1935
+ id: idCreator(),
1936
+ rowId: rows[rowIndex].id,
1937
+ columnId: columns[columnIndex].id,
1938
+ textHeight: testHeights[index],
1939
+ text: {
1940
+ children: [
1941
+ {
1942
+ text: defaultTexts[index].text
1943
+ }
1944
+ ],
1945
+ align: defaultTexts[index].align
1946
+ }
1947
+ };
1948
+ });
1571
1949
  };
1572
1950
 
1573
1951
  const createGeometryElement = (shape, points, text, options = {}, textProperties = {}) => {
@@ -1755,6 +2133,9 @@ const createTextElement = (board, points, text = DefaultTextProperty.text, textH
1755
2133
  const createDefaultGeometry = (board, points, shape) => {
1756
2134
  const memorizedLatest = getMemorizedLatestByPointer(shape);
1757
2135
  const textHeight = getTextShapeProperty(board, DefaultTextProperty.text, memorizedLatest.textProperties['font-size']).height;
2136
+ if (PlaitDrawElement.isUMLClassOrInterface({ shape })) {
2137
+ return createUMLClassOrInterfaceGeometryElement(board, shape, points);
2138
+ }
1758
2139
  if (isMultipleTextShape(shape)) {
1759
2140
  return createMultipleTextGeometryElement(shape, points, {
1760
2141
  strokeWidth: DefaultBasicShapeProperty.strokeWidth,
@@ -1770,12 +2151,14 @@ const createDefaultGeometry = (board, points, shape) => {
1770
2151
  };
1771
2152
  const editText = (board, element, text) => {
1772
2153
  const textManage = text ? getTextManage(`${element.id}-${text.key}`) : getFirstTextManage(element);
1773
- textManage.edit(() => {
1774
- // delay to avoid blinking
1775
- setTimeout(() => {
1776
- rerenderGeometryActive(board, element);
1777
- }, 200);
1778
- });
2154
+ if (textManage) {
2155
+ textManage.edit(() => {
2156
+ // delay to avoid blinking
2157
+ setTimeout(() => {
2158
+ rerenderGeometryActive(board, element);
2159
+ }, 200);
2160
+ });
2161
+ }
1779
2162
  rerenderGeometryActive(board, element);
1780
2163
  };
1781
2164
  const rerenderGeometryActive = (board, element) => {
@@ -1785,7 +2168,13 @@ const rerenderGeometryActive = (board, element) => {
1785
2168
  activeGenerator.processDrawing(element, PlaitBoard.getElementActiveHost(board), { selected });
1786
2169
  };
1787
2170
  const isGeometryIncludeText = (element) => {
1788
- return PlaitDrawElement.isGeometry(element) && element.text && element.textHeight && !GEOMETRY_WITHOUT_TEXT.includes(element.shape);
2171
+ return isSingleTextGeometry(element) || isMultipleTextGeometry(element);
2172
+ };
2173
+ const isSingleTextShape = (shape) => {
2174
+ return !GEOMETRY_WITHOUT_TEXT.includes(shape) && !isMultipleTextShape(shape);
2175
+ };
2176
+ const isSingleTextGeometry = (element) => {
2177
+ return PlaitDrawElement.isGeometry(element) && isSingleTextShape(element.shape);
1789
2178
  };
1790
2179
 
1791
2180
  const isSelfLoop = (element) => {
@@ -1844,292 +2233,84 @@ const getElbowPoints = (board, element) => {
1844
2233
  // |
1845
2234
  // nextPoint---sourcePoint---keyPoint1
1846
2235
  // The correct rendering should be (nextPoint should be filtered out):
1847
- // keyPoint2
1848
- // |
1849
- // |
1850
- // sourcePoint---keyPoint1
1851
- const ret = simplifyOrthogonalPoints(renderPoints);
1852
- return ret;
1853
- }
1854
- };
1855
- const getNextSourceAndTargetPoints = (board, element) => {
1856
- const options = getElbowLineRouteOptions(board, element);
1857
- return [options.nextSourcePoint, options.nextTargetPoint];
1858
- };
1859
- const getSourceAndTargetRectangle = (board, element, handleRefPair) => {
1860
- let sourceElement = element.source.boundId ? getElementById(board, element.source.boundId) : undefined;
1861
- let targetElement = element.target.boundId ? getElementById(board, element.target.boundId) : undefined;
1862
- if (!sourceElement) {
1863
- const source = handleRefPair.source;
1864
- sourceElement = createFakeElement(source.point, source.vector);
1865
- }
1866
- if (!targetElement) {
1867
- const target = handleRefPair.target;
1868
- targetElement = createFakeElement(target.point, target.vector);
1869
- }
1870
- let sourceRectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
1871
- const rotatedSourceCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(sourceRectangle), sourceElement) ||
1872
- RectangleClient.getCornerPoints(sourceRectangle);
1873
- sourceRectangle = RectangleClient.getRectangleByPoints(rotatedSourceCornerPoints);
1874
- sourceRectangle = RectangleClient.inflate(sourceRectangle, getStrokeWidthByElement(sourceElement) * 2);
1875
- let targetRectangle = RectangleClient.getRectangleByPoints(targetElement.points);
1876
- const rotatedTargetCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(targetRectangle), targetElement) ||
1877
- RectangleClient.getCornerPoints(targetRectangle);
1878
- targetRectangle = RectangleClient.getRectangleByPoints(rotatedTargetCornerPoints);
1879
- targetRectangle = RectangleClient.inflate(targetRectangle, getStrokeWidthByElement(targetElement) * 2);
1880
- return {
1881
- sourceRectangle,
1882
- targetRectangle
1883
- };
1884
- };
1885
- const createFakeElement = (startPoint, vector) => {
1886
- const point = getPointByVectorComponent(startPoint, vector, -25);
1887
- const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(point, 50, 50));
1888
- return createGeometryElement(BasicShapes.rectangle, points, '');
1889
- };
1890
- function getNextRenderPoints(board, element, renderPoints) {
1891
- let newRenderKeyPoints = renderPoints ?? getElbowPoints(board, element);
1892
- const [nextSourcePoint, nextTargetPoint] = getNextSourceAndTargetPoints(board, element);
1893
- newRenderKeyPoints.splice(0, 1, nextSourcePoint);
1894
- newRenderKeyPoints.splice(-1, 1, nextTargetPoint);
1895
- return removeDuplicatePoints(newRenderKeyPoints);
1896
- }
1897
-
1898
- const getSelectedDrawElements = (board, elements) => {
1899
- const selectedElements = elements?.length ? elements : getSelectedElements(board);
1900
- return selectedElements.filter(value => PlaitDrawElement.isDrawElement(value));
1901
- };
1902
- const getSelectedGeometryElements = (board) => {
1903
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isGeometry(value));
1904
- return selectedElements;
1905
- };
1906
- const getSelectedLineElements = (board) => {
1907
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isLine(value));
1908
- return selectedElements;
1909
- };
1910
- const getSelectedImageElements = (board) => {
1911
- const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isImage(value));
1912
- return selectedElements;
1913
- };
1914
- const isSingleSelectSwimlane = (board) => {
1915
- const selectedElements = getSelectedElements(board);
1916
- return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isSwimlane(selectedElements[0]);
1917
- };
1918
- const isSingleSelectTable = (board) => {
1919
- const selectedElements = getSelectedElements(board);
1920
- return selectedElements && selectedElements.length === 1 && PlaitTableElement.isTable(selectedElements[0]);
1921
- };
1922
- const getSelectedTableElements = (board, elements) => {
1923
- const selectedElements = elements?.length ? elements : getSelectedElements(board);
1924
- return selectedElements.filter(value => PlaitTableElement.isTable(value));
1925
- };
1926
-
1927
- var LineResizeHandle;
1928
- (function (LineResizeHandle) {
1929
- LineResizeHandle["source"] = "source";
1930
- LineResizeHandle["target"] = "target";
1931
- LineResizeHandle["addHandle"] = "addHandle";
1932
- })(LineResizeHandle || (LineResizeHandle = {}));
1933
- const getHitLineResizeHandleRef = (board, element, point) => {
1934
- let dataPoints = PlaitLine.getPoints(board, element);
1935
- const index = getHitPointIndex(dataPoints, point);
1936
- if (index !== -1) {
1937
- const handleIndex = index;
1938
- if (index === 0) {
1939
- return { handle: LineResizeHandle.source, handleIndex };
1940
- }
1941
- if (index === dataPoints.length - 1) {
1942
- return { handle: LineResizeHandle.target, handleIndex };
1943
- }
1944
- // elbow line, data points only verify source connection point and target connection point
1945
- if (element.shape !== LineShape.elbow) {
1946
- return { handleIndex };
1947
- }
1948
- }
1949
- const middlePoints = getMiddlePoints(board, element);
1950
- const indexOfMiddlePoints = getHitPointIndex(middlePoints, point);
1951
- if (indexOfMiddlePoints !== -1) {
1952
- return {
1953
- handle: LineResizeHandle.addHandle,
1954
- handleIndex: indexOfMiddlePoints
1955
- };
1956
- }
1957
- return undefined;
1958
- };
1959
- function getHitPointIndex(points, movingPoint) {
1960
- const rectangles = points.map(point => {
1961
- return {
1962
- x: point[0] - RESIZE_HANDLE_DIAMETER / 2,
1963
- y: point[1] - RESIZE_HANDLE_DIAMETER / 2,
1964
- width: RESIZE_HANDLE_DIAMETER,
1965
- height: RESIZE_HANDLE_DIAMETER
1966
- };
1967
- });
1968
- const rectangle = rectangles.find(rectangle => {
1969
- return RectangleClient.isHit(RectangleClient.getRectangleByPoints([movingPoint, movingPoint]), rectangle);
1970
- });
1971
- return rectangle ? rectangles.indexOf(rectangle) : -1;
1972
- }
1973
- const getHitLineTextIndex = (board, element, point) => {
1974
- const texts = element.texts;
1975
- if (!texts.length)
1976
- return -1;
1977
- const points = getLinePoints(board, element);
1978
- return texts.findIndex(text => {
1979
- const center = getPointOnPolyline(points, text.position);
1980
- const rectangle = {
1981
- x: center[0] - text.width / 2,
1982
- y: center[1] - text.height / 2,
1983
- width: text.width,
1984
- height: text.height
1985
- };
1986
- return RectangleClient.isHit(rectangle, RectangleClient.getRectangleByPoints([point, point]));
1987
- });
1988
- };
1989
-
1990
- const isTextExceedingBounds = (geometry) => {
1991
- const client = RectangleClient.getRectangleByPoints(geometry.points);
1992
- if (geometry.textHeight && geometry.textHeight > client.height) {
1993
- return true;
1994
- }
1995
- return false;
1996
- };
1997
- const isHitLineText = (board, element, point) => {
1998
- return getHitLineTextIndex(board, element, point) !== -1;
1999
- };
2000
- const isHitPolyLine = (pathPoints, point) => {
2001
- const distance = distanceBetweenPointAndSegments(pathPoints, point);
2002
- return distance <= HIT_DISTANCE_BUFFER;
2003
- };
2004
- const isHitLine = (board, element, point) => {
2005
- const points = getLinePoints(board, element);
2006
- const isHitText = isHitLineText(board, element, point);
2007
- return isHitText || isHitPolyLine(points, point);
2008
- };
2009
- const isHitElementText = (element, point) => {
2010
- const engine = getEngine(element.shape);
2011
- if (isMultipleTextGeometry(element)) {
2012
- const texts = element.texts;
2013
- return texts.some(item => {
2014
- const textClient = engine.getTextRectangle(element, { key: item.key });
2015
- return RectangleClient.isPointInRectangle(textClient, point);
2016
- });
2017
- }
2018
- else {
2019
- const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
2020
- return RectangleClient.isPointInRectangle(textClient, point);
2021
- }
2022
- };
2023
- const isRectangleHitElementText = (element, rectangle) => {
2024
- const engine = getEngine(element.shape);
2025
- if (isMultipleTextGeometry(element)) {
2026
- const texts = element.texts;
2027
- return texts.some(item => {
2028
- const textClient = engine.getTextRectangle(element, { key: item.key });
2029
- const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(textClient), element) || RectangleClient.getCornerPoints(textClient);
2030
- return isPolylineHitRectangle(rotatedCornerPoints, rectangle);
2031
- });
2032
- }
2033
- else {
2034
- const textClient = engine.getTextRectangle ? engine.getTextRectangle(element) : getTextRectangle(element);
2035
- const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(textClient), element) || RectangleClient.getCornerPoints(textClient);
2036
- return isPolylineHitRectangle(rotatedCornerPoints, rectangle);
2037
- }
2038
- };
2039
- const isRectangleHitDrawElement = (board, element, selection) => {
2040
- const rangeRectangle = RectangleClient.getRectangleByPoints([selection.anchor, selection.focus]);
2041
- if (PlaitDrawElement.isGeometry(element)) {
2042
- const client = RectangleClient.getRectangleByPoints(element.points);
2043
- let rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(client), element) || RectangleClient.getCornerPoints(client);
2044
- const isHitElement = isPolylineHitRectangle(rotatedCornerPoints, rangeRectangle);
2045
- if (isHitElement) {
2046
- return isHitElement;
2047
- }
2048
- return isRectangleHitElementText(element, rangeRectangle);
2049
- }
2050
- if (PlaitDrawElement.isImage(element)) {
2051
- const client = RectangleClient.getRectangleByPoints(element.points);
2052
- const rotatedCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(client), element) || RectangleClient.getCornerPoints(client);
2053
- return isPolylineHitRectangle(rotatedCornerPoints, rangeRectangle);
2054
- }
2055
- if (PlaitDrawElement.isLine(element)) {
2056
- const points = getLinePoints(board, element);
2057
- return isPolylineHitRectangle(points, rangeRectangle);
2058
- }
2059
- return null;
2060
- };
2061
- const isHitDrawElement = (board, element, point) => {
2062
- const rectangle = board.getRectangle(element);
2063
- point = rotateAntiPointsByElement(point, element) || point;
2064
- if (PlaitDrawElement.isGeometry(element)) {
2065
- const fill = getFillByElement(board, element);
2066
- if (isHitEdgeOfShape(board, element, point, HIT_DISTANCE_BUFFER)) {
2067
- return true;
2068
- }
2069
- const engine = getEngine(getElementShape(element));
2070
- // when shape equals text, fill is not allowed
2071
- if (fill !== DefaultDrawStyle.fill && fill !== TRANSPARENT && !PlaitDrawElement.isText(element)) {
2072
- const isHitInside = engine.isInsidePoint(rectangle, point);
2073
- if (isHitInside) {
2074
- return isHitInside;
2075
- }
2076
- }
2077
- else {
2078
- // if shape equals text, only check text rectangle
2079
- if (PlaitDrawElement.isText(element)) {
2080
- const textClient = getTextRectangle(element);
2081
- let isHitText = RectangleClient.isPointInRectangle(textClient, point);
2082
- return isHitText;
2083
- }
2084
- // check textRectangle of element
2085
- const isHitText = isHitElementText(element, point);
2086
- if (isHitText) {
2087
- return isHitText;
2088
- }
2089
- }
2236
+ // keyPoint2
2237
+ // |
2238
+ // |
2239
+ // sourcePoint---keyPoint1
2240
+ const ret = simplifyOrthogonalPoints(renderPoints);
2241
+ return ret;
2090
2242
  }
2091
- if (PlaitDrawElement.isImage(element)) {
2092
- const client = RectangleClient.getRectangleByPoints(element.points);
2093
- return RectangleClient.isPointInRectangle(client, point);
2243
+ };
2244
+ const getNextSourceAndTargetPoints = (board, element) => {
2245
+ const options = getElbowLineRouteOptions(board, element);
2246
+ return [options.nextSourcePoint, options.nextTargetPoint];
2247
+ };
2248
+ const getSourceAndTargetRectangle = (board, element, handleRefPair) => {
2249
+ let sourceElement = element.source.boundId ? getElementById(board, element.source.boundId) : undefined;
2250
+ let targetElement = element.target.boundId ? getElementById(board, element.target.boundId) : undefined;
2251
+ if (!sourceElement) {
2252
+ const source = handleRefPair.source;
2253
+ sourceElement = createFakeElement(source.point, source.vector);
2094
2254
  }
2095
- if (PlaitDrawElement.isLine(element)) {
2096
- return isHitLine(board, element, point);
2255
+ if (!targetElement) {
2256
+ const target = handleRefPair.target;
2257
+ targetElement = createFakeElement(target.point, target.vector);
2097
2258
  }
2098
- return null;
2259
+ let sourceRectangle = RectangleClient.getRectangleByPoints(sourceElement.points);
2260
+ const rotatedSourceCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(sourceRectangle), sourceElement) ||
2261
+ RectangleClient.getCornerPoints(sourceRectangle);
2262
+ sourceRectangle = RectangleClient.getRectangleByPoints(rotatedSourceCornerPoints);
2263
+ sourceRectangle = RectangleClient.inflate(sourceRectangle, getStrokeWidthByElement(sourceElement) * 2);
2264
+ let targetRectangle = RectangleClient.getRectangleByPoints(targetElement.points);
2265
+ const rotatedTargetCornerPoints = rotatePointsByElement(RectangleClient.getCornerPoints(targetRectangle), targetElement) ||
2266
+ RectangleClient.getCornerPoints(targetRectangle);
2267
+ targetRectangle = RectangleClient.getRectangleByPoints(rotatedTargetCornerPoints);
2268
+ targetRectangle = RectangleClient.inflate(targetRectangle, getStrokeWidthByElement(targetElement) * 2);
2269
+ return {
2270
+ sourceRectangle,
2271
+ targetRectangle
2272
+ };
2099
2273
  };
2100
- const isHitEdgeOfShape = (board, element, point, hitDistanceBuffer) => {
2101
- const nearestPoint = getNearestPoint(element, point);
2102
- const distance = distanceBetweenPointAndPoint(nearestPoint[0], nearestPoint[1], point[0], point[1]);
2103
- return distance <= hitDistanceBuffer;
2274
+ const createFakeElement = (startPoint, vector) => {
2275
+ const point = getPointByVectorComponent(startPoint, vector, -25);
2276
+ const points = RectangleClient.getPoints(RectangleClient.getRectangleByCenterPoint(point, 50, 50));
2277
+ return createGeometryElement(BasicShapes.rectangle, points, '');
2104
2278
  };
2105
- const isInsideOfShape = (board, element, point, hitDistanceBuffer) => {
2106
- const client = RectangleClient.inflate(RectangleClient.getRectangleByPoints(element.points), hitDistanceBuffer);
2107
- return getEngine(getElementShape(element)).isInsidePoint(client, point);
2279
+ function getNextRenderPoints(board, element, renderPoints) {
2280
+ let newRenderKeyPoints = renderPoints ?? getElbowPoints(board, element);
2281
+ const [nextSourcePoint, nextTargetPoint] = getNextSourceAndTargetPoints(board, element);
2282
+ newRenderKeyPoints.splice(0, 1, nextSourcePoint);
2283
+ newRenderKeyPoints.splice(-1, 1, nextTargetPoint);
2284
+ return removeDuplicatePoints(newRenderKeyPoints);
2285
+ }
2286
+
2287
+ const getSelectedDrawElements = (board, elements) => {
2288
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
2289
+ return selectedElements.filter(value => PlaitDrawElement.isDrawElement(value));
2108
2290
  };
2109
- const isHitElementInside = (board, element, point) => {
2110
- const rectangle = board.getRectangle(element);
2111
- point = rotateAntiPointsByElement(point, element) || point;
2112
- if (PlaitDrawElement.isGeometry(element)) {
2113
- const engine = getEngine(getElementShape(element));
2114
- const isHitInside = engine.isInsidePoint(rectangle, point);
2115
- if (isHitInside) {
2116
- return isHitInside;
2117
- }
2118
- if (engine.getTextRectangle) {
2119
- const isHitText = isHitElementText(element, point);
2120
- if (isHitText) {
2121
- return isHitText;
2122
- }
2123
- }
2124
- }
2125
- if (PlaitDrawElement.isImage(element)) {
2126
- const client = RectangleClient.getRectangleByPoints(element.points);
2127
- return RectangleClient.isPointInRectangle(client, point);
2128
- }
2129
- if (PlaitDrawElement.isLine(element)) {
2130
- return isHitLine(board, element, point);
2131
- }
2132
- return null;
2291
+ const getSelectedGeometryElements = (board) => {
2292
+ const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isGeometry(value));
2293
+ return selectedElements;
2294
+ };
2295
+ const getSelectedLineElements = (board) => {
2296
+ const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isLine(value));
2297
+ return selectedElements;
2298
+ };
2299
+ const getSelectedImageElements = (board) => {
2300
+ const selectedElements = getSelectedElements(board).filter(value => PlaitDrawElement.isImage(value));
2301
+ return selectedElements;
2302
+ };
2303
+ const isSingleSelectSwimlane = (board) => {
2304
+ const selectedElements = getSelectedElements(board);
2305
+ return selectedElements && selectedElements.length === 1 && PlaitDrawElement.isSwimlane(selectedElements[0]);
2306
+ };
2307
+ const isSingleSelectTable = (board) => {
2308
+ const selectedElements = getSelectedElements(board);
2309
+ return selectedElements && selectedElements.length === 1 && PlaitTableElement.isTable(selectedElements[0]);
2310
+ };
2311
+ const getSelectedTableElements = (board, elements) => {
2312
+ const selectedElements = elements?.length ? elements : getSelectedElements(board);
2313
+ return selectedElements.filter(value => PlaitTableElement.isTable(value));
2133
2314
  };
2134
2315
 
2135
2316
  const resizeLine = (board, options, path) => {
@@ -2365,9 +2546,7 @@ const addSwimlaneRow = (board, swimlane, index) => {
2365
2546
  const newRows = [...swimlane.rows];
2366
2547
  const newRowId = idCreator();
2367
2548
  newRows.splice(index, 0, { id: newRowId });
2368
- let newCells = createNewRowCells(swimlane, newRowId);
2369
- newCells.shift();
2370
- newCells = [...swimlane.cells, ...newCells];
2549
+ const newCells = [...swimlane.cells, ...createNewSwimlaneCells(swimlane, newRowId, 'column')];
2371
2550
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2372
2551
  const lastRowHeight = RectangleClient.getRectangleByPoints(lastCellPoints).height;
2373
2552
  const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] + lastRowHeight]];
@@ -2379,9 +2558,7 @@ const addSwimlaneColumn = (board, swimlane, index) => {
2379
2558
  const newColumns = [...swimlane.columns];
2380
2559
  const newColumnId = idCreator();
2381
2560
  newColumns.splice(index, 0, { id: newColumnId });
2382
- let newCells = createNewColumnCells(swimlane, newColumnId);
2383
- newCells.shift();
2384
- newCells = [...swimlane.cells, ...newCells];
2561
+ const newCells = [...swimlane.cells, ...createNewSwimlaneCells(swimlane, newColumnId, 'row')];
2385
2562
  const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points;
2386
2563
  const lastColumnWidth = RectangleClient.getRectangleByPoints(lastCellPoints).width;
2387
2564
  const newPoints = [swimlane.points[0], [swimlane.points[1][0] + lastColumnWidth, swimlane.points[1][1]]];
@@ -2401,7 +2578,8 @@ const removeSwimlaneRow = (board, swimlane, index) => {
2401
2578
  const newCells = swimlane.cells.filter(item => item.rowId !== removeRow.id);
2402
2579
  let removeRowHeight = removeRow.height;
2403
2580
  if (!removeRowHeight) {
2404
- const cellPoints = getCellWithPoints(board, swimlane, swimlane.cells[index].id).points;
2581
+ const rowCell = swimlane.cells.find(item => item.rowId === removeRow.id);
2582
+ const cellPoints = getCellWithPoints(board, swimlane, rowCell.id).points;
2405
2583
  removeRowHeight = RectangleClient.getRectangleByPoints(cellPoints).height;
2406
2584
  }
2407
2585
  const newPoints = [swimlane.points[0], [swimlane.points[1][0], swimlane.points[1][1] - removeRowHeight]];
@@ -2422,7 +2600,8 @@ const removeSwimlaneColumn = (board, swimlane, index) => {
2422
2600
  const newCells = swimlane.cells.filter(item => item.columnId !== removeColumn.id);
2423
2601
  let removeColumnWidth = removeColumn.width;
2424
2602
  if (!removeColumnWidth) {
2425
- const cellPoints = getCellWithPoints(board, swimlane, swimlane.cells[index].id).points;
2603
+ const columnCell = swimlane.cells.find(item => item.columnId === removeColumn.id);
2604
+ const cellPoints = getCellWithPoints(board, swimlane, columnCell.id).points;
2426
2605
  removeColumnWidth = RectangleClient.getRectangleByPoints(cellPoints).width;
2427
2606
  }
2428
2607
  const newPoints = [swimlane.points[0], [swimlane.points[1][0] - removeColumnWidth, swimlane.points[1][1]]];
@@ -2430,19 +2609,23 @@ const removeSwimlaneColumn = (board, swimlane, index) => {
2430
2609
  }
2431
2610
  }
2432
2611
  };
2433
- const createNewColumnCells = (swimlane, newColumnId) => {
2434
- return swimlane.rows.map(row => ({
2435
- id: idCreator(),
2436
- rowId: row.id,
2437
- columnId: newColumnId
2438
- }));
2439
- };
2440
- const createNewRowCells = (swimlane, newRowId) => {
2441
- return swimlane.columns.map(column => ({
2612
+ const createNewSwimlaneCells = (swimlane, newId, type) => {
2613
+ const cells = swimlane[`${type}s`].map(item => ({
2442
2614
  id: idCreator(),
2443
- rowId: newRowId,
2444
- columnId: column.id
2615
+ rowId: type === 'row' ? item.id : newId,
2616
+ columnId: type === 'row' ? newId : item.id
2445
2617
  }));
2618
+ cells.shift();
2619
+ cells[0] = {
2620
+ ...cells[0],
2621
+ text: {
2622
+ children: [{ text: 'Lane' }],
2623
+ align: Alignment.center,
2624
+ direction: type === 'row' ? undefined : 'vertical'
2625
+ },
2626
+ textHeight: 20
2627
+ };
2628
+ return cells;
2446
2629
  };
2447
2630
  const updateSwimlane = (board, swimlane, newColumns, newRows, newCells, newPoints) => {
2448
2631
  const path = PlaitBoard.findPath(board, swimlane);
@@ -4757,6 +4940,7 @@ const TableEngine = {
4757
4940
  const cellBottomBorder = drawLine$1(rs, [x, y + height], [x + width, y + height], roughOptions);
4758
4941
  g.append(cellRightBorder, cellBottomBorder);
4759
4942
  });
4943
+ setStrokeLinecap(g, 'round');
4760
4944
  return g;
4761
4945
  },
4762
4946
  isInsidePoint(rectangle, point) {
@@ -5074,6 +5258,130 @@ const CombinedFragmentEngine = {
5074
5258
  }
5075
5259
  };
5076
5260
 
5261
+ const DeletionEngine = {
5262
+ draw(board, rectangle, options) {
5263
+ const rs = PlaitBoard.getRoughSVG(board);
5264
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y} L${rectangle.x + rectangle.width} ${rectangle.y + rectangle.height}
5265
+ M${rectangle.x + rectangle.width} ${rectangle.y} L${rectangle.x} ${rectangle.y + rectangle.height}
5266
+ `, { ...options, fillStyle: 'solid', strokeWidth: 4 });
5267
+ return shape;
5268
+ },
5269
+ isInsidePoint(rectangle, point) {
5270
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5271
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5272
+ },
5273
+ getCornerPoints(rectangle) {
5274
+ return RectangleClient.getCornerPoints(rectangle);
5275
+ },
5276
+ getNearestPoint(rectangle, point) {
5277
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5278
+ },
5279
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5280
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5281
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5282
+ return getPolygonEdgeByConnectionPoint(corners, point);
5283
+ },
5284
+ getConnectorPoints(rectangle) {
5285
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5286
+ }
5287
+ };
5288
+
5289
+ const ActiveClassEngine = {
5290
+ draw(board, rectangle, options) {
5291
+ const rs = PlaitBoard.getRoughSVG(board);
5292
+ 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 +
5293
+ rectangle.height} M${rectangle.x + rectangle.width - rectangle.width * 0.125} ${rectangle.y} L${rectangle.x +
5294
+ rectangle.width -
5295
+ rectangle.width * 0.125} ${rectangle.y + rectangle.height}`, { ...options, fillStyle: 'solid' });
5296
+ setStrokeLinecap(shape, 'round');
5297
+ return shape;
5298
+ },
5299
+ isInsidePoint(rectangle, point) {
5300
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5301
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5302
+ },
5303
+ getCornerPoints(rectangle) {
5304
+ return RectangleClient.getCornerPoints(rectangle);
5305
+ },
5306
+ getNearestPoint(rectangle, point) {
5307
+ return getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5308
+ },
5309
+ getEdgeByConnectionPoint(rectangle, pointOfRectangle) {
5310
+ const corners = RectangleEngine.getCornerPoints(rectangle);
5311
+ const point = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5312
+ return getPolygonEdgeByConnectionPoint(corners, point);
5313
+ },
5314
+ getConnectorPoints(rectangle) {
5315
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5316
+ },
5317
+ getTextRectangle: (element) => {
5318
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5319
+ const strokeWidth = getStrokeWidthByElement(element);
5320
+ const height = element.textHeight;
5321
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth * 2 - elementRectangle.width * 0.125 * 2;
5322
+ return {
5323
+ height,
5324
+ width: width > 0 ? width : 0,
5325
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth + elementRectangle.width * 0.125,
5326
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5327
+ };
5328
+ }
5329
+ };
5330
+
5331
+ const NoteEngine = {
5332
+ draw(board, rectangle, options) {
5333
+ const rs = PlaitBoard.getRoughSVG(board);
5334
+ const shape = rs.path(`M${rectangle.x} ${rectangle.y}
5335
+ h${rectangle.width - 16}
5336
+ v16
5337
+ h16
5338
+ v${rectangle.height - 16}
5339
+ h${-rectangle.width}
5340
+ Z
5341
+ M${rectangle.x + rectangle.width - 16} ${rectangle.y}
5342
+ A16 16, 0,0,1, ${rectangle.x + rectangle.width} ${rectangle.y + 16}
5343
+ `, { ...options, fillStyle: 'solid' });
5344
+ setStrokeLinecap(shape, 'round');
5345
+ return shape;
5346
+ },
5347
+ isInsidePoint(rectangle, point) {
5348
+ const rangeRectangle = RectangleClient.getRectangleByPoints([point, point]);
5349
+ return RectangleClient.isHit(rectangle, rangeRectangle);
5350
+ },
5351
+ getCornerPoints(rectangle) {
5352
+ return RectangleClient.getCornerPoints(rectangle);
5353
+ },
5354
+ getNearestPoint(rectangle, point) {
5355
+ const nearestPoint = getNearestPointBetweenPointAndSegments(point, RectangleEngine.getCornerPoints(rectangle));
5356
+ if (nearestPoint[0] > rectangle.x + rectangle.width - 16 && nearestPoint[1] < rectangle.y + 16) {
5357
+ return getNearestPointBetweenPointAndEllipse(point, [rectangle.x + rectangle.width - 16, rectangle.y + 16], 16, 16);
5358
+ }
5359
+ return nearestPoint;
5360
+ },
5361
+ getTangentVectorByConnectionPoint(rectangle, pointOfRectangle) {
5362
+ const connectionPoint = RectangleClient.getConnectionPoint(rectangle, pointOfRectangle);
5363
+ const centerPoint = [rectangle.x + (rectangle.width * 3) / 4, rectangle.y + rectangle.height / 2];
5364
+ const point = [connectionPoint[0] - centerPoint[0], -(connectionPoint[1] - centerPoint[1])];
5365
+ const slope = getEllipseTangentSlope(point[0], point[1], 16, 16);
5366
+ return getVectorFromPointAndSlope(point[0], point[1], slope);
5367
+ },
5368
+ getConnectorPoints(rectangle) {
5369
+ return RectangleClient.getEdgeCenterPoints(rectangle);
5370
+ },
5371
+ getTextRectangle: (element) => {
5372
+ const elementRectangle = RectangleClient.getRectangleByPoints(element.points);
5373
+ const strokeWidth = getStrokeWidthByElement(element);
5374
+ const height = element.textHeight;
5375
+ const width = elementRectangle.width - ShapeDefaultSpace.rectangleAndText * 2 - strokeWidth - 15;
5376
+ return {
5377
+ height,
5378
+ width: width > 0 ? width : 0,
5379
+ x: elementRectangle.x + ShapeDefaultSpace.rectangleAndText + strokeWidth,
5380
+ y: elementRectangle.y + (elementRectangle.height - height) / 2
5381
+ };
5382
+ }
5383
+ };
5384
+
5077
5385
  const ShapeEngineMap = {
5078
5386
  [BasicShapes.rectangle]: RectangleEngine,
5079
5387
  [BasicShapes.diamond]: DiamondEngine,
@@ -5126,8 +5434,18 @@ const ShapeEngineMap = {
5126
5434
  [UMLSymbols.actor]: ActorEngine,
5127
5435
  [UMLSymbols.useCase]: EllipseEngine,
5128
5436
  [UMLSymbols.container]: ContainerEngine,
5437
+ [UMLSymbols.note]: NoteEngine,
5129
5438
  [UMLSymbols.package]: PackageEngine,
5130
- [UMLSymbols.combinedFragment]: CombinedFragmentEngine
5439
+ [UMLSymbols.combinedFragment]: CombinedFragmentEngine,
5440
+ [UMLSymbols.class]: TableEngine,
5441
+ [UMLSymbols.interface]: TableEngine,
5442
+ [UMLSymbols.activation]: RectangleEngine,
5443
+ [UMLSymbols.object]: RectangleEngine,
5444
+ [UMLSymbols.deletion]: DeletionEngine,
5445
+ [UMLSymbols.activityClass]: ActiveClassEngine,
5446
+ [UMLSymbols.simpleClass]: RectangleEngine,
5447
+ [UMLSymbols.port]: RectangleEngine,
5448
+ [UMLSymbols.branchMerge]: DiamondEngine
5131
5449
  };
5132
5450
  const getEngine = (shape) => {
5133
5451
  return ShapeEngineMap[shape];
@@ -5381,7 +5699,7 @@ const PlaitDrawElement = {
5381
5699
  return Object.keys(SwimlaneSymbols).includes(value.shape) && value.shape === SwimlaneSymbols.swimlaneHorizontal;
5382
5700
  },
5383
5701
  isUMLClassOrInterface: (value) => {
5384
- return false;
5702
+ return Object.keys(UMLSymbols).includes(value.shape) && [UMLSymbols.class, UMLSymbols.interface].includes(value.shape);
5385
5703
  }
5386
5704
  };
5387
5705
 
@@ -5838,7 +6156,7 @@ const withDrawHotkey = (board) => {
5838
6156
  const hitElement = getHitElementByPoint(board, point);
5839
6157
  if (hitElement && PlaitDrawElement.isGeometry(hitElement)) {
5840
6158
  if (isMultipleTextGeometry(hitElement)) {
5841
- const hitText = getHitText(hitElement, point) ||
6159
+ const hitText = getHitMultipleGeometryText(hitElement, point) ||
5842
6160
  hitElement.texts.find(item => item.key.includes(MultipleTextGeometryCommonTextKeys.content)) ||
5843
6161
  hitElement.texts[0];
5844
6162
  editText(board, hitElement, hitText);
@@ -5853,6 +6171,21 @@ const withDrawHotkey = (board) => {
5853
6171
  return board;
5854
6172
  };
5855
6173
 
6174
+ class TableGenerator extends Generator {
6175
+ canDraw(element, data) {
6176
+ return true;
6177
+ }
6178
+ draw(element, data) {
6179
+ const rectangle = RectangleClient.getRectangleByPoints(element.points);
6180
+ return getEngine(TableSymbols.table).draw(this.board, rectangle, {
6181
+ strokeWidth: 2,
6182
+ stroke: getDrawDefaultStrokeColor(this.board.theme.themeColorMode),
6183
+ }, {
6184
+ element: element
6185
+ });
6186
+ }
6187
+ }
6188
+
5856
6189
  const isGeometryDndMode = (board) => {
5857
6190
  const geometryPointers = getGeometryPointers();
5858
6191
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
@@ -5865,6 +6198,14 @@ const isGeometryDrawingMode = (board) => {
5865
6198
  const drawingMode = isGeometryPointer && isDrawingMode(board);
5866
6199
  return drawingMode;
5867
6200
  };
6201
+ const getGeometryGeneratorByShape = (board, shape) => {
6202
+ if (PlaitDrawElement.isUMLClassOrInterface({ shape: shape })) {
6203
+ return new TableGenerator(board);
6204
+ }
6205
+ else {
6206
+ return new GeometryShapeGenerator(board);
6207
+ }
6208
+ };
5868
6209
  const withGeometryCreateByDrag = (board) => {
5869
6210
  const { pointerMove, globalPointerUp, pointerUp } = board;
5870
6211
  let geometryShapeG = null;
@@ -5873,12 +6214,12 @@ const withGeometryCreateByDrag = (board) => {
5873
6214
  board.pointerMove = (event) => {
5874
6215
  geometryShapeG?.remove();
5875
6216
  geometryShapeG = createG();
5876
- const geometryGenerator = new GeometryShapeGenerator(board);
5877
6217
  const geometryPointers = getGeometryPointers();
5878
6218
  const isGeometryPointer = PlaitBoard.isInPointer(board, geometryPointers);
5879
6219
  const dragMode = isGeometryPointer && isDndMode(board);
5880
6220
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
5881
6221
  const pointer = PlaitBoard.getPointer(board);
6222
+ const geometryGenerator = getGeometryGeneratorByShape(board, pointer);
5882
6223
  if (dragMode) {
5883
6224
  const memorizedLatest = getMemorizedLatestByPointer(pointer);
5884
6225
  if (pointer === BasicShapes.text) {
@@ -5973,9 +6314,9 @@ const withGeometryCreateByDrawing = (board) => {
5973
6314
  board.pointerMove = (event) => {
5974
6315
  geometryShapeG?.remove();
5975
6316
  geometryShapeG = createG();
5976
- const geometryGenerator = new GeometryShapeGenerator(board);
5977
6317
  const movingPoint = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
5978
6318
  const pointer = PlaitBoard.getPointer(board);
6319
+ const geometryGenerator = getGeometryGeneratorByShape(board, pointer);
5979
6320
  snapG?.remove();
5980
6321
  if (start && isGeometryDrawingMode(board)) {
5981
6322
  let points = normalizeShapePoints([start, movingPoint], isShift);
@@ -6108,7 +6449,8 @@ const withDrawFragment = (baseBoard) => {
6108
6449
  const tableElements = drawElements.filter(value => PlaitDrawElement.isTable(value));
6109
6450
  const boundLineElements = [
6110
6451
  ...getBoundedLineElements(board, geometryElements),
6111
- ...getBoundedLineElements(board, imageElements)
6452
+ ...getBoundedLineElements(board, imageElements),
6453
+ ...getBoundedLineElements(board, tableElements)
6112
6454
  ].filter(line => !lineElements.includes(line));
6113
6455
  data.push(...[
6114
6456
  ...geometryElements,
@@ -6275,7 +6617,7 @@ const withGeometryResize = (board) => {
6275
6617
  snapG = resizeSnapRef.snapG;
6276
6618
  PlaitBoard.getElementActiveHost(board).append(snapG);
6277
6619
  let points = resizeSnapRef.activePoints;
6278
- if (PlaitDrawElement.isGeometry(resizeRef.element)) {
6620
+ if (PlaitDrawElement.isGeometry(resizeRef.element) && isGeometryIncludeText(resizeRef.element)) {
6279
6621
  const { height: textHeight } = getFirstTextManage(resizeRef.element).getSize();
6280
6622
  DrawTransforms.resizeGeometry(board, points, textHeight, resizeRef.path);
6281
6623
  }
@@ -6876,21 +7218,6 @@ const withDrawRotate = (board) => {
6876
7218
  return board;
6877
7219
  };
6878
7220
 
6879
- class TableGenerator extends Generator {
6880
- canDraw(element, data) {
6881
- return true;
6882
- }
6883
- draw(element, data) {
6884
- const rectangle = RectangleClient.getRectangleByPoints(element.points);
6885
- return getEngine(TableSymbols.table).draw(this.board, rectangle, {
6886
- strokeWidth: 2,
6887
- stroke: getDrawDefaultStrokeColor(this.board.theme.themeColorMode),
6888
- }, {
6889
- element: element
6890
- });
6891
- }
6892
- }
6893
-
6894
7221
  class TableComponent extends CommonElementFlavour {
6895
7222
  constructor() {
6896
7223
  super();
@@ -6942,7 +7269,9 @@ class TableComponent extends CommonElementFlavour {
6942
7269
  });
6943
7270
  }
6944
7271
  getDrawShapeTexts(cells) {
6945
- return cells.map(item => {
7272
+ return cells
7273
+ .filter(item => isCellIncludeText(item))
7274
+ .map(item => {
6946
7275
  return {
6947
7276
  key: item.id,
6948
7277
  text: item.text,
@@ -7202,7 +7531,13 @@ function buildSwimlaneTable(element) {
7202
7531
  };
7203
7532
  }
7204
7533
  if (item.text && item.textHeight && !item.text.direction) {
7205
- item.text.direction = 'vertical';
7534
+ item = {
7535
+ ...item,
7536
+ text: {
7537
+ ...item.text,
7538
+ direction: 'vertical'
7539
+ }
7540
+ };
7206
7541
  }
7207
7542
  return item;
7208
7543
  });
@@ -7554,5 +7889,5 @@ const withDraw = (board) => {
7554
7889
  * Generated bundle index. Do not edit.
7555
7890
  */
7556
7891
 
7557
- 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, 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, getGeometryPointers, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitShape, getHitText, 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, getTextManage, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isDrawElementsIncludeText, isGeometryIncludeText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectSwimlane, isSingleSelectTable, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setTextManage, traverseDrawShapes, withDraw, withLineAutoComplete };
7892
+ export { BasicShapes, DEFAULT_IMAGE_WIDTH, DEFAULT_TEXT_HEIGHT, DefaultActivationProperty, DefaultActorProperty, DefaultArrowProperty, DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultClassProperty, DefaultCloudProperty, DefaultCombinedFragmentProperty, DefaultConnectorProperty, DefaultContainerProperty, DefaultDataBaseProperty, DefaultDataProperty, DefaultDecisionProperty, DefaultDeletionProperty, DefaultDocumentProperty, DefaultDrawActiveStyle, DefaultDrawStyle, DefaultFlowchartProperty, DefaultFlowchartPropertyMap, DefaultInterfaceProperty, DefaultInternalStorageProperty, DefaultManualInputProperty, DefaultMergeProperty, DefaultMultiDocumentProperty, DefaultNoteProperty, DefaultObjectProperty, DefaultPackageProperty, DefaultPentagonArrowProperty, DefaultPortProperty, DefaultSwimlaneHorizontalProperty, DefaultSwimlanePropertyMap, DefaultSwimlaneVerticalProperty, DefaultTextProperty, DefaultTwoWayArrowProperty, DefaultUMLPropertyMap, DrawThemeColors, DrawTransforms, FlowchartSymbols, GEOMETRY_WITHOUT_TEXT, GEOMETRY_WITH_MULTIPLE_TEXT, GeometryComponent, GeometryShapeGenerator, GeometryThreshold, KEY_TO_TEXT_MANAGE, LINE_HIT_GEOMETRY_BUFFER, LINE_SNAPPING_BUFFER, LINE_SNAPPING_CONNECTOR_BUFFER, LineActiveGenerator, LineAutoCompleteGenerator, LineComponent, LineHandleKey, LineMarkerType, LineShape, MemorizeKey, MultipleTextGeometryCommonTextKeys, MultipleTextGeometryTextKeys, PlaitDrawElement, PlaitGeometry, PlaitLine, Q2C, ShapeDefaultSpace, SingleTextGenerator, StrokeStyle, SwimlaneSymbols, TableGenerator, TableSymbols, TextGenerator, UMLSymbols, WithLineAutoCompletePluginKey, alignElbowSegment, alignPoints, buildDefaultTextsByShape, createDefaultFlowchart, createDefaultGeometry, createGeometryElement, createGeometryElementWithText, createGeometryElementWithoutText, createLineElement, createMultipleTextGeometryElement, createTextElement, createUMLClassOrInterfaceGeometryElement, debugGenerator$1 as debugGenerator, deleteTextManage, drawBoundReaction, drawGeometry, drawLine, drawLineArrow, drawShape, editText, getAutoCompletePoints, getBasicPointers, getCenterPointsOnPolygon$1 as getCenterPointsOnPolygon, getConnectionPoint, getCurvePoints, getDefaultBasicShapeProperty, getDefaultFlowchartProperty, getDefaultGeometryPoints, getDefaultGeometryProperty, getDefaultTextPoints, getDefaultUMLProperty, getDrawDefaultStrokeColor, getElbowLineRouteOptions, getElbowPoints, getFillByElement, getFlowchartDefaultFill, getFlowchartPointers, getGeometryAlign, getGeometryPointers, getHitConnection, getHitConnectorPoint, getHitIndexOfAutoCompletePoint, getHitMultipleGeometryText, getHitShape, getIndexAndDeleteCountByKeyPoint, getLineDashByElement, getLineHandleRefPair, getLineMemorizedLatest, getLinePointers, getLinePoints, getLineTextRectangle, getLines, getMemorizeKey, getMemorizedLatestByPointer, getMemorizedLatestShape, getMidKeyPoints, getMiddlePoints, getMirrorDataPoints, getMultipleTextGeometryTextKeys, getNearestPoint, getNextRenderPoints, getNextSourceAndTargetPoints, getResizedPreviousAndNextPoint, getSelectedDrawElements, getSelectedGeometryElements, getSelectedImageElements, getSelectedLineElements, getSelectedTableElements, getSnapResizingRef, getSnapResizingRefOptions, getSnappingRef, getSnappingShape, getSourceAndTargetRectangle, getStrokeColorByElement, getStrokeStyleByElement, getStrokeWidthByElement, getSwimlanePointers, getTextKey, getTextManage, getTextRectangle, getTextShapeProperty, getUMLPointers, getVectorByConnection, handleLineCreating, hasIllegalElbowPoint, insertElement, isDrawElementIncludeText, isDrawElementsIncludeText, isGeometryIncludeText, isHitDrawElement, isHitEdgeOfShape, isHitElementInside, isHitElementText, isHitLine, isHitLineText, isHitPolyLine, isInsideOfShape, isMultipleTextGeometry, isMultipleTextShape, isRectangleHitDrawElement, isRectangleHitElementText, isSelfLoop, isSingleSelectSwimlane, isSingleSelectTable, isSingleTextGeometry, isSingleTextShape, isTextExceedingBounds, isUpdatedHandleIndex, isUseDefaultOrthogonalRoute, memorizeLatestShape, memorizeLatestText, rerenderGeometryActive, setTextManage, traverseDrawShapes, withDraw, withLineAutoComplete };
7558
7893
  //# sourceMappingURL=plait-draw.mjs.map