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] 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()); +};