From 1c58e34484c99afdb36ff9a1ae75664949b1797d Mon Sep 17 00:00:00 2001 From: MissLixf <32625824+MissLixf@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:38:31 +0800 Subject: [PATCH 1/4] feat(draw): unclosed element can not set fill color #WIK-15921 (#939) --- .changeset/cuddly-candles-agree.md | 5 +++++ packages/draw/src/constants/geometry.ts | 8 ++++++++ packages/draw/src/utils/common.ts | 16 ++++++++++++++-- packages/draw/src/utils/geometry.ts | 5 +++++ packages/draw/src/utils/style/stroke.ts | 7 +++++-- .../setting-panel/setting-panel.component.html | 2 +- .../setting-panel/setting-panel.component.ts | 12 +++++++++--- 7 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 .changeset/cuddly-candles-agree.md diff --git a/.changeset/cuddly-candles-agree.md b/.changeset/cuddly-candles-agree.md new file mode 100644 index 000000000..c89d19b88 --- /dev/null +++ b/.changeset/cuddly-candles-agree.md @@ -0,0 +1,5 @@ +--- +'@plait/draw': patch +--- + +add isDrawElementClosed function diff --git a/packages/draw/src/constants/geometry.ts b/packages/draw/src/constants/geometry.ts index ef37543d7..71300ec99 100644 --- a/packages/draw/src/constants/geometry.ts +++ b/packages/draw/src/constants/geometry.ts @@ -306,3 +306,11 @@ export const GEOMETRY_WITHOUT_TEXT = [ ] as GeometryShapes[]; export const GEOMETRY_WITH_MULTIPLE_TEXT = [UMLSymbols.package, UMLSymbols.combinedFragment]; + +export const GEOMETRY_NOT_CLOSED = [ + FlowchartSymbols.noteCurlyLeft, + FlowchartSymbols.noteCurlyRight, + FlowchartSymbols.noteSquare, + UMLSymbols.requiredInterface, + UMLSymbols.deletion +] as GeometryShapes[]; diff --git a/packages/draw/src/utils/common.ts b/packages/draw/src/utils/common.ts index 98c740c18..41f20b6fe 100644 --- a/packages/draw/src/utils/common.ts +++ b/packages/draw/src/utils/common.ts @@ -40,7 +40,7 @@ import { PlaitBaseTable } from '../interfaces/table'; import { memorizeLatestShape } from './memorize'; import { isHitEdgeOfShape, isInsideOfShape } from './hit'; import { getHitConnectorPoint } from './arrow-line'; -import { getNearestPoint, isGeometryIncludeText, isSingleTextGeometry } from './geometry'; +import { getNearestPoint, isGeometryClosed, isGeometryIncludeText, isSingleTextGeometry } from './geometry'; import { isMultipleTextGeometry } from './multi-text-geometry'; import { PlaitDrawShapeText } from '../generators/text.generator'; @@ -99,6 +99,18 @@ export const isDrawElementsIncludeText = (elements: PlaitDrawElement[]) => { }); }; +export const isDrawElementClosed = (element: PlaitDrawElement) => { + if (PlaitDrawElement.isText(element) || PlaitDrawElement.isArrowLine(element) || PlaitDrawElement.isImage(element)) { + return false; + } + + if (PlaitDrawElement.isGeometry(element)) { + return isGeometryClosed(element); + } + + return true; +}; + export const getSnappingShape = (board: PlaitBoard, point: Point): PlaitShapeElement | null => { let hitElement: PlaitShapeElement | null = getHitShape(board, point); if (hitElement) { @@ -184,7 +196,7 @@ export const drawBoundReaction = ( { stroke: SELECTION_BORDER_COLOR, strokeWidth: 0, - fill: SELECTION_FILL_COLOR, + fill: isDrawElementClosed(element) ? SELECTION_FILL_COLOR : DefaultDrawStyle.fill, fillStyle: 'solid' }, drawOptions diff --git a/packages/draw/src/utils/geometry.ts b/packages/draw/src/utils/geometry.ts index ba2e74429..7de98360e 100644 --- a/packages/draw/src/utils/geometry.ts +++ b/packages/draw/src/utils/geometry.ts @@ -9,6 +9,7 @@ import { DefaultUMLPropertyMap, DrawPointerType, DrawThemeColors, + GEOMETRY_NOT_CLOSED, GEOMETRY_WITHOUT_TEXT, ShapeDefaultSpace, getFlowchartPointers, @@ -390,3 +391,7 @@ export const isSingleTextShape = (shape: GeometryShapes) => { export const isSingleTextGeometry = (element: PlaitGeometry) => { return PlaitDrawElement.isGeometry(element) && isSingleTextShape(element.shape); }; + +export const isGeometryClosed = (element: PlaitGeometry) => { + return !GEOMETRY_NOT_CLOSED.includes(element.shape); +}; diff --git a/packages/draw/src/utils/style/stroke.ts b/packages/draw/src/utils/style/stroke.ts index 32492d8b1..0f5c19cb5 100644 --- a/packages/draw/src/utils/style/stroke.ts +++ b/packages/draw/src/utils/style/stroke.ts @@ -2,7 +2,7 @@ import { PlaitBaseTable, PlaitDrawElement, StrokeStyle } from '../../interfaces' import { DefaultDrawStyle } from '../../constants'; import { PlaitBoard, PlaitElement } from '@plait/core'; import { getDrawDefaultStrokeColor, getFlowchartDefaultFill } from '../geometry'; -import { getStrokeWidthByElement } from '../common'; +import { getStrokeWidthByElement, isDrawElementClosed } from '../common'; export const getStrokeColorByElement = (board: PlaitBoard, element: PlaitElement) => { const defaultColor = getDrawDefaultStrokeColor(board.theme.themeColorMode); @@ -11,7 +11,10 @@ export const getStrokeColorByElement = (board: PlaitBoard, element: PlaitElement }; export const getFillByElement = (board: PlaitBoard, element: PlaitElement) => { - const defaultFill = PlaitDrawElement.isFlowchart(element) ? getFlowchartDefaultFill(board.theme.themeColorMode) : DefaultDrawStyle.fill; + const defaultFill = + PlaitDrawElement.isFlowchart(element) && isDrawElementClosed(element as PlaitDrawElement) + ? getFlowchartDefaultFill(board.theme.themeColorMode) + : DefaultDrawStyle.fill; const fill = element.fill || defaultFill; return fill; }; diff --git a/src/app/components/setting-panel/setting-panel.component.html b/src/app/components/setting-panel/setting-panel.component.html index a90e90f1b..13019c040 100644 --- a/src/app/components/setting-panel/setting-panel.component.html +++ b/src/app/components/setting-panel/setting-panel.component.html @@ -287,7 +287,7 @@ -
+
填充颜色:
isDrawElementClosed(item)); if (this.isSelectSwimlane) { this.swimlaneCount = getSwimlaneCount(getSelectedElements(this.board)[0] as PlaitSwimlane); } @@ -200,7 +205,6 @@ export class AppSettingPanelComponent extends PlaitIslandBaseComponent implement this.cdr.markForCheck(); }); } - const selectedDrawElements = getSelectedDrawElements(this.board); this.isIncludeText = selectedMindElements.length ? true : isDrawElementsIncludeText(selectedDrawElements); } @@ -244,7 +248,9 @@ export class AppSettingPanelComponent extends PlaitIslandBaseComponent implement if (tableElement) { DrawTransforms.setTableFill(this.board, element, property, path); } else { - Transforms.setNode(this.board, { fill: property }, path); + if (isDrawElementClosed(element as PlaitDrawElement)) { + Transforms.setNode(this.board, { fill: property }, path); + } } } }); From b6aad2054861240ebab57e165c675594c8826a2d Mon Sep 17 00:00:00 2001 From: huanhuanwa <44698191+huanhuanwa@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:04:35 +0800 Subject: [PATCH 2/4] fix(draw): adjust line dash value for dotted #WIK-15965 (#941) --- .changeset/yellow-chairs-scream.md | 5 +++++ packages/core/src/utils/drawing/rectangle.ts | 4 +++- packages/draw/src/engines/basic-shapes/ellipse.ts | 7 +++++-- .../draw/src/engines/basic-shapes/round-comment.ts | 7 +++++-- packages/draw/src/engines/flowchart/or.ts | 9 +++++---- .../draw/src/engines/flowchart/summing-junction.ts | 10 ++++++---- packages/draw/src/engines/uml/deletion.ts | 10 +++++++++- packages/draw/src/utils/style/stroke.ts | 4 ++-- 8 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 .changeset/yellow-chairs-scream.md diff --git a/.changeset/yellow-chairs-scream.md b/.changeset/yellow-chairs-scream.md new file mode 100644 index 000000000..a0013cc5f --- /dev/null +++ b/.changeset/yellow-chairs-scream.md @@ -0,0 +1,5 @@ +--- +'@plait/draw': patch +--- + +adjust line dash value for dotted diff --git a/packages/core/src/utils/drawing/rectangle.ts b/packages/core/src/utils/drawing/rectangle.ts index 441db387b..dd819fdd2 100644 --- a/packages/core/src/utils/drawing/rectangle.ts +++ b/packages/core/src/utils/drawing/rectangle.ts @@ -39,10 +39,12 @@ export function drawRoundRectangle( const point7 = [x1, y2 - radius]; const point8 = [x1, y1 + radius]; - return rs.path( + const rectangleG = rs.path( `M${point2[0]} ${point2[1]} A ${radius} ${radius}, 0, 0, 1, ${point3[0]} ${point3[1]} L ${point4[0]} ${point4[1]} A ${radius} ${radius}, 0, 0, 1, ${point5[0]} ${point5[1]} L ${point6[0]} ${point6[1]} A ${radius} ${radius}, 0, 0, 1, ${point7[0]} ${point7[1]} L ${point8[0]} ${point8[1]} A ${radius} ${radius}, 0, 0, 1, ${point1[0]} ${point1[1]} Z`, options ); + setStrokeLinecap(rectangleG, 'round'); + return rectangleG; } export const drawRectangle = (board: PlaitBoard, rectangle: RectangleClient, options: Options) => { diff --git a/packages/draw/src/engines/basic-shapes/ellipse.ts b/packages/draw/src/engines/basic-shapes/ellipse.ts index 7968ca81f..25e2de89f 100644 --- a/packages/draw/src/engines/basic-shapes/ellipse.ts +++ b/packages/draw/src/engines/basic-shapes/ellipse.ts @@ -6,7 +6,8 @@ import { getEllipseTangentSlope, getVectorFromPointAndSlope, isPointInEllipse, - getNearestPointBetweenPointAndEllipse + getNearestPointBetweenPointAndEllipse, + setStrokeLinecap } from '@plait/core'; import { PlaitGeometry, ShapeEngine } from '../../interfaces'; import { Options } from 'roughjs/bin/core'; @@ -22,7 +23,9 @@ export function createEllipseEngine(createOptions?: CreateEllipseOptions): Shape draw(board: PlaitBoard, rectangle: RectangleClient, options: Options) { const centerPoint = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2]; const rs = PlaitBoard.getRoughSVG(board); - return rs.ellipse(centerPoint[0], centerPoint[1], rectangle.width, rectangle.height, { ...options, fillStyle: 'solid' }); + const shape = rs.ellipse(centerPoint[0], centerPoint[1], rectangle.width, rectangle.height, { ...options, fillStyle: 'solid' }); + setStrokeLinecap(shape, 'round'); + return shape; }, isInsidePoint(rectangle: RectangleClient, point: Point) { const centerPoint: Point = [rectangle.x + rectangle.width / 2, rectangle.y + rectangle.height / 2]; diff --git a/packages/draw/src/engines/basic-shapes/round-comment.ts b/packages/draw/src/engines/basic-shapes/round-comment.ts index 1782fc698..d04e6499e 100644 --- a/packages/draw/src/engines/basic-shapes/round-comment.ts +++ b/packages/draw/src/engines/basic-shapes/round-comment.ts @@ -5,7 +5,8 @@ import { RectangleClient, getNearestPointBetweenPointAndSegments, isPointInPolygon, - isPointInRoundRectangle + isPointInRoundRectangle, + setStrokeLinecap } from '@plait/core'; import { PlaitGeometry, ShapeEngine } from '../../interfaces'; import { Options } from 'roughjs/bin/core'; @@ -38,10 +39,12 @@ export const RoundCommentEngine: ShapeEngine = { const point10 = [x1 + rectangle.width / 4, rectangle.y + rectangle.height]; const point11 = [x1 + rectangle.width / 2, y2]; - return rs.path( + const shape = rs.path( `M${point2[0]} ${point2[1]} A ${radius} ${radius}, 0, 0, 1, ${point3[0]} ${point3[1]} L ${point4[0]} ${point4[1]} A ${radius} ${radius}, 0, 0, 1, ${point5[0]} ${point5[1]} L ${point11[0]} ${point11[1]} ${point10[0]} ${point10[1]} ${point9[0]} ${point9[1]} ${point6[0]} ${point6[1]} A ${radius} ${radius}, 0, 0, 1, ${point7[0]} ${point7[1]} L ${point8[0]} ${point8[1]} A ${radius} ${radius}, 0, 0, 1, ${point1[0]} ${point1[1]} Z`, { ...options, fillStyle: 'solid' } ); + setStrokeLinecap(shape, 'round'); + return shape; }, isInsidePoint(rectangle: RectangleClient, point: Point) { const points: Point[] = [ diff --git a/packages/draw/src/engines/flowchart/or.ts b/packages/draw/src/engines/flowchart/or.ts index 3baa9a473..2956a5146 100644 --- a/packages/draw/src/engines/flowchart/or.ts +++ b/packages/draw/src/engines/flowchart/or.ts @@ -1,7 +1,6 @@ -import { PlaitBoard, RectangleClient } from '@plait/core'; -import { PlaitGeometry, ShapeEngine } from '../../interfaces'; +import { PlaitBoard, RectangleClient, setStrokeLinecap } from '@plait/core'; +import { ShapeEngine } from '../../interfaces'; import { Options } from 'roughjs/bin/core'; -import { getTextRectangle } from '../../utils'; import { createEllipseEngine } from '../basic-shapes/ellipse'; export const OrEngine: ShapeEngine = createEllipseEngine({ @@ -10,7 +9,7 @@ export const OrEngine: ShapeEngine = createEllipseEngine({ const rx = rectangle.width / 2; const ry = rectangle.height / 2; const startPoint = [rectangle.x + rectangle.width, rectangle.y + rectangle.height / 2]; - return rs.path( + const shape = rs.path( `M${startPoint[0]} ${startPoint[1]} A${rx},${ry} 0 1,1 ${startPoint[0]} ${startPoint[1] - 0.01} M${rectangle.x} ${rectangle.y + rectangle.height / 2} @@ -20,5 +19,7 @@ export const OrEngine: ShapeEngine = createEllipseEngine({ `, { ...options, fillStyle: 'solid' } ); + setStrokeLinecap(shape, 'round'); + return shape; } }); diff --git a/packages/draw/src/engines/flowchart/summing-junction.ts b/packages/draw/src/engines/flowchart/summing-junction.ts index 98965892b..2e8d533f4 100644 --- a/packages/draw/src/engines/flowchart/summing-junction.ts +++ b/packages/draw/src/engines/flowchart/summing-junction.ts @@ -1,7 +1,6 @@ -import { PlaitBoard, RectangleClient, getCrossingPointsBetweenEllipseAndSegment } from '@plait/core'; -import { PlaitGeometry, ShapeEngine } from '../../interfaces'; +import { PlaitBoard, RectangleClient, getCrossingPointsBetweenEllipseAndSegment, setStrokeLinecap } from '@plait/core'; +import { ShapeEngine } from '../../interfaces'; import { Options } from 'roughjs/bin/core'; -import { getTextRectangle } from '../../utils'; import { createEllipseEngine } from '../basic-shapes/ellipse'; export const SummingJunctionEngine: ShapeEngine = createEllipseEngine({ @@ -28,7 +27,7 @@ export const SummingJunctionEngine: ShapeEngine = createEllipseEngine({ ry ); - return rs.path( + const shape = rs.path( `M${startPoint[0]} ${startPoint[1]} A${rx},${ry} 0 1,1 ${startPoint[0]} ${startPoint[1] - 0.01} M${line1Points[0][0]} ${line1Points[0][1]} @@ -38,5 +37,8 @@ export const SummingJunctionEngine: ShapeEngine = createEllipseEngine({ `, { ...options, fillStyle: 'solid' } ); + + setStrokeLinecap(shape, 'round'); + return shape; } }); diff --git a/packages/draw/src/engines/uml/deletion.ts b/packages/draw/src/engines/uml/deletion.ts index 63a5d977f..3fb1d5337 100644 --- a/packages/draw/src/engines/uml/deletion.ts +++ b/packages/draw/src/engines/uml/deletion.ts @@ -1,4 +1,11 @@ -import { PlaitBoard, Point, PointOfRectangle, RectangleClient, getNearestPointBetweenPointAndSegments } from '@plait/core'; +import { + PlaitBoard, + Point, + PointOfRectangle, + RectangleClient, + getNearestPointBetweenPointAndSegments, + setStrokeLinecap +} from '@plait/core'; import { ShapeEngine } from '../../interfaces'; import { Options } from 'roughjs/bin/core'; import { getPolygonEdgeByConnectionPoint } from '../../utils/polygon'; @@ -13,6 +20,7 @@ export const DeletionEngine: ShapeEngine = { `, { ...options, fillStyle: 'solid', strokeWidth: 4 } ); + setStrokeLinecap(shape, 'round'); return shape; }, isInsidePoint(rectangle: RectangleClient, point: Point) { diff --git a/packages/draw/src/utils/style/stroke.ts b/packages/draw/src/utils/style/stroke.ts index 0f5c19cb5..248d647f4 100644 --- a/packages/draw/src/utils/style/stroke.ts +++ b/packages/draw/src/utils/style/stroke.ts @@ -1,4 +1,4 @@ -import { PlaitBaseTable, PlaitDrawElement, StrokeStyle } from '../../interfaces'; +import { PlaitDrawElement, StrokeStyle } from '../../interfaces'; import { DefaultDrawStyle } from '../../constants'; import { PlaitBoard, PlaitElement } from '@plait/core'; import { getDrawDefaultStrokeColor, getFlowchartDefaultFill } from '../geometry'; @@ -24,7 +24,7 @@ export const getLineDashByElement = (element: PlaitElement) => { case StrokeStyle.dashed: return [8, 8 + getStrokeWidthByElement(element)]; case StrokeStyle.dotted: - return [0, 4 + getStrokeWidthByElement(element)]; + return [2, 4 + getStrokeWidthByElement(element)]; default: return undefined; } From ff83a27067e09169eb9caa818e5d419a8a47b5b1 Mon Sep 17 00:00:00 2001 From: huanhuanwa <44698191+huanhuanwa@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:32:29 +0800 Subject: [PATCH 3/4] fix(draw): fix link swimlane error by autocomplete #WIK-15966 (#940) --- .changeset/rotten-insects-destroy.md | 5 + package-lock.json | 99 +++++++++---------- package.json | 1 + .../draw/src/plugins/with-swimlane-create.ts | 9 +- packages/draw/src/transforms/arrow-line.ts | 47 +-------- packages/draw/src/transforms/common.ts | 46 +++++++++ packages/draw/src/transforms/geometry.ts | 40 +++----- packages/draw/src/transforms/index.ts | 11 ++- packages/draw/src/transforms/swimlane.ts | 1 - .../src/utils/arrow-line/arrow-line-common.ts | 47 ++++++++- packages/draw/src/utils/swimlane.ts | 8 +- 11 files changed, 176 insertions(+), 138 deletions(-) create mode 100644 .changeset/rotten-insects-destroy.md create mode 100644 packages/draw/src/transforms/common.ts diff --git a/.changeset/rotten-insects-destroy.md b/.changeset/rotten-insects-destroy.md new file mode 100644 index 000000000..9997aac90 --- /dev/null +++ b/.changeset/rotten-insects-destroy.md @@ -0,0 +1,5 @@ +--- +'@plait/draw': patch +--- + +fix link swimlane error by autocomplete diff --git a/package-lock.json b/package-lock.json index 589e5ead0..b9137bc6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "graphology": "^0.25.4", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-types": "^0.24.7", "is-hotkey": "^0.2.0", "points-on-curve": "^1.0.0", "roughjs": "^4.5.2", @@ -9488,6 +9489,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -12331,8 +12333,7 @@ "node_modules/graphology-types": { "version": "0.24.7", "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.7.tgz", - "integrity": "sha512-tdcqOOpwArNjEr0gNQKCXwaNCWnQJrog14nJNQPeemcLnXQUUGrsCWpWkVKt46zLjcS6/KGoayeJfHHyPDlvwA==", - "peer": true + "integrity": "sha512-tdcqOOpwArNjEr0gNQKCXwaNCWnQJrog14nJNQPeemcLnXQUUGrsCWpWkVKt46zLjcS6/KGoayeJfHHyPDlvwA==" }, "node_modules/graphology-utils": { "version": "2.5.2", @@ -15436,7 +15437,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -22796,7 +22798,8 @@ }, "packages/angular-board": { "name": "@plait/angular-board", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -22808,7 +22811,8 @@ }, "packages/angular-text": { "name": "@plait/angular-text", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -22832,7 +22836,8 @@ }, "packages/common": { "name": "@plait/common", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -22842,7 +22847,8 @@ }, "packages/core": { "name": "@plait/core", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -22856,7 +22862,8 @@ }, "packages/draw": { "name": "@plait/draw", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -22866,34 +22873,39 @@ }, "packages/flow": { "name": "@plait/flow", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } }, "packages/graph-viz": { "name": "@plait/graph-viz", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" + }, + "peerDependencies": { + "graphology": "^0.25.4", + "graphology-layout": "^0.6.1", + "graphology-layout-forceatlas2": "^0.10.1" } }, "packages/layouts": { "name": "@plait/layouts", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } }, "packages/mind": { "name": "@plait/mind", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" - }, - "peerDependencies": { - "@angular/common": "^17.2.4", - "@angular/core": "^17.2.4" } }, "packages/mindmap": { @@ -22947,7 +22959,8 @@ }, "packages/text-plugins": { "name": "@plait/text-plugins", - "version": "0.62.0-next.3", + "version": "0.62.0-next.7", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } @@ -23859,8 +23872,7 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "requires": {} + "dev": true }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -26197,8 +26209,7 @@ "version": "17.2.3", "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.2.3.tgz", "integrity": "sha512-+d5Q7/ctDHePYZXcg0GFwL/AbyEkPMHoCiT7pmLI0B0n87D/mYKK/qmVN1VANBrFLTuIe8RtcL0aJ9pw8HAxWA==", - "dev": true, - "requires": {} + "dev": true }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -27538,8 +27549,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz", "integrity": "sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==", - "dev": true, - "requires": {} + "dev": true }, "@webassemblyjs/ast": { "version": "1.11.6", @@ -27758,15 +27768,13 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "requires": {} + "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "adjust-sourcemap-loader": { "version": "4.0.0", @@ -29878,6 +29886,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -30799,8 +30808,7 @@ "version": "8.5.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-prettier": { "version": "4.2.1", @@ -32076,14 +32084,12 @@ "graphology-types": { "version": "0.24.7", "resolved": "https://registry.npmjs.org/graphology-types/-/graphology-types-0.24.7.tgz", - "integrity": "sha512-tdcqOOpwArNjEr0gNQKCXwaNCWnQJrog14nJNQPeemcLnXQUUGrsCWpWkVKt46zLjcS6/KGoayeJfHHyPDlvwA==", - "peer": true + "integrity": "sha512-tdcqOOpwArNjEr0gNQKCXwaNCWnQJrog14nJNQPeemcLnXQUUGrsCWpWkVKt46zLjcS6/KGoayeJfHHyPDlvwA==" }, "graphology-utils": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/graphology-utils/-/graphology-utils-2.5.2.tgz", - "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==", - "requires": {} + "integrity": "sha512-ckHg8MXrXJkOARk56ZaSCM1g1Wihe2d6iTmz1enGOz4W/l831MBCKSayeFQfowgF8wd+PQ4rlch/56Vs/VZLDQ==" }, "handle-thing": { "version": "2.0.1", @@ -32481,8 +32487,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} + "dev": true }, "ieee754": { "version": "1.2.1", @@ -33640,8 +33645,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz", "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==", - "dev": true, - "requires": {} + "dev": true }, "karma-source-map-support": { "version": "1.4.0", @@ -34407,7 +34411,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "multicast-dns": { "version": "7.2.5", @@ -35911,8 +35916,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.4", @@ -38384,8 +38388,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "json-schema-traverse": { "version": "0.4.1", @@ -38673,8 +38676,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "requires": {} + "dev": true }, "ts-morph": { "version": "7.3.0", @@ -39518,8 +39520,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "json-schema-traverse": { "version": "0.4.1", @@ -39608,8 +39609,7 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -39800,8 +39800,7 @@ "version": "8.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "requires": {} + "dev": true }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index eb49d8600..29b95bad5 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "graphology": "^0.25.4", "graphology-layout": "^0.6.1", "graphology-layout-forceatlas2": "^0.10.1", + "graphology-types": "^0.24.7", "is-hotkey": "^0.2.0", "points-on-curve": "^1.0.0", "roughjs": "^4.5.2", diff --git a/packages/draw/src/plugins/with-swimlane-create.ts b/packages/draw/src/plugins/with-swimlane-create.ts index cbfb52375..dbd76203c 100644 --- a/packages/draw/src/plugins/with-swimlane-create.ts +++ b/packages/draw/src/plugins/with-swimlane-create.ts @@ -1,7 +1,6 @@ import { PlaitBoard, Point, RectangleClient, createG, preventTouchMove, toHostPoint, toViewBoxPoint } from '@plait/core'; import { PlaitSwimlane, SwimlaneDrawSymbols } from '../interfaces'; import { insertElement } from '../utils'; -import { getSwimlanePointers } from '../constants'; import { normalizeShapePoints, isDndMode, @@ -13,7 +12,7 @@ import { import { isKeyHotkey } from 'is-hotkey'; import { getSnapResizingRef } from '../utils/snap-resizing'; import { TableGenerator } from '../generators/table.generator'; -import { createDefaultSwimlane, getDefaultSwimlanePoints } from '../utils/swimlane'; +import { createDefaultSwimlane, getDefaultSwimlanePoints, isSwimlanePointers } from '../utils/swimlane'; export interface FakeCreateTextRef { g: SVGGElement; @@ -21,15 +20,13 @@ export interface FakeCreateTextRef { } const isSwimlaneDndMode = (board: PlaitBoard) => { - const swimlanePointers = getSwimlanePointers(); - const isSwimlanePointer = PlaitBoard.isInPointer(board, swimlanePointers); + const isSwimlanePointer = isSwimlanePointers(board); const dndMode = isSwimlanePointer && isDndMode(board); return dndMode; }; const isSwimlaneDrawingMode = (board: PlaitBoard) => { - const swimlanePointers = getSwimlanePointers(); - const isSwimlanePointer = PlaitBoard.isInPointer(board, swimlanePointers); + const isSwimlanePointer = isSwimlanePointers(board); const drawingMode = isSwimlanePointer && isDrawingMode(board); return drawingMode; }; diff --git a/packages/draw/src/transforms/arrow-line.ts b/packages/draw/src/transforms/arrow-line.ts index d593c4296..fea21c1e4 100644 --- a/packages/draw/src/transforms/arrow-line.ts +++ b/packages/draw/src/transforms/arrow-line.ts @@ -6,12 +6,11 @@ import { ArrowLineText, MemorizeKey, PlaitArrowLine, - PlaitDrawElement, - PlaitGeometry + PlaitShapeElement } from '../interfaces'; import { memorizeLatest } from '@plait/common'; import { getSelectedArrowLineElements } from '../utils/selected'; -import { getHitConnection, getArrowLinePoints } from '../utils/arrow-line/arrow-line-basic'; +import { getHitConnection } from '../utils/arrow-line/arrow-line-basic'; export const resizeArrowLine = (board: PlaitBoard, options: Partial, path: Path) => { Transforms.setNode(board, options, path); @@ -53,49 +52,11 @@ export const setArrowLineShape = (board: PlaitBoard, newProperties: Partial; path: Path }[] -) => { - const lines = findElements(board, { - match: (element: PlaitElement) => { - if (PlaitDrawElement.isArrowLine(element)) { - return element.source.boundId === geometry.id || element.target.boundId === geometry.id; - } - return false; - }, - recursion: element => true - }) as PlaitArrowLine[]; - if (lines.length) { - lines.forEach(line => { - const isSourceBound = line.source.boundId === geometry.id; - const handle = isSourceBound ? 'source' : 'target'; - const object = { ...line[handle] }; - const linePoints = getArrowLinePoints(board, line); - const point = isSourceBound ? linePoints[0] : linePoints[linePoints.length - 1]; - object.connection = getHitConnection(board, point, geometry); - const path = PlaitBoard.findPath(board, line); - const index = refs.findIndex(obj => Path.equals(obj.path, path)); - if (index === -1) { - refs.push({ - property: { - [handle]: object - }, - path - }); - } else { - refs[index].property = { ...refs[index].property, [handle]: object }; - } - }); - } -}; - -export const connectArrowLineToGeometry = ( +export const connectArrowLineToDraw = ( board: PlaitBoard, lineElement: PlaitArrowLine, handle: ArrowLineHandleKey, - geometryElement: PlaitGeometry + geometryElement: PlaitShapeElement ) => { const linePoints = PlaitArrowLine.getPoints(board, lineElement); const point = handle === ArrowLineHandleKey.source ? linePoints[0] : linePoints[linePoints.length - 1]; diff --git a/packages/draw/src/transforms/common.ts b/packages/draw/src/transforms/common.ts new file mode 100644 index 000000000..5c33c11bb --- /dev/null +++ b/packages/draw/src/transforms/common.ts @@ -0,0 +1,46 @@ +import { getDirectionByVector, getPointByVectorComponent } from '@plait/common'; +import { PlaitBoard, Vector, Direction, RectangleClient, Point } from '@plait/core'; +import { createDefaultSwimlane, insertElement } from '../utils'; +import { insertGeometry } from './geometry'; +import { BasicShapes, FlowchartSymbols, GeometryShapes, SwimlaneDrawSymbols, UMLSymbols } from '../interfaces'; +import { + DefaultBasicShapeProperty, + DefaultBasicShapePropertyMap, + DefaultFlowchartPropertyMap, + DefaultSwimlanePropertyMap, + DefaultUMLPropertyMap, + getSwimlanePointers +} from '../constants'; + +export const insertDrawByVector = (board: PlaitBoard, point: Point, shape: GeometryShapes | SwimlaneDrawSymbols, vector: Vector) => { + const swimlanePointers = getSwimlanePointers(); + const isSwimlanePointer = swimlanePointers.includes(shape); + let shapeProperty = + DefaultFlowchartPropertyMap[shape as FlowchartSymbols] || + DefaultBasicShapePropertyMap[shape as BasicShapes] || + DefaultUMLPropertyMap[shape as UMLSymbols] || + DefaultBasicShapeProperty; + if (isSwimlanePointer) { + shapeProperty = DefaultSwimlanePropertyMap[shape]; + } + const direction = getDirectionByVector(vector); + if (direction) { + let offset = 0; + if ([Direction.left, Direction.right].includes(direction)) { + offset = -shapeProperty.width / 2; + } else { + offset = -shapeProperty.height / 2; + } + const vectorPoint = getPointByVectorComponent(point, vector, offset); + const points = RectangleClient.getPoints( + RectangleClient.getRectangleByCenterPoint(vectorPoint, shapeProperty.width, shapeProperty.height) + ); + if (isSwimlanePointer) { + const swimlane = createDefaultSwimlane(shape as SwimlaneDrawSymbols, points); + insertElement(board, swimlane); + return swimlane; + } + return insertGeometry(board, points, shape as GeometryShapes); + } + return null; +}; diff --git a/packages/draw/src/transforms/geometry.ts b/packages/draw/src/transforms/geometry.ts index a040f0f49..b6660a9a3 100644 --- a/packages/draw/src/transforms/geometry.ts +++ b/packages/draw/src/transforms/geometry.ts @@ -1,11 +1,16 @@ -import { PlaitBoard, Transforms, Point, Path, PlaitNode, getSelectedElements, Vector, Direction, RectangleClient } from '@plait/core'; -import { PlaitDrawElement, GeometryShapes, PlaitText, FlowchartSymbols, BasicShapes, UMLSymbols, PlaitArrowLine } from '../interfaces'; -import { createDefaultGeometry, createTextElement, getMemorizedLatestByPointer, getTextShapeProperty, insertElement } from '../utils'; +import { PlaitBoard, Transforms, Point, Path, PlaitNode, getSelectedElements } from '@plait/core'; +import { PlaitDrawElement, GeometryShapes, PlaitText, BasicShapes, PlaitArrowLine } from '../interfaces'; +import { + collectArrowLineUpdatedRefsByGeometry, + createDefaultGeometry, + createTextElement, + getMemorizedLatestByPointer, + getTextShapeProperty, + insertElement +} from '../utils'; import { Element } from 'slate'; -import { getDirectionByVector, getPointByVectorComponent, normalizeShapePoints } from '@plait/common'; +import { normalizeShapePoints } from '@plait/common'; import { DrawTransforms } from '.'; -import { collectArrowLineUpdatedRefsByGeometry } from './arrow-line'; -import { DefaultBasicShapeProperty, DefaultBasicShapePropertyMap, DefaultFlowchartPropertyMap, DefaultUMLPropertyMap } from '../constants'; export const insertGeometry = (board: PlaitBoard, points: [Point, Point], shape: GeometryShapes) => { const newElement = createDefaultGeometry(board, points, shape); @@ -13,29 +18,6 @@ export const insertGeometry = (board: PlaitBoard, points: [Point, Point], shape: return newElement; }; -export const insertGeometryByVector = (board: PlaitBoard, point: Point, shape: GeometryShapes, vector: Vector) => { - const shapeProperty = - DefaultFlowchartPropertyMap[shape as FlowchartSymbols] || - DefaultBasicShapePropertyMap[shape as BasicShapes] || - DefaultUMLPropertyMap[shape as UMLSymbols] || - DefaultBasicShapeProperty; - const direction = getDirectionByVector(vector); - if (direction) { - let offset = 0; - if ([Direction.left, Direction.right].includes(direction)) { - offset = -shapeProperty.width / 2; - } else { - offset = -shapeProperty.height / 2; - } - const vectorPoint = getPointByVectorComponent(point, vector, offset); - const points = RectangleClient.getPoints( - RectangleClient.getRectangleByCenterPoint(vectorPoint, shapeProperty.width, shapeProperty.height) - ); - return insertGeometry(board, points, shape); - } - return null; -}; - export const insertText = (board: PlaitBoard, point: Point, text: string | Element) => { const memorizedLatest = getMemorizedLatestByPointer(BasicShapes.text); const property = getTextShapeProperty(board, text, memorizedLatest.textProperties['font-size']); diff --git a/packages/draw/src/transforms/index.ts b/packages/draw/src/transforms/index.ts index 815ebe7d7..b319e2fd0 100644 --- a/packages/draw/src/transforms/index.ts +++ b/packages/draw/src/transforms/index.ts @@ -1,8 +1,8 @@ -import { insertText, insertGeometry, resizeGeometry, switchGeometryShape, insertGeometryByVector } from './geometry'; +import { insertText, insertGeometry, resizeGeometry, switchGeometryShape } from './geometry'; import { setText, setTextSize } from './geometry-text'; import { insertImage } from './image'; import { - connectArrowLineToGeometry, + connectArrowLineToDraw, removeArrowLineText, resizeArrowLine, setArrowLineMark, @@ -13,6 +13,7 @@ import { addSwimlaneColumn, addSwimlaneRow, removeSwimlaneColumn, removeSwimlane import { setDrawShapeText } from './multi-text-geometry-text'; import { setTableText } from './table-text'; import { setTableFill } from './table'; +import { insertDrawByVector } from './common'; export const DrawTransforms = { setText, @@ -27,14 +28,14 @@ export const DrawTransforms = { setArrowLineMark, setArrowLineShape, insertImage, + connectArrowLineToDraw, switchGeometryShape, - connectArrowLineToGeometry, - insertGeometryByVector, setTableText, addSwimlaneRow, addSwimlaneColumn, removeSwimlaneRow, removeSwimlaneColumn, updateSwimlaneCount, - setTableFill + setTableFill, + insertDrawByVector }; diff --git a/packages/draw/src/transforms/swimlane.ts b/packages/draw/src/transforms/swimlane.ts index 38f423ea7..d8db1160d 100644 --- a/packages/draw/src/transforms/swimlane.ts +++ b/packages/draw/src/transforms/swimlane.ts @@ -61,7 +61,6 @@ export const addSwimlaneColumn = (board: PlaitBoard, swimlane: PlaitSwimlane, in const lastCellPoints = getCellWithPoints(board, swimlane, swimlane.cells[swimlane.cells.length - 1].id).points; const lastColumnWidth = RectangleClient.getRectangleByPoints(lastCellPoints).width; const newPoints: Point[] = [swimlane.points[0], [swimlane.points[1][0] + lastColumnWidth * count, swimlane.points[1][1]]]; - updateSwimlane(board, swimlane, newColumns, swimlane.rows, newCells, newPoints); } }; diff --git a/packages/draw/src/utils/arrow-line/arrow-line-common.ts b/packages/draw/src/utils/arrow-line/arrow-line-common.ts index 4f2136436..e6b49b18c 100644 --- a/packages/draw/src/utils/arrow-line/arrow-line-common.ts +++ b/packages/draw/src/utils/arrow-line/arrow-line-common.ts @@ -7,7 +7,10 @@ import { Direction, Vector, hasValidAngle, - rotatePointsByElement + rotatePointsByElement, + findElements, + PlaitElement, + Path } from '@plait/core'; import { getDirectionFactor, @@ -27,12 +30,14 @@ import { ArrowLineMarkerType, PlaitArrowLine, PlaitGeometry, - PlaitShapeElement + PlaitShapeElement, + PlaitDrawElement } from '../../interfaces'; import { getEngine } from '../../engines'; import { getElementShape } from '../shape'; import { getSourceAndTargetRectangle } from './elbow'; import { getStrokeWidthByElement } from '../common'; +import { getArrowLinePoints, getHitConnection } from './arrow-line-basic'; export const getArrowLineHandleRefPair = (board: PlaitBoard, element: PlaitArrowLine): ArrowLineHandleRefPair => { const strokeWidth = getStrokeWidthByElement(element); @@ -161,3 +166,41 @@ export const getElbowLineRouteOptions = (board: PlaitBoard, element: PlaitArrowL targetOuterRectangle }; }; + +export const collectArrowLineUpdatedRefsByGeometry = ( + board: PlaitBoard, + element: PlaitShapeElement, + refs: { property: Partial; path: Path }[] +) => { + const lines = findElements(board, { + match: (element: PlaitElement) => { + if (PlaitDrawElement.isArrowLine(element)) { + return element.source.boundId === element.id || element.target.boundId === element.id; + } + return false; + }, + recursion: element => true + }) as PlaitArrowLine[]; + if (lines.length) { + lines.forEach(line => { + const isSourceBound = line.source.boundId === element.id; + const handle = isSourceBound ? 'source' : 'target'; + const object = { ...line[handle] }; + const linePoints = getArrowLinePoints(board, line); + const point = isSourceBound ? linePoints[0] : linePoints[linePoints.length - 1]; + object.connection = getHitConnection(board, point, element); + const path = PlaitBoard.findPath(board, line); + const index = refs.findIndex(obj => Path.equals(obj.path, path)); + if (index === -1) { + refs.push({ + property: { + [handle]: object + }, + path + }); + } else { + refs[index].property = { ...refs[index].property, [handle]: object }; + } + }); + } +}; diff --git a/packages/draw/src/utils/swimlane.ts b/packages/draw/src/utils/swimlane.ts index bed8dc25b..8264d23c4 100644 --- a/packages/draw/src/utils/swimlane.ts +++ b/packages/draw/src/utils/swimlane.ts @@ -1,5 +1,5 @@ -import { idCreator, Point, RectangleClient } from '@plait/core'; -import { DefaultSwimlanePropertyMap, SWIMLANE_HEADER_SIZE } from '../constants'; +import { idCreator, PlaitBoard, Point, RectangleClient } from '@plait/core'; +import { DefaultSwimlanePropertyMap, getSwimlanePointers, SWIMLANE_HEADER_SIZE } from '../constants'; import { PlaitDrawElement, PlaitSwimlane, PlaitTableCell, SwimlaneDrawSymbols, SwimlaneSymbols } from '../interfaces'; import { createCell } from './table'; @@ -135,3 +135,7 @@ export const adjustSwimlaneShape = (shape: SwimlaneDrawSymbols): SwimlaneSymbols ? SwimlaneSymbols.swimlaneHorizontal : SwimlaneSymbols.swimlaneVertical; }; + +export const isSwimlanePointers = (board: PlaitBoard) => { + return PlaitBoard.isInPointer(board, getSwimlanePointers()); +}; From 7d1e71348f2c4da4c86df5b6402f2e8cef9a8508 Mon Sep 17 00:00:00 2001 From: huanhuanwa <44698191+huanhuanwa@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:58:04 +0800 Subject: [PATCH 4/4] fix(draw): throw new Error when get cell points (#942) --- .changeset/modern-clocks-doubt.md | 5 ++ packages/draw/src/engines/table/table.ts | 78 +++++++++++++++--------- packages/draw/src/utils/table.ts | 15 +++-- 3 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 .changeset/modern-clocks-doubt.md diff --git a/.changeset/modern-clocks-doubt.md b/.changeset/modern-clocks-doubt.md new file mode 100644 index 000000000..f5c03002f --- /dev/null +++ b/.changeset/modern-clocks-doubt.md @@ -0,0 +1,5 @@ +--- +'@plait/draw': patch +--- + +throw new Error when get cell points diff --git a/packages/draw/src/engines/table/table.ts b/packages/draw/src/engines/table/table.ts index 5434365ef..e4d1ae310 100644 --- a/packages/draw/src/engines/table/table.ts +++ b/packages/draw/src/engines/table/table.ts @@ -10,31 +10,37 @@ import { getNearestPointBetweenPointAndRoundRectangle, getRoundRectangleRadius } export const TableEngine: ShapeEngine = { draw(board: PlaitBoard, rectangle: RectangleClient, roughOptions: Options, options?: PlaitTableDrawOptions) { - const rs = PlaitBoard.getRoughSVG(board); const g = createG(); - const { x, y, width, height } = rectangle; - const tableTopBorder = drawLine(rs, [x, y], [x + width, y], roughOptions); - const tableLeftBorder = drawLine(rs, [x, y], [x, y + height], roughOptions); - g.append(tableTopBorder, tableLeftBorder); - const pointCells = getCellsWithPoints(board, { ...options?.element } as PlaitTable); - pointCells.forEach(cell => { - const rectangle = RectangleClient.getRectangleByPoints(cell.points!); - const { x, y, width, height } = rectangle; - const cellRectangle = drawRectangle( - board, - { - x: x + ACTIVE_STROKE_WIDTH, - y: y + ACTIVE_STROKE_WIDTH, - width: width - ACTIVE_STROKE_WIDTH * 2, - height: height - ACTIVE_STROKE_WIDTH * 2 - }, - { fill: cell.fill, fillStyle: 'solid', strokeWidth: 0 } - ); - const cellRightBorder = drawLine(rs, [x + width, y], [x + width, y + height], roughOptions); - const cellBottomBorder = drawLine(rs, [x, y + height], [x + width, y + height], roughOptions); - g.append(cellRectangle, cellRightBorder, cellBottomBorder); - }); - setStrokeLinecap(g, 'round'); + try { + const pointCells = getCellsWithPoints(board, { ...options?.element } as PlaitTable); + if (pointCells) { + const rs = PlaitBoard.getRoughSVG(board); + const { x, y, width, height } = rectangle; + const tableTopBorder = drawLine(rs, [x, y], [x + width, y], roughOptions); + const tableLeftBorder = drawLine(rs, [x, y], [x, y + height], roughOptions); + g.append(tableTopBorder, tableLeftBorder); + pointCells.forEach(cell => { + const rectangle = RectangleClient.getRectangleByPoints(cell.points!); + const { x, y, width, height } = rectangle; + const cellRectangle = drawRectangle( + board, + { + x: x + ACTIVE_STROKE_WIDTH, + y: y + ACTIVE_STROKE_WIDTH, + width: width - ACTIVE_STROKE_WIDTH * 2, + height: height - ACTIVE_STROKE_WIDTH * 2 + }, + { fill: cell.fill, fillStyle: 'solid', strokeWidth: 0 } + ); + const cellRightBorder = drawLine(rs, [x + width, y], [x + width, y + height], roughOptions); + const cellBottomBorder = drawLine(rs, [x, y + height], [x + width, y + height], roughOptions); + g.append(cellRectangle, cellRightBorder, cellBottomBorder); + }); + setStrokeLinecap(g, 'round'); + } + } catch (error) { + console.error(error); + } return g; }, isInsidePoint(rectangle: RectangleClient, point: Point) { @@ -51,12 +57,26 @@ export const TableEngine: ShapeEngine item.id === cellId); - return cells[cellIndex]; + try { + const cells = getCellsWithPoints(board as PlaitTableBoard, table); + const cellIndex = cells && table.cells.findIndex(item => item.id === cellId); + return cells[cellIndex]; + } catch (error) { + throw new Error('can not get table cell points'); + } } function calculateCellsSize(items: { id: string; [key: string]: any }[], tableSize: number, count: number, isWidth: boolean) {