@logicflow/core 2.0.0-beta.1 → 2.0.0-beta.3
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 +8 -8
- package/dist/index.min.js +9 -3
- package/es/LogicFlow.d.ts +37 -20
- package/es/LogicFlow.js +27 -24
- package/es/LogicFlow.js.map +1 -1
- package/es/common/drag.d.ts +51 -0
- package/es/common/drag.js +145 -0
- package/es/common/drag.js.map +1 -0
- package/es/common/history.d.ts +28 -0
- package/es/common/history.js +92 -0
- package/es/common/history.js.map +1 -0
- package/es/common/index.d.ts +5 -0
- package/es/common/index.js +6 -0
- package/es/common/index.js.map +1 -0
- package/es/common/keyboard.d.ts +34 -0
- package/es/common/keyboard.js +80 -0
- package/es/common/keyboard.js.map +1 -0
- package/es/common/matrix.d.ts +30 -0
- package/es/common/matrix.js +155 -0
- package/es/common/matrix.js.map +1 -0
- package/es/common/vector.d.ts +23 -0
- package/es/common/vector.js +97 -0
- package/es/common/vector.js.map +1 -0
- package/es/event/eventEmitter.js +1 -1
- package/es/event/eventEmitter.js.map +1 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/index.js.map +1 -1
- package/es/model/SnaplineModel.d.ts +2 -0
- package/es/model/edge/BaseEdgeModel.d.ts +5 -9
- package/es/model/edge/BaseEdgeModel.js +26 -23
- package/es/model/edge/BaseEdgeModel.js.map +1 -1
- package/es/model/edge/BezierEdgeModel.d.ts +2 -0
- package/es/model/edge/LineEdgeModel.d.ts +2 -0
- package/es/model/edge/PolylineEdgeModel.d.ts +2 -0
- package/es/model/node/BaseNodeModel.js +22 -21
- package/es/model/node/BaseNodeModel.js.map +1 -1
- package/es/model/node/CircleNodeModel.d.ts +2 -0
- package/es/model/node/CircleNodeModel.js +2 -2
- package/es/model/node/CircleNodeModel.js.map +1 -1
- package/es/model/node/DiamondNodeModel.d.ts +2 -0
- package/es/model/node/DiamondNodeModel.js +2 -1
- package/es/model/node/DiamondNodeModel.js.map +1 -1
- package/es/model/node/EllipseNodeModel.d.ts +2 -0
- package/es/model/node/EllipseNodeModel.js +2 -1
- package/es/model/node/EllipseNodeModel.js.map +1 -1
- package/es/model/node/HtmlNodeModel.d.ts +2 -2
- package/es/model/node/HtmlNodeModel.js.map +1 -1
- package/es/model/node/PolygonNodeModel.d.ts +2 -0
- package/es/model/node/PolygonNodeModel.js +2 -2
- package/es/model/node/PolygonNodeModel.js.map +1 -1
- package/es/model/node/RectNodeModel.d.ts +3 -0
- package/es/model/node/RectNodeModel.js +8 -2
- package/es/model/node/RectNodeModel.js.map +1 -1
- package/es/model/node/TextNodeModel.d.ts +4 -2
- package/es/options.d.ts +2 -2
- package/es/options.js +2 -11
- package/es/options.js.map +1 -1
- package/es/tool/tool.js.map +1 -1
- package/es/util/edge.d.ts +6 -0
- package/es/util/edge.js +15 -1
- package/es/util/edge.js.map +1 -1
- package/es/util/node.d.ts +6 -2
- package/es/util/node.js +22 -7
- package/es/util/node.js.map +1 -1
- package/es/view/Anchor.d.ts +1 -1
- package/es/view/Anchor.js +3 -3
- package/es/view/Anchor.js.map +1 -1
- package/es/view/Control.js +14 -2
- package/es/view/Control.js.map +1 -1
- package/es/view/Graph.d.ts +3 -0
- package/es/view/Graph.js +38 -3
- package/es/view/Graph.js.map +1 -1
- package/es/view/edge/AdjustPoint.js +3 -3
- package/es/view/edge/AdjustPoint.js.map +1 -1
- package/es/view/edge/BaseEdge.d.ts +2 -2
- package/es/view/edge/BaseEdge.js +5 -5
- package/es/view/node/BaseNode.d.ts +2 -2
- package/es/view/node/BaseNode.js +5 -5
- package/es/view/node/TextNode.js +1 -1
- package/es/view/node/TextNode.js.map +1 -1
- package/es/view/shape/Circle.d.ts +9 -1
- package/es/view/shape/Circle.js +5 -5
- package/es/view/shape/Circle.js.map +1 -1
- package/es/view/shape/Ellipse.d.ts +10 -1
- package/es/view/shape/Ellipse.js +5 -5
- package/es/view/shape/Ellipse.js.map +1 -1
- package/es/view/shape/Line.d.ts +14 -1
- package/es/view/shape/Line.js +5 -7
- package/es/view/shape/Line.js.map +1 -1
- package/es/view/shape/Path.d.ts +3 -2
- package/es/view/shape/Path.js +3 -3
- package/es/view/shape/Path.js.map +1 -1
- package/es/view/shape/Polygon.d.ts +5 -3
- package/es/view/shape/Polygon.js +6 -6
- package/es/view/shape/Polygon.js.map +1 -1
- package/es/view/shape/Polyline.d.ts +7 -1
- package/es/view/shape/Polyline.js +8 -6
- package/es/view/shape/Polyline.js.map +1 -1
- package/es/view/shape/Rect.d.ts +11 -13
- package/es/view/shape/Rect.js +6 -9
- package/es/view/shape/Rect.js.map +1 -1
- package/es/view/shape/Text.d.ts +19 -1
- package/es/view/shape/Text.js +28 -21
- package/es/view/shape/Text.js.map +1 -1
- package/es/view/text/BaseText.d.ts +12 -15
- package/es/view/text/BaseText.js +37 -27
- package/es/view/text/BaseText.js.map +1 -1
- package/es/view/text/LineText.d.ts +19 -7
- package/es/view/text/LineText.js +62 -54
- package/es/view/text/LineText.js.map +1 -1
- package/lib/LogicFlow.d.ts +37 -20
- package/lib/LogicFlow.js +26 -23
- package/lib/LogicFlow.js.map +1 -1
- package/lib/common/drag.d.ts +51 -0
- package/lib/common/drag.js +148 -0
- package/lib/common/drag.js.map +1 -0
- package/lib/common/history.d.ts +28 -0
- package/lib/common/history.js +95 -0
- package/lib/common/history.js.map +1 -0
- package/lib/common/index.d.ts +5 -0
- package/lib/common/index.js +22 -0
- package/lib/common/index.js.map +1 -0
- package/lib/common/keyboard.d.ts +34 -0
- package/lib/common/keyboard.js +86 -0
- package/lib/common/keyboard.js.map +1 -0
- package/lib/common/matrix.d.ts +30 -0
- package/lib/common/matrix.js +158 -0
- package/lib/common/matrix.js.map +1 -0
- package/lib/common/vector.d.ts +23 -0
- package/lib/common/vector.js +101 -0
- package/lib/common/vector.js.map +1 -0
- package/lib/event/eventEmitter.js +1 -1
- package/lib/event/eventEmitter.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/model/SnaplineModel.d.ts +2 -0
- package/lib/model/edge/BaseEdgeModel.d.ts +5 -9
- package/lib/model/edge/BaseEdgeModel.js +25 -22
- package/lib/model/edge/BaseEdgeModel.js.map +1 -1
- package/lib/model/edge/BezierEdgeModel.d.ts +2 -0
- package/lib/model/edge/LineEdgeModel.d.ts +2 -0
- package/lib/model/edge/PolylineEdgeModel.d.ts +2 -0
- package/lib/model/node/BaseNodeModel.js +21 -20
- package/lib/model/node/BaseNodeModel.js.map +1 -1
- package/lib/model/node/CircleNodeModel.d.ts +2 -0
- package/lib/model/node/CircleNodeModel.js +2 -2
- package/lib/model/node/CircleNodeModel.js.map +1 -1
- package/lib/model/node/DiamondNodeModel.d.ts +2 -0
- package/lib/model/node/DiamondNodeModel.js +2 -1
- package/lib/model/node/DiamondNodeModel.js.map +1 -1
- package/lib/model/node/EllipseNodeModel.d.ts +2 -0
- package/lib/model/node/EllipseNodeModel.js +2 -1
- package/lib/model/node/EllipseNodeModel.js.map +1 -1
- package/lib/model/node/HtmlNodeModel.d.ts +2 -2
- package/lib/model/node/HtmlNodeModel.js.map +1 -1
- package/lib/model/node/PolygonNodeModel.d.ts +2 -0
- package/lib/model/node/PolygonNodeModel.js +2 -2
- package/lib/model/node/PolygonNodeModel.js.map +1 -1
- package/lib/model/node/RectNodeModel.d.ts +3 -0
- package/lib/model/node/RectNodeModel.js +8 -2
- package/lib/model/node/RectNodeModel.js.map +1 -1
- package/lib/model/node/TextNodeModel.d.ts +4 -2
- package/lib/options.d.ts +2 -2
- package/lib/options.js +2 -11
- package/lib/options.js.map +1 -1
- package/lib/tool/tool.js.map +1 -1
- package/lib/util/edge.d.ts +6 -0
- package/lib/util/edge.js +16 -1
- package/lib/util/edge.js.map +1 -1
- package/lib/util/node.d.ts +6 -2
- package/lib/util/node.js +24 -9
- package/lib/util/node.js.map +1 -1
- package/lib/view/Anchor.d.ts +1 -1
- package/lib/view/Anchor.js +2 -2
- package/lib/view/Anchor.js.map +1 -1
- package/lib/view/Control.js +14 -2
- package/lib/view/Control.js.map +1 -1
- package/lib/view/Graph.d.ts +3 -0
- package/lib/view/Graph.js +37 -2
- package/lib/view/Graph.js.map +1 -1
- package/lib/view/edge/AdjustPoint.js +2 -2
- package/lib/view/edge/AdjustPoint.js.map +1 -1
- package/lib/view/edge/BaseEdge.d.ts +2 -2
- package/lib/view/edge/BaseEdge.js +5 -5
- package/lib/view/node/BaseNode.d.ts +2 -2
- package/lib/view/node/BaseNode.js +5 -5
- package/lib/view/node/TextNode.js +1 -1
- package/lib/view/node/TextNode.js.map +1 -1
- package/lib/view/shape/Circle.d.ts +9 -1
- package/lib/view/shape/Circle.js +5 -5
- package/lib/view/shape/Circle.js.map +1 -1
- package/lib/view/shape/Ellipse.d.ts +10 -1
- package/lib/view/shape/Ellipse.js +5 -5
- package/lib/view/shape/Ellipse.js.map +1 -1
- package/lib/view/shape/Line.d.ts +14 -1
- package/lib/view/shape/Line.js +5 -7
- package/lib/view/shape/Line.js.map +1 -1
- package/lib/view/shape/Path.d.ts +3 -2
- package/lib/view/shape/Path.js +3 -3
- package/lib/view/shape/Path.js.map +1 -1
- package/lib/view/shape/Polygon.d.ts +5 -3
- package/lib/view/shape/Polygon.js +6 -6
- package/lib/view/shape/Polygon.js.map +1 -1
- package/lib/view/shape/Polyline.d.ts +7 -1
- package/lib/view/shape/Polyline.js +8 -6
- package/lib/view/shape/Polyline.js.map +1 -1
- package/lib/view/shape/Rect.d.ts +11 -13
- package/lib/view/shape/Rect.js +6 -9
- package/lib/view/shape/Rect.js.map +1 -1
- package/lib/view/shape/Text.d.ts +19 -1
- package/lib/view/shape/Text.js +29 -21
- package/lib/view/shape/Text.js.map +1 -1
- package/lib/view/text/BaseText.d.ts +12 -15
- package/lib/view/text/BaseText.js +40 -27
- package/lib/view/text/BaseText.js.map +1 -1
- package/lib/view/text/LineText.d.ts +19 -7
- package/lib/view/text/LineText.js +62 -57
- package/lib/view/text/LineText.js.map +1 -1
- package/package.json +2 -1
- package/src/LogicFlow.tsx +97 -55
- package/src/common/drag.ts +205 -0
- package/src/common/history.ts +108 -0
- package/src/common/index.ts +6 -0
- package/src/common/keyboard.ts +108 -0
- package/src/common/matrix.ts +122 -0
- package/src/common/vector.ts +93 -0
- package/src/event/eventEmitter.ts +1 -1
- package/src/index.ts +1 -1
- package/src/model/edge/BaseEdgeModel.ts +31 -21
- package/src/model/node/BaseNodeModel.ts +27 -19
- package/src/model/node/CircleNodeModel.ts +2 -2
- package/src/model/node/DiamondNodeModel.ts +2 -0
- package/src/model/node/EllipseNodeModel.ts +2 -0
- package/src/model/node/HtmlNodeModel.ts +2 -2
- package/src/model/node/PolygonNodeModel.ts +2 -2
- package/src/model/node/RectNodeModel.ts +9 -2
- package/src/options.ts +4 -13
- package/src/tool/tool.ts +1 -1
- package/src/util/edge.ts +26 -1
- package/src/util/node.ts +29 -8
- package/src/view/Anchor.tsx +4 -4
- package/src/view/Control.tsx +5 -2
- package/src/view/Graph.tsx +14 -2
- package/src/view/edge/AdjustPoint.tsx +3 -3
- package/src/view/edge/BaseEdge.tsx +7 -7
- package/src/view/node/BaseNode.tsx +7 -7
- package/src/view/node/TextNode.tsx +1 -1
- package/src/view/shape/Circle.tsx +21 -7
- package/src/view/shape/Ellipse.tsx +20 -6
- package/src/view/shape/Line.tsx +24 -9
- package/src/view/shape/Path.tsx +9 -6
- package/src/view/shape/Polygon.tsx +13 -10
- package/src/view/shape/Polyline.tsx +20 -8
- package/src/view/shape/Rect.tsx +19 -19
- package/src/view/shape/Text.tsx +64 -33
- package/src/view/text/BaseText.tsx +67 -41
- package/src/view/text/LineText.tsx +94 -80
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import Mousetrap, { MousetrapInstance } from 'mousetrap'
|
|
2
|
+
import { forEach, isArray } from 'lodash-es'
|
|
3
|
+
import LogicFlow from '..'
|
|
4
|
+
|
|
5
|
+
export class Keyboard {
|
|
6
|
+
private target: HTMLElement
|
|
7
|
+
readonly mousetrap: MousetrapInstance
|
|
8
|
+
options: Required<Keyboard.Options>
|
|
9
|
+
|
|
10
|
+
constructor(options: Keyboard.Options) {
|
|
11
|
+
const { lf } = options
|
|
12
|
+
if (!options.keyboard) {
|
|
13
|
+
options.keyboard = { enabled: false }
|
|
14
|
+
}
|
|
15
|
+
this.options = options as Required<Keyboard.Options>
|
|
16
|
+
this.target = lf.container
|
|
17
|
+
this.mousetrap = new Mousetrap(this.target)
|
|
18
|
+
|
|
19
|
+
if (options.keyboard?.enabled) {
|
|
20
|
+
this.enable(true)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected formatKey(key: string) {
|
|
25
|
+
return key
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/\s/g, '')
|
|
28
|
+
.replace('delete', 'del')
|
|
29
|
+
.replace('cmd', 'command')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private getKeys(keys: string | string[]) {
|
|
33
|
+
return (isArray(keys) ? keys : [keys]).map((key) => this.formatKey(key))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get disabled() {
|
|
37
|
+
return this.options.keyboard?.enabled !== true
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
on(
|
|
41
|
+
keys: string | string[],
|
|
42
|
+
callback: Keyboard.HandlerFunc,
|
|
43
|
+
action?: Keyboard.ActionType,
|
|
44
|
+
) {
|
|
45
|
+
this.mousetrap.bind(this.getKeys(keys), callback, action)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
off(keys: string | string[], action?: Keyboard.ActionType) {
|
|
49
|
+
this.mousetrap.unbind(this.getKeys(keys), action)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
enable(force: boolean) {
|
|
53
|
+
if (this.disabled || force) {
|
|
54
|
+
this.options.keyboard.enabled = true
|
|
55
|
+
if (this.target instanceof HTMLElement) {
|
|
56
|
+
this.target.setAttribute('tabindex', '-1')
|
|
57
|
+
// 去掉节点被选中时 container 出现的边框
|
|
58
|
+
this.target.style.outline = 'none'
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
disable() {
|
|
64
|
+
if (!this.disabled) {
|
|
65
|
+
this.options.keyboard.enabled = false
|
|
66
|
+
if (this.target instanceof HTMLElement) {
|
|
67
|
+
this.target.removeAttribute('tabindex')
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
initShortcuts() {
|
|
73
|
+
const { shortcuts } = this.options.keyboard
|
|
74
|
+
if (shortcuts) {
|
|
75
|
+
if (isArray(shortcuts)) {
|
|
76
|
+
forEach(shortcuts, ({ keys, callback, action }) => {
|
|
77
|
+
this.on(keys, callback, action)
|
|
78
|
+
})
|
|
79
|
+
} else {
|
|
80
|
+
const { keys, callback, action } = shortcuts
|
|
81
|
+
this.on(keys, callback, action)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export namespace Keyboard {
|
|
88
|
+
export type ActionType = 'keypress' | 'keydown' | 'keyup'
|
|
89
|
+
export type HandlerFunc = (e: KeyboardEvent) => void
|
|
90
|
+
|
|
91
|
+
export interface Shortcut {
|
|
92
|
+
keys: string | string[]
|
|
93
|
+
callback: HandlerFunc
|
|
94
|
+
action?: ActionType
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface KeyboardDef {
|
|
98
|
+
enabled: boolean
|
|
99
|
+
shortcuts?: Shortcut | Shortcut[]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface Options {
|
|
103
|
+
lf: LogicFlow
|
|
104
|
+
keyboard?: KeyboardDef
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export default Keyboard
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Vector } from './vector'
|
|
2
|
+
|
|
3
|
+
export class Matrix extends Array {
|
|
4
|
+
rows: number
|
|
5
|
+
columns: number
|
|
6
|
+
|
|
7
|
+
constructor(...vectors: any[]) {
|
|
8
|
+
super(vectors.length)
|
|
9
|
+
this.fill(new Array(3))
|
|
10
|
+
vectors.forEach((v: any, index: number) => {
|
|
11
|
+
this[index] = v
|
|
12
|
+
})
|
|
13
|
+
this.columns = vectors[0].length
|
|
14
|
+
this.rows = vectors.length
|
|
15
|
+
Object.setPrototypeOf(this, Matrix.prototype)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getRow(index: number) {
|
|
19
|
+
return this[index]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getColumn(index: number) {
|
|
23
|
+
return [...this.map((row: number[]) => row[index])]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 转置
|
|
27
|
+
transpose() {
|
|
28
|
+
const rows: any[] = []
|
|
29
|
+
for (let i = 0; i < this.columns; i++) {
|
|
30
|
+
rows.push(this.getColumn(i))
|
|
31
|
+
}
|
|
32
|
+
return new Matrix(...rows)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 叉乘
|
|
36
|
+
cross(m1: Matrix) {
|
|
37
|
+
const arr = new Array(this.rows).fill('').map((): any => [])
|
|
38
|
+
if (this.columns === m1.rows) {
|
|
39
|
+
for (let i = 0; i < this.rows; i++) {
|
|
40
|
+
const row = this.getRow(i)
|
|
41
|
+
for (let j = 0; j < m1.columns; j++) {
|
|
42
|
+
const column = m1.getColumn(j)
|
|
43
|
+
arr[i][j] = row.reduce(
|
|
44
|
+
(prev: number, r: number, index: number) =>
|
|
45
|
+
prev + r * column[index],
|
|
46
|
+
0,
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return new Matrix(...arr)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 返回二维坐标(降维)
|
|
55
|
+
to2D() {
|
|
56
|
+
return this.map((item: any) => [item[0], item[1]])
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
toString(): string {
|
|
60
|
+
const [[a, b], [c, d], [e, f]] = this
|
|
61
|
+
return `matrix(${a} ${b} ${c} ${d} ${e} ${f})`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
translate(tx: number, ty: number): Matrix {
|
|
65
|
+
return this.cross(new TranslateMatrix(tx, ty))
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
rotate(angle: number): Matrix {
|
|
69
|
+
return this.cross(new RotateMatrix(angle))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
scale(sx: number, sy: number): Matrix {
|
|
73
|
+
return this.cross(new ScaleMatrix(sx, sy))
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export class RotateMatrix extends Matrix {
|
|
78
|
+
constructor(theta: number) {
|
|
79
|
+
super(
|
|
80
|
+
new Vector(+Math.cos(theta).toFixed(2), +Math.sin(theta).toFixed(2), 0),
|
|
81
|
+
new Vector(-Math.sin(theta).toFixed(2), +Math.cos(theta).toFixed(2), 0),
|
|
82
|
+
new Vector(0, 0, 1),
|
|
83
|
+
)
|
|
84
|
+
Object.setPrototypeOf(this, RotateMatrix.prototype)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
inverse() {
|
|
88
|
+
return this.transpose()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export class ScaleMatrix extends Matrix {
|
|
93
|
+
private readonly sx: number
|
|
94
|
+
private readonly sy: number
|
|
95
|
+
|
|
96
|
+
constructor(sx: number, sy: number) {
|
|
97
|
+
super(new Vector(sx, 0, 0), new Vector(0, sy, 0), new Vector(0, 0, 1))
|
|
98
|
+
this.sx = sx
|
|
99
|
+
this.sy = sy
|
|
100
|
+
Object.setPrototypeOf(this, ScaleMatrix.prototype)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
inverse() {
|
|
104
|
+
return new ScaleMatrix(1 / this.sx, 1 / this.sy)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export class TranslateMatrix extends Matrix {
|
|
109
|
+
private readonly tx: number
|
|
110
|
+
private readonly ty: number
|
|
111
|
+
|
|
112
|
+
constructor(tx: number, ty: number) {
|
|
113
|
+
super(new Vector(1, 0, 0), new Vector(0, 1, 0), new Vector(tx, ty, 1))
|
|
114
|
+
this.tx = tx
|
|
115
|
+
this.ty = ty
|
|
116
|
+
Object.setPrototypeOf(this, TranslateMatrix.prototype)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
inverse() {
|
|
120
|
+
return new TranslateMatrix(-this.tx, -this.ty)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
function isVector(a1: any, a2: any): boolean {
|
|
2
|
+
return a1 instanceof Vector && a2 instanceof Vector
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
class Base extends Array {
|
|
6
|
+
x: number
|
|
7
|
+
y: number
|
|
8
|
+
z: number
|
|
9
|
+
|
|
10
|
+
constructor(x: number, y: number, z: number) {
|
|
11
|
+
super(3)
|
|
12
|
+
this[0] = x
|
|
13
|
+
this[1] = y
|
|
14
|
+
this[2] = z
|
|
15
|
+
this.x = x
|
|
16
|
+
this.y = y
|
|
17
|
+
this.z = z
|
|
18
|
+
Object.setPrototypeOf(this, Base.prototype)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
add(v1: Vector | Point): Vector | Point {
|
|
22
|
+
if (isVector(this, v1)) {
|
|
23
|
+
return new Vector(this.x + v1.x, this.y + v1.y)
|
|
24
|
+
}
|
|
25
|
+
const z = this.z + v1.z
|
|
26
|
+
return new Point((this.x + v1.x) / z, (this.y + v1.y) / z)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
subtract(v1: Vector | Point): Vector | Point {
|
|
30
|
+
if (isVector(this, v1)) {
|
|
31
|
+
return new Vector(this.x - v1.x, this.y - v1.y)
|
|
32
|
+
}
|
|
33
|
+
const z = this.z - v1.z
|
|
34
|
+
return z === 0
|
|
35
|
+
? new Vector(this.x - v1.x, this.y - v1.y)
|
|
36
|
+
: new Point((this.x - v1.x) / z, (this.y - v1.y) / z)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class Vector extends Base {
|
|
41
|
+
constructor(x: number, y: number, z?: number) {
|
|
42
|
+
super(x, y, z ?? 0)
|
|
43
|
+
Object.setPrototypeOf(this, Vector.prototype)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
toString(): string {
|
|
47
|
+
return 'Vector'
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dot(v1: Vector) {
|
|
51
|
+
return v1.reduce((prev, cur, index) => prev + cur * this[index])
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
cross(v1: Vector) {
|
|
55
|
+
return new Vector(
|
|
56
|
+
this.y * v1.z - this.z * v1.y,
|
|
57
|
+
this.z * v1.x - this.x * v1.z,
|
|
58
|
+
this.x * v1.y - this.y * v1.x,
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getLength() {
|
|
63
|
+
return Math.hypot(this.x, this.y)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
normalize() {
|
|
67
|
+
const len = this.getLength()
|
|
68
|
+
return new Vector(this.x / len, this.y / len)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
crossZ(v1: Vector) {
|
|
72
|
+
return this.x * v1.y - this.y * v1.x
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
angle(v1: Vector) {
|
|
76
|
+
const negative = this.crossZ(v1)
|
|
77
|
+
const r = Math.acos(this.normalize().dot(v1.normalize()))
|
|
78
|
+
return negative >= 0 ? r : -r
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class Point extends Base {
|
|
83
|
+
constructor(x: number, y: number) {
|
|
84
|
+
super(x, y, 1)
|
|
85
|
+
Object.setPrototypeOf(this, Point.prototype)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
toString(): string {
|
|
89
|
+
return 'Point'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { Vector, Point }
|
|
@@ -77,7 +77,7 @@ export default class EventEmitter {
|
|
|
77
77
|
emit(evts: string, eventArgs: EventCallback) {
|
|
78
78
|
evts?.split(',').forEach((evt) => {
|
|
79
79
|
const events = this._events[evt] || []
|
|
80
|
-
// TODO: 这是什么???
|
|
80
|
+
// TODO: 这是什么??? +1
|
|
81
81
|
const wildcardEvents = this._events[WILDCARD] || []
|
|
82
82
|
// 实际的处理 emit 方法
|
|
83
83
|
const doEmit = (es: EventType[]) => {
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,6 @@ export * from './options'
|
|
|
16
16
|
export * from './keyboard'
|
|
17
17
|
export { ElementState, ModelType, ElementType, EventType } from './constant'
|
|
18
18
|
|
|
19
|
-
export {
|
|
19
|
+
export { formatAnchorConnectValidateData } from './util/node'
|
|
20
20
|
|
|
21
21
|
export default LogicFlow
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assign, cloneDeep, find } from 'lodash-es'
|
|
1
|
+
import { assign, cloneDeep, find, isUndefined } from 'lodash-es'
|
|
2
2
|
import { action, computed, observable, toJS } from 'mobx'
|
|
3
3
|
import { BaseNodeModel, GraphModel, Model } from '..'
|
|
4
4
|
import LogicFlow from '../../LogicFlow'
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import Point = LogicFlow.Point
|
|
21
21
|
import EdgeData = LogicFlow.EdgeData
|
|
22
22
|
import EdgeConfig = LogicFlow.EdgeConfig
|
|
23
|
+
import TextConfig = LogicFlow.TextConfig
|
|
23
24
|
|
|
24
25
|
export interface IBaseEdgeModel extends Model.BaseModel {
|
|
25
26
|
/**
|
|
@@ -56,7 +57,7 @@ export class BaseEdgeModel implements IBaseEdgeModel {
|
|
|
56
57
|
@observable startPoint!: Point
|
|
57
58
|
@observable endPoint!: Point
|
|
58
59
|
|
|
59
|
-
@observable text = {
|
|
60
|
+
@observable text: Required<TextConfig> = {
|
|
60
61
|
value: '',
|
|
61
62
|
x: 0,
|
|
62
63
|
y: 0,
|
|
@@ -431,8 +432,7 @@ export class BaseEdgeModel implements IBaseEdgeModel {
|
|
|
431
432
|
|
|
432
433
|
/**
|
|
433
434
|
* 设置边的属性,会触发重新渲染
|
|
434
|
-
* @param
|
|
435
|
-
* @param val 属性值
|
|
435
|
+
* @param properties 要更新的 properties,会做合并
|
|
436
436
|
*/
|
|
437
437
|
@action
|
|
438
438
|
setProperties(properties: Record<string, any>): void {
|
|
@@ -497,28 +497,38 @@ export class BaseEdgeModel implements IBaseEdgeModel {
|
|
|
497
497
|
* 内部方法,处理初始化文本格式
|
|
498
498
|
*/
|
|
499
499
|
@action formatText(data: EdgeConfig) {
|
|
500
|
-
// 暂时处理,只传入text的情况
|
|
501
500
|
const { x, y } = this.textPosition
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
return
|
|
501
|
+
const { text } = data
|
|
502
|
+
let textConfig: Required<TextConfig> = {
|
|
503
|
+
value: '',
|
|
504
|
+
x,
|
|
505
|
+
y,
|
|
506
|
+
draggable: false,
|
|
507
|
+
editable: true,
|
|
511
508
|
}
|
|
512
509
|
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
510
|
+
if (text) {
|
|
511
|
+
if (typeof text === 'string') {
|
|
512
|
+
textConfig = {
|
|
513
|
+
...textConfig,
|
|
514
|
+
value: text,
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
textConfig = {
|
|
518
|
+
...textConfig,
|
|
519
|
+
x: text.x ?? x,
|
|
520
|
+
y: text.y ?? y,
|
|
521
|
+
value: text.value ?? '',
|
|
522
|
+
}
|
|
523
|
+
if (!isUndefined(text.draggable)) {
|
|
524
|
+
textConfig.draggable = text.draggable
|
|
525
|
+
}
|
|
526
|
+
if (!isUndefined(text.editable)) {
|
|
527
|
+
textConfig.editable = text.editable
|
|
528
|
+
}
|
|
520
529
|
}
|
|
521
530
|
}
|
|
531
|
+
this.text = textConfig
|
|
522
532
|
}
|
|
523
533
|
|
|
524
534
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { action, computed, isObservable, observable, toJS } from 'mobx'
|
|
2
|
-
import { assign, cloneDeep, has, isNil, mapKeys } from 'lodash-es'
|
|
2
|
+
import { assign, cloneDeep, has, isNil, isUndefined, mapKeys } from 'lodash-es'
|
|
3
3
|
import { GraphModel, Model } from '..'
|
|
4
4
|
import LogicFlow from '../../LogicFlow'
|
|
5
5
|
import {
|
|
@@ -186,6 +186,7 @@ export class BaseNodeModel implements IBaseNodeModel {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
this.formatText(data)
|
|
189
|
+
// 在下面又将 NodeConfig 中的数据赋值给了 this,应该会触发 setAttributes,确认是否符合预期
|
|
189
190
|
assign(this, pickNodeConfig(data)) // TODO: 确认 constructor 中赋值 properties 是否必要
|
|
190
191
|
const { overlapMode } = this.graphModel
|
|
191
192
|
if (overlapMode === OverlapMode.INCREASE) {
|
|
@@ -219,27 +220,34 @@ export class BaseNodeModel implements IBaseNodeModel {
|
|
|
219
220
|
* 始化文本属性
|
|
220
221
|
*/
|
|
221
222
|
private formatText(data: NodeConfig): void {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if (typeof
|
|
232
|
-
|
|
233
|
-
value: data.text,
|
|
234
|
-
x: data.x,
|
|
235
|
-
y: data.y,
|
|
236
|
-
draggable: false,
|
|
237
|
-
editable: true,
|
|
238
|
-
}
|
|
223
|
+
const { x, y, text } = data
|
|
224
|
+
let textConfig: TextConfig = {
|
|
225
|
+
value: '',
|
|
226
|
+
x,
|
|
227
|
+
y,
|
|
228
|
+
draggable: false,
|
|
229
|
+
editable: true,
|
|
230
|
+
}
|
|
231
|
+
if (text) {
|
|
232
|
+
if (typeof text === 'string') {
|
|
233
|
+
textConfig.value = text
|
|
239
234
|
} else {
|
|
240
|
-
|
|
235
|
+
textConfig = {
|
|
236
|
+
...textConfig,
|
|
237
|
+
x: text.x ?? x,
|
|
238
|
+
y: text.y ?? y,
|
|
239
|
+
value: text.value ?? '',
|
|
240
|
+
}
|
|
241
|
+
if (!isUndefined(text.draggable)) {
|
|
242
|
+
textConfig.draggable = text.draggable
|
|
243
|
+
}
|
|
244
|
+
if (!isUndefined(text.editable)) {
|
|
245
|
+
textConfig.draggable = text.draggable
|
|
246
|
+
}
|
|
241
247
|
}
|
|
242
248
|
}
|
|
249
|
+
|
|
250
|
+
data.text = textConfig
|
|
243
251
|
}
|
|
244
252
|
|
|
245
253
|
/**
|
|
@@ -54,11 +54,11 @@ export class CircleNodeModel extends BaseNodeModel {
|
|
|
54
54
|
theme: { circle },
|
|
55
55
|
},
|
|
56
56
|
} = this
|
|
57
|
-
const { style: customStyle } = this.properties
|
|
57
|
+
const { style: customStyle = {} } = this.properties
|
|
58
58
|
return {
|
|
59
59
|
...style,
|
|
60
|
-
...(customStyle ?? {}),
|
|
61
60
|
...cloneDeep(circle),
|
|
61
|
+
...cloneDeep(customStyle),
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -7,7 +7,7 @@ import { observable } from 'mobx'
|
|
|
7
7
|
import LogicFlow from '../../LogicFlow'
|
|
8
8
|
import GraphModel from '../GraphModel'
|
|
9
9
|
|
|
10
|
-
export type
|
|
10
|
+
export type IHtmlNodeProperties = {
|
|
11
11
|
width?: number
|
|
12
12
|
height?: number
|
|
13
13
|
style?: LogicFlow.CommonTheme
|
|
@@ -18,7 +18,7 @@ export type IHtmlNodeModel = {
|
|
|
18
18
|
|
|
19
19
|
export class HtmlNodeModel extends BaseNodeModel {
|
|
20
20
|
modelType = ModelType.HTML_NODE
|
|
21
|
-
@observable properties:
|
|
21
|
+
@observable properties: IHtmlNodeProperties = {}
|
|
22
22
|
|
|
23
23
|
constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) {
|
|
24
24
|
super(data, graphModel)
|
|
@@ -66,11 +66,11 @@ export class PolygonNodeModel extends BaseNodeModel {
|
|
|
66
66
|
theme: { polygon },
|
|
67
67
|
},
|
|
68
68
|
} = this
|
|
69
|
-
const { style: customStyle } = this.properties
|
|
69
|
+
const { style: customStyle = {} } = this.properties
|
|
70
70
|
return {
|
|
71
71
|
...style,
|
|
72
72
|
...cloneDeep(polygon),
|
|
73
|
-
...
|
|
73
|
+
...cloneDeep(customStyle),
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -8,6 +8,7 @@ import { ModelType } from '../../constant'
|
|
|
8
8
|
export type IRectNodeModel = {
|
|
9
9
|
width?: number
|
|
10
10
|
height?: number
|
|
11
|
+
radius?: number
|
|
11
12
|
style?: LogicFlow.CommonTheme
|
|
12
13
|
textStyle?: LogicFlow.CommonTheme
|
|
13
14
|
|
|
@@ -21,17 +22,21 @@ export class RectNodeModel extends BaseNodeModel {
|
|
|
21
22
|
|
|
22
23
|
constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) {
|
|
23
24
|
super(data, graphModel)
|
|
24
|
-
this.properties = data.properties || {}
|
|
25
25
|
|
|
26
|
+
// TODO:类字段初始化会覆盖 super、setAttributes 中设置的属性
|
|
27
|
+
this.properties = data.properties || {}
|
|
28
|
+
// TODO: bug here, 上面更新 properties 会触发 setAttributes,下面再主动调用,会导致触发两次
|
|
26
29
|
this.setAttributes()
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
setAttributes() {
|
|
30
33
|
super.setAttributes()
|
|
31
34
|
|
|
32
|
-
const { width, height } = this.properties
|
|
35
|
+
const { width, height, radius } = this.properties
|
|
33
36
|
if (width) this.width = width
|
|
34
37
|
if (height) this.height = height
|
|
38
|
+
// 矩形特有
|
|
39
|
+
if (radius) this.radius = radius
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
getDefaultAnchor() {
|
|
@@ -47,9 +52,11 @@ export class RectNodeModel extends BaseNodeModel {
|
|
|
47
52
|
getNodeStyle() {
|
|
48
53
|
const style = super.getNodeStyle()
|
|
49
54
|
const { rect } = this.graphModel.theme
|
|
55
|
+
const { style: customStyle = {} } = this.properties
|
|
50
56
|
return {
|
|
51
57
|
...style,
|
|
52
58
|
...cloneDeep(rect),
|
|
59
|
+
...cloneDeep(customStyle),
|
|
53
60
|
}
|
|
54
61
|
}
|
|
55
62
|
}
|
package/src/options.ts
CHANGED
|
@@ -10,8 +10,8 @@ import GridOptions = Grid.GridOptions
|
|
|
10
10
|
export namespace Options {
|
|
11
11
|
import NodeData = LogicFlow.NodeData
|
|
12
12
|
import EdgeData = LogicFlow.EdgeData
|
|
13
|
-
import ExtensionConstructor = LogicFlow.ExtensionConstructor
|
|
14
13
|
import GraphData = LogicFlow.GraphData
|
|
14
|
+
import ExtensionType = LogicFlow.ExtensionType
|
|
15
15
|
export type EdgeType = 'line' | 'polyline' | 'bezier' | string
|
|
16
16
|
export type BackgroundConfig = {
|
|
17
17
|
// 背景图片地址
|
|
@@ -88,7 +88,7 @@ export namespace Options {
|
|
|
88
88
|
guards?: GuardsConfig
|
|
89
89
|
overlapMode?: OverlapMode
|
|
90
90
|
|
|
91
|
-
plugins?:
|
|
91
|
+
plugins?: ExtensionType[]
|
|
92
92
|
pluginsOptions?: Record<string, any>
|
|
93
93
|
disabledPlugins?: string[]
|
|
94
94
|
disabledTools?: string[]
|
|
@@ -111,22 +111,13 @@ export namespace Options {
|
|
|
111
111
|
export function get(options: Partial<Manual>) {
|
|
112
112
|
const { ...others } = options
|
|
113
113
|
const container = options.container
|
|
114
|
-
if (container
|
|
115
|
-
if (options.width == null) {
|
|
116
|
-
others.width = container.clientWidth
|
|
117
|
-
}
|
|
118
|
-
if (options.height == null) {
|
|
119
|
-
others.height = container.clientHeight
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
114
|
+
if (!container) {
|
|
122
115
|
throw new Error(
|
|
123
116
|
'Ensure the container of LogicFlow is specified and valid.',
|
|
124
117
|
)
|
|
125
118
|
}
|
|
126
119
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return result
|
|
120
|
+
return assign({}, defaults, others) as Options.Definition
|
|
130
121
|
}
|
|
131
122
|
}
|
|
132
123
|
|
package/src/tool/tool.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { VNode } from 'preact'
|
|
|
3
3
|
import TextEdit from './TextEditTool'
|
|
4
4
|
import MultipleSelect from './MultipleSelectTool'
|
|
5
5
|
import LogicFlow from '../LogicFlow'
|
|
6
|
-
import { GraphModel, BaseEdgeModel, BaseNodeModel } from '../model'
|
|
7
6
|
import { ElementState, EventType } from '../constant'
|
|
7
|
+
import { GraphModel, BaseEdgeModel, BaseNodeModel } from '../model'
|
|
8
8
|
|
|
9
9
|
export type IToolProps = {
|
|
10
10
|
textEditElement?: BaseNodeModel | BaseEdgeModel
|