@flowgram.ai/free-lines-plugin 0.1.0-alpha.7 → 0.1.0-alpha.8

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.
package/dist/esm/index.js CHANGED
@@ -51,7 +51,7 @@ var WorkflowPointStyle = styled.div`
51
51
  border-radius: 50%;
52
52
  width: 20px;
53
53
  height: 20px;
54
- background-color: #fff;
54
+ background-color: var(--g-workflow-port-color-background, #fff);
55
55
  transform: scale(0.5);
56
56
  transition: all 0.2s linear 0s;
57
57
  }
@@ -64,12 +64,12 @@ var WorkflowPointStyle = styled.div`
64
64
  width: 100%;
65
65
  height: 100%;
66
66
  border-radius: 50%;
67
- background: #9197F1;
67
+ background: var(--g-workflow-port-color-secondary, #9197f1);
68
68
  transform: scale(0.4, 0.4);
69
69
  transition: all 0.2s linear 0s;
70
70
 
71
71
  &.hasError {
72
- background: red;
72
+ background: var(--g-workflow-port-color-error, red);
73
73
  }
74
74
 
75
75
  .symbol {
@@ -78,7 +78,7 @@ var WorkflowPointStyle = styled.div`
78
78
  height: 14px;
79
79
  opacity: 0;
80
80
  pointer-events: none;
81
- color: #fff;
81
+ color: var(--g-workflow-port-color-background, #fff);
82
82
  transition: opacity 0.2s linear 0s;
83
83
 
84
84
  & > svg {
@@ -95,21 +95,21 @@ var WorkflowPointStyle = styled.div`
95
95
  width: 8px;
96
96
  height: 8px;
97
97
  opacity: 0;
98
- background: #9197f1;
98
+ background: var(--g-workflow-port-color-secondary, #9197f1);
99
99
  border-radius: 50%;
100
100
  transition: opacity 0.2s linear 0s;
101
101
  }
102
102
  }
103
103
 
104
104
  &.linked .bg:not(.hasError) {
105
- background: #4d53e8;
105
+ background: var(--g-workflow-port-color-primary, #4d53e8);
106
106
  }
107
107
 
108
108
  &.hovered .bg:not(.hasError) {
109
109
  border: none;
110
110
  cursor: crosshair;
111
111
  transform: scale(1, 1);
112
- background: #4d53e8;
112
+ background: var(--g-workflow-port-color-primary, #4d53e8);
113
113
 
114
114
  & > .symbol {
115
115
  opacity: 1;
@@ -124,7 +124,7 @@ var WorkflowPointStyle = styled.div`
124
124
  &::after,
125
125
  &::before {
126
126
  content: '';
127
- background: #fff;
127
+ background: var(--g-workflow-port-color-background, #fff);
128
128
  border-radius: 2px;
129
129
  position: absolute;
130
130
  }
@@ -133,14 +133,14 @@ var WorkflowPointStyle = styled.div`
133
133
  left: 4px;
134
134
  width: 2px;
135
135
  height: 6px;
136
- box-shadow: 0 4px #fff;
136
+ box-shadow: 0 4px var(--g-workflow-port-color-background, #fff);
137
137
  }
138
138
 
139
139
  &::before {
140
140
  top: 4px;
141
141
  width: 6px;
142
142
  height: 2px;
143
- box-shadow: 4px 0 #fff;
143
+ box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);
144
144
  }
145
145
  `;
146
146
 
@@ -154,6 +154,7 @@ function CrossHair() {
154
154
  var WorkflowPortRender = (
155
155
  // eslint-disable-next-line react/display-name
156
156
  React2.memo((props) => {
157
+ var _a;
157
158
  const hoverService = useService(WorkflowHoverService);
158
159
  const linesManager = useService(WorkflowLinesManager);
159
160
  const { entity, onClick } = props;
@@ -162,7 +163,7 @@ var WorkflowPortRender = (
162
163
  const [posX, updatePosX] = useState(relativePosition.x);
163
164
  const [posY, updatePosY] = useState(relativePosition.y);
164
165
  const [hovered, setHovered] = useState(false);
165
- const [linked, setLinked] = useState(Boolean(entity?.lines?.length));
166
+ const [linked, setLinked] = useState(Boolean((_a = entity == null ? void 0 : entity.lines) == null ? void 0 : _a.length));
166
167
  const [hasError, setHasError] = useState(props.entity.hasError);
167
168
  const readonly = usePlaygroundReadonlyState();
168
169
  useEffect(() => {
@@ -198,7 +199,7 @@ var WorkflowPortRender = (
198
199
  dispose4.dispose();
199
200
  };
200
201
  }, [hoverService, entity, targetElement]);
201
- const className = classNames(props.className || "", {
202
+ const className = classNames("workflow-port-render", props.className || "", {
202
203
  hovered: !readonly && hovered && !disabled && portType !== "input",
203
204
  // 有线条链接的时候深蓝色小圆点
204
205
  linked
@@ -452,31 +453,40 @@ var WorkflowLinesLayer = class extends Layer {
452
453
  }
453
454
  }
454
455
  lineProps(line) {
455
- const renderData = line.getData(WorkflowLineRenderData2);
456
- const { renderVersion } = renderData;
457
456
  const { lineType } = this.workflowDocument.linesManager;
458
457
  const selected = this.selectService.isSelected(line.id);
459
- const { version: lineVersion, color } = line;
460
- const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;
458
+ const hovered = this.hoverService.isHovered(line.id);
459
+ const version = this.lineVersion(line);
461
460
  return {
462
461
  key: line.id,
463
462
  color: line.color,
464
463
  selected,
464
+ hovered,
465
465
  line,
466
466
  lineType,
467
467
  version,
468
468
  strokePrefix: this.layerID
469
469
  };
470
470
  }
471
+ lineVersion(line) {
472
+ const renderData = line.getData(WorkflowLineRenderData2);
473
+ const { renderVersion } = renderData;
474
+ const selected = this.selectService.isSelected(line.id);
475
+ const hovered = this.hoverService.isHovered(line.id);
476
+ const { version: lineVersion, color } = line;
477
+ const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${selected ? "T" : "F"},h:${hovered ? "T" : "F"}`;
478
+ return version;
479
+ }
471
480
  lineComponent(props) {
472
- const RenderInsideLine = this.options.renderInsideLine ?? (() => /* @__PURE__ */ React5.createElement(React5.Fragment, null));
481
+ var _a;
482
+ const RenderInsideLine = (_a = this.options.renderInsideLine) != null ? _a : () => /* @__PURE__ */ React5.createElement(React5.Fragment, null);
473
483
  return /* @__PURE__ */ React5.createElement(WorkflowLineRender, { ...props }, /* @__PURE__ */ React5.createElement(RenderInsideLine, { ...props }));
474
484
  }
475
485
  renderLine(line) {
476
486
  const lineProps = this.lineProps(line);
477
487
  const cache = this.mountedLines.get(line.id);
478
488
  const isCached = cache !== void 0;
479
- const { portal: cachedPortal, version: cachedVersion } = cache ?? {};
489
+ const { portal: cachedPortal, version: cachedVersion } = cache != null ? cache : {};
480
490
  if (isCached && cachedVersion === lineProps.version) {
481
491
  return cachedPortal;
482
492
  }
@@ -665,7 +675,8 @@ var WorkflowBezierLineContribution = class {
665
675
  this.entity = entity;
666
676
  }
667
677
  get path() {
668
- return this.data?.path ?? "";
678
+ var _a, _b;
679
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
669
680
  }
670
681
  calcDistance(pos) {
671
682
  if (!this.data) {
@@ -936,7 +947,8 @@ var WorkflowFoldLineContribution = class {
936
947
  this.entity = entity;
937
948
  }
938
949
  get path() {
939
- return this.data?.path ?? "";
950
+ var _a, _b;
951
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
940
952
  }
941
953
  calcDistance(pos) {
942
954
  if (!this.data) {
@@ -1017,7 +1029,8 @@ var WorkflowStraightLineContribution = class {
1017
1029
  this.entity = entity;
1018
1030
  }
1019
1031
  get path() {
1020
- return this.data?.path ?? "";
1032
+ var _a, _b;
1033
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1021
1034
  }
1022
1035
  calcDistance(pos) {
1023
1036
  if (!this.data) {
@@ -1078,7 +1091,8 @@ var WorkflowArkLineContribution = class {
1078
1091
  this.entity = entity;
1079
1092
  }
1080
1093
  get path() {
1081
- return this.data?.path ?? "";
1094
+ var _a, _b;
1095
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1082
1096
  }
1083
1097
  calcDistance(pos) {
1084
1098
  if (!this.data) {
@@ -1167,7 +1181,8 @@ var WorkflowManhattanLineContribution = class {
1167
1181
  this.entity = entity;
1168
1182
  }
1169
1183
  get path() {
1170
- return this.data?.path ?? "";
1184
+ var _a, _b;
1185
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1171
1186
  }
1172
1187
  calcDistance(pos) {
1173
1188
  if (!this.data) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/workflow-port-render/index.tsx","../../src/constants/points.ts","../../src/components/workflow-port-render/style.ts","../../src/components/workflow-port-render/cross-hair.tsx","../../src/constants/lines.ts","../../src/create-free-lines-plugin.ts","../../src/layer/workflow-lines-layer.tsx","../../src/components/workflow-line-render/index.tsx","../../src/components/workflow-line-render/line-svg.tsx","../../src/components/workflow-line-render/index.style.ts","../../src/components/workflow-line-render/arrow.tsx","../../src/contributions/bezier/bezier-controls.ts","../../src/contributions/bezier/index.ts","../../src/contributions/fold/index.ts","../../src/contributions/fold/fold-line.ts","../../src/contributions/straight/index.ts","../../src/contributions/straight/point-on-line.ts","../../src/contributions/arc/index.ts","../../src/contributions/manhattan/index.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\n};\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 计算点到折线的最短距离\n * @param points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["React","React","WorkflowLinesManager","ReactDOM","React","useState","WorkflowHoverService","WorkflowLineRenderData","React","styled","React","React","React","useState","WorkflowLineRenderData","React","ReactDOM","WorkflowHoverService","BezierControlType","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","FoldLine","xDir","yDir","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","WorkflowLinesManager"]}
1
+ {"version":3,"sources":["../../src/components/workflow-port-render/index.tsx","../../src/constants/points.ts","../../src/components/workflow-port-render/style.ts","../../src/components/workflow-port-render/cross-hair.tsx","../../src/constants/lines.ts","../../src/create-free-lines-plugin.ts","../../src/layer/workflow-lines-layer.tsx","../../src/components/workflow-line-render/index.tsx","../../src/components/workflow-line-render/line-svg.tsx","../../src/components/workflow-line-render/index.style.ts","../../src/components/workflow-line-render/arrow.tsx","../../src/contributions/bezier/bezier-controls.ts","../../src/contributions/bezier/index.ts","../../src/contributions/fold/index.ts","../../src/contributions/fold/fold-line.ts","../../src/contributions/straight/index.ts","../../src/contributions/straight/point-on-line.ts","../../src/contributions/arc/index.ts","../../src/contributions/manhattan/index.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames('workflow-port-render', props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: var(--g-workflow-port-color-background, #fff);\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: var(--g-workflow-port-color-secondary, #9197f1);\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: var(--g-workflow-port-color-error, red);\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: var(--g-workflow-port-color-background, #fff);\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: var(--g-workflow-port-color-secondary, #9197f1);\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: var(--g-workflow-port-color-primary, #4d53e8);\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: var(--g-workflow-port-color-primary, #4d53e8);\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: var(--g-workflow-port-color-background, #fff);\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px var(--g-workflow-port-color-background, #fff);\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const version = this.lineVersion(line);\n\n return {\n key: line.id,\n color: line.color,\n selected,\n hovered,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineVersion(line: WorkflowLineEntity): string {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${\n selected ? 'T' : 'F'\n },h:${hovered ? 'T' : 'F'}`;\n\n return version;\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\n};\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 计算点到折线的最短距离\n * @param points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["React","React","WorkflowLinesManager","ReactDOM","React","useState","WorkflowHoverService","WorkflowLineRenderData","React","styled","React","React","React","useState","WorkflowLineRenderData","React","ReactDOM","WorkflowHoverService","BezierControlType","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","FoldLine","xDir","yDir","Rectangle","POINT_RADIUS","LineType","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","Point","Rectangle","POINT_RADIUS","WorkflowLinesManager"]}
package/dist/index.d.mts CHANGED
@@ -21,6 +21,7 @@ interface LineRenderProps {
21
21
  key: string;
22
22
  color?: string;
23
23
  selected?: boolean;
24
+ hovered?: boolean;
24
25
  line: WorkflowLineEntity;
25
26
  lineType: LineRenderType;
26
27
  version: string;
@@ -59,6 +60,7 @@ declare class WorkflowLinesLayer extends Layer<LinesLayerOptions> {
59
60
  render(): JSX.Element;
60
61
  private bumpVersion;
61
62
  private lineProps;
63
+ private lineVersion;
62
64
  private lineComponent;
63
65
  private renderLine;
64
66
  private get renderElement();
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ interface LineRenderProps {
21
21
  key: string;
22
22
  color?: string;
23
23
  selected?: boolean;
24
+ hovered?: boolean;
24
25
  line: WorkflowLineEntity;
25
26
  lineType: LineRenderType;
26
27
  version: string;
@@ -59,6 +60,7 @@ declare class WorkflowLinesLayer extends Layer<LinesLayerOptions> {
59
60
  render(): JSX.Element;
60
61
  private bumpVersion;
61
62
  private lineProps;
63
+ private lineVersion;
62
64
  private lineComponent;
63
65
  private renderLine;
64
66
  private get renderElement();
package/dist/index.js CHANGED
@@ -93,7 +93,7 @@ var WorkflowPointStyle = import_styled_components.default.div`
93
93
  border-radius: 50%;
94
94
  width: 20px;
95
95
  height: 20px;
96
- background-color: #fff;
96
+ background-color: var(--g-workflow-port-color-background, #fff);
97
97
  transform: scale(0.5);
98
98
  transition: all 0.2s linear 0s;
99
99
  }
@@ -106,12 +106,12 @@ var WorkflowPointStyle = import_styled_components.default.div`
106
106
  width: 100%;
107
107
  height: 100%;
108
108
  border-radius: 50%;
109
- background: #9197F1;
109
+ background: var(--g-workflow-port-color-secondary, #9197f1);
110
110
  transform: scale(0.4, 0.4);
111
111
  transition: all 0.2s linear 0s;
112
112
 
113
113
  &.hasError {
114
- background: red;
114
+ background: var(--g-workflow-port-color-error, red);
115
115
  }
116
116
 
117
117
  .symbol {
@@ -120,7 +120,7 @@ var WorkflowPointStyle = import_styled_components.default.div`
120
120
  height: 14px;
121
121
  opacity: 0;
122
122
  pointer-events: none;
123
- color: #fff;
123
+ color: var(--g-workflow-port-color-background, #fff);
124
124
  transition: opacity 0.2s linear 0s;
125
125
 
126
126
  & > svg {
@@ -137,21 +137,21 @@ var WorkflowPointStyle = import_styled_components.default.div`
137
137
  width: 8px;
138
138
  height: 8px;
139
139
  opacity: 0;
140
- background: #9197f1;
140
+ background: var(--g-workflow-port-color-secondary, #9197f1);
141
141
  border-radius: 50%;
142
142
  transition: opacity 0.2s linear 0s;
143
143
  }
144
144
  }
145
145
 
146
146
  &.linked .bg:not(.hasError) {
147
- background: #4d53e8;
147
+ background: var(--g-workflow-port-color-primary, #4d53e8);
148
148
  }
149
149
 
150
150
  &.hovered .bg:not(.hasError) {
151
151
  border: none;
152
152
  cursor: crosshair;
153
153
  transform: scale(1, 1);
154
- background: #4d53e8;
154
+ background: var(--g-workflow-port-color-primary, #4d53e8);
155
155
 
156
156
  & > .symbol {
157
157
  opacity: 1;
@@ -166,7 +166,7 @@ var WorkflowPointStyle = import_styled_components.default.div`
166
166
  &::after,
167
167
  &::before {
168
168
  content: '';
169
- background: #fff;
169
+ background: var(--g-workflow-port-color-background, #fff);
170
170
  border-radius: 2px;
171
171
  position: absolute;
172
172
  }
@@ -175,14 +175,14 @@ var WorkflowPointStyle = import_styled_components.default.div`
175
175
  left: 4px;
176
176
  width: 2px;
177
177
  height: 6px;
178
- box-shadow: 0 4px #fff;
178
+ box-shadow: 0 4px var(--g-workflow-port-color-background, #fff);
179
179
  }
180
180
 
181
181
  &::before {
182
182
  top: 4px;
183
183
  width: 6px;
184
184
  height: 2px;
185
- box-shadow: 4px 0 #fff;
185
+ box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);
186
186
  }
187
187
  `;
188
188
 
@@ -196,6 +196,7 @@ function CrossHair() {
196
196
  var WorkflowPortRender = (
197
197
  // eslint-disable-next-line react/display-name
198
198
  import_react2.default.memo((props) => {
199
+ var _a;
199
200
  const hoverService = (0, import_core.useService)(import_free_layout_core.WorkflowHoverService);
200
201
  const linesManager = (0, import_core.useService)(import_free_layout_core.WorkflowLinesManager);
201
202
  const { entity, onClick } = props;
@@ -204,7 +205,7 @@ var WorkflowPortRender = (
204
205
  const [posX, updatePosX] = (0, import_react2.useState)(relativePosition.x);
205
206
  const [posY, updatePosY] = (0, import_react2.useState)(relativePosition.y);
206
207
  const [hovered, setHovered] = (0, import_react2.useState)(false);
207
- const [linked, setLinked] = (0, import_react2.useState)(Boolean(entity?.lines?.length));
208
+ const [linked, setLinked] = (0, import_react2.useState)(Boolean((_a = entity == null ? void 0 : entity.lines) == null ? void 0 : _a.length));
208
209
  const [hasError, setHasError] = (0, import_react2.useState)(props.entity.hasError);
209
210
  const readonly = (0, import_free_layout_core.usePlaygroundReadonlyState)();
210
211
  (0, import_react2.useEffect)(() => {
@@ -240,7 +241,7 @@ var WorkflowPortRender = (
240
241
  dispose4.dispose();
241
242
  };
242
243
  }, [hoverService, entity, targetElement]);
243
- const className = (0, import_clsx.default)(props.className || "", {
244
+ const className = (0, import_clsx.default)("workflow-port-render", props.className || "", {
244
245
  hovered: !readonly && hovered && !disabled && portType !== "input",
245
246
  // 有线条链接的时候深蓝色小圆点
246
247
  linked
@@ -485,31 +486,40 @@ var WorkflowLinesLayer = class extends import_core2.Layer {
485
486
  }
486
487
  }
487
488
  lineProps(line) {
488
- const renderData = line.getData(import_free_layout_core4.WorkflowLineRenderData);
489
- const { renderVersion } = renderData;
490
489
  const { lineType } = this.workflowDocument.linesManager;
491
490
  const selected = this.selectService.isSelected(line.id);
492
- const { version: lineVersion, color } = line;
493
- const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;
491
+ const hovered = this.hoverService.isHovered(line.id);
492
+ const version = this.lineVersion(line);
494
493
  return {
495
494
  key: line.id,
496
495
  color: line.color,
497
496
  selected,
497
+ hovered,
498
498
  line,
499
499
  lineType,
500
500
  version,
501
501
  strokePrefix: this.layerID
502
502
  };
503
503
  }
504
+ lineVersion(line) {
505
+ const renderData = line.getData(import_free_layout_core4.WorkflowLineRenderData);
506
+ const { renderVersion } = renderData;
507
+ const selected = this.selectService.isSelected(line.id);
508
+ const hovered = this.hoverService.isHovered(line.id);
509
+ const { version: lineVersion, color } = line;
510
+ const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${selected ? "T" : "F"},h:${hovered ? "T" : "F"}`;
511
+ return version;
512
+ }
504
513
  lineComponent(props) {
505
- const RenderInsideLine = this.options.renderInsideLine ?? (() => /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null));
514
+ var _a;
515
+ const RenderInsideLine = (_a = this.options.renderInsideLine) != null ? _a : () => /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null);
506
516
  return /* @__PURE__ */ import_react6.default.createElement(WorkflowLineRender, { ...props }, /* @__PURE__ */ import_react6.default.createElement(RenderInsideLine, { ...props }));
507
517
  }
508
518
  renderLine(line) {
509
519
  const lineProps = this.lineProps(line);
510
520
  const cache = this.mountedLines.get(line.id);
511
521
  const isCached = cache !== void 0;
512
- const { portal: cachedPortal, version: cachedVersion } = cache ?? {};
522
+ const { portal: cachedPortal, version: cachedVersion } = cache != null ? cache : {};
513
523
  if (isCached && cachedVersion === lineProps.version) {
514
524
  return cachedPortal;
515
525
  }
@@ -696,7 +706,8 @@ var WorkflowBezierLineContribution = class {
696
706
  this.entity = entity;
697
707
  }
698
708
  get path() {
699
- return this.data?.path ?? "";
709
+ var _a, _b;
710
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
700
711
  }
701
712
  calcDistance(pos) {
702
713
  if (!this.data) {
@@ -965,7 +976,8 @@ var WorkflowFoldLineContribution = class {
965
976
  this.entity = entity;
966
977
  }
967
978
  get path() {
968
- return this.data?.path ?? "";
979
+ var _a, _b;
980
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
969
981
  }
970
982
  calcDistance(pos) {
971
983
  if (!this.data) {
@@ -1044,7 +1056,8 @@ var WorkflowStraightLineContribution = class {
1044
1056
  this.entity = entity;
1045
1057
  }
1046
1058
  get path() {
1047
- return this.data?.path ?? "";
1059
+ var _a, _b;
1060
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1048
1061
  }
1049
1062
  calcDistance(pos) {
1050
1063
  if (!this.data) {
@@ -1103,7 +1116,8 @@ var WorkflowArkLineContribution = class {
1103
1116
  this.entity = entity;
1104
1117
  }
1105
1118
  get path() {
1106
- return this.data?.path ?? "";
1119
+ var _a, _b;
1120
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1107
1121
  }
1108
1122
  calcDistance(pos) {
1109
1123
  if (!this.data) {
@@ -1190,7 +1204,8 @@ var WorkflowManhattanLineContribution = class {
1190
1204
  this.entity = entity;
1191
1205
  }
1192
1206
  get path() {
1193
- return this.data?.path ?? "";
1207
+ var _a, _b;
1208
+ return (_b = (_a = this.data) == null ? void 0 : _a.path) != null ? _b : "";
1194
1209
  }
1195
1210
  calcDistance(pos) {
1196
1211
  if (!this.data) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/workflow-port-render/index.tsx","../src/constants/points.ts","../src/components/workflow-port-render/style.ts","../src/components/workflow-port-render/cross-hair.tsx","../src/constants/lines.ts","../src/create-free-lines-plugin.ts","../src/layer/workflow-lines-layer.tsx","../src/components/workflow-line-render/index.tsx","../src/components/workflow-line-render/line-svg.tsx","../src/components/workflow-line-render/index.style.ts","../src/components/workflow-line-render/arrow.tsx","../src/contributions/bezier/bezier-controls.ts","../src/contributions/bezier/index.ts","../src/contributions/fold/index.ts","../src/contributions/fold/fold-line.ts","../src/contributions/straight/index.ts","../src/contributions/straight/point-on-line.ts","../src/contributions/arc/index.ts","../src/contributions/manhattan/index.ts"],"sourcesContent":["export * from './components/workflow-port-render';\nexport * from './constants/lines';\nexport * from './create-free-lines-plugin';\nexport * from './layer';\nexport * from './type';\nexport * from './contributions';\n","import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames(props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: #fff;\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: #9197F1;\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: red;\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: #fff;\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: #9197f1;\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: #4d53e8;\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: #4d53e8;\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: #fff;\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px #fff;\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 #fff;\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;\n return {\n key: line.id,\n color: line.color,\n selected,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\n};\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 计算点到折线的最短距离\n * @param points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["import_react","styled","React","React","classNames","ReactDOM","import_free_layout_core","import_core","import_react_dom","import_react","import_free_layout_core","import_core","import_react","import_react","import_clsx","import_free_layout_core","import_styled_components","styled","import_react","React","React","clsx","React","ReactDOM","import_utils","BezierControlType","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","FoldLine","xDir","yDir","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","import_free_layout_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/workflow-port-render/index.tsx","../src/constants/points.ts","../src/components/workflow-port-render/style.ts","../src/components/workflow-port-render/cross-hair.tsx","../src/constants/lines.ts","../src/create-free-lines-plugin.ts","../src/layer/workflow-lines-layer.tsx","../src/components/workflow-line-render/index.tsx","../src/components/workflow-line-render/line-svg.tsx","../src/components/workflow-line-render/index.style.ts","../src/components/workflow-line-render/arrow.tsx","../src/contributions/bezier/bezier-controls.ts","../src/contributions/bezier/index.ts","../src/contributions/fold/index.ts","../src/contributions/fold/fold-line.ts","../src/contributions/straight/index.ts","../src/contributions/straight/point-on-line.ts","../src/contributions/arc/index.ts","../src/contributions/manhattan/index.ts"],"sourcesContent":["export * from './components/workflow-port-render';\nexport * from './constants/lines';\nexport * from './create-free-lines-plugin';\nexport * from './layer';\nexport * from './type';\nexport * from './contributions';\n","import ReactDOM from 'react-dom';\nimport React, { useEffect, useState } from 'react';\n\nimport classNames from 'clsx';\nimport {\n WorkflowHoverService,\n type WorkflowPortEntity,\n usePlaygroundReadonlyState,\n WorkflowLinesManager,\n} from '@flowgram.ai/free-layout-core';\nimport { useService } from '@flowgram.ai/core';\n\nimport { PORT_BG_CLASS_NAME } from '../../constants/points';\nimport { WorkflowPointStyle } from './style';\nimport CrossHair from './cross-hair';\n\nexport interface WorkflowPortRenderProps {\n entity: WorkflowPortEntity;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLDivElement>;\n}\n\nexport const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =\n // eslint-disable-next-line react/display-name\n React.memo<WorkflowPortRenderProps>((props: WorkflowPortRenderProps) => {\n const hoverService = useService<WorkflowHoverService>(WorkflowHoverService);\n const linesManager = useService<WorkflowLinesManager>(WorkflowLinesManager);\n const { entity, onClick } = props;\n const { portType, relativePosition, disabled } = entity;\n const [targetElement, setTargetElement] = useState(entity.targetElement);\n const [posX, updatePosX] = useState(relativePosition.x);\n const [posY, updatePosY] = useState(relativePosition.y);\n const [hovered, setHovered] = useState(false);\n const [linked, setLinked] = useState(Boolean(entity?.lines?.length));\n const [hasError, setHasError] = useState(props.entity.hasError);\n const readonly = usePlaygroundReadonlyState();\n\n useEffect(() => {\n // useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate\n entity.validate();\n setHasError(entity.hasError);\n const dispose = entity.onEntityChange(() => {\n // 如果有挂载的节点,不需要更新位置信息\n if (entity.targetElement) {\n if (entity.targetElement !== targetElement) {\n setTargetElement(entity.targetElement);\n }\n return;\n }\n const newPos = entity.relativePosition;\n // 加上 round 避免点位抖动\n updatePosX(Math.round(newPos.x));\n updatePosY(Math.round(newPos.y));\n });\n const dispose2 = hoverService.onHoveredChange((id) => {\n setHovered(hoverService.isHovered(entity.id));\n });\n const dispose3 = entity.onErrorChanged(() => {\n setHasError(entity.hasError);\n });\n const dispose4 = linesManager.onAvailableLinesChange(() => {\n setTimeout(() => {\n if (linesManager.disposed || entity.disposed) return;\n setLinked(Boolean(entity.lines.length));\n }, 0);\n });\n return () => {\n dispose.dispose();\n dispose2.dispose();\n dispose3.dispose();\n dispose4.dispose();\n };\n }, [hoverService, entity, targetElement]);\n\n // 监听变化\n const className = classNames('workflow-port-render', props.className || '', {\n hovered: !readonly && hovered && !disabled && portType !== 'input',\n // 有线条链接的时候深蓝色小圆点\n linked,\n });\n const content = (\n <WorkflowPointStyle\n className={className}\n style={targetElement ? props.style : { ...props.style, left: posX, top: posY }}\n onClick={onClick}\n data-port-entity-id={entity.id}\n data-port-entity-type={entity.portType}\n data-testid=\"sdk.workflow.canvas.node.port\"\n >\n <div className={classNames('bg-circle', 'workflow-bg-circle')}></div>\n <div\n className={classNames({\n bg: true,\n [PORT_BG_CLASS_NAME]: true,\n 'workflow-point-bg': true,\n hasError,\n })}\n >\n <CrossHair />\n </div>\n <div className=\"focus-circle\" />\n </WorkflowPointStyle>\n );\n if (targetElement) {\n return ReactDOM.createPortal(content, targetElement);\n }\n return content;\n });\n","// 连接点半径\n\nexport const STROKE_WIDTH_SLECTED = 3;\n\nexport const STROKE_WIDTH = 2;\n\nexport const PORT_BG_CLASS_NAME = 'workflow-port-bg';\n","import styled from 'styled-components';\n\nexport const WorkflowPointStyle = styled.div`\n width: 20px;\n height: 20px;\n border-radius: 50%;\n margin-top: -10px;\n margin-left: -10px;\n left: 50%;\n top: 50%;\n position: absolute;\n // 非 hover 状态下的样式\n border: none;\n\n & > .symbol {\n opacity: 0;\n }\n\n .bg-circle {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n border-radius: 50%;\n width: 20px;\n height: 20px;\n background-color: var(--g-workflow-port-color-background, #fff);\n transform: scale(0.5);\n transition: all 0.2s linear 0s;\n }\n\n .bg {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: var(--g-workflow-port-color-secondary, #9197f1);\n transform: scale(0.4, 0.4);\n transition: all 0.2s linear 0s;\n\n &.hasError {\n background: var(--g-workflow-port-color-error, red);\n }\n\n .symbol {\n position: absolute;\n width: 14px;\n height: 14px;\n opacity: 0;\n pointer-events: none;\n color: var(--g-workflow-port-color-background, #fff);\n transition: opacity 0.2s linear 0s;\n\n & > svg {\n width: 14px;\n height: 14px;\n }\n }\n\n .focus-circle {\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 8px;\n height: 8px;\n opacity: 0;\n background: var(--g-workflow-port-color-secondary, #9197f1);\n border-radius: 50%;\n transition: opacity 0.2s linear 0s;\n }\n }\n\n &.linked .bg:not(.hasError) {\n background: var(--g-workflow-port-color-primary, #4d53e8);\n }\n\n &.hovered .bg:not(.hasError) {\n border: none;\n cursor: crosshair;\n transform: scale(1, 1);\n background: var(--g-workflow-port-color-primary, #4d53e8);\n\n & > .symbol {\n opacity: 1;\n }\n }\n\n .cross-hair {\n position: relative;\n left: 2px;\n top: 2px;\n\n &::after,\n &::before {\n content: '';\n background: var(--g-workflow-port-color-background, #fff);\n border-radius: 2px;\n position: absolute;\n }\n\n &::after {\n left: 4px;\n width: 2px;\n height: 6px;\n box-shadow: 0 4px var(--g-workflow-port-color-background, #fff);\n }\n\n &::before {\n top: 4px;\n width: 6px;\n height: 2px;\n box-shadow: 4px 0 var(--g-workflow-port-color-background, #fff);\n }\n`;\n","import React from 'react';\n\n// demo 环境自绘 cross-hair,正式环境使用 IconAdd\nexport default function CrossHair(): JSX.Element {\n return (\n <div className=\"symbol\">\n <div className=\"cross-hair\" />\n </div>\n );\n}\n","// 箭头宽度\nexport const LINE_OFFSET = 6;\n\nexport const LINE_PADDING = 12;\n","import { WorkflowLinesManager } from '@flowgram.ai/free-layout-core';\nimport { definePluginCreator, PluginContext } from '@flowgram.ai/core';\n\nimport { FreeLinesPluginOptions } from './type';\nimport { WorkflowLinesLayer } from './layer';\nimport { WorkflowBezierLineContribution, WorkflowFoldLineContribution } from './contributions';\n\nexport const createFreeLinesPlugin = definePluginCreator({\n singleton: true,\n onInit: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n ctx.playground.registerLayer(WorkflowLinesLayer, {\n ...opts,\n });\n },\n onReady: (ctx: PluginContext, opts: FreeLinesPluginOptions) => {\n const linesManager = ctx.container.get(WorkflowLinesManager);\n linesManager\n .registerContribution(WorkflowBezierLineContribution)\n .registerContribution(WorkflowFoldLineContribution);\n\n if (opts.contributions) {\n opts.contributions.forEach((contribution) => {\n linesManager.registerContribution(contribution);\n });\n }\n\n if (opts.defaultLineType) {\n linesManager.switchLineType(opts.defaultLineType);\n }\n },\n});\n","import ReactDOM from 'react-dom';\nimport React, { ReactNode, useLayoutEffect, useState } from 'react';\n\nimport { inject, injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { StackingContextManager } from '@flowgram.ai/free-stack-plugin';\nimport {\n nanoid,\n WorkflowDocument,\n WorkflowHoverService,\n WorkflowLineEntity,\n WorkflowLineRenderData,\n WorkflowNodeEntity,\n WorkflowPortEntity,\n WorkflowSelectService,\n} from '@flowgram.ai/free-layout-core';\nimport { Layer, observeEntities, observeEntityDatas, TransformData } from '@flowgram.ai/core';\n\nimport { LineRenderProps, LinesLayerOptions } from '../type';\nimport { WorkflowLineRender } from '../components';\n\n@injectable()\nexport class WorkflowLinesLayer extends Layer<LinesLayerOptions> {\n static type = 'WorkflowLinesLayer';\n\n @inject(WorkflowHoverService) hoverService: WorkflowHoverService;\n\n @inject(WorkflowSelectService) selectService: WorkflowSelectService;\n\n @inject(StackingContextManager) stackContext: StackingContextManager;\n\n @observeEntities(WorkflowLineEntity) readonly lines: WorkflowLineEntity[];\n\n @observeEntities(WorkflowPortEntity) readonly ports: WorkflowPortEntity[];\n\n @observeEntityDatas(WorkflowNodeEntity, TransformData)\n readonly trans: TransformData[];\n\n @inject(WorkflowDocument) protected workflowDocument: WorkflowDocument;\n\n private layerID = nanoid();\n\n private mountedLines: Map<\n string,\n {\n line: WorkflowLineEntity;\n portal: ReactNode;\n version: string;\n }\n > = new Map();\n\n private _version = 0;\n\n /**\n * 节点线条\n */\n public node = domUtils.createDivWithClass('gedit-playground-layer gedit-flow-lines-layer');\n\n public onZoom(scale: number): void {\n this.node.style.transform = `scale(${scale})`;\n }\n\n public onReady() {\n this.pipelineNode.appendChild(this.node);\n this.toDispose.pushAll([\n this.selectService.onSelectionChanged(() => this.render()),\n this.hoverService.onHoveredChange(() => this.render()),\n this.workflowDocument.linesManager.onForceUpdate(() => {\n this.mountedLines.clear();\n this.bumpVersion();\n this.render();\n }),\n ]);\n }\n\n public dispose() {\n this.mountedLines.clear();\n }\n\n public render(): JSX.Element {\n const [, forceUpdate] = useState({});\n\n useLayoutEffect(() => {\n const updateLines = (): void => {\n let needsUpdate = false;\n\n // 批量处理所有线条的更新\n this.lines.forEach((line) => {\n const renderData = line.getData(WorkflowLineRenderData);\n const oldVersion = renderData.renderVersion;\n renderData.update();\n // 如果有任何一条线发生变化,标记需要更新\n if (renderData.renderVersion !== oldVersion) {\n needsUpdate = true;\n }\n });\n\n // 只在确实需要更新时触发重渲染\n if (needsUpdate) {\n forceUpdate({});\n }\n };\n\n const rafId = requestAnimationFrame(updateLines);\n return () => cancelAnimationFrame(rafId);\n }, [this.lines]); // 依赖项包含 lines\n\n const lines = this.lines.map((line) => this.renderLine(line));\n return <>{lines}</>;\n }\n\n // 用来绕过 memo\n private bumpVersion() {\n this._version = this._version + 1;\n if (this._version === Number.MAX_SAFE_INTEGER) {\n this._version = 0;\n }\n }\n\n private lineProps(line: WorkflowLineEntity): LineRenderProps {\n const { lineType } = this.workflowDocument.linesManager;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const version = this.lineVersion(line);\n\n return {\n key: line.id,\n color: line.color,\n selected,\n hovered,\n line,\n lineType,\n version,\n strokePrefix: this.layerID,\n };\n }\n\n private lineVersion(line: WorkflowLineEntity): string {\n const renderData = line.getData(WorkflowLineRenderData);\n const { renderVersion } = renderData;\n const selected = this.selectService.isSelected(line.id);\n const hovered = this.hoverService.isHovered(line.id);\n const { version: lineVersion, color } = line;\n\n const version = `v:${this._version},lv:${lineVersion},rv:${renderVersion},c:${color},s:${\n selected ? 'T' : 'F'\n },h:${hovered ? 'T' : 'F'}`;\n\n return version;\n }\n\n private lineComponent(props: LineRenderProps): ReactNode {\n const RenderInsideLine = this.options.renderInsideLine ?? (() => <></>);\n return (\n <WorkflowLineRender {...props}>\n <RenderInsideLine {...props} />\n </WorkflowLineRender>\n );\n }\n\n private renderLine(line: WorkflowLineEntity): ReactNode {\n const lineProps = this.lineProps(line);\n const cache = this.mountedLines.get(line.id);\n const isCached = cache !== undefined;\n const { portal: cachedPortal, version: cachedVersion } = cache ?? {};\n if (isCached && cachedVersion === lineProps.version) {\n // 如果已有缓存且版本相同,则直接返回缓存的 portal\n return cachedPortal;\n }\n if (!isCached) {\n // 如果缓存不存在,则将 line 挂载到 renderElement 上\n this.renderElement.appendChild(line.node);\n line.onDispose(() => {\n this.mountedLines.delete(line.id);\n line.node.remove();\n });\n }\n // 刷新缓存\n const portal = ReactDOM.createPortal(this.lineComponent(lineProps), line.node);\n this.mountedLines.set(line.id, { line, portal, version: lineProps.version });\n return portal;\n }\n\n private get renderElement(): HTMLElement {\n return this.stackContext.node;\n }\n}\n","import { memo } from 'react';\n\nimport { LineSVG } from './line-svg';\n\nexport const WorkflowLineRender = memo(\n LineSVG,\n (prevProps, nextProps) => prevProps.version === nextProps.version\n);\n","import React from 'react';\n\nimport clsx from 'clsx';\nimport { type IPoint } from '@flowgram.ai/utils';\nimport { POINT_RADIUS } from '@flowgram.ai/free-layout-core';\nimport { WorkflowLineRenderData } from '@flowgram.ai/free-layout-core';\n\nimport { LineRenderProps } from '../../type';\nimport { STROKE_WIDTH_SLECTED, STROKE_WIDTH } from '../../constants/points';\nimport { LINE_OFFSET } from '../../constants/lines';\nimport { LineStyle } from './index.style';\nimport { ArrowRenderer } from './arrow';\n\nconst PADDING = 12;\n\n// eslint-disable-next-line react/display-name\nexport const LineSVG = (props: LineRenderProps) => {\n const { line, color, selected, children, strokePrefix } = props;\n const { position, reverse, vertical, hideArrow } = line;\n\n const renderData = line.getData(WorkflowLineRenderData);\n const { bounds, path: bezierPath } = renderData;\n\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bounds.x + PADDING,\n y: p.y - bounds.y + PADDING,\n });\n\n const fromPos = toRelative(position.from);\n const toPos = toRelative(position.to);\n\n // 箭头位置计算\n const arrowToPos: IPoint = vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n const arrowFromPos: IPoint = vertical\n ? { x: fromPos.x, y: fromPos.y + POINT_RADIUS + LINE_OFFSET }\n : { x: fromPos.x + POINT_RADIUS + LINE_OFFSET, y: fromPos.y };\n\n const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;\n\n const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;\n\n const path = (\n <path\n d={bezierPath}\n fill=\"none\"\n stroke={`url(#${strokeID})`}\n strokeWidth={strokeWidth}\n className={clsx(\n line.className,\n // 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中\n !line.className && (line.processing || line.flowing ? 'dashed-line flowing-line' : '')\n )}\n />\n );\n\n return (\n <LineStyle\n style={{\n left: bounds.x - PADDING,\n top: bounds.y - PADDING,\n position: 'absolute',\n }}\n >\n {children}\n <svg width={bounds.width + PADDING * 2} height={bounds.height + PADDING * 2}>\n <defs>\n <linearGradient\n x1={vertical ? '100%' : '0%'}\n y1={vertical ? '0%' : '100%'}\n x2=\"100%\"\n y2=\"100%\"\n id={strokeID}\n gradientUnits=\"userSpaceOnUse\"\n >\n <stop stopColor={color} offset=\"0%\" />\n <stop stopColor={color} offset=\"100%\" />\n </linearGradient>\n </defs>\n <g>\n {path}\n <ArrowRenderer\n id={strokeID}\n reverseArrow={reverse}\n pos={reverse ? arrowFromPos : arrowToPos}\n strokeWidth={strokeWidth}\n vertical={vertical}\n hide={hideArrow}\n />\n </g>\n </svg>\n </LineStyle>\n );\n};\n","import styled from 'styled-components';\n\n// 添加一个固定类名,用于选中该节点\n\nexport const LineStyle = styled.div.attrs({\n className: 'gedit-flow-activity-edge',\n})`\n position: absolute;\n\n @keyframes flowingDash {\n to {\n stroke-dashoffset: -13;\n }\n }\n\n .dashed-line {\n stroke-dasharray: 8, 5;\n }\n\n .flowing-line {\n animation: flowingDash 0.5s linear infinite;\n }\n`;\n","import React from 'react';\n\nimport { LINE_OFFSET } from '../../constants/lines';\n\nexport function ArrowRenderer({\n id,\n pos,\n reverseArrow,\n strokeWidth,\n vertical,\n hide,\n}: {\n id: string;\n strokeWidth: number;\n reverseArrow: boolean;\n pos: {\n x: number;\n y: number;\n };\n vertical?: boolean;\n hide?: boolean;\n}) {\n if (hide) {\n return null;\n }\n const arrowPath = vertical\n ? reverseArrow\n ? `M ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${pos.y - LINE_OFFSET} L ${\n pos.x + LINE_OFFSET\n },${pos.y}`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x + LINE_OFFSET\n },${pos.y - LINE_OFFSET}`\n : reverseArrow\n ? `M ${pos.x},${pos.y + LINE_OFFSET} L ${pos.x - LINE_OFFSET},${pos.y} L ${pos.x},${\n pos.y - LINE_OFFSET\n }`\n : `M ${pos.x - LINE_OFFSET},${pos.y - LINE_OFFSET} L ${pos.x},${pos.y} L ${\n pos.x - LINE_OFFSET\n },${pos.y + LINE_OFFSET}`;\n\n return (\n <path\n d={arrowPath}\n strokeLinecap=\"round\"\n stroke={`url(#${id})`}\n fill=\"none\"\n strokeWidth={strokeWidth}\n />\n );\n}\n","import { type IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport enum BezierControlType {\n RIGHT_TOP,\n RIGHT_BOTTOM,\n LEFT_TOP,\n LEFT_BOTTOM,\n}\n\nconst CONTROL_MAX = 300;\n/**\n * 获取贝塞尔曲线横向的控制节点\n * @param fromPos\n * @param toPos\n */\nexport function getBezierHorizontalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n if (fromPos.x <= toPos.x) {\n type = fromPos.y <= toPos.y ? BezierControlType.RIGHT_BOTTOM : BezierControlType.RIGHT_TOP;\n } else {\n type = fromPos.y <= toPos.y ? BezierControlType.LEFT_BOTTOM : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n // eslint-disable-next-line default-case\n switch (type) {\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.rightBottom.x - rect.width / 2,\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x + rect.width / 2,\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x - rect.width / 2,\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x + rect.width / 2,\n y: rect.leftBottom.y,\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightBottom.y,\n },\n {\n x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftTop.y,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),\n y: rect.rightTop.y,\n },\n {\n x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),\n y: rect.leftBottom.y,\n },\n ];\n }\n return controls;\n}\n\n/**\n * 获取贝塞尔曲线垂直方向的控制节点\n * @param fromPos 起始点\n * @param toPos 终点\n */\nexport function getBezierVerticalControlPoints(fromPos: IPoint, toPos: IPoint): IPoint[] {\n const rect = Rectangle.createRectangleWithTwoPoints(fromPos, toPos);\n let type: BezierControlType;\n\n if (fromPos.y <= toPos.y) {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_BOTTOM : BezierControlType.LEFT_BOTTOM;\n } else {\n type = fromPos.x <= toPos.x ? BezierControlType.RIGHT_TOP : BezierControlType.LEFT_TOP;\n }\n\n let controls: IPoint[];\n\n switch (type) {\n case BezierControlType.RIGHT_BOTTOM:\n controls = [\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y + rect.height / 2,\n },\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.LEFT_BOTTOM:\n controls = [\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y + rect.height / 2,\n },\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y - rect.height / 2,\n },\n ];\n break;\n case BezierControlType.RIGHT_TOP:\n controls = [\n {\n x: rect.leftBottom.x,\n y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.rightTop.x,\n y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n case BezierControlType.LEFT_TOP:\n controls = [\n {\n x: rect.rightBottom.x,\n y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX),\n },\n {\n x: rect.leftTop.x,\n y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX),\n },\n ];\n break;\n }\n\n return controls;\n}\n","export {\n BezierControlType,\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\nimport { Bezier } from 'bezier-js';\nimport { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport {\n getBezierHorizontalControlPoints,\n getBezierVerticalControlPoints,\n} from './bezier-controls';\n\nexport interface BezierData {\n fromPos: IPoint;\n toPos: IPoint;\n bbox: Rectangle; // 外围矩形\n controls: IPoint[]; // 控制点\n bezier: Bezier;\n path: string;\n}\n\nexport class WorkflowBezierLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.BEZIER;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: BezierData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return Point.getDistance(pos, this.data.bezier.project(pos));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n this.data = this.calcBezier(params.fromPos, params.toPos);\n }\n\n private calcBezier(fromPos: IPoint, toPos: IPoint): BezierData {\n const controls = this.entity.vertical\n ? getBezierVerticalControlPoints(fromPos, toPos)\n : getBezierHorizontalControlPoints(fromPos, toPos);\n const bezier = new Bezier([fromPos, ...controls, toPos]);\n const bbox = bezier.bbox();\n const bboxBounds = new Rectangle(\n bbox.x.min,\n bbox.y.min,\n bbox.x.max - bbox.x.min,\n bbox.y.max - bbox.y.min\n );\n\n const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });\n\n this.data = {\n fromPos,\n toPos,\n bezier,\n bbox: bboxBounds,\n controls,\n path,\n };\n return this.data;\n }\n\n private getPath(params: {\n bbox: Rectangle;\n fromPos: IPoint;\n toPos: IPoint;\n controls: IPoint[];\n }): string {\n const { bbox } = params;\n // 相对位置转换函数\n const toRelative = (p: IPoint): IPoint => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n });\n const fromPos = toRelative(params.fromPos);\n const toPos = toRelative(params.toPos);\n\n const controls = params.controls.map((c) => toRelative(c));\n\n // 渲染端点位置计算\n const renderToPos: IPoint = this.entity.vertical\n ? { x: toPos.x, y: toPos.y - POINT_RADIUS }\n : { x: toPos.x - POINT_RADIUS, y: toPos.y };\n\n const getPathData = (): string => {\n const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(',');\n const curveType = controls.length === 1 ? 'S' : 'C';\n\n if (this.entity.vertical) {\n return `M${fromPos.x} ${fromPos.y + POINT_RADIUS} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n }\n return `M${fromPos.x + POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${\n renderToPos.x\n } ${renderToPos.y}`;\n };\n const path = getPathData();\n return path;\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\nimport { LineType } from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { FoldLine } from './fold-line';\n\nexport interface FoldData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowFoldLineContribution implements WorkflowLineRenderContribution {\n public static type = LineType.LINE_CHART;\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: FoldData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n return FoldLine.getFoldLineToPointDistance(this.data.points, pos);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = FoldLine.getPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = FoldLine.getBounds(points);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n const path = FoldLine.getSmoothStepPath(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';\n\n/**\n * 计算点到线段的距离\n * @param point 待测试点\n * @param segStart 线段起点\n * @param segEnd 线段终点\n */\nconst getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {\n const { x: px, y: py } = point;\n const { x: x1, y: y1 } = segStart;\n const { x: x2, y: y2 } = segEnd;\n\n const A = px - x1;\n const B = py - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n // 参数方程中的t参数\n const param = lenSq === 0 ? -1 : dot / lenSq;\n\n let xx: number;\n let yy: number;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = px - xx;\n const dy = py - yy;\n\n return Math.sqrt(dx * dx + dy * dy);\n};\n\nexport namespace FoldLine {\n const EDGE_RADIUS = 5;\n const OFFSET = 20;\n\n function getEdgeCenter({ source, target }: { source: IPoint; target: IPoint }): [number, number] {\n const xOffset = Math.abs(target.x - source.x) / 2;\n const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;\n\n const yOffset = Math.abs(target.y - source.y) / 2;\n const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;\n\n return [centerX, centerY];\n }\n\n const getDirection = ({ source, target }: { source: IPoint; target: IPoint }): IPoint =>\n source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };\n\n // eslint-disable-next-line complexity\n export function getPoints({\n source,\n target,\n vertical = false,\n }: {\n source: IPoint;\n target: IPoint;\n vertical?: boolean;\n }): IPoint[] {\n // from 节点的出发方向\n const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };\n // to 节点的接收方向\n const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };\n const sourceGapped: IPoint = {\n x: source.x + sourceDir.x * OFFSET,\n y: source.y + sourceDir.y * OFFSET,\n };\n const targetGapped: IPoint = {\n x: target.x + targetDir.x * OFFSET,\n y: target.y + targetDir.y * OFFSET,\n };\n const dir = vertical\n ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 }\n : getDirection({ source: sourceGapped, target: targetGapped });\n const dirAccessor = dir.x !== 0 ? 'x' : 'y';\n const currDir = dir[dirAccessor];\n\n let points: IPoint[] = [];\n let centerX, centerY;\n\n const [defaultCenterX, defaultCenterY] = getEdgeCenter({\n source,\n target,\n });\n\n // 计算向量乘积\n if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {\n centerX = defaultCenterX;\n centerY = defaultCenterY;\n\n const verticalSplit: IPoint[] = [\n { x: centerX, y: sourceGapped.y },\n { x: centerX, y: targetGapped.y },\n ];\n\n const horizontalSplit: IPoint[] = [\n { x: sourceGapped.x, y: centerY },\n { x: targetGapped.x, y: centerY },\n ];\n\n if (sourceDir[dirAccessor] === currDir) {\n points = dirAccessor === 'x' ? verticalSplit : horizontalSplit;\n } else {\n points = dirAccessor === 'x' ? horizontalSplit : verticalSplit;\n }\n } else {\n // sourceTarget means we take x from source and y from target, targetSource is the opposite\n const sourceTarget: IPoint[] = [{ x: sourceGapped.x, y: targetGapped.y }];\n const targetSource: IPoint[] = [{ x: targetGapped.x, y: sourceGapped.y }];\n // this handles edges with same handle positions\n if (dirAccessor === 'x') {\n points = sourceDir.x === currDir ? targetSource : sourceTarget;\n } else {\n points = sourceDir.y === currDir ? sourceTarget : targetSource;\n }\n\n // these are conditions for handling mixed handle positions like Right -> Bottom for example\n const dirAccessorOpposite = dirAccessor === 'x' ? 'y' : 'x';\n const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];\n const sourceGtTargetOppo =\n sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];\n const sourceLtTargetOppo =\n sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];\n const flipSourceTarget =\n (sourceDir[dirAccessor] === 1 &&\n ((!isSameDir && sourceGtTargetOppo) || (isSameDir && sourceLtTargetOppo))) ||\n (sourceDir[dirAccessor] !== 1 &&\n ((!isSameDir && sourceLtTargetOppo) || (isSameDir && sourceGtTargetOppo)));\n\n if (flipSourceTarget) {\n points = dirAccessor === 'x' ? sourceTarget : targetSource;\n }\n\n const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };\n const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };\n const maxXDistance = Math.max(\n Math.abs(sourceGapPoint.x - points[0].x),\n Math.abs(targetGapPoint.x - points[0].x)\n );\n const maxYDistance = Math.max(\n Math.abs(sourceGapPoint.y - points[0].y),\n Math.abs(targetGapPoint.y - points[0].y)\n );\n\n if (maxXDistance >= maxYDistance) {\n centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;\n centerY = points[0].y;\n } else {\n centerX = points[0].x;\n centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;\n }\n }\n\n const pathPoints = [\n source,\n { x: sourceGapped.x, y: sourceGapped.y },\n ...points,\n { x: targetGapped.x, y: targetGapped.y },\n target,\n ];\n\n return pathPoints;\n }\n\n function getBend(a: IPoint, b: IPoint, c: IPoint): string {\n const bendSize = Math.min(\n Point.getDistance(a, b) / 2,\n Point.getDistance(b, c) / 2,\n EDGE_RADIUS\n );\n const { x, y } = b;\n\n // no bend\n if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {\n return `L${x} ${y}`;\n }\n\n // first segment is horizontal\n if (a.y === y) {\n const xDir = a.x < c.x ? -1 : 1;\n const yDir = a.y < c.y ? 1 : -1;\n return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;\n }\n\n const xDir = a.x < c.x ? 1 : -1;\n const yDir = a.y < c.y ? -1 : 1;\n return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;\n }\n\n /**\n * 实现 reactFlow 原本的折叠线交互\n */\n export function getSmoothStepPath(points: IPoint[]): string {\n const path = points.reduce<string>((res, p, i) => {\n let segment = '';\n\n if (i > 0 && i < points.length - 1) {\n segment = getBend(points[i - 1], p, points[i + 1]);\n } else {\n segment = `${i === 0 ? 'M' : 'L'}${p.x} ${p.y}`;\n }\n\n res += segment;\n\n return res;\n }, '');\n\n return path;\n }\n export function getBounds(points: IPoint[]): Rectangle {\n const xList = points.map((p) => p.x);\n const yList = points.map((p) => p.y);\n const left = Math.min(...xList);\n const right = Math.max(...xList);\n const top = Math.min(...yList);\n const bottom = Math.max(...yList);\n return Rectangle.createRectangleWithTwoPoints(\n {\n x: left,\n y: top,\n },\n {\n x: right,\n y: bottom,\n }\n );\n }\n /**\n * 计算点到折线的最短距离\n * @param points 折线的所有端点\n * @param pos 待测试点\n * @returns 最短距离\n */\n export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {\n // 特殊情况处理\n if (points.length === 0) {\n return Infinity;\n }\n\n if (points.length === 1) {\n return Point.getDistance(points[0]!, pos);\n }\n\n // 构建线段数组\n const lines: [IPoint, IPoint][] = [];\n for (let i = 0; i < points.length - 1; i++) {\n lines.push([points[i]!, points[i + 1]!]);\n }\n\n // 计算点到每个线段的最短距离\n const distances = lines.map((line) => {\n const [p1, p2] = line;\n return getPointToSegmentDistance(pos, p1, p2);\n });\n\n return Math.min(...distances);\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\nimport { projectPointOnLine } from './point-on-line';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowStraightLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowStraightLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: StraightData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n const [start, end] = this.data.points;\n return Point.getDistance(pos, projectPointOnLine(pos, start, end));\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n // 根据方向预先计算源点和目标点的偏移\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const points = [\n {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n ];\n\n const bbox = Rectangle.createRectangleWithTwoPoints(points[0], points[1]);\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成直线路径\n const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n}\n","import { IPoint, Rectangle } from '@flowgram.ai/utils';\n\nexport interface StraightData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\n/**\n * 计算点到直线的投影点\n */\nexport function projectPointOnLine(point: IPoint, lineStart: IPoint, lineEnd: IPoint): IPoint {\n const dx = lineEnd.x - lineStart.x;\n const dy = lineEnd.y - lineStart.y;\n\n // 如果是垂直线\n if (dx === 0) {\n return { x: lineStart.x, y: point.y };\n }\n // 如果是水平线\n if (dy === 0) {\n return { x: point.x, y: lineStart.y };\n }\n\n const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);\n const clampedT = Math.max(0, Math.min(1, t));\n\n return {\n x: lineStart.x + clampedT * dx,\n y: lineStart.y + clampedT * dy,\n };\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ArcData {\n fromPos: IPoint;\n toPos: IPoint;\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowArkLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowArkLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ArcData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n\n const { fromPos, toPos, bbox } = this.data;\n\n // 首先检查点是否在包围盒范围内\n if (!bbox.contains(pos.x, pos.y)) {\n // 如果点在包围盒外,计算到包围盒边界的最短距离\n const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));\n const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // 计算圆弧的中心点和半径\n const center = {\n x: (fromPos.x + toPos.x) / 2,\n y: (fromPos.y + toPos.y) / 2,\n };\n const radius = Point.getDistance(fromPos, center);\n\n // 计算点到圆心的距离\n const distanceToCenter = Point.getDistance(pos, center);\n\n // 返回点到圆弧的近似距离\n return Math.abs(distanceToCenter - radius);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n const start = {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n };\n const end = {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n };\n\n // 计算圆弧的包围盒\n const bbox = this.calculateArcBBox(start, end);\n\n // 生成圆弧路径\n const path = this.getArcPath(start, end, bbox);\n\n this.data = {\n fromPos: start,\n toPos: end,\n path,\n bbox,\n };\n }\n\n private calculateArcBBox(start: IPoint, end: IPoint): Rectangle {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const radius = Math.sqrt(dx * dx + dy * dy) / 2;\n\n const centerX = (start.x + end.x) / 2;\n const centerY = (start.y + end.y) / 2;\n\n return new Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);\n }\n\n private getArcPath(start: IPoint, end: IPoint, bbox: Rectangle): string {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n // 调整点到相对坐标\n const startRel = {\n x: start.x - bbox.x + LINE_PADDING,\n y: start.y - bbox.y + LINE_PADDING,\n };\n const endRel = {\n x: end.x - bbox.x + LINE_PADDING,\n y: end.y - bbox.y + LINE_PADDING,\n };\n\n // 使用 SVG 圆弧命令\n return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${\n endRel.y\n }`;\n }\n}\n","import { IPoint, Point, Rectangle } from '@flowgram.ai/utils';\nimport {\n POINT_RADIUS,\n WorkflowLineEntity,\n WorkflowLineRenderContribution,\n} from '@flowgram.ai/free-layout-core';\n\nimport { LINE_PADDING } from '../../constants/lines';\n\nexport interface ManhattanData {\n points: IPoint[];\n path: string;\n bbox: Rectangle;\n}\n\nexport class WorkflowManhattanLineContribution implements WorkflowLineRenderContribution {\n public static type = 'WorkflowManhattanLineContribution';\n\n public entity: WorkflowLineEntity;\n\n constructor(entity: WorkflowLineEntity) {\n this.entity = entity;\n }\n\n private data?: ManhattanData;\n\n public get path(): string {\n return this.data?.path ?? '';\n }\n\n public calcDistance(pos: IPoint): number {\n if (!this.data) {\n return Number.MAX_SAFE_INTEGER;\n }\n // 计算点到所有线段的最小距离\n return Math.min(\n ...this.data.points.slice(1).map((point, index) => {\n const prevPoint = this.data!.points[index];\n return this.getDistanceToLineSegment(pos, prevPoint, point);\n })\n );\n }\n\n private getDistanceToLineSegment(point: IPoint, start: IPoint, end: IPoint): number {\n // 计算线段的方向向量\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n\n // 如果线段退化为一个点\n if (dx === 0 && dy === 0) {\n return Point.getDistance(point, start);\n }\n\n // 计算投影点的参数 t\n const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);\n\n // 如果投影点在线段外部,返回到端点的距离\n if (t < 0) return Point.getDistance(point, start);\n if (t > 1) return Point.getDistance(point, end);\n\n // 投影点在线段上,计算实际距离\n const projectionPoint = {\n x: start.x + t * dx,\n y: start.y + t * dy,\n };\n return Point.getDistance(point, projectionPoint);\n }\n\n public get bounds(): Rectangle {\n if (!this.data) {\n return new Rectangle();\n }\n return this.data.bbox;\n }\n\n public update(params: { fromPos: IPoint; toPos: IPoint }): void {\n const { fromPos, toPos } = params;\n const { vertical } = this.entity;\n\n const sourceOffset = {\n x: vertical ? 0 : POINT_RADIUS,\n y: vertical ? POINT_RADIUS : 0,\n };\n const targetOffset = {\n x: vertical ? 0 : -POINT_RADIUS,\n y: vertical ? -POINT_RADIUS : 0,\n };\n\n // 计算曼哈顿路径的点\n const points = this.getManhattanPoints({\n source: {\n x: fromPos.x + sourceOffset.x,\n y: fromPos.y + sourceOffset.y,\n },\n target: {\n x: toPos.x + targetOffset.x,\n y: toPos.y + targetOffset.y,\n },\n vertical,\n });\n\n const bbox = Rectangle.createRectangleWithTwoPoints(\n points.reduce(\n (min, p) => ({\n x: Math.min(min.x, p.x),\n y: Math.min(min.y, p.y),\n }),\n points[0]\n ),\n points.reduce(\n (max, p) => ({\n x: Math.max(max.x, p.x),\n y: Math.max(max.y, p.y),\n }),\n points[0]\n )\n );\n\n // 调整所有点到 SVG 视口坐标系\n const adjustedPoints = points.map((p) => ({\n x: p.x - bbox.x + LINE_PADDING,\n y: p.y - bbox.y + LINE_PADDING,\n }));\n\n // 生成路径\n const path = this.getPathFromPoints(adjustedPoints);\n\n this.data = {\n points,\n path,\n bbox,\n };\n }\n\n private getManhattanPoints(params: {\n source: IPoint;\n target: IPoint;\n vertical: boolean;\n }): IPoint[] {\n const { source, target, vertical } = params;\n const points: IPoint[] = [source];\n\n if (vertical) {\n // 垂直优先布局\n if (source.y !== target.y) {\n points.push({ x: source.x, y: target.y });\n }\n if (source.x !== target.x) {\n points.push({ x: target.x, y: target.y });\n }\n } else {\n // 水平优先布局\n if (source.x !== target.x) {\n points.push({ x: target.x, y: source.y });\n }\n if (source.y !== target.y) {\n points.push({ x: target.x, y: target.y });\n }\n }\n\n if (points[points.length - 1] !== target) {\n points.push(target);\n }\n\n return points;\n }\n\n private getPathFromPoints(points: IPoint[]): string {\n return points.reduce((path, point, index) => {\n if (index === 0) {\n return `M ${point.x} ${point.y}`;\n }\n return `${path} L ${point.x} ${point.y}`;\n }, '');\n }\n}\n"],"mappings":"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","names":["import_react","styled","React","React","classNames","ReactDOM","import_free_layout_core","import_core","import_react_dom","import_react","import_free_layout_core","import_core","import_react","import_react","import_clsx","import_free_layout_core","import_styled_components","styled","import_react","React","React","clsx","React","ReactDOM","import_utils","BezierControlType","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","FoldLine","xDir","yDir","import_utils","import_free_layout_core","import_utils","import_free_layout_core","import_utils","import_free_layout_core"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/free-lines-plugin",
3
- "version": "0.1.0-alpha.7",
3
+ "version": "0.1.0-alpha.8",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -20,11 +20,11 @@
20
20
  "clsx": "^1.1.1",
21
21
  "inversify": "^6.0.1",
22
22
  "reflect-metadata": "~0.2.2",
23
- "@flowgram.ai/core": "0.1.0-alpha.7",
24
- "@flowgram.ai/free-layout-core": "0.1.0-alpha.7",
25
- "@flowgram.ai/free-stack-plugin": "0.1.0-alpha.7",
26
- "@flowgram.ai/utils": "0.1.0-alpha.7",
27
- "@flowgram.ai/renderer": "0.1.0-alpha.7"
23
+ "@flowgram.ai/core": "0.1.0-alpha.8",
24
+ "@flowgram.ai/free-layout-core": "0.1.0-alpha.8",
25
+ "@flowgram.ai/free-stack-plugin": "0.1.0-alpha.8",
26
+ "@flowgram.ai/utils": "0.1.0-alpha.8",
27
+ "@flowgram.ai/renderer": "0.1.0-alpha.8"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@types/bezier-js": "4.1.3",
@@ -40,12 +40,12 @@
40
40
  "tsup": "^8.0.1",
41
41
  "typescript": "^5.0.4",
42
42
  "vitest": "^0.34.6",
43
- "@flowgram.ai/eslint-config": "0.1.0-alpha.7",
44
- "@flowgram.ai/ts-config": "0.1.0-alpha.7"
43
+ "@flowgram.ai/eslint-config": "0.1.0-alpha.8",
44
+ "@flowgram.ai/ts-config": "0.1.0-alpha.8"
45
45
  },
46
46
  "peerDependencies": {
47
- "react": ">=17",
48
- "react-dom": ">=17",
47
+ "react": ">=16.8",
48
+ "react-dom": ">=16.8",
49
49
  "styled-components": ">=4"
50
50
  },
51
51
  "publishConfig": {