@flowgram.ai/free-lines-plugin 0.1.5 → 0.1.7
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 +835 -132
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +135 -8
- package/dist/index.d.ts +135 -8
- package/dist/index.js +845 -143
- package/dist/index.js.map +1 -1
- package/package.json +10 -8
package/dist/index.js
CHANGED
|
@@ -38,10 +38,20 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
38
38
|
// src/index.ts
|
|
39
39
|
var src_exports = {};
|
|
40
40
|
__export(src_exports, {
|
|
41
|
+
BezierControlType: () => BezierControlType,
|
|
41
42
|
LINE_OFFSET: () => LINE_OFFSET,
|
|
42
|
-
|
|
43
|
+
LINE_PADDING: () => LINE_PADDING,
|
|
44
|
+
LinesLayer: () => WorkflowLinesLayer,
|
|
45
|
+
WorkflowArkLineContribution: () => WorkflowArkLineContribution,
|
|
46
|
+
WorkflowBezierLineContribution: () => WorkflowBezierLineContribution,
|
|
47
|
+
WorkflowFoldLineContribution: () => WorkflowFoldLineContribution,
|
|
48
|
+
WorkflowLinesLayer: () => WorkflowLinesLayer,
|
|
49
|
+
WorkflowManhattanLineContribution: () => WorkflowManhattanLineContribution,
|
|
43
50
|
WorkflowPortRender: () => WorkflowPortRender,
|
|
44
|
-
|
|
51
|
+
WorkflowStraightLineContribution: () => WorkflowStraightLineContribution,
|
|
52
|
+
createFreeLinesPlugin: () => createFreeLinesPlugin,
|
|
53
|
+
getBezierHorizontalControlPoints: () => getBezierHorizontalControlPoints,
|
|
54
|
+
getBezierVerticalControlPoints: () => getBezierVerticalControlPoints
|
|
45
55
|
});
|
|
46
56
|
module.exports = __toCommonJS(src_exports);
|
|
47
57
|
|
|
@@ -269,27 +279,30 @@ var WorkflowPortRender = (
|
|
|
269
279
|
|
|
270
280
|
// src/constants/lines.ts
|
|
271
281
|
var LINE_OFFSET = 6;
|
|
282
|
+
var LINE_PADDING = 12;
|
|
272
283
|
|
|
273
284
|
// src/create-free-lines-plugin.ts
|
|
285
|
+
var import_free_layout_core12 = require("@flowgram.ai/free-layout-core");
|
|
274
286
|
var import_core3 = require("@flowgram.ai/core");
|
|
275
287
|
|
|
276
|
-
// src/layer/lines-layer.tsx
|
|
288
|
+
// src/layer/workflow-lines-layer.tsx
|
|
277
289
|
var import_react_dom2 = __toESM(require("react-dom"));
|
|
278
|
-
var
|
|
290
|
+
var import_react6 = __toESM(require("react"));
|
|
279
291
|
var import_inversify = require("inversify");
|
|
280
292
|
var import_utils = require("@flowgram.ai/utils");
|
|
281
|
-
var
|
|
293
|
+
var import_free_layout_core4 = require("@flowgram.ai/free-layout-core");
|
|
282
294
|
var import_core2 = require("@flowgram.ai/core");
|
|
283
295
|
|
|
284
|
-
// src/components/
|
|
285
|
-
var
|
|
286
|
-
var import_free_layout_core4 = require("@flowgram.ai/free-layout-core");
|
|
296
|
+
// src/components/workflow-line-render/index.tsx
|
|
297
|
+
var import_react5 = require("react");
|
|
287
298
|
|
|
288
|
-
// src/components/
|
|
299
|
+
// src/components/workflow-line-render/line-svg.tsx
|
|
289
300
|
var import_react4 = __toESM(require("react"));
|
|
301
|
+
var import_clsx2 = __toESM(require("clsx"));
|
|
290
302
|
var import_free_layout_core2 = require("@flowgram.ai/free-layout-core");
|
|
303
|
+
var import_free_layout_core3 = require("@flowgram.ai/free-layout-core");
|
|
291
304
|
|
|
292
|
-
// src/components/
|
|
305
|
+
// src/components/workflow-line-render/index.style.ts
|
|
293
306
|
var import_styled_components2 = __toESM(require("styled-components"));
|
|
294
307
|
var LineStyle = import_styled_components2.default.div.attrs({
|
|
295
308
|
className: "gedit-flow-activity-edge"
|
|
@@ -302,13 +315,16 @@ var LineStyle = import_styled_components2.default.div.attrs({
|
|
|
302
315
|
}
|
|
303
316
|
}
|
|
304
317
|
|
|
305
|
-
.
|
|
318
|
+
.dashed-line {
|
|
306
319
|
stroke-dasharray: 8, 5;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.flowing-line {
|
|
307
323
|
animation: flowingDash 0.5s linear infinite;
|
|
308
324
|
}
|
|
309
325
|
`;
|
|
310
326
|
|
|
311
|
-
// src/components/
|
|
327
|
+
// src/components/workflow-line-render/arrow.tsx
|
|
312
328
|
var import_react3 = __toESM(require("react"));
|
|
313
329
|
function ArrowRenderer({
|
|
314
330
|
id,
|
|
@@ -334,116 +350,48 @@ function ArrowRenderer({
|
|
|
334
350
|
);
|
|
335
351
|
}
|
|
336
352
|
|
|
337
|
-
// src/components/
|
|
338
|
-
var FoldLineRender = (props) => {
|
|
339
|
-
const { selected, color, line, children } = props;
|
|
340
|
-
const { to, from } = line.position;
|
|
341
|
-
const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;
|
|
342
|
-
const arrowToPos = {
|
|
343
|
-
x: to.x - import_free_layout_core2.POINT_RADIUS,
|
|
344
|
-
y: to.y
|
|
345
|
-
};
|
|
346
|
-
const arrowFromPos = {
|
|
347
|
-
x: from.x + import_free_layout_core2.POINT_RADIUS + LINE_OFFSET,
|
|
348
|
-
y: from.y
|
|
349
|
-
};
|
|
350
|
-
return /* @__PURE__ */ import_react4.default.createElement(LineStyle, null, children, /* @__PURE__ */ import_react4.default.createElement("svg", { overflow: "visible" }, /* @__PURE__ */ import_react4.default.createElement("defs", null, /* @__PURE__ */ import_react4.default.createElement(
|
|
351
|
-
"linearGradient",
|
|
352
|
-
{
|
|
353
|
-
x1: "0%",
|
|
354
|
-
y1: "100%",
|
|
355
|
-
x2: "100%",
|
|
356
|
-
y2: "100%",
|
|
357
|
-
id: line.id,
|
|
358
|
-
gradientUnits: "userSpaceOnUse"
|
|
359
|
-
},
|
|
360
|
-
/* @__PURE__ */ import_react4.default.createElement("stop", { stopColor: color, offset: "0%" }),
|
|
361
|
-
/* @__PURE__ */ import_react4.default.createElement("stop", { stopColor: color, offset: "100%" })
|
|
362
|
-
)), /* @__PURE__ */ import_react4.default.createElement("g", null, /* @__PURE__ */ import_react4.default.createElement(
|
|
363
|
-
"path",
|
|
364
|
-
{
|
|
365
|
-
d: line.bezier.foldPath,
|
|
366
|
-
fill: "none",
|
|
367
|
-
strokeLinecap: "round",
|
|
368
|
-
stroke: color,
|
|
369
|
-
strokeWidth,
|
|
370
|
-
className: line.flowing || line.processing ? "flowing-line" : ""
|
|
371
|
-
}
|
|
372
|
-
), /* @__PURE__ */ import_react4.default.createElement(
|
|
373
|
-
ArrowRenderer,
|
|
374
|
-
{
|
|
375
|
-
id: line.id,
|
|
376
|
-
reverseArrow: line.reverse,
|
|
377
|
-
pos: line.reverse ? arrowFromPos : arrowToPos,
|
|
378
|
-
strokeWidth,
|
|
379
|
-
hide: line.hideArrow
|
|
380
|
-
}
|
|
381
|
-
))));
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
// src/components/lines/bezier-line/index.tsx
|
|
385
|
-
var import_react5 = __toESM(require("react"));
|
|
386
|
-
var import_free_layout_core3 = require("@flowgram.ai/free-layout-core");
|
|
353
|
+
// src/components/workflow-line-render/line-svg.tsx
|
|
387
354
|
var PADDING = 12;
|
|
388
|
-
var
|
|
389
|
-
const { line, color,
|
|
390
|
-
const { bbox } = line.bezier;
|
|
355
|
+
var LineSVG = (props) => {
|
|
356
|
+
const { line, color, selected, children, strokePrefix } = props;
|
|
391
357
|
const { position, reverse, vertical, hideArrow } = line;
|
|
358
|
+
const renderData = line.getData(import_free_layout_core3.WorkflowLineRenderData);
|
|
359
|
+
const { bounds, path: bezierPath } = renderData;
|
|
392
360
|
const toRelative = (p) => ({
|
|
393
|
-
x: p.x -
|
|
394
|
-
y: p.y -
|
|
361
|
+
x: p.x - bounds.x + PADDING,
|
|
362
|
+
y: p.y - bounds.y + PADDING
|
|
395
363
|
});
|
|
396
364
|
const fromPos = toRelative(position.from);
|
|
397
365
|
const toPos = toRelative(position.to);
|
|
398
|
-
const arrowToPos = vertical ? { x: toPos.x, y: toPos.y -
|
|
399
|
-
const arrowFromPos = vertical ? { x: fromPos.x, y: fromPos.y +
|
|
400
|
-
const controls = line.bezier.controls.map((c) => toRelative(c));
|
|
401
|
-
const getLinearStartColor = () => {
|
|
402
|
-
if (vertical) {
|
|
403
|
-
return fromPos.y < arrowToPos.y ? fromColor : toColor;
|
|
404
|
-
}
|
|
405
|
-
return fromPos.x < arrowToPos.x ? fromColor : toColor;
|
|
406
|
-
};
|
|
407
|
-
const getLinearEndColor = () => {
|
|
408
|
-
if (vertical) {
|
|
409
|
-
return fromPos.y < arrowToPos.y ? toColor : fromColor;
|
|
410
|
-
}
|
|
411
|
-
return fromPos.x < arrowToPos.x ? toColor : fromColor;
|
|
412
|
-
};
|
|
413
|
-
const linearStartColor = getLinearStartColor();
|
|
414
|
-
const linearEndColor = getLinearEndColor();
|
|
415
|
-
const getPathData = () => {
|
|
416
|
-
const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(",");
|
|
417
|
-
const curveType = controls.length === 1 ? "S" : "C";
|
|
418
|
-
if (vertical) {
|
|
419
|
-
return `M${fromPos.x} ${fromPos.y + import_free_layout_core3.POINT_RADIUS} ${curveType} ${controlPoints}, ${arrowToPos.x} ${arrowToPos.y}`;
|
|
420
|
-
}
|
|
421
|
-
return `M${fromPos.x + import_free_layout_core3.POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${arrowToPos.x} ${arrowToPos.y}`;
|
|
422
|
-
};
|
|
423
|
-
const pathData = getPathData();
|
|
366
|
+
const arrowToPos = vertical ? { x: toPos.x, y: toPos.y - import_free_layout_core2.POINT_RADIUS } : { x: toPos.x - import_free_layout_core2.POINT_RADIUS, y: toPos.y };
|
|
367
|
+
const arrowFromPos = vertical ? { x: fromPos.x, y: fromPos.y + import_free_layout_core2.POINT_RADIUS + LINE_OFFSET } : { x: fromPos.x + import_free_layout_core2.POINT_RADIUS + LINE_OFFSET, y: fromPos.y };
|
|
424
368
|
const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;
|
|
425
369
|
const strokeID = strokePrefix ? `${strokePrefix}-${line.id}` : line.id;
|
|
426
|
-
const path = /* @__PURE__ */
|
|
370
|
+
const path = /* @__PURE__ */ import_react4.default.createElement(
|
|
427
371
|
"path",
|
|
428
372
|
{
|
|
429
|
-
d:
|
|
373
|
+
d: bezierPath,
|
|
430
374
|
fill: "none",
|
|
431
375
|
stroke: `url(#${strokeID})`,
|
|
432
376
|
strokeWidth,
|
|
433
|
-
className:
|
|
377
|
+
className: (0, import_clsx2.default)(
|
|
378
|
+
line.className,
|
|
379
|
+
// 显示流动线条的条件:没有自定义线条class,并且线条处于流动或处理中
|
|
380
|
+
!line.className && (line.processing || line.flowing ? "dashed-line flowing-line" : "")
|
|
381
|
+
)
|
|
434
382
|
}
|
|
435
383
|
);
|
|
436
|
-
return /* @__PURE__ */
|
|
384
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
437
385
|
LineStyle,
|
|
438
386
|
{
|
|
439
387
|
style: {
|
|
440
|
-
left:
|
|
441
|
-
top:
|
|
388
|
+
left: bounds.x - PADDING,
|
|
389
|
+
top: bounds.y - PADDING,
|
|
442
390
|
position: "absolute"
|
|
443
391
|
}
|
|
444
392
|
},
|
|
445
393
|
children,
|
|
446
|
-
/* @__PURE__ */
|
|
394
|
+
/* @__PURE__ */ import_react4.default.createElement("svg", { width: bounds.width + PADDING * 2, height: bounds.height + PADDING * 2 }, /* @__PURE__ */ import_react4.default.createElement("defs", null, /* @__PURE__ */ import_react4.default.createElement(
|
|
447
395
|
"linearGradient",
|
|
448
396
|
{
|
|
449
397
|
x1: vertical ? "100%" : "0%",
|
|
@@ -453,9 +401,9 @@ var BezierLineRender = (props) => {
|
|
|
453
401
|
id: strokeID,
|
|
454
402
|
gradientUnits: "userSpaceOnUse"
|
|
455
403
|
},
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
/* @__PURE__ */
|
|
458
|
-
)), /* @__PURE__ */
|
|
404
|
+
/* @__PURE__ */ import_react4.default.createElement("stop", { stopColor: color, offset: "0%" }),
|
|
405
|
+
/* @__PURE__ */ import_react4.default.createElement("stop", { stopColor: color, offset: "100%" })
|
|
406
|
+
)), /* @__PURE__ */ import_react4.default.createElement("g", null, path, /* @__PURE__ */ import_react4.default.createElement(
|
|
459
407
|
ArrowRenderer,
|
|
460
408
|
{
|
|
461
409
|
id: strokeID,
|
|
@@ -465,27 +413,21 @@ var BezierLineRender = (props) => {
|
|
|
465
413
|
vertical,
|
|
466
414
|
hide: hideArrow
|
|
467
415
|
}
|
|
468
|
-
)
|
|
416
|
+
)))
|
|
469
417
|
);
|
|
470
418
|
};
|
|
471
419
|
|
|
472
|
-
// src/components/
|
|
473
|
-
var
|
|
474
|
-
|
|
475
|
-
return /* @__PURE__ */ import_react6.default.createElement(FoldLineRender, { ...props });
|
|
476
|
-
}
|
|
477
|
-
return /* @__PURE__ */ import_react6.default.createElement(BezierLineRender, { ...props });
|
|
478
|
-
};
|
|
479
|
-
var LineRender = (0, import_react6.memo)(
|
|
480
|
-
LineTypeRender,
|
|
420
|
+
// src/components/workflow-line-render/index.tsx
|
|
421
|
+
var WorkflowLineRender = (0, import_react5.memo)(
|
|
422
|
+
LineSVG,
|
|
481
423
|
(prevProps, nextProps) => prevProps.version === nextProps.version
|
|
482
424
|
);
|
|
483
425
|
|
|
484
|
-
// src/layer/lines-layer.tsx
|
|
485
|
-
var
|
|
426
|
+
// src/layer/workflow-lines-layer.tsx
|
|
427
|
+
var WorkflowLinesLayer = class extends import_core2.Layer {
|
|
486
428
|
constructor() {
|
|
487
429
|
super(...arguments);
|
|
488
|
-
this.layerID = (0,
|
|
430
|
+
this.layerID = (0, import_free_layout_core4.nanoid)();
|
|
489
431
|
this.mountedLines = /* @__PURE__ */ new Map();
|
|
490
432
|
this._version = 0;
|
|
491
433
|
/**
|
|
@@ -512,14 +454,15 @@ var LinesLayer = class extends import_core2.Layer {
|
|
|
512
454
|
this.mountedLines.clear();
|
|
513
455
|
}
|
|
514
456
|
render() {
|
|
515
|
-
const [, forceUpdate] = (0,
|
|
516
|
-
(0,
|
|
457
|
+
const [, forceUpdate] = (0, import_react6.useState)({});
|
|
458
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
517
459
|
const updateLines = () => {
|
|
518
460
|
let needsUpdate = false;
|
|
519
461
|
this.lines.forEach((line) => {
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
462
|
+
const renderData = line.getData(import_free_layout_core4.WorkflowLineRenderData);
|
|
463
|
+
const oldVersion = renderData.renderVersion;
|
|
464
|
+
renderData.update();
|
|
465
|
+
if (renderData.renderVersion !== oldVersion) {
|
|
523
466
|
needsUpdate = true;
|
|
524
467
|
}
|
|
525
468
|
});
|
|
@@ -531,7 +474,7 @@ var LinesLayer = class extends import_core2.Layer {
|
|
|
531
474
|
return () => cancelAnimationFrame(rafId);
|
|
532
475
|
}, [this.lines]);
|
|
533
476
|
const lines = this.lines.map((line) => this.renderLine(line));
|
|
534
|
-
return /* @__PURE__ */
|
|
477
|
+
return /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, lines);
|
|
535
478
|
}
|
|
536
479
|
// 用来绕过 memo
|
|
537
480
|
bumpVersion() {
|
|
@@ -541,10 +484,12 @@ var LinesLayer = class extends import_core2.Layer {
|
|
|
541
484
|
}
|
|
542
485
|
}
|
|
543
486
|
lineProps(line) {
|
|
487
|
+
const renderData = line.getData(import_free_layout_core4.WorkflowLineRenderData);
|
|
488
|
+
const { renderVersion } = renderData;
|
|
544
489
|
const { lineType } = this.workflowDocument.linesManager;
|
|
545
490
|
const selected = this.selectService.isSelected(line.id);
|
|
546
|
-
const { version: lineVersion,
|
|
547
|
-
const version = `${this._version}:${lineVersion}:${
|
|
491
|
+
const { version: lineVersion, color } = line;
|
|
492
|
+
const version = `${this._version}:${lineVersion}:${renderVersion}:${color}:${selected}`;
|
|
548
493
|
return {
|
|
549
494
|
key: line.id,
|
|
550
495
|
color: line.color,
|
|
@@ -556,8 +501,8 @@ var LinesLayer = class extends import_core2.Layer {
|
|
|
556
501
|
};
|
|
557
502
|
}
|
|
558
503
|
lineComponent(props) {
|
|
559
|
-
const RenderInsideLine = this.options.renderInsideLine ?? (() => /* @__PURE__ */
|
|
560
|
-
return /* @__PURE__ */
|
|
504
|
+
const RenderInsideLine = this.options.renderInsideLine ?? (() => /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null));
|
|
505
|
+
return /* @__PURE__ */ import_react6.default.createElement(WorkflowLineRender, { ...props }, /* @__PURE__ */ import_react6.default.createElement(RenderInsideLine, { ...props }));
|
|
561
506
|
}
|
|
562
507
|
renderLine(line) {
|
|
563
508
|
const lineProps = this.lineProps(line);
|
|
@@ -590,33 +535,768 @@ var LinesLayer = class extends import_core2.Layer {
|
|
|
590
535
|
return this.node;
|
|
591
536
|
}
|
|
592
537
|
};
|
|
593
|
-
|
|
538
|
+
WorkflowLinesLayer.type = "WorkflowLinesLayer";
|
|
594
539
|
__decorateClass([
|
|
595
|
-
(0, import_inversify.inject)(
|
|
596
|
-
],
|
|
540
|
+
(0, import_inversify.inject)(import_free_layout_core4.WorkflowHoverService)
|
|
541
|
+
], WorkflowLinesLayer.prototype, "hoverService", 2);
|
|
597
542
|
__decorateClass([
|
|
598
|
-
(0, import_inversify.inject)(
|
|
599
|
-
],
|
|
543
|
+
(0, import_inversify.inject)(import_free_layout_core4.WorkflowSelectService)
|
|
544
|
+
], WorkflowLinesLayer.prototype, "selectService", 2);
|
|
600
545
|
__decorateClass([
|
|
601
|
-
(0, import_core2.observeEntities)(
|
|
602
|
-
],
|
|
546
|
+
(0, import_core2.observeEntities)(import_free_layout_core4.WorkflowLineEntity)
|
|
547
|
+
], WorkflowLinesLayer.prototype, "lines", 2);
|
|
603
548
|
__decorateClass([
|
|
604
|
-
(0, import_core2.observeEntities)(
|
|
605
|
-
],
|
|
549
|
+
(0, import_core2.observeEntities)(import_free_layout_core4.WorkflowPortEntity)
|
|
550
|
+
], WorkflowLinesLayer.prototype, "ports", 2);
|
|
606
551
|
__decorateClass([
|
|
607
|
-
(0, import_core2.observeEntityDatas)(
|
|
608
|
-
],
|
|
552
|
+
(0, import_core2.observeEntityDatas)(import_free_layout_core4.WorkflowNodeEntity, import_core2.TransformData)
|
|
553
|
+
], WorkflowLinesLayer.prototype, "trans", 2);
|
|
609
554
|
__decorateClass([
|
|
610
|
-
(0, import_inversify.inject)(
|
|
611
|
-
],
|
|
612
|
-
|
|
555
|
+
(0, import_inversify.inject)(import_free_layout_core4.WorkflowDocument)
|
|
556
|
+
], WorkflowLinesLayer.prototype, "workflowDocument", 2);
|
|
557
|
+
WorkflowLinesLayer = __decorateClass([
|
|
613
558
|
(0, import_inversify.injectable)()
|
|
614
|
-
],
|
|
559
|
+
], WorkflowLinesLayer);
|
|
560
|
+
|
|
561
|
+
// src/contributions/bezier/bezier-controls.ts
|
|
562
|
+
var import_utils2 = require("@flowgram.ai/utils");
|
|
563
|
+
var BezierControlType = /* @__PURE__ */ ((BezierControlType2) => {
|
|
564
|
+
BezierControlType2[BezierControlType2["RIGHT_TOP"] = 0] = "RIGHT_TOP";
|
|
565
|
+
BezierControlType2[BezierControlType2["RIGHT_BOTTOM"] = 1] = "RIGHT_BOTTOM";
|
|
566
|
+
BezierControlType2[BezierControlType2["LEFT_TOP"] = 2] = "LEFT_TOP";
|
|
567
|
+
BezierControlType2[BezierControlType2["LEFT_BOTTOM"] = 3] = "LEFT_BOTTOM";
|
|
568
|
+
return BezierControlType2;
|
|
569
|
+
})(BezierControlType || {});
|
|
570
|
+
var CONTROL_MAX = 300;
|
|
571
|
+
function getBezierHorizontalControlPoints(fromPos, toPos) {
|
|
572
|
+
const rect = import_utils2.Rectangle.createRectangleWithTwoPoints(fromPos, toPos);
|
|
573
|
+
let type;
|
|
574
|
+
if (fromPos.x <= toPos.x) {
|
|
575
|
+
type = fromPos.y <= toPos.y ? 1 /* RIGHT_BOTTOM */ : 0 /* RIGHT_TOP */;
|
|
576
|
+
} else {
|
|
577
|
+
type = fromPos.y <= toPos.y ? 3 /* LEFT_BOTTOM */ : 2 /* LEFT_TOP */;
|
|
578
|
+
}
|
|
579
|
+
let controls;
|
|
580
|
+
switch (type) {
|
|
581
|
+
case 0 /* RIGHT_TOP */:
|
|
582
|
+
controls = [
|
|
583
|
+
{
|
|
584
|
+
x: rect.rightBottom.x - rect.width / 2,
|
|
585
|
+
y: rect.rightBottom.y
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
x: rect.leftTop.x + rect.width / 2,
|
|
589
|
+
y: rect.leftTop.y
|
|
590
|
+
}
|
|
591
|
+
];
|
|
592
|
+
break;
|
|
593
|
+
case 1 /* RIGHT_BOTTOM */:
|
|
594
|
+
controls = [
|
|
595
|
+
{
|
|
596
|
+
x: rect.rightTop.x - rect.width / 2,
|
|
597
|
+
y: rect.rightTop.y
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
x: rect.leftBottom.x + rect.width / 2,
|
|
601
|
+
y: rect.leftBottom.y
|
|
602
|
+
}
|
|
603
|
+
];
|
|
604
|
+
break;
|
|
605
|
+
case 2 /* LEFT_TOP */:
|
|
606
|
+
controls = [
|
|
607
|
+
{
|
|
608
|
+
x: rect.rightBottom.x + Math.min(rect.width, CONTROL_MAX),
|
|
609
|
+
y: rect.rightBottom.y
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
x: rect.leftTop.x - Math.min(rect.width, CONTROL_MAX),
|
|
613
|
+
y: rect.leftTop.y
|
|
614
|
+
}
|
|
615
|
+
];
|
|
616
|
+
break;
|
|
617
|
+
case 3 /* LEFT_BOTTOM */:
|
|
618
|
+
controls = [
|
|
619
|
+
{
|
|
620
|
+
x: rect.rightTop.x + Math.min(rect.width, CONTROL_MAX),
|
|
621
|
+
y: rect.rightTop.y
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
x: rect.leftBottom.x - Math.min(rect.width, CONTROL_MAX),
|
|
625
|
+
y: rect.leftBottom.y
|
|
626
|
+
}
|
|
627
|
+
];
|
|
628
|
+
}
|
|
629
|
+
return controls;
|
|
630
|
+
}
|
|
631
|
+
function getBezierVerticalControlPoints(fromPos, toPos) {
|
|
632
|
+
const rect = import_utils2.Rectangle.createRectangleWithTwoPoints(fromPos, toPos);
|
|
633
|
+
let type;
|
|
634
|
+
if (fromPos.y <= toPos.y) {
|
|
635
|
+
type = fromPos.x <= toPos.x ? 1 /* RIGHT_BOTTOM */ : 3 /* LEFT_BOTTOM */;
|
|
636
|
+
} else {
|
|
637
|
+
type = fromPos.x <= toPos.x ? 0 /* RIGHT_TOP */ : 2 /* LEFT_TOP */;
|
|
638
|
+
}
|
|
639
|
+
let controls;
|
|
640
|
+
switch (type) {
|
|
641
|
+
case 1 /* RIGHT_BOTTOM */:
|
|
642
|
+
controls = [
|
|
643
|
+
{
|
|
644
|
+
x: rect.leftTop.x,
|
|
645
|
+
y: rect.leftTop.y + rect.height / 2
|
|
646
|
+
},
|
|
647
|
+
{
|
|
648
|
+
x: rect.rightBottom.x,
|
|
649
|
+
y: rect.rightBottom.y - rect.height / 2
|
|
650
|
+
}
|
|
651
|
+
];
|
|
652
|
+
break;
|
|
653
|
+
case 3 /* LEFT_BOTTOM */:
|
|
654
|
+
controls = [
|
|
655
|
+
{
|
|
656
|
+
x: rect.rightTop.x,
|
|
657
|
+
y: rect.rightTop.y + rect.height / 2
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
x: rect.leftBottom.x,
|
|
661
|
+
y: rect.leftBottom.y - rect.height / 2
|
|
662
|
+
}
|
|
663
|
+
];
|
|
664
|
+
break;
|
|
665
|
+
case 0 /* RIGHT_TOP */:
|
|
666
|
+
controls = [
|
|
667
|
+
{
|
|
668
|
+
x: rect.leftBottom.x,
|
|
669
|
+
y: rect.leftBottom.y + Math.min(rect.height, CONTROL_MAX)
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
x: rect.rightTop.x,
|
|
673
|
+
y: rect.rightTop.y - Math.min(rect.height, CONTROL_MAX)
|
|
674
|
+
}
|
|
675
|
+
];
|
|
676
|
+
break;
|
|
677
|
+
case 2 /* LEFT_TOP */:
|
|
678
|
+
controls = [
|
|
679
|
+
{
|
|
680
|
+
x: rect.rightBottom.x,
|
|
681
|
+
y: rect.rightBottom.y + Math.min(rect.height, CONTROL_MAX)
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
x: rect.leftTop.x,
|
|
685
|
+
y: rect.leftTop.y - Math.min(rect.height, CONTROL_MAX)
|
|
686
|
+
}
|
|
687
|
+
];
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
return controls;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// src/contributions/bezier/index.ts
|
|
694
|
+
var import_bezier_js = require("bezier-js");
|
|
695
|
+
var import_utils3 = require("@flowgram.ai/utils");
|
|
696
|
+
var import_free_layout_core5 = require("@flowgram.ai/free-layout-core");
|
|
697
|
+
var import_free_layout_core6 = require("@flowgram.ai/free-layout-core");
|
|
698
|
+
var WorkflowBezierLineContribution = class {
|
|
699
|
+
constructor(entity) {
|
|
700
|
+
this.entity = entity;
|
|
701
|
+
}
|
|
702
|
+
get path() {
|
|
703
|
+
return this.data?.path ?? "";
|
|
704
|
+
}
|
|
705
|
+
calcDistance(pos) {
|
|
706
|
+
if (!this.data) {
|
|
707
|
+
return Number.MAX_SAFE_INTEGER;
|
|
708
|
+
}
|
|
709
|
+
return import_utils3.Point.getDistance(pos, this.data.bezier.project(pos));
|
|
710
|
+
}
|
|
711
|
+
get bounds() {
|
|
712
|
+
if (!this.data) {
|
|
713
|
+
return new import_utils3.Rectangle();
|
|
714
|
+
}
|
|
715
|
+
return this.data.bbox;
|
|
716
|
+
}
|
|
717
|
+
update(params) {
|
|
718
|
+
this.data = this.calcBezier(params.fromPos, params.toPos);
|
|
719
|
+
}
|
|
720
|
+
calcBezier(fromPos, toPos) {
|
|
721
|
+
const controls = this.entity.vertical ? getBezierVerticalControlPoints(fromPos, toPos) : getBezierHorizontalControlPoints(fromPos, toPos);
|
|
722
|
+
const bezier = new import_bezier_js.Bezier([fromPos, ...controls, toPos]);
|
|
723
|
+
const bbox = bezier.bbox();
|
|
724
|
+
const bboxBounds = new import_utils3.Rectangle(
|
|
725
|
+
bbox.x.min,
|
|
726
|
+
bbox.y.min,
|
|
727
|
+
bbox.x.max - bbox.x.min,
|
|
728
|
+
bbox.y.max - bbox.y.min
|
|
729
|
+
);
|
|
730
|
+
const path = this.getPath({ bbox: bboxBounds, fromPos, toPos, controls });
|
|
731
|
+
this.data = {
|
|
732
|
+
fromPos,
|
|
733
|
+
toPos,
|
|
734
|
+
bezier,
|
|
735
|
+
bbox: bboxBounds,
|
|
736
|
+
controls,
|
|
737
|
+
path
|
|
738
|
+
};
|
|
739
|
+
return this.data;
|
|
740
|
+
}
|
|
741
|
+
getPath(params) {
|
|
742
|
+
const { bbox } = params;
|
|
743
|
+
const toRelative = (p) => ({
|
|
744
|
+
x: p.x - bbox.x + LINE_PADDING,
|
|
745
|
+
y: p.y - bbox.y + LINE_PADDING
|
|
746
|
+
});
|
|
747
|
+
const fromPos = toRelative(params.fromPos);
|
|
748
|
+
const toPos = toRelative(params.toPos);
|
|
749
|
+
const controls = params.controls.map((c) => toRelative(c));
|
|
750
|
+
const renderToPos = this.entity.vertical ? { x: toPos.x, y: toPos.y - import_free_layout_core5.POINT_RADIUS } : { x: toPos.x - import_free_layout_core5.POINT_RADIUS, y: toPos.y };
|
|
751
|
+
const getPathData = () => {
|
|
752
|
+
const controlPoints = controls.map((s) => `${s.x} ${s.y}`).join(",");
|
|
753
|
+
const curveType = controls.length === 1 ? "S" : "C";
|
|
754
|
+
if (this.entity.vertical) {
|
|
755
|
+
return `M${fromPos.x} ${fromPos.y + import_free_layout_core5.POINT_RADIUS} ${curveType} ${controlPoints}, ${renderToPos.x} ${renderToPos.y}`;
|
|
756
|
+
}
|
|
757
|
+
return `M${fromPos.x + import_free_layout_core5.POINT_RADIUS} ${fromPos.y} ${curveType} ${controlPoints}, ${renderToPos.x} ${renderToPos.y}`;
|
|
758
|
+
};
|
|
759
|
+
const path = getPathData();
|
|
760
|
+
return path;
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
WorkflowBezierLineContribution.type = import_free_layout_core6.LineType.BEZIER;
|
|
764
|
+
|
|
765
|
+
// src/contributions/fold/index.ts
|
|
766
|
+
var import_utils5 = require("@flowgram.ai/utils");
|
|
767
|
+
var import_free_layout_core7 = require("@flowgram.ai/free-layout-core");
|
|
768
|
+
var import_free_layout_core8 = require("@flowgram.ai/free-layout-core");
|
|
769
|
+
|
|
770
|
+
// src/contributions/fold/fold-line.ts
|
|
771
|
+
var import_utils4 = require("@flowgram.ai/utils");
|
|
772
|
+
function pointLineDistance(p1, p2, p3) {
|
|
773
|
+
let len;
|
|
774
|
+
if (p1.x - p2.x === 0) {
|
|
775
|
+
len = Math.abs(p3.x - p1.x);
|
|
776
|
+
} else {
|
|
777
|
+
const A = (p1.y - p2.y) / (p1.x - p2.x);
|
|
778
|
+
const B = p1.y - A * p1.x;
|
|
779
|
+
len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));
|
|
780
|
+
}
|
|
781
|
+
return len;
|
|
782
|
+
}
|
|
783
|
+
var FoldLine;
|
|
784
|
+
((FoldLine2) => {
|
|
785
|
+
const EDGE_RADIUS = 5;
|
|
786
|
+
const OFFSET = 20;
|
|
787
|
+
function getEdgeCenter({ source, target }) {
|
|
788
|
+
const xOffset = Math.abs(target.x - source.x) / 2;
|
|
789
|
+
const centerX = target.x < source.x ? target.x + xOffset : target.x - xOffset;
|
|
790
|
+
const yOffset = Math.abs(target.y - source.y) / 2;
|
|
791
|
+
const centerY = target.y < source.y ? target.y + yOffset : target.y - yOffset;
|
|
792
|
+
return [centerX, centerY];
|
|
793
|
+
}
|
|
794
|
+
const getDirection = ({ source, target }) => source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 };
|
|
795
|
+
function getPoints({
|
|
796
|
+
source,
|
|
797
|
+
target,
|
|
798
|
+
vertical = false
|
|
799
|
+
}) {
|
|
800
|
+
const sourceDir = vertical ? { x: 0, y: 1 } : { x: 1, y: 0 };
|
|
801
|
+
const targetDir = vertical ? { x: 0, y: -1 } : { x: -1, y: 0 };
|
|
802
|
+
const sourceGapped = {
|
|
803
|
+
x: source.x + sourceDir.x * OFFSET,
|
|
804
|
+
y: source.y + sourceDir.y * OFFSET
|
|
805
|
+
};
|
|
806
|
+
const targetGapped = {
|
|
807
|
+
x: target.x + targetDir.x * OFFSET,
|
|
808
|
+
y: target.y + targetDir.y * OFFSET
|
|
809
|
+
};
|
|
810
|
+
const dir = vertical ? { x: 0, y: sourceGapped.y < targetGapped.y ? 1 : -1 } : getDirection({ source: sourceGapped, target: targetGapped });
|
|
811
|
+
const dirAccessor = dir.x !== 0 ? "x" : "y";
|
|
812
|
+
const currDir = dir[dirAccessor];
|
|
813
|
+
let points = [];
|
|
814
|
+
let centerX, centerY;
|
|
815
|
+
const [defaultCenterX, defaultCenterY] = getEdgeCenter({
|
|
816
|
+
source,
|
|
817
|
+
target
|
|
818
|
+
});
|
|
819
|
+
if (sourceDir[dirAccessor] * targetDir[dirAccessor] === -1) {
|
|
820
|
+
centerX = defaultCenterX;
|
|
821
|
+
centerY = defaultCenterY;
|
|
822
|
+
const verticalSplit = [
|
|
823
|
+
{ x: centerX, y: sourceGapped.y },
|
|
824
|
+
{ x: centerX, y: targetGapped.y }
|
|
825
|
+
];
|
|
826
|
+
const horizontalSplit = [
|
|
827
|
+
{ x: sourceGapped.x, y: centerY },
|
|
828
|
+
{ x: targetGapped.x, y: centerY }
|
|
829
|
+
];
|
|
830
|
+
if (sourceDir[dirAccessor] === currDir) {
|
|
831
|
+
points = dirAccessor === "x" ? verticalSplit : horizontalSplit;
|
|
832
|
+
} else {
|
|
833
|
+
points = dirAccessor === "x" ? horizontalSplit : verticalSplit;
|
|
834
|
+
}
|
|
835
|
+
} else {
|
|
836
|
+
const sourceTarget = [{ x: sourceGapped.x, y: targetGapped.y }];
|
|
837
|
+
const targetSource = [{ x: targetGapped.x, y: sourceGapped.y }];
|
|
838
|
+
if (dirAccessor === "x") {
|
|
839
|
+
points = sourceDir.x === currDir ? targetSource : sourceTarget;
|
|
840
|
+
} else {
|
|
841
|
+
points = sourceDir.y === currDir ? sourceTarget : targetSource;
|
|
842
|
+
}
|
|
843
|
+
const dirAccessorOpposite = dirAccessor === "x" ? "y" : "x";
|
|
844
|
+
const isSameDir = sourceDir[dirAccessor] === targetDir[dirAccessorOpposite];
|
|
845
|
+
const sourceGtTargetOppo = sourceGapped[dirAccessorOpposite] > targetGapped[dirAccessorOpposite];
|
|
846
|
+
const sourceLtTargetOppo = sourceGapped[dirAccessorOpposite] < targetGapped[dirAccessorOpposite];
|
|
847
|
+
const flipSourceTarget = sourceDir[dirAccessor] === 1 && (!isSameDir && sourceGtTargetOppo || isSameDir && sourceLtTargetOppo) || sourceDir[dirAccessor] !== 1 && (!isSameDir && sourceLtTargetOppo || isSameDir && sourceGtTargetOppo);
|
|
848
|
+
if (flipSourceTarget) {
|
|
849
|
+
points = dirAccessor === "x" ? sourceTarget : targetSource;
|
|
850
|
+
}
|
|
851
|
+
const sourceGapPoint = { x: sourceGapped.x, y: sourceGapped.y };
|
|
852
|
+
const targetGapPoint = { x: targetGapped.x, y: targetGapped.y };
|
|
853
|
+
const maxXDistance = Math.max(
|
|
854
|
+
Math.abs(sourceGapPoint.x - points[0].x),
|
|
855
|
+
Math.abs(targetGapPoint.x - points[0].x)
|
|
856
|
+
);
|
|
857
|
+
const maxYDistance = Math.max(
|
|
858
|
+
Math.abs(sourceGapPoint.y - points[0].y),
|
|
859
|
+
Math.abs(targetGapPoint.y - points[0].y)
|
|
860
|
+
);
|
|
861
|
+
if (maxXDistance >= maxYDistance) {
|
|
862
|
+
centerX = (sourceGapPoint.x + targetGapPoint.x) / 2;
|
|
863
|
+
centerY = points[0].y;
|
|
864
|
+
} else {
|
|
865
|
+
centerX = points[0].x;
|
|
866
|
+
centerY = (sourceGapPoint.y + targetGapPoint.y) / 2;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
const pathPoints = [
|
|
870
|
+
source,
|
|
871
|
+
{ x: sourceGapped.x, y: sourceGapped.y },
|
|
872
|
+
...points,
|
|
873
|
+
{ x: targetGapped.x, y: targetGapped.y },
|
|
874
|
+
target
|
|
875
|
+
];
|
|
876
|
+
return pathPoints;
|
|
877
|
+
}
|
|
878
|
+
FoldLine2.getPoints = getPoints;
|
|
879
|
+
function getBend(a, b, c) {
|
|
880
|
+
const bendSize = Math.min(
|
|
881
|
+
import_utils4.Point.getDistance(a, b) / 2,
|
|
882
|
+
import_utils4.Point.getDistance(b, c) / 2,
|
|
883
|
+
EDGE_RADIUS
|
|
884
|
+
);
|
|
885
|
+
const { x, y } = b;
|
|
886
|
+
if (a.x === x && x === c.x || a.y === y && y === c.y) {
|
|
887
|
+
return `L${x} ${y}`;
|
|
888
|
+
}
|
|
889
|
+
if (a.y === y) {
|
|
890
|
+
const xDir2 = a.x < c.x ? -1 : 1;
|
|
891
|
+
const yDir2 = a.y < c.y ? 1 : -1;
|
|
892
|
+
return `L ${x + bendSize * xDir2},${y}Q ${x},${y} ${x},${y + bendSize * yDir2}`;
|
|
893
|
+
}
|
|
894
|
+
const xDir = a.x < c.x ? 1 : -1;
|
|
895
|
+
const yDir = a.y < c.y ? -1 : 1;
|
|
896
|
+
return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
|
|
897
|
+
}
|
|
898
|
+
function getSmoothStepPath(points) {
|
|
899
|
+
const path = points.reduce((res, p, i) => {
|
|
900
|
+
let segment = "";
|
|
901
|
+
if (i > 0 && i < points.length - 1) {
|
|
902
|
+
segment = getBend(points[i - 1], p, points[i + 1]);
|
|
903
|
+
} else {
|
|
904
|
+
segment = `${i === 0 ? "M" : "L"}${p.x} ${p.y}`;
|
|
905
|
+
}
|
|
906
|
+
res += segment;
|
|
907
|
+
return res;
|
|
908
|
+
}, "");
|
|
909
|
+
return path;
|
|
910
|
+
}
|
|
911
|
+
FoldLine2.getSmoothStepPath = getSmoothStepPath;
|
|
912
|
+
function getBounds(points) {
|
|
913
|
+
const xList = points.map((p) => p.x);
|
|
914
|
+
const yList = points.map((p) => p.y);
|
|
915
|
+
const left = Math.min(...xList);
|
|
916
|
+
const right = Math.max(...xList);
|
|
917
|
+
const top = Math.min(...yList);
|
|
918
|
+
const bottom = Math.max(...yList);
|
|
919
|
+
return import_utils4.Rectangle.createRectangleWithTwoPoints(
|
|
920
|
+
{
|
|
921
|
+
x: left,
|
|
922
|
+
y: top
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
x: right,
|
|
926
|
+
y: bottom
|
|
927
|
+
}
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
FoldLine2.getBounds = getBounds;
|
|
931
|
+
function getFoldLineToPointDistance(points, pos) {
|
|
932
|
+
const bounds = getBounds(points);
|
|
933
|
+
if (bounds.contains(pos.x, pos.y)) {
|
|
934
|
+
const lines = points.reduce((res, point, index) => {
|
|
935
|
+
if (index === 0) {
|
|
936
|
+
return res;
|
|
937
|
+
}
|
|
938
|
+
res.push([points[index - 1], point]);
|
|
939
|
+
return res;
|
|
940
|
+
}, []);
|
|
941
|
+
return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));
|
|
942
|
+
}
|
|
943
|
+
return Math.min(...points.map((p) => import_utils4.Point.getDistance(p, pos)));
|
|
944
|
+
}
|
|
945
|
+
FoldLine2.getFoldLineToPointDistance = getFoldLineToPointDistance;
|
|
946
|
+
})(FoldLine || (FoldLine = {}));
|
|
947
|
+
|
|
948
|
+
// src/contributions/fold/index.ts
|
|
949
|
+
var WorkflowFoldLineContribution = class {
|
|
950
|
+
constructor(entity) {
|
|
951
|
+
this.entity = entity;
|
|
952
|
+
}
|
|
953
|
+
get path() {
|
|
954
|
+
return this.data?.path ?? "";
|
|
955
|
+
}
|
|
956
|
+
calcDistance(pos) {
|
|
957
|
+
if (!this.data) {
|
|
958
|
+
return Number.MAX_SAFE_INTEGER;
|
|
959
|
+
}
|
|
960
|
+
return FoldLine.getFoldLineToPointDistance(this.data.points, pos);
|
|
961
|
+
}
|
|
962
|
+
get bounds() {
|
|
963
|
+
if (!this.data) {
|
|
964
|
+
return new import_utils5.Rectangle();
|
|
965
|
+
}
|
|
966
|
+
return this.data.bbox;
|
|
967
|
+
}
|
|
968
|
+
update(params) {
|
|
969
|
+
const { fromPos, toPos } = params;
|
|
970
|
+
const { vertical } = this.entity;
|
|
971
|
+
const sourceOffset = {
|
|
972
|
+
x: vertical ? 0 : import_free_layout_core7.POINT_RADIUS,
|
|
973
|
+
y: vertical ? import_free_layout_core7.POINT_RADIUS : 0
|
|
974
|
+
};
|
|
975
|
+
const targetOffset = {
|
|
976
|
+
x: vertical ? 0 : -import_free_layout_core7.POINT_RADIUS,
|
|
977
|
+
y: vertical ? -import_free_layout_core7.POINT_RADIUS : 0
|
|
978
|
+
};
|
|
979
|
+
const points = FoldLine.getPoints({
|
|
980
|
+
source: {
|
|
981
|
+
x: fromPos.x + sourceOffset.x,
|
|
982
|
+
y: fromPos.y + sourceOffset.y
|
|
983
|
+
},
|
|
984
|
+
target: {
|
|
985
|
+
x: toPos.x + targetOffset.x,
|
|
986
|
+
y: toPos.y + targetOffset.y
|
|
987
|
+
},
|
|
988
|
+
vertical
|
|
989
|
+
});
|
|
990
|
+
const bbox = FoldLine.getBounds(points);
|
|
991
|
+
const adjustedPoints = points.map((p) => ({
|
|
992
|
+
x: p.x - bbox.x + LINE_PADDING,
|
|
993
|
+
y: p.y - bbox.y + LINE_PADDING
|
|
994
|
+
}));
|
|
995
|
+
const path = FoldLine.getSmoothStepPath(adjustedPoints);
|
|
996
|
+
this.data = {
|
|
997
|
+
points,
|
|
998
|
+
path,
|
|
999
|
+
bbox
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
WorkflowFoldLineContribution.type = import_free_layout_core8.LineType.LINE_CHART;
|
|
1004
|
+
|
|
1005
|
+
// src/contributions/straight/index.ts
|
|
1006
|
+
var import_utils6 = require("@flowgram.ai/utils");
|
|
1007
|
+
var import_free_layout_core9 = require("@flowgram.ai/free-layout-core");
|
|
1008
|
+
|
|
1009
|
+
// src/contributions/straight/point-on-line.ts
|
|
1010
|
+
function projectPointOnLine(point, lineStart, lineEnd) {
|
|
1011
|
+
const dx = lineEnd.x - lineStart.x;
|
|
1012
|
+
const dy = lineEnd.y - lineStart.y;
|
|
1013
|
+
if (dx === 0) {
|
|
1014
|
+
return { x: lineStart.x, y: point.y };
|
|
1015
|
+
}
|
|
1016
|
+
if (dy === 0) {
|
|
1017
|
+
return { x: point.x, y: lineStart.y };
|
|
1018
|
+
}
|
|
1019
|
+
const t = ((point.x - lineStart.x) * dx + (point.y - lineStart.y) * dy) / (dx * dx + dy * dy);
|
|
1020
|
+
const clampedT = Math.max(0, Math.min(1, t));
|
|
1021
|
+
return {
|
|
1022
|
+
x: lineStart.x + clampedT * dx,
|
|
1023
|
+
y: lineStart.y + clampedT * dy
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// src/contributions/straight/index.ts
|
|
1028
|
+
var WorkflowStraightLineContribution = class {
|
|
1029
|
+
constructor(entity) {
|
|
1030
|
+
this.entity = entity;
|
|
1031
|
+
}
|
|
1032
|
+
get path() {
|
|
1033
|
+
return this.data?.path ?? "";
|
|
1034
|
+
}
|
|
1035
|
+
calcDistance(pos) {
|
|
1036
|
+
if (!this.data) {
|
|
1037
|
+
return Number.MAX_SAFE_INTEGER;
|
|
1038
|
+
}
|
|
1039
|
+
const [start, end] = this.data.points;
|
|
1040
|
+
return import_utils6.Point.getDistance(pos, projectPointOnLine(pos, start, end));
|
|
1041
|
+
}
|
|
1042
|
+
get bounds() {
|
|
1043
|
+
if (!this.data) {
|
|
1044
|
+
return new import_utils6.Rectangle();
|
|
1045
|
+
}
|
|
1046
|
+
return this.data.bbox;
|
|
1047
|
+
}
|
|
1048
|
+
update(params) {
|
|
1049
|
+
const { fromPos, toPos } = params;
|
|
1050
|
+
const { vertical } = this.entity;
|
|
1051
|
+
const sourceOffset = {
|
|
1052
|
+
x: vertical ? 0 : import_free_layout_core9.POINT_RADIUS,
|
|
1053
|
+
y: vertical ? import_free_layout_core9.POINT_RADIUS : 0
|
|
1054
|
+
};
|
|
1055
|
+
const targetOffset = {
|
|
1056
|
+
x: vertical ? 0 : -import_free_layout_core9.POINT_RADIUS,
|
|
1057
|
+
y: vertical ? -import_free_layout_core9.POINT_RADIUS : 0
|
|
1058
|
+
};
|
|
1059
|
+
const points = [
|
|
1060
|
+
{
|
|
1061
|
+
x: fromPos.x + sourceOffset.x,
|
|
1062
|
+
y: fromPos.y + sourceOffset.y
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
x: toPos.x + targetOffset.x,
|
|
1066
|
+
y: toPos.y + targetOffset.y
|
|
1067
|
+
}
|
|
1068
|
+
];
|
|
1069
|
+
const bbox = import_utils6.Rectangle.createRectangleWithTwoPoints(points[0], points[1]);
|
|
1070
|
+
const adjustedPoints = points.map((p) => ({
|
|
1071
|
+
x: p.x - bbox.x + LINE_PADDING,
|
|
1072
|
+
y: p.y - bbox.y + LINE_PADDING
|
|
1073
|
+
}));
|
|
1074
|
+
const path = `M ${adjustedPoints[0].x} ${adjustedPoints[0].y} L ${adjustedPoints[1].x} ${adjustedPoints[1].y}`;
|
|
1075
|
+
this.data = {
|
|
1076
|
+
points,
|
|
1077
|
+
path,
|
|
1078
|
+
bbox
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
WorkflowStraightLineContribution.type = "WorkflowStraightLineContribution";
|
|
1083
|
+
|
|
1084
|
+
// src/contributions/arc/index.ts
|
|
1085
|
+
var import_utils7 = require("@flowgram.ai/utils");
|
|
1086
|
+
var import_free_layout_core10 = require("@flowgram.ai/free-layout-core");
|
|
1087
|
+
var WorkflowArkLineContribution = class {
|
|
1088
|
+
constructor(entity) {
|
|
1089
|
+
this.entity = entity;
|
|
1090
|
+
}
|
|
1091
|
+
get path() {
|
|
1092
|
+
return this.data?.path ?? "";
|
|
1093
|
+
}
|
|
1094
|
+
calcDistance(pos) {
|
|
1095
|
+
if (!this.data) {
|
|
1096
|
+
return Number.MAX_SAFE_INTEGER;
|
|
1097
|
+
}
|
|
1098
|
+
const { fromPos, toPos, bbox } = this.data;
|
|
1099
|
+
if (!bbox.contains(pos.x, pos.y)) {
|
|
1100
|
+
const dx = Math.max(bbox.x - pos.x, 0, pos.x - (bbox.x + bbox.width));
|
|
1101
|
+
const dy = Math.max(bbox.y - pos.y, 0, pos.y - (bbox.y + bbox.height));
|
|
1102
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
1103
|
+
}
|
|
1104
|
+
const center = {
|
|
1105
|
+
x: (fromPos.x + toPos.x) / 2,
|
|
1106
|
+
y: (fromPos.y + toPos.y) / 2
|
|
1107
|
+
};
|
|
1108
|
+
const radius = import_utils7.Point.getDistance(fromPos, center);
|
|
1109
|
+
const distanceToCenter = import_utils7.Point.getDistance(pos, center);
|
|
1110
|
+
return Math.abs(distanceToCenter - radius);
|
|
1111
|
+
}
|
|
1112
|
+
get bounds() {
|
|
1113
|
+
if (!this.data) {
|
|
1114
|
+
return new import_utils7.Rectangle();
|
|
1115
|
+
}
|
|
1116
|
+
return this.data.bbox;
|
|
1117
|
+
}
|
|
1118
|
+
update(params) {
|
|
1119
|
+
const { fromPos, toPos } = params;
|
|
1120
|
+
const { vertical } = this.entity;
|
|
1121
|
+
const sourceOffset = {
|
|
1122
|
+
x: vertical ? 0 : import_free_layout_core10.POINT_RADIUS,
|
|
1123
|
+
y: vertical ? import_free_layout_core10.POINT_RADIUS : 0
|
|
1124
|
+
};
|
|
1125
|
+
const targetOffset = {
|
|
1126
|
+
x: vertical ? 0 : -import_free_layout_core10.POINT_RADIUS,
|
|
1127
|
+
y: vertical ? -import_free_layout_core10.POINT_RADIUS : 0
|
|
1128
|
+
};
|
|
1129
|
+
const start = {
|
|
1130
|
+
x: fromPos.x + sourceOffset.x,
|
|
1131
|
+
y: fromPos.y + sourceOffset.y
|
|
1132
|
+
};
|
|
1133
|
+
const end = {
|
|
1134
|
+
x: toPos.x + targetOffset.x,
|
|
1135
|
+
y: toPos.y + targetOffset.y
|
|
1136
|
+
};
|
|
1137
|
+
const bbox = this.calculateArcBBox(start, end);
|
|
1138
|
+
const path = this.getArcPath(start, end, bbox);
|
|
1139
|
+
this.data = {
|
|
1140
|
+
fromPos: start,
|
|
1141
|
+
toPos: end,
|
|
1142
|
+
path,
|
|
1143
|
+
bbox
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
calculateArcBBox(start, end) {
|
|
1147
|
+
const dx = end.x - start.x;
|
|
1148
|
+
const dy = end.y - start.y;
|
|
1149
|
+
const radius = Math.sqrt(dx * dx + dy * dy) / 2;
|
|
1150
|
+
const centerX = (start.x + end.x) / 2;
|
|
1151
|
+
const centerY = (start.y + end.y) / 2;
|
|
1152
|
+
return new import_utils7.Rectangle(centerX - radius, centerY - radius, radius * 2, radius * 2);
|
|
1153
|
+
}
|
|
1154
|
+
getArcPath(start, end, bbox) {
|
|
1155
|
+
const dx = end.x - start.x;
|
|
1156
|
+
const dy = end.y - start.y;
|
|
1157
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
1158
|
+
const startRel = {
|
|
1159
|
+
x: start.x - bbox.x + LINE_PADDING,
|
|
1160
|
+
y: start.y - bbox.y + LINE_PADDING
|
|
1161
|
+
};
|
|
1162
|
+
const endRel = {
|
|
1163
|
+
x: end.x - bbox.x + LINE_PADDING,
|
|
1164
|
+
y: end.y - bbox.y + LINE_PADDING
|
|
1165
|
+
};
|
|
1166
|
+
return `M ${startRel.x} ${startRel.y} A ${distance / 2} ${distance / 2} 0 0 1 ${endRel.x} ${endRel.y}`;
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
WorkflowArkLineContribution.type = "WorkflowArkLineContribution";
|
|
1170
|
+
|
|
1171
|
+
// src/contributions/manhattan/index.ts
|
|
1172
|
+
var import_utils8 = require("@flowgram.ai/utils");
|
|
1173
|
+
var import_free_layout_core11 = require("@flowgram.ai/free-layout-core");
|
|
1174
|
+
var WorkflowManhattanLineContribution = class {
|
|
1175
|
+
constructor(entity) {
|
|
1176
|
+
this.entity = entity;
|
|
1177
|
+
}
|
|
1178
|
+
get path() {
|
|
1179
|
+
return this.data?.path ?? "";
|
|
1180
|
+
}
|
|
1181
|
+
calcDistance(pos) {
|
|
1182
|
+
if (!this.data) {
|
|
1183
|
+
return Number.MAX_SAFE_INTEGER;
|
|
1184
|
+
}
|
|
1185
|
+
return Math.min(
|
|
1186
|
+
...this.data.points.slice(1).map((point, index) => {
|
|
1187
|
+
const prevPoint = this.data.points[index];
|
|
1188
|
+
return this.getDistanceToLineSegment(pos, prevPoint, point);
|
|
1189
|
+
})
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
getDistanceToLineSegment(point, start, end) {
|
|
1193
|
+
const dx = end.x - start.x;
|
|
1194
|
+
const dy = end.y - start.y;
|
|
1195
|
+
if (dx === 0 && dy === 0) {
|
|
1196
|
+
return import_utils8.Point.getDistance(point, start);
|
|
1197
|
+
}
|
|
1198
|
+
const t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / (dx * dx + dy * dy);
|
|
1199
|
+
if (t < 0) return import_utils8.Point.getDistance(point, start);
|
|
1200
|
+
if (t > 1) return import_utils8.Point.getDistance(point, end);
|
|
1201
|
+
const projectionPoint = {
|
|
1202
|
+
x: start.x + t * dx,
|
|
1203
|
+
y: start.y + t * dy
|
|
1204
|
+
};
|
|
1205
|
+
return import_utils8.Point.getDistance(point, projectionPoint);
|
|
1206
|
+
}
|
|
1207
|
+
get bounds() {
|
|
1208
|
+
if (!this.data) {
|
|
1209
|
+
return new import_utils8.Rectangle();
|
|
1210
|
+
}
|
|
1211
|
+
return this.data.bbox;
|
|
1212
|
+
}
|
|
1213
|
+
update(params) {
|
|
1214
|
+
const { fromPos, toPos } = params;
|
|
1215
|
+
const { vertical } = this.entity;
|
|
1216
|
+
const sourceOffset = {
|
|
1217
|
+
x: vertical ? 0 : import_free_layout_core11.POINT_RADIUS,
|
|
1218
|
+
y: vertical ? import_free_layout_core11.POINT_RADIUS : 0
|
|
1219
|
+
};
|
|
1220
|
+
const targetOffset = {
|
|
1221
|
+
x: vertical ? 0 : -import_free_layout_core11.POINT_RADIUS,
|
|
1222
|
+
y: vertical ? -import_free_layout_core11.POINT_RADIUS : 0
|
|
1223
|
+
};
|
|
1224
|
+
const points = this.getManhattanPoints({
|
|
1225
|
+
source: {
|
|
1226
|
+
x: fromPos.x + sourceOffset.x,
|
|
1227
|
+
y: fromPos.y + sourceOffset.y
|
|
1228
|
+
},
|
|
1229
|
+
target: {
|
|
1230
|
+
x: toPos.x + targetOffset.x,
|
|
1231
|
+
y: toPos.y + targetOffset.y
|
|
1232
|
+
},
|
|
1233
|
+
vertical
|
|
1234
|
+
});
|
|
1235
|
+
const bbox = import_utils8.Rectangle.createRectangleWithTwoPoints(
|
|
1236
|
+
points.reduce(
|
|
1237
|
+
(min, p) => ({
|
|
1238
|
+
x: Math.min(min.x, p.x),
|
|
1239
|
+
y: Math.min(min.y, p.y)
|
|
1240
|
+
}),
|
|
1241
|
+
points[0]
|
|
1242
|
+
),
|
|
1243
|
+
points.reduce(
|
|
1244
|
+
(max, p) => ({
|
|
1245
|
+
x: Math.max(max.x, p.x),
|
|
1246
|
+
y: Math.max(max.y, p.y)
|
|
1247
|
+
}),
|
|
1248
|
+
points[0]
|
|
1249
|
+
)
|
|
1250
|
+
);
|
|
1251
|
+
const adjustedPoints = points.map((p) => ({
|
|
1252
|
+
x: p.x - bbox.x + LINE_PADDING,
|
|
1253
|
+
y: p.y - bbox.y + LINE_PADDING
|
|
1254
|
+
}));
|
|
1255
|
+
const path = this.getPathFromPoints(adjustedPoints);
|
|
1256
|
+
this.data = {
|
|
1257
|
+
points,
|
|
1258
|
+
path,
|
|
1259
|
+
bbox
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
getManhattanPoints(params) {
|
|
1263
|
+
const { source, target, vertical } = params;
|
|
1264
|
+
const points = [source];
|
|
1265
|
+
if (vertical) {
|
|
1266
|
+
if (source.y !== target.y) {
|
|
1267
|
+
points.push({ x: source.x, y: target.y });
|
|
1268
|
+
}
|
|
1269
|
+
if (source.x !== target.x) {
|
|
1270
|
+
points.push({ x: target.x, y: target.y });
|
|
1271
|
+
}
|
|
1272
|
+
} else {
|
|
1273
|
+
if (source.x !== target.x) {
|
|
1274
|
+
points.push({ x: target.x, y: source.y });
|
|
1275
|
+
}
|
|
1276
|
+
if (source.y !== target.y) {
|
|
1277
|
+
points.push({ x: target.x, y: target.y });
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
if (points[points.length - 1] !== target) {
|
|
1281
|
+
points.push(target);
|
|
1282
|
+
}
|
|
1283
|
+
return points;
|
|
1284
|
+
}
|
|
1285
|
+
getPathFromPoints(points) {
|
|
1286
|
+
return points.reduce((path, point, index) => {
|
|
1287
|
+
if (index === 0) {
|
|
1288
|
+
return `M ${point.x} ${point.y}`;
|
|
1289
|
+
}
|
|
1290
|
+
return `${path} L ${point.x} ${point.y}`;
|
|
1291
|
+
}, "");
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
WorkflowManhattanLineContribution.type = "WorkflowManhattanLineContribution";
|
|
615
1295
|
|
|
616
1296
|
// src/create-free-lines-plugin.ts
|
|
617
1297
|
var createFreeLinesPlugin = (0, import_core3.definePluginCreator)({
|
|
618
1298
|
onInit: (ctx, opts) => {
|
|
619
|
-
ctx.playground.registerLayer(
|
|
1299
|
+
ctx.playground.registerLayer(WorkflowLinesLayer, {
|
|
620
1300
|
...opts,
|
|
621
1301
|
renderElement: () => {
|
|
622
1302
|
if (typeof opts.renderElement === "function") {
|
|
@@ -626,13 +1306,35 @@ var createFreeLinesPlugin = (0, import_core3.definePluginCreator)({
|
|
|
626
1306
|
}
|
|
627
1307
|
}
|
|
628
1308
|
});
|
|
1309
|
+
},
|
|
1310
|
+
onReady: (ctx, opts) => {
|
|
1311
|
+
const linesManager = ctx.container.get(import_free_layout_core12.WorkflowLinesManager);
|
|
1312
|
+
linesManager.registerContribution(WorkflowBezierLineContribution).registerContribution(WorkflowFoldLineContribution);
|
|
1313
|
+
if (opts.contributions) {
|
|
1314
|
+
opts.contributions.forEach((contribution) => {
|
|
1315
|
+
linesManager.registerContribution(contribution);
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
if (opts.defaultLineType) {
|
|
1319
|
+
linesManager.switchLineType(opts.defaultLineType);
|
|
1320
|
+
}
|
|
629
1321
|
}
|
|
630
1322
|
});
|
|
631
1323
|
// Annotate the CommonJS export names for ESM import in node:
|
|
632
1324
|
0 && (module.exports = {
|
|
1325
|
+
BezierControlType,
|
|
633
1326
|
LINE_OFFSET,
|
|
1327
|
+
LINE_PADDING,
|
|
634
1328
|
LinesLayer,
|
|
1329
|
+
WorkflowArkLineContribution,
|
|
1330
|
+
WorkflowBezierLineContribution,
|
|
1331
|
+
WorkflowFoldLineContribution,
|
|
1332
|
+
WorkflowLinesLayer,
|
|
1333
|
+
WorkflowManhattanLineContribution,
|
|
635
1334
|
WorkflowPortRender,
|
|
636
|
-
|
|
1335
|
+
WorkflowStraightLineContribution,
|
|
1336
|
+
createFreeLinesPlugin,
|
|
1337
|
+
getBezierHorizontalControlPoints,
|
|
1338
|
+
getBezierVerticalControlPoints
|
|
637
1339
|
});
|
|
638
1340
|
//# sourceMappingURL=index.js.map
|