@logicflow/core 2.0.13 → 2.0.15
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/.turbo/turbo-build$colon$dev.log +2 -2
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +12 -0
- package/__tests__/algorithm/index.test.ts +22 -17
- package/__tests__/algorithm/outline.test.ts +9 -9
- package/__tests__/event/event.test.ts +18 -18
- package/__tests__/history/history.test.ts +23 -23
- package/__tests__/logicflow.test.ts +236 -228
- package/__tests__/model/graphmodel.test.ts +51 -31
- package/__tests__/util/compatible.test.ts +5 -5
- package/__tests__/util/geometry.test.ts +10 -10
- package/__tests__/util/graph.test.ts +12 -12
- package/__tests__/util/matrix.test.ts +26 -26
- package/__tests__/util/node.test.ts +22 -22
- package/__tests__/util/sampling.test.ts +6 -10
- package/__tests__/util/vector.test.ts +36 -36
- package/__tests__/util/zIndex.test.ts +6 -6
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/LogicFlow.d.ts +24 -4
- package/es/LogicFlow.js +28 -6
- package/es/model/GraphModel.d.ts +34 -1
- package/es/model/GraphModel.js +36 -5
- package/es/model/node/RectNodeModel.js +3 -0
- package/es/options.d.ts +1 -0
- package/es/util/theme.d.ts +67 -2
- package/es/util/theme.js +189 -2
- package/es/view/edge/BaseEdge.d.ts +4 -0
- package/es/view/edge/BaseEdge.js +45 -3
- package/es/view/overlay/Grid.js +3 -2
- package/es/view/shape/Polygon.d.ts +8 -0
- package/es/view/shape/Polygon.js +50 -3
- package/lib/LogicFlow.d.ts +24 -4
- package/lib/LogicFlow.js +27 -5
- package/lib/model/GraphModel.d.ts +34 -1
- package/lib/model/GraphModel.js +34 -3
- package/lib/model/node/RectNodeModel.js +3 -0
- package/lib/options.d.ts +1 -0
- package/lib/util/theme.d.ts +67 -2
- package/lib/util/theme.js +192 -2
- package/lib/view/edge/BaseEdge.d.ts +4 -0
- package/lib/view/edge/BaseEdge.js +45 -3
- package/lib/view/overlay/Grid.js +3 -2
- package/lib/view/shape/Polygon.d.ts +8 -0
- package/lib/view/shape/Polygon.js +52 -4
- package/package.json +1 -1
- package/src/LogicFlow.tsx +48 -6
- package/src/model/GraphModel.ts +48 -3
- package/src/model/edge/index.ts +4 -4
- package/src/model/index.ts +7 -7
- package/src/model/node/RectNodeModel.ts +2 -1
- package/src/model/node/index.ts +8 -8
- package/src/options.ts +1 -0
- package/src/util/theme.ts +198 -3
- package/src/view/edge/BaseEdge.tsx +96 -12
- package/src/view/overlay/Grid.tsx +2 -1
- package/src/view/shape/Polygon.tsx +56 -4
- package/stats.html +1 -1
|
@@ -317,6 +317,31 @@ var BaseEdge = /** @class */ (function (_super) {
|
|
|
317
317
|
}
|
|
318
318
|
return ((0, jsx_runtime_1.jsx)("g", { children: (0, jsx_runtime_1.jsxs)("defs", { children: [(0, jsx_runtime_1.jsx)("marker", { id: "marker-start-".concat(id), refX: -refX, refY: refY, overflow: "visible", orient: "auto", markerUnits: "userSpaceOnUse", children: this.getStartArrow() }), (0, jsx_runtime_1.jsx)("marker", { id: "marker-end-".concat(id), refX: refX, refY: refY, overflow: "visible", orient: theta, markerUnits: "userSpaceOnUse", children: this.getEndArrow() })] }) }));
|
|
319
319
|
};
|
|
320
|
+
/**
|
|
321
|
+
* Private helper method to generate arrow path based on type and parameters
|
|
322
|
+
*/
|
|
323
|
+
BaseEdge.prototype.getArrowPath = function (arrowType, props) {
|
|
324
|
+
var stroke = props.stroke, _a = props.fill, fill = _a === void 0 ? stroke : _a, strokeWidth = props.strokeWidth, _b = props.offset, offset = _b === void 0 ? 10 : _b, verticalLength = props.verticalLength, strokeLinecap = props.strokeLinecap, strokeLinejoin = props.strokeLinejoin, transform = props.transform;
|
|
325
|
+
var arrowPath = '';
|
|
326
|
+
switch (arrowType) {
|
|
327
|
+
case 'solid':
|
|
328
|
+
arrowPath = "M".concat(-offset / 4, ",0 L").concat((3 * offset) / 4, ",").concat(verticalLength, " L").concat((3 * offset) / 4, ",-").concat(verticalLength, " Z");
|
|
329
|
+
break;
|
|
330
|
+
case 'hollow':
|
|
331
|
+
arrowPath = "M".concat(-offset / 4, ",0 L").concat((3 * offset) / 4, ",").concat(verticalLength, " L").concat(-offset / 4, ",0 L").concat((3 * offset) / 4, ",-").concat(verticalLength, " L").concat(-offset / 4, ",0 Z");
|
|
332
|
+
break;
|
|
333
|
+
case 'diamond':
|
|
334
|
+
arrowPath = "M".concat(-offset / 2, ",0 L0,").concat(verticalLength, " L").concat(offset / 2, ",0 L0,-").concat(verticalLength, " L").concat(-offset / 2, ",0 Z");
|
|
335
|
+
break;
|
|
336
|
+
case 'circle':
|
|
337
|
+
arrowPath = "M".concat(-offset / 2, ",0 A").concat(offset / 4, ",").concat(offset / 4, " 0 1,0 ").concat(offset / 2, ",0 A").concat(offset / 4, ",").concat(offset / 4, " 0 1,0 ").concat(-offset / 2, ",0 Z");
|
|
338
|
+
break;
|
|
339
|
+
default:
|
|
340
|
+
arrowPath = '';
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
return ((0, jsx_runtime_1.jsx)("path", { d: arrowPath, stroke: stroke, fill: fill, strokeWidth: strokeWidth, strokeLinecap: strokeLinecap, strokeLinejoin: strokeLinejoin, transform: transform }));
|
|
344
|
+
};
|
|
320
345
|
/**
|
|
321
346
|
* @overridable 可重写,自定义边起点箭头形状。
|
|
322
347
|
* @example
|
|
@@ -331,7 +356,16 @@ var BaseEdge = /** @class */ (function (_super) {
|
|
|
331
356
|
* }
|
|
332
357
|
*/
|
|
333
358
|
BaseEdge.prototype.getStartArrow = function () {
|
|
334
|
-
|
|
359
|
+
var model = this.props.model;
|
|
360
|
+
var _a = model.getArrowStyle(), stroke = _a.stroke, strokeWidth = _a.strokeWidth, offset = _a.offset, verticalLength = _a.verticalLength, _b = _a.startArrowType, startArrowType = _b === void 0 ? 'none' : _b, strokeLinecap = _a.strokeLinecap, strokeLinejoin = _a.strokeLinejoin;
|
|
361
|
+
return this.getArrowPath(startArrowType, {
|
|
362
|
+
stroke: stroke,
|
|
363
|
+
strokeWidth: strokeWidth,
|
|
364
|
+
offset: offset,
|
|
365
|
+
verticalLength: verticalLength,
|
|
366
|
+
strokeLinecap: strokeLinecap,
|
|
367
|
+
strokeLinejoin: strokeLinejoin,
|
|
368
|
+
});
|
|
335
369
|
};
|
|
336
370
|
/**
|
|
337
371
|
* @overridable 可重写,自定义边终点箭头形状。
|
|
@@ -348,8 +382,16 @@ var BaseEdge = /** @class */ (function (_super) {
|
|
|
348
382
|
*/
|
|
349
383
|
BaseEdge.prototype.getEndArrow = function () {
|
|
350
384
|
var model = this.props.model;
|
|
351
|
-
var _a = model.getArrowStyle(), stroke = _a.stroke, strokeWidth = _a.strokeWidth, offset = _a.offset, verticalLength = _a.verticalLength;
|
|
352
|
-
return
|
|
385
|
+
var _a = model.getArrowStyle(), stroke = _a.stroke, strokeWidth = _a.strokeWidth, offset = _a.offset, verticalLength = _a.verticalLength, _b = _a.endArrowType, endArrowType = _b === void 0 ? 'solid' : _b, strokeLinecap = _a.strokeLinecap, strokeLinejoin = _a.strokeLinejoin;
|
|
386
|
+
return this.getArrowPath(endArrowType, {
|
|
387
|
+
stroke: stroke,
|
|
388
|
+
strokeWidth: strokeWidth,
|
|
389
|
+
offset: offset,
|
|
390
|
+
verticalLength: verticalLength,
|
|
391
|
+
strokeLinecap: strokeLinecap,
|
|
392
|
+
strokeLinejoin: strokeLinejoin,
|
|
393
|
+
transform: 'rotate(180)',
|
|
394
|
+
});
|
|
353
395
|
};
|
|
354
396
|
/**
|
|
355
397
|
* @overridable 可重写,自定义调整边连接节点形状。在开启了adjustEdgeStartAndEnd的时候,会显示调整点。
|
package/lib/view/overlay/Grid.js
CHANGED
|
@@ -57,8 +57,9 @@ var Grid = /** @class */ (function (_super) {
|
|
|
57
57
|
return ((0, jsx_runtime_1.jsx)("path", { d: d, stroke: color, strokeWidth: strokeWidth / 2, opacity: opacity, fill: "transparent" }));
|
|
58
58
|
};
|
|
59
59
|
Grid.prototype.render = function () {
|
|
60
|
-
var
|
|
61
|
-
|
|
60
|
+
var _a = this.props.graphModel, transformModel = _a.transformModel, grid = _a.grid;
|
|
61
|
+
this.gridOptions = grid;
|
|
62
|
+
var _b = this.gridOptions, type = _b.type, _c = _b.size, size = _c === void 0 ? 1 : _c;
|
|
62
63
|
var SCALE_X = transformModel.SCALE_X, SKEW_Y = transformModel.SKEW_Y, SKEW_X = transformModel.SKEW_X, SCALE_Y = transformModel.SCALE_Y, TRANSLATE_X = transformModel.TRANSLATE_X, TRANSLATE_Y = transformModel.TRANSLATE_Y;
|
|
63
64
|
var matrixString = [
|
|
64
65
|
SCALE_X,
|
|
@@ -5,6 +5,14 @@ export type IPolygonProps = {
|
|
|
5
5
|
x?: number;
|
|
6
6
|
y?: number;
|
|
7
7
|
className?: string;
|
|
8
|
+
radius?: number;
|
|
8
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* 生成带圆角的多边形路径
|
|
12
|
+
* @param points 多边形顶点坐标数组
|
|
13
|
+
* @param radius 圆角半径
|
|
14
|
+
* @returns SVG 路径字符串
|
|
15
|
+
*/
|
|
16
|
+
export declare function createRoundedPolygonPath(points: any, radius: any): string;
|
|
9
17
|
export declare function Polygon(props: IPolygonProps): h.JSX.Element;
|
|
10
18
|
export default Polygon;
|
|
@@ -27,11 +27,52 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
27
27
|
return ar;
|
|
28
28
|
};
|
|
29
29
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.Polygon = void 0;
|
|
30
|
+
exports.Polygon = exports.createRoundedPolygonPath = void 0;
|
|
31
31
|
var jsx_runtime_1 = require("preact/jsx-runtime");
|
|
32
32
|
var lodash_es_1 = require("lodash-es");
|
|
33
|
+
/**
|
|
34
|
+
* 生成带圆角的多边形路径
|
|
35
|
+
* @param points 多边形顶点坐标数组
|
|
36
|
+
* @param radius 圆角半径
|
|
37
|
+
* @returns SVG 路径字符串
|
|
38
|
+
*/
|
|
39
|
+
function createRoundedPolygonPath(points, radius) {
|
|
40
|
+
var pointList = points.map(function (point) { return ({ x: point[0], y: point[1] }); });
|
|
41
|
+
var len = pointList.length;
|
|
42
|
+
if (len < 3)
|
|
43
|
+
return '';
|
|
44
|
+
var r = Math.abs(radius);
|
|
45
|
+
var path = '';
|
|
46
|
+
for (var i = 0; i < len; i++) {
|
|
47
|
+
var prev = pointList[(i - 1 + len) % len];
|
|
48
|
+
var curr = pointList[i];
|
|
49
|
+
var next = pointList[(i + 1) % len];
|
|
50
|
+
// 向量
|
|
51
|
+
var v1 = { x: curr.x - prev.x, y: curr.y - prev.y };
|
|
52
|
+
var v2 = { x: next.x - curr.x, y: next.y - curr.y };
|
|
53
|
+
// 单位向量
|
|
54
|
+
var len1 = Math.hypot(v1.x, v1.y);
|
|
55
|
+
var len2 = Math.hypot(v2.x, v2.y);
|
|
56
|
+
var u1 = { x: v1.x / len1, y: v1.y / len1 };
|
|
57
|
+
var u2 = { x: v2.x / len2, y: v2.y / len2 };
|
|
58
|
+
// 起点 = curr - u1 * r,终点 = curr + u2 * r
|
|
59
|
+
var start = { x: curr.x - u1.x * r, y: curr.y - u1.y * r };
|
|
60
|
+
var end = { x: curr.x + u2.x * r, y: curr.y + u2.y * r };
|
|
61
|
+
if (i === 0) {
|
|
62
|
+
path += "M ".concat(start.x, " ").concat(start.y, " ");
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
path += "L ".concat(start.x, " ").concat(start.y, " ");
|
|
66
|
+
}
|
|
67
|
+
// Q 控制点是当前拐角点
|
|
68
|
+
path += "Q ".concat(curr.x, " ").concat(curr.y, " ").concat(end.x, " ").concat(end.y, " ");
|
|
69
|
+
}
|
|
70
|
+
path += 'Z';
|
|
71
|
+
return path;
|
|
72
|
+
}
|
|
73
|
+
exports.createRoundedPolygonPath = createRoundedPolygonPath;
|
|
33
74
|
function Polygon(props) {
|
|
34
|
-
var _a = props.points, points = _a === void 0 ? [] : _a, className = props.className;
|
|
75
|
+
var _a = props.points, points = _a === void 0 ? [] : _a, className = props.className, radius = props.radius;
|
|
35
76
|
var attrs = {
|
|
36
77
|
fill: 'transparent',
|
|
37
78
|
fillOpacity: 1,
|
|
@@ -52,8 +93,15 @@ function Polygon(props) {
|
|
|
52
93
|
else {
|
|
53
94
|
attrs.className = 'lf-basic-shape';
|
|
54
95
|
}
|
|
55
|
-
|
|
56
|
-
|
|
96
|
+
if (radius) {
|
|
97
|
+
var path = createRoundedPolygonPath(points, radius);
|
|
98
|
+
attrs.d = path;
|
|
99
|
+
return (0, jsx_runtime_1.jsx)("path", __assign({}, attrs));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
attrs.points = points.map(function (point) { return point.join(','); }).join(' ');
|
|
103
|
+
return (0, jsx_runtime_1.jsx)("polygon", __assign({}, attrs));
|
|
104
|
+
}
|
|
57
105
|
}
|
|
58
106
|
exports.Polygon = Polygon;
|
|
59
107
|
exports.default = Polygon;
|
package/package.json
CHANGED
package/src/LogicFlow.tsx
CHANGED
|
@@ -14,7 +14,12 @@ import {
|
|
|
14
14
|
|
|
15
15
|
import Graph from './view/Graph'
|
|
16
16
|
import * as _View from './view'
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
formatData,
|
|
19
|
+
addThemeMode,
|
|
20
|
+
removeThemeMode,
|
|
21
|
+
clearThemeMode,
|
|
22
|
+
} from './util'
|
|
18
23
|
|
|
19
24
|
import { Dnd, snapline } from './view/behavior'
|
|
20
25
|
import Tool from './tool'
|
|
@@ -22,6 +27,7 @@ import History from './history'
|
|
|
22
27
|
import Keyboard, { initDefaultShortcut } from './keyboard'
|
|
23
28
|
import { EventCallback, CallbackArgs, EventArgs } from './event/eventEmitter'
|
|
24
29
|
import { ElementType, EventType, SegmentDirection } from './constant'
|
|
30
|
+
import { Grid } from './view/overlay'
|
|
25
31
|
|
|
26
32
|
import Extension = LogicFlow.Extension
|
|
27
33
|
import ExtensionConfig = LogicFlow.ExtensionConfig
|
|
@@ -829,7 +835,7 @@ export class LogicFlow {
|
|
|
829
835
|
|
|
830
836
|
/**
|
|
831
837
|
* 设置元素的自定义属性
|
|
832
|
-
* @see
|
|
838
|
+
* @see http://logicflow.cn/api/detail#setproperties
|
|
833
839
|
* @param id 元素的id
|
|
834
840
|
* @param properties 自定义属性
|
|
835
841
|
*/
|
|
@@ -889,7 +895,7 @@ export class LogicFlow {
|
|
|
889
895
|
/**
|
|
890
896
|
* 更新流程图编辑相关设置
|
|
891
897
|
* @param {object} config 编辑配置
|
|
892
|
-
* @see
|
|
898
|
+
* @see http://logicflow.cn/api/detail#updateeditconfig
|
|
893
899
|
*/
|
|
894
900
|
updateEditConfig(config: Partial<IEditConfigType>) {
|
|
895
901
|
const { editConfigModel, transformModel } = this.graphModel
|
|
@@ -914,7 +920,7 @@ export class LogicFlow {
|
|
|
914
920
|
|
|
915
921
|
/**
|
|
916
922
|
* 获取流程图当前编辑相关设置
|
|
917
|
-
* @see
|
|
923
|
+
* @see http://logicflow.cn/api/detail#geteditconfig
|
|
918
924
|
*/
|
|
919
925
|
getEditConfig() {
|
|
920
926
|
return this.graphModel.editConfigModel.getConfig()
|
|
@@ -928,8 +934,18 @@ export class LogicFlow {
|
|
|
928
934
|
* @param { object } style 自定义主题样式
|
|
929
935
|
* todo docs link
|
|
930
936
|
*/
|
|
931
|
-
setTheme(
|
|
932
|
-
|
|
937
|
+
setTheme(
|
|
938
|
+
style: Partial<LogicFlow.Theme>,
|
|
939
|
+
themeMode?: 'radius' | 'dark' | 'colorful' | 'default' | string,
|
|
940
|
+
): void {
|
|
941
|
+
this.graphModel.setTheme(style, themeMode)
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* 获取当前主题样式
|
|
945
|
+
* @see todo docs link
|
|
946
|
+
*/
|
|
947
|
+
getTheme(): LogicFlow.Theme {
|
|
948
|
+
return this.graphModel.getTheme()
|
|
933
949
|
}
|
|
934
950
|
|
|
935
951
|
private focusByElement(id: string) {
|
|
@@ -1333,6 +1349,23 @@ export class LogicFlow {
|
|
|
1333
1349
|
})
|
|
1334
1350
|
}
|
|
1335
1351
|
|
|
1352
|
+
/**
|
|
1353
|
+
* 添加主题模式
|
|
1354
|
+
* @param themeMode 主题模式
|
|
1355
|
+
* @param style 主题样式
|
|
1356
|
+
*/
|
|
1357
|
+
static addThemeMode(themeMode: string, style: Partial<LogicFlow.Theme>) {
|
|
1358
|
+
addThemeMode(themeMode, style)
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
static removeThemeMode(themeMode: string) {
|
|
1362
|
+
removeThemeMode(themeMode)
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
static clearThemeMode() {
|
|
1366
|
+
clearThemeMode()
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1336
1369
|
private installPlugins(disabledPlugins: string[] = []) {
|
|
1337
1370
|
const extensionsAddByUse = Array.from(
|
|
1338
1371
|
LogicFlow.extensions,
|
|
@@ -1399,6 +1432,7 @@ export class LogicFlow {
|
|
|
1399
1432
|
this.graphModel.destroy()
|
|
1400
1433
|
this.tool.destroy()
|
|
1401
1434
|
this.history.destroy()
|
|
1435
|
+
this.clearThemeMode()
|
|
1402
1436
|
for (const extensionName in this.extension) {
|
|
1403
1437
|
const extensionInstance = this.extension[extensionName]
|
|
1404
1438
|
if ('destroy' in extensionInstance) {
|
|
@@ -1801,6 +1835,10 @@ export namespace LogicFlow {
|
|
|
1801
1835
|
refX?: number
|
|
1802
1836
|
refY?: number
|
|
1803
1837
|
verticalLength: number
|
|
1838
|
+
endArrowType?: 'solid' | 'hollow' | 'diamond' | 'circle' | 'none' // 结束箭头类型
|
|
1839
|
+
startArrowType?: 'solid' | 'hollow' | 'diamond' | 'circle' | 'none' // 开始箭头类型
|
|
1840
|
+
strokeLinecap?: 'butt' | 'round' | 'square' // 线条的端点样式
|
|
1841
|
+
strokeLinejoin?: 'miter' | 'round' | 'bevel' // 线条的连接样式
|
|
1804
1842
|
} & CommonTheme
|
|
1805
1843
|
export type ArrowAttributesType = {
|
|
1806
1844
|
d: string
|
|
@@ -1855,6 +1893,10 @@ export namespace LogicFlow {
|
|
|
1855
1893
|
edgeAdjust: CircleTheme
|
|
1856
1894
|
outline: OutlineTheme // 节点选择状态下外侧的选框样式
|
|
1857
1895
|
edgeAnimation: EdgeAnimation // 边动画样式
|
|
1896
|
+
|
|
1897
|
+
// 画布背景
|
|
1898
|
+
background?: boolean | Partial<LFOptions.BackgroundConfig>
|
|
1899
|
+
grid?: boolean | Partial<Grid.GridOptions>
|
|
1858
1900
|
}
|
|
1859
1901
|
}
|
|
1860
1902
|
|
package/src/model/GraphModel.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
merge,
|
|
6
6
|
isBoolean,
|
|
7
7
|
debounce,
|
|
8
|
+
cloneDeep,
|
|
8
9
|
isNil,
|
|
9
10
|
} from 'lodash-es'
|
|
10
11
|
import { action, computed, observable } from 'mobx'
|
|
@@ -42,6 +43,8 @@ import {
|
|
|
42
43
|
setupTheme,
|
|
43
44
|
snapToGrid,
|
|
44
45
|
updateTheme,
|
|
46
|
+
backgroundModeMap,
|
|
47
|
+
gridModeMap,
|
|
45
48
|
} from '../util'
|
|
46
49
|
import EventEmitter from '../event/eventEmitter'
|
|
47
50
|
import { Grid } from '../view/overlay'
|
|
@@ -64,6 +67,8 @@ export class GraphModel {
|
|
|
64
67
|
|
|
65
68
|
// 流程图主题配置
|
|
66
69
|
@observable theme: LogicFlow.Theme
|
|
70
|
+
// 初始化样式
|
|
71
|
+
customStyles: object
|
|
67
72
|
// 网格配置
|
|
68
73
|
@observable grid: Grid.GridOptions
|
|
69
74
|
// 事件中心
|
|
@@ -165,8 +170,11 @@ export class GraphModel {
|
|
|
165
170
|
// TODO:需要让用户设置成 0 吗?后面可以讨论一下
|
|
166
171
|
this.gridSize = grid.size || 1 // 默认 gridSize 设置为 1
|
|
167
172
|
}
|
|
168
|
-
this.
|
|
173
|
+
this.customStyles = options.style || {}
|
|
169
174
|
this.grid = Grid.getGridOptions(grid ?? false)
|
|
175
|
+
this.theme = setupTheme(options.style, options.themeMode)
|
|
176
|
+
this.theme.grid = cloneDeep(this.grid)
|
|
177
|
+
this.theme.background = cloneDeep(this.background)
|
|
170
178
|
this.edgeType = options.edgeType || 'polyline'
|
|
171
179
|
this.animation = setupAnimation(animation)
|
|
172
180
|
this.overlapMode = options.overlapMode || OverlapMode.DEFAULT
|
|
@@ -1471,8 +1479,45 @@ export class GraphModel {
|
|
|
1471
1479
|
* 设置主题
|
|
1472
1480
|
* todo docs link
|
|
1473
1481
|
*/
|
|
1474
|
-
@action setTheme(
|
|
1475
|
-
|
|
1482
|
+
@action setTheme(
|
|
1483
|
+
style: Partial<LogicFlow.Theme>,
|
|
1484
|
+
themeMode?: 'radius' | 'dark' | 'colorful' | 'default' | string,
|
|
1485
|
+
) {
|
|
1486
|
+
if (themeMode) {
|
|
1487
|
+
// 修改背景颜色
|
|
1488
|
+
backgroundModeMap[themeMode] &&
|
|
1489
|
+
this.updateBackgroundOptions({
|
|
1490
|
+
...(typeof this.background === 'object' ? this.background : {}),
|
|
1491
|
+
...backgroundModeMap[themeMode],
|
|
1492
|
+
})
|
|
1493
|
+
gridModeMap[themeMode] &&
|
|
1494
|
+
this.updateGridOptions(
|
|
1495
|
+
Grid.getGridOptions({ ...this.grid, ...gridModeMap[themeMode] }),
|
|
1496
|
+
)
|
|
1497
|
+
}
|
|
1498
|
+
if (style.background) {
|
|
1499
|
+
this.updateBackgroundOptions(style.background)
|
|
1500
|
+
}
|
|
1501
|
+
if (style.grid) {
|
|
1502
|
+
const formattedGrid = Grid.getGridOptions(style.grid ?? false)
|
|
1503
|
+
this.updateGridOptions(formattedGrid)
|
|
1504
|
+
}
|
|
1505
|
+
this.theme = updateTheme({ ...this.customStyles, ...style }, themeMode)
|
|
1506
|
+
this.customStyles = { ...this.customStyles, ...style }
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
/**
|
|
1510
|
+
* 设置主题
|
|
1511
|
+
* todo docs link
|
|
1512
|
+
*/
|
|
1513
|
+
@action getTheme() {
|
|
1514
|
+
const { background, grid } = this
|
|
1515
|
+
const theme = {
|
|
1516
|
+
...cloneDeep(this.theme),
|
|
1517
|
+
background,
|
|
1518
|
+
grid,
|
|
1519
|
+
}
|
|
1520
|
+
return theme
|
|
1476
1521
|
}
|
|
1477
1522
|
|
|
1478
1523
|
/**
|
package/src/model/edge/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './BaseEdgeModel'
|
|
2
|
-
export * from './BezierEdgeModel'
|
|
3
|
-
export * from './LineEdgeModel'
|
|
4
|
-
export * from './PolylineEdgeModel'
|
|
1
|
+
export * from './BaseEdgeModel'
|
|
2
|
+
export * from './BezierEdgeModel'
|
|
3
|
+
export * from './LineEdgeModel'
|
|
4
|
+
export * from './PolylineEdgeModel'
|
package/src/model/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from './edge'
|
|
2
|
-
export * from './node'
|
|
1
|
+
export * from './edge'
|
|
2
|
+
export * from './node'
|
|
3
3
|
|
|
4
|
-
export * from './BaseModel'
|
|
5
|
-
export * from './EditConfigModel'
|
|
6
|
-
export * from './GraphModel'
|
|
7
|
-
export * from './SnaplineModel'
|
|
8
|
-
export * from './TransformModel'
|
|
4
|
+
export * from './BaseModel'
|
|
5
|
+
export * from './EditConfigModel'
|
|
6
|
+
export * from './GraphModel'
|
|
7
|
+
export * from './SnaplineModel'
|
|
8
|
+
export * from './TransformModel'
|
|
@@ -36,11 +36,12 @@ export class RectNodeModel<
|
|
|
36
36
|
super.setAttributes()
|
|
37
37
|
|
|
38
38
|
const { width, height, radius } = this.properties
|
|
39
|
+
const { radius: styleRadius } = this.getNodeStyle()
|
|
39
40
|
if (!isNil(width)) this.width = width
|
|
40
41
|
if (!isNil(height)) this.height = height
|
|
41
|
-
|
|
42
42
|
// 矩形特有
|
|
43
43
|
if (!isNil(radius)) this.radius = radius
|
|
44
|
+
if (!isNil(styleRadius)) this.radius = styleRadius
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
getDefaultAnchor() {
|
package/src/model/node/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from './BaseNodeModel'
|
|
2
|
-
export * from './CircleNodeModel'
|
|
3
|
-
export * from './DiamondNodeModel'
|
|
4
|
-
export * from './EllipseNodeModel'
|
|
5
|
-
export * from './PolygonNodeModel'
|
|
6
|
-
export * from './RectNodeModel'
|
|
7
|
-
export * from './TextNodeModel'
|
|
8
|
-
export * from './HtmlNodeModel'
|
|
1
|
+
export * from './BaseNodeModel'
|
|
2
|
+
export * from './CircleNodeModel'
|
|
3
|
+
export * from './DiamondNodeModel'
|
|
4
|
+
export * from './EllipseNodeModel'
|
|
5
|
+
export * from './PolygonNodeModel'
|
|
6
|
+
export * from './RectNodeModel'
|
|
7
|
+
export * from './TextNodeModel'
|
|
8
|
+
export * from './HtmlNodeModel'
|
package/src/options.ts
CHANGED
package/src/util/theme.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cloneDeep, merge } from 'lodash-es'
|
|
1
|
+
import { cloneDeep, merge, assign } from 'lodash-es'
|
|
2
2
|
import LogicFlow from '../LogicFlow'
|
|
3
3
|
|
|
4
4
|
export const defaultTheme: LogicFlow.Theme = {
|
|
@@ -135,13 +135,178 @@ export const defaultTheme: LogicFlow.Theme = {
|
|
|
135
135
|
strokeDasharray: '3,3',
|
|
136
136
|
},
|
|
137
137
|
}
|
|
138
|
+
export const radiusMode: any = {
|
|
139
|
+
rect: { radius: 8 },
|
|
140
|
+
diamond: { radius: 8 },
|
|
141
|
+
polygon: { radius: 8 },
|
|
142
|
+
polyline: { radius: 8 },
|
|
143
|
+
arrow: {
|
|
144
|
+
strokeLinecap: 'round',
|
|
145
|
+
strokeLinejoin: 'round',
|
|
146
|
+
offset: 10,
|
|
147
|
+
verticalLength: 5, // 箭头垂直于边的距离
|
|
148
|
+
},
|
|
149
|
+
snapline: {
|
|
150
|
+
strokeLinecap: 'round',
|
|
151
|
+
strokeLinejoin: 'round',
|
|
152
|
+
stroke: '#949494',
|
|
153
|
+
strokeWidth: 1,
|
|
154
|
+
},
|
|
155
|
+
outline: {
|
|
156
|
+
radius: 8,
|
|
157
|
+
fill: 'transparent',
|
|
158
|
+
stroke: '#949494',
|
|
159
|
+
strokeDasharray: '3,3',
|
|
160
|
+
hover: {
|
|
161
|
+
stroke: '#949494',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
resizeOutline: {
|
|
165
|
+
radius: 8,
|
|
166
|
+
fill: 'none',
|
|
167
|
+
stroke: 'transparent', // 矩形默认不显示调整边框
|
|
168
|
+
strokeWidth: 1,
|
|
169
|
+
strokeDasharray: '3,3',
|
|
170
|
+
},
|
|
171
|
+
}
|
|
172
|
+
export const darkMode: any = {
|
|
173
|
+
baseNode: {
|
|
174
|
+
fill: '#23272e',
|
|
175
|
+
stroke: '#fefeff',
|
|
176
|
+
},
|
|
177
|
+
baseEdge: {
|
|
178
|
+
stroke: '#fefeff',
|
|
179
|
+
},
|
|
180
|
+
rect: { radius: 8 },
|
|
181
|
+
diamond: { radius: 8 },
|
|
182
|
+
polygon: { radius: 8 },
|
|
183
|
+
polyline: { radius: 8 },
|
|
184
|
+
nodeText: {
|
|
185
|
+
color: '#fefeff',
|
|
186
|
+
overflowMode: 'default',
|
|
187
|
+
fontSize: 12,
|
|
188
|
+
lineHeight: 1.2,
|
|
189
|
+
},
|
|
190
|
+
arrow: {
|
|
191
|
+
strokeLinecap: 'round',
|
|
192
|
+
strokeLinejoin: 'round',
|
|
193
|
+
offset: 10,
|
|
194
|
+
verticalLength: 5, // 箭头垂直于边的距离
|
|
195
|
+
},
|
|
196
|
+
snapline: {
|
|
197
|
+
strokeLinecap: 'round',
|
|
198
|
+
strokeLinejoin: 'round',
|
|
199
|
+
stroke: '#949494',
|
|
200
|
+
strokeWidth: 1,
|
|
201
|
+
},
|
|
202
|
+
outline: {
|
|
203
|
+
radius: 8,
|
|
204
|
+
fill: 'transparent',
|
|
205
|
+
stroke: '#949494',
|
|
206
|
+
strokeDasharray: '3,3',
|
|
207
|
+
hover: {
|
|
208
|
+
stroke: '#949494',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
resizeOutline: {
|
|
212
|
+
radius: 8,
|
|
213
|
+
fill: 'none',
|
|
214
|
+
stroke: 'transparent', // 矩形默认不显示调整边框
|
|
215
|
+
strokeWidth: 1,
|
|
216
|
+
strokeDasharray: '3,3',
|
|
217
|
+
},
|
|
218
|
+
}
|
|
219
|
+
export const colorfulMode: any = {
|
|
220
|
+
rect: { fill: '#72CBFF', stroke: '#3ABDF9', radius: 8 },
|
|
221
|
+
circle: { fill: '#FFE075', stroke: '#F9CE3A', radius: 8 },
|
|
222
|
+
ellipse: { fill: '#FFA8A8', stroke: '#FF6B66', radius: 8 },
|
|
223
|
+
text: { fill: '#72CBFF', radius: 8 },
|
|
224
|
+
diamond: { fill: '#96F7AF', stroke: '#40EF7E', radius: 8 },
|
|
225
|
+
polygon: { fill: '#E0A8FF', stroke: '#C271FF', radius: 8 },
|
|
226
|
+
polyline: { radius: 8 },
|
|
227
|
+
arrow: {
|
|
228
|
+
strokeLinecap: 'round',
|
|
229
|
+
strokeLinejoin: 'round',
|
|
230
|
+
offset: 10,
|
|
231
|
+
verticalLength: 5, // 箭头垂直于边的距离
|
|
232
|
+
},
|
|
233
|
+
snapline: {
|
|
234
|
+
strokeLinecap: 'round',
|
|
235
|
+
strokeLinejoin: 'round',
|
|
236
|
+
stroke: '#949494',
|
|
237
|
+
strokeWidth: 1,
|
|
238
|
+
},
|
|
239
|
+
outline: {
|
|
240
|
+
radius: 8,
|
|
241
|
+
fill: 'transparent',
|
|
242
|
+
stroke: '#949494',
|
|
243
|
+
strokeDasharray: '3,3',
|
|
244
|
+
hover: {
|
|
245
|
+
stroke: '#949494',
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
resizeOutline: {
|
|
249
|
+
radius: 8,
|
|
250
|
+
fill: 'none',
|
|
251
|
+
stroke: 'transparent', // 矩形默认不显示调整边框
|
|
252
|
+
strokeWidth: 1,
|
|
253
|
+
strokeDasharray: '3,3',
|
|
254
|
+
},
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export const themeModeMap = {
|
|
258
|
+
colorful: colorfulMode,
|
|
259
|
+
dark: darkMode,
|
|
260
|
+
radius: radiusMode,
|
|
261
|
+
default: defaultTheme,
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// 不同主题的背景色
|
|
265
|
+
export const darkBackground = {
|
|
266
|
+
background: '#23272e',
|
|
267
|
+
}
|
|
268
|
+
export const colorfulBackground = {
|
|
269
|
+
background: '#fefeff',
|
|
270
|
+
}
|
|
271
|
+
export const defaultBackground = {
|
|
272
|
+
background: '#ffffff',
|
|
273
|
+
}
|
|
274
|
+
export const backgroundModeMap = {
|
|
275
|
+
colorful: colorfulBackground,
|
|
276
|
+
dark: darkBackground,
|
|
277
|
+
radius: defaultBackground,
|
|
278
|
+
default: defaultBackground,
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// 不同主题的网格样式
|
|
282
|
+
export const darkGrid = {
|
|
283
|
+
color: '#66676a',
|
|
284
|
+
thickness: 1,
|
|
285
|
+
}
|
|
286
|
+
export const colorfulGrid = {
|
|
287
|
+
color: '#dadada',
|
|
288
|
+
thickness: 1,
|
|
289
|
+
}
|
|
290
|
+
export const defaultGrid = {
|
|
291
|
+
color: '#acacac',
|
|
292
|
+
thickness: 1,
|
|
293
|
+
}
|
|
294
|
+
export const gridModeMap = {
|
|
295
|
+
colorful: colorfulGrid,
|
|
296
|
+
dark: darkGrid,
|
|
297
|
+
radius: defaultGrid,
|
|
298
|
+
default: defaultGrid,
|
|
299
|
+
}
|
|
138
300
|
|
|
139
301
|
/* 主题(全局样式)相关工具方法 */
|
|
140
302
|
export const setupTheme = (
|
|
141
303
|
customTheme?: Partial<LogicFlow.Theme>,
|
|
304
|
+
themeMode?: 'radius' | 'dark' | 'colorful' | 'default' | string,
|
|
142
305
|
): LogicFlow.Theme => {
|
|
143
306
|
let theme = cloneDeep(defaultTheme)
|
|
144
|
-
|
|
307
|
+
if (themeMode) {
|
|
308
|
+
theme = merge(theme, themeModeMap[themeMode])
|
|
309
|
+
}
|
|
145
310
|
if (customTheme) {
|
|
146
311
|
/**
|
|
147
312
|
* 为了不让默认样式被覆盖,使用 merge 方法
|
|
@@ -172,9 +337,39 @@ export const setupTheme = (
|
|
|
172
337
|
*/
|
|
173
338
|
theme = merge(theme, customTheme)
|
|
174
339
|
}
|
|
175
|
-
|
|
176
340
|
return theme
|
|
177
341
|
}
|
|
178
342
|
|
|
343
|
+
export const addThemeMode = (
|
|
344
|
+
themeMode: string,
|
|
345
|
+
style: Partial<LogicFlow.Theme>,
|
|
346
|
+
): void => {
|
|
347
|
+
if (themeModeMap[themeMode]) {
|
|
348
|
+
console.warn(`theme mode ${themeMode} already exists`)
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
themeModeMap[themeMode] = style
|
|
352
|
+
backgroundModeMap[themeMode] = style.background || defaultBackground
|
|
353
|
+
gridModeMap[themeMode] = style.grid || defaultGrid
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export const removeThemeMode = (themeMode: string): void => {
|
|
357
|
+
delete themeModeMap[themeMode]
|
|
358
|
+
delete backgroundModeMap[themeMode]
|
|
359
|
+
delete gridModeMap[themeMode]
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export const clearThemeMode = (): void => {
|
|
363
|
+
const resetTheme = {
|
|
364
|
+
colorful: {},
|
|
365
|
+
dark: {},
|
|
366
|
+
radius: {},
|
|
367
|
+
default: {},
|
|
368
|
+
}
|
|
369
|
+
assign(themeModeMap, resetTheme)
|
|
370
|
+
assign(backgroundModeMap, resetTheme)
|
|
371
|
+
assign(gridModeMap, resetTheme)
|
|
372
|
+
}
|
|
373
|
+
|
|
179
374
|
/* 更新 theme 方法 */
|
|
180
375
|
export const updateTheme = setupTheme
|