Skip to content

Commit fa9f126

Browse files
committed
docs: add feature-examples DEMO 项目,用于汇总所有官方 demo,后续再 docs 中使用
1 parent 6be5a2c commit fa9f126

35 files changed

+1769
-0
lines changed

Diff for: examples/feature-examples/.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/node_modules
2+
/.env.local
3+
/.umirc.local.ts
4+
/config/config.local.ts
5+
/src/.umi
6+
/src/.umi-production
7+
/src/.umi-test
8+
/dist
9+
.swc

Diff for: examples/feature-examples/.umirc.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { defineConfig } from 'umi'
2+
3+
export default defineConfig({
4+
routes: [
5+
{
6+
path: '/',
7+
component: './graph',
8+
name: 'graph',
9+
},
10+
{
11+
path: '/native-nodes',
12+
component: './nodes/native',
13+
name: 'native nodes',
14+
},
15+
{
16+
path: '/custom-nodes',
17+
name: 'custom nodes',
18+
routes: [
19+
{ path: 'custom-nodes', redirect: 'custom-nodes/rect' },
20+
{
21+
path: '/custom-nodes/rect',
22+
name: '矩形节点',
23+
component: './nodes/custom/Rect',
24+
},
25+
{
26+
path: '/custom-nodes/ellipse',
27+
name: '椭圆节点',
28+
component: './nodes/custom/Ellipse',
29+
},
30+
{
31+
path: '/custom-nodes/icon',
32+
name: '图标节点',
33+
component: './nodes/custom/Icon',
34+
},
35+
{
36+
path: '/custom-nodes/image',
37+
name: '图像节点',
38+
component: './nodes/custom/Image',
39+
},
40+
{
41+
path: '/custom-nodes/html',
42+
name: 'HTML节点',
43+
component: './nodes/custom/Html',
44+
},
45+
{
46+
path: '/custom-nodes/theme',
47+
name: '自定义主题',
48+
component: './nodes/custom/Theme',
49+
},
50+
],
51+
},
52+
],
53+
npmClient: 'pnpm',
54+
})

Diff for: examples/feature-examples/package.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"private": true,
3+
"name": "@logicflow/feature-examples",
4+
"author": "boyongjiong <[email protected]>",
5+
"scripts": {
6+
"dev": "umi dev",
7+
"build": "umi build",
8+
"postinstall": "umi setup",
9+
"setup": "umi setup",
10+
"start": "npm run dev"
11+
},
12+
"dependencies": {
13+
"@ant-design/icons": "^5.0.1",
14+
"@ant-design/pro-layout": "^7.19.0",
15+
"@logicflow/core": "workspace:latest",
16+
"@logicflow/engine": "workspace:latest",
17+
"@logicflow/extension": "workspace:latest",
18+
"antd": "^5.4.0",
19+
"umi": "^4.2.1"
20+
},
21+
"devDependencies": {
22+
"@types/react": "^18.0.33",
23+
"@types/react-dom": "^18.0.11",
24+
"typescript": "^5.0.3"
25+
}
26+
}

Diff for: examples/feature-examples/src/assets/yay.jpg

177 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { EllipseNode, EllipseNodeModel, LogicFlow } from '@logicflow/core'
2+
import { cloneDeep } from 'lodash-es'
3+
4+
export type CustomProperties = {
5+
// 形状属性
6+
rx?: number
7+
ry?: number
8+
9+
// 文字位置属性
10+
refX?: number
11+
refY?: number
12+
13+
// 样式属性
14+
style?: LogicFlow.CommonTheme
15+
textStyle?: LogicFlow.TextNodeTheme
16+
}
17+
18+
class CustomEllipseNode extends EllipseNode {}
19+
20+
class CustomEllipseNodeModel extends EllipseNodeModel {
21+
setAttributes() {
22+
const { rx, ry } = this.properties as CustomProperties
23+
if (rx) {
24+
this.rx = rx
25+
}
26+
if (ry) {
27+
this.ry = ry
28+
}
29+
}
30+
31+
getTextStyle(): LogicFlow.TextNodeTheme {
32+
// const { x, y, width, height } = this
33+
const {
34+
refX = 0,
35+
refY = 0,
36+
textStyle,
37+
} = this.properties as CustomProperties
38+
const style = super.getTextStyle()
39+
40+
// 通过 transform 重新设置 text 的位置
41+
return {
42+
...style,
43+
...(cloneDeep(textStyle) || {}),
44+
transform: `matrix(1 0 0 1 ${refX} ${refY})`,
45+
}
46+
}
47+
48+
getNodeStyle(): LogicFlow.CommonTheme {
49+
const style = super.getNodeStyle()
50+
const { style: customNodeStyle } = this.properties as CustomProperties
51+
52+
return {
53+
...style,
54+
...(cloneDeep(customNodeStyle) || {}),
55+
}
56+
}
57+
}
58+
59+
export default {
60+
type: 'customEllipse',
61+
view: CustomEllipseNode,
62+
model: CustomEllipseNodeModel,
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { HtmlNode, HtmlNodeModel, LogicFlow } from '@logicflow/core'
2+
3+
export type CustomProperties = {
4+
// 形状属性
5+
width?: number
6+
height?: number
7+
radius?: number
8+
9+
// 样式属性
10+
style?: LogicFlow.CommonTheme
11+
textStyle?: LogicFlow.TextNodeTheme
12+
}
13+
14+
class CustomHtmlNode extends HtmlNode {
15+
setHtml(rootEl: HTMLElement) {
16+
const { properties } = this.props.model
17+
18+
const el = document.createElement('div')
19+
el.className = 'uml-wrapper'
20+
el.innerHTML = `
21+
<div>
22+
<div class="uml-head">Head</div>
23+
<div class="uml-body">
24+
<div><button class="uml-btn" onclick="setData()">+</button> ${properties.name}</div>
25+
<div>${properties.body}</div>
26+
</div>
27+
<div class="uml-footer">
28+
<div>setHead(Head $head)</div>
29+
<div>setBody(Body $body)</div>
30+
</div>
31+
</div>
32+
`
33+
rootEl.innerHTML = ''
34+
rootEl.appendChild(el)
35+
36+
// @ts-ignore
37+
window.setData = () => {
38+
const { graphModel, model } = this.props
39+
graphModel.eventCenter.emit('custom:button-click', model)
40+
}
41+
}
42+
}
43+
44+
class CustomHtmlNodeModel extends HtmlNodeModel {
45+
setAttributes() {
46+
console.log('this.properties', this.properties)
47+
const { width, height, radius } = this.properties as CustomProperties
48+
this.width = width || 300
49+
this.height = height || 150
50+
this.text.editable = false
51+
if (radius) {
52+
this.radius = radius
53+
}
54+
}
55+
}
56+
57+
export default {
58+
type: 'customHtml',
59+
view: CustomHtmlNode,
60+
model: CustomHtmlNodeModel,
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { LogicFlow, RectNode, RectNodeModel, h } from '@logicflow/core'
2+
import { cloneDeep } from 'lodash-es'
3+
4+
export type CustomProperties = {
5+
// 形状属性
6+
width?: number
7+
height?: number
8+
radius?: number
9+
10+
// 文字位置属性
11+
refX?: number
12+
refY?: number
13+
14+
// 样式属性
15+
style?: LogicFlow.CommonTheme
16+
textStyle?: LogicFlow.TextNodeTheme
17+
}
18+
19+
class CustomIconNode extends RectNode {
20+
getCustomIcon = (): h.JSX.Element => {
21+
const { model } = this.props
22+
const { x, y, width, height } = model
23+
console.log('model.modelType', model.modelType)
24+
const style = model.getNodeStyle()
25+
26+
// TODO: 目前没办法自适应 path 的大小,path 与 width、height 需要同步
27+
return h(
28+
'svg',
29+
{
30+
x: x - width / 2,
31+
y: y - height / 2,
32+
width,
33+
height,
34+
viewBox: `0 0 ${width} ${height}`,
35+
},
36+
[
37+
h('circle', {
38+
cx: '50%',
39+
cy: '50%',
40+
r: '50%',
41+
fill: 'white',
42+
}),
43+
h('path', {
44+
d: style.path,
45+
fill: style.fill,
46+
stroke: style.stroke,
47+
// d: 'M 0 5 10 0 C 20 0 20 20 10 20 L 0 15 Z',
48+
// d: 'M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z',
49+
// d: 'M690.366075 350.568358c0-98.876614-79.937349-179.048571-178.558027-179.048571-98.59935 0-178.515371 80.150629-178.515371 179.048571 0 98.833958 79.916021 178.963259 178.515371 178.963259C610.428726 529.531617 690.366075 449.380988 690.366075 350.568358M376.140632 350.568358c0-75.159877 60.72082-136.072649 135.667416-136.072649 74.989253 0 135.667416 60.912772 135.667416 136.072649 0 75.117221-60.678164 136.029993-135.667416 136.029993C436.861451 486.577022 376.140632 425.664251 376.140632 350.568358M197.284012 762.923936 197.284012 778.472049l15.526785 0 291.255186 0.127968L819.784387 778.472049l15.569441 0 0-15.548113c0-139.783721-136.413897-285.581938-311.026243-273.275681-10.002833 0.703824-24.740482 9.128385-34.658002 9.938849-8.573857 0.74648 13.692577 8.232609 14.396401 16.827793 9.021745-0.789136 6.313088 13.095393 15.505457 13.095393 150.597017 0 263.14488 103.07823 263.14488 224.62651l15.441473-15.590769-285.816546-0.042656-278.991585 1.81288 15.526785 15.612097c0-82.752645 75.095893-152.70849 136.861785-191.824044 7.25152-4.58552 8.659169-17.659585 4.862784-22.906273-6.846288-9.426977-19.877697-8.701825-28.046322-6.014496C285.262018 560.521203 197.284012 667.758394 197.284012 762.923936',
50+
}),
51+
],
52+
)
53+
}
54+
55+
getShape = (): h.JSX.Element => {
56+
const { model } = this.props
57+
const { x, y, width, height, radius } = model
58+
console.log('model.modelType', model.modelType)
59+
const style = model.getNodeStyle()
60+
61+
return h('g', {}, [
62+
h('rect', {
63+
...style,
64+
stroke: 'transparent',
65+
fill: 'transparent',
66+
x: x - width / 2,
67+
y: y - height / 2,
68+
rx: radius,
69+
ry: radius,
70+
width,
71+
height,
72+
}),
73+
this.getCustomIcon(),
74+
])
75+
}
76+
77+
getText(): h.JSX.Element | null {
78+
return null
79+
}
80+
}
81+
82+
class CustomIconNodeModel extends RectNodeModel {
83+
setAttributes() {
84+
console.log('this.properties', this.properties)
85+
const { width, height, radius } = this.properties as CustomProperties
86+
if (width) {
87+
this.width = width
88+
}
89+
if (height) {
90+
this.height = height
91+
}
92+
if (radius) {
93+
this.radius = radius
94+
}
95+
}
96+
97+
getTextStyle(): LogicFlow.TextNodeTheme {
98+
// const { x, y, width, height } = this
99+
const {
100+
refX = 0,
101+
refY = 0,
102+
textStyle,
103+
} = this.properties as CustomProperties
104+
const style = super.getTextStyle()
105+
106+
// 通过 transform 重新设置 text 的位置
107+
return {
108+
...style,
109+
fill: 'red',
110+
...(cloneDeep(textStyle) || {}),
111+
transform: `matrix(1 0 0 1 ${refX} ${refY})`,
112+
}
113+
}
114+
115+
getNodeStyle(): LogicFlow.CommonTheme {
116+
const style = super.getNodeStyle()
117+
const {
118+
style: customNodeStyle,
119+
// radius = 0, // 第二种方式,设置圆角
120+
} = this.properties as CustomProperties
121+
122+
return {
123+
...style,
124+
...(cloneDeep(customNodeStyle) || {}),
125+
// rx: radius,
126+
// ry: radius,
127+
}
128+
}
129+
}
130+
131+
export default {
132+
type: 'customIcon',
133+
view: CustomIconNode,
134+
model: CustomIconNodeModel,
135+
}

0 commit comments

Comments
 (0)