1
- import { Card , Divider , Button , Space } from 'antd'
1
+ import { Card , Divider , Button , Space , Select , Input } from 'antd'
2
2
import LogicFlow from '@logicflow/core'
3
- import { useEffect , useRef } from 'react'
4
- import { FlowPath } from '@logicflow/extension'
3
+ import { useEffect , useRef , useState } from 'react'
4
+ import { Snapshot , DndPanel } from '@logicflow/extension'
5
5
6
6
import './index.less'
7
7
import '@logicflow/core/es/index.css'
@@ -11,17 +11,16 @@ import data from './data'
11
11
import Uml from './uml'
12
12
13
13
const config : Partial < LogicFlow . Options > = {
14
- stopScrollGraph : true ,
15
- stopZoomGraph : true ,
14
+ partial : true ,
16
15
grid : {
17
16
type : 'dot' ,
18
17
size : 20 ,
19
18
} ,
20
- plugins : [ FlowPath ] ,
19
+ plugins : [ Snapshot , DndPanel ] ,
21
20
}
22
21
23
- interface Snapshot {
24
- data : LogicFlow . GraphConfigData
22
+ interface SnapshotResponse {
23
+ data : Blob
25
24
width : number
26
25
height : number
27
26
}
@@ -30,74 +29,163 @@ export default function HighLightExtension() {
30
29
const containerRef = useRef < HTMLDivElement | null > ( null )
31
30
const imgRef = useRef < HTMLImageElement | null > ( null )
32
31
33
- let lf : LogicFlow
34
- useEffect ( ( ) => {
35
- lf = new LogicFlow ( {
36
- container : containerRef . current ! ,
37
- ...config ,
38
- } )
39
-
40
- lf . register ( Uml )
32
+ const [ fileName , setFileName ] = useState < undefined | string > ( undefined ) // 文件名
33
+ const [ fileType , setFileType ] = useState < string > ( 'png' ) // 下载的图片类型
34
+ const [ width , setWidth ] = useState < string | undefined > ( ) // 宽度
35
+ const [ height , setHeight ] = useState < string | undefined > ( undefined ) // 高度
36
+ const [ padding , setPaddding ] = useState < string | undefined > ( undefined ) //padding
41
37
42
- lf . render ( data )
43
- lf . translateCenter ( )
38
+ const lfRef = useRef < LogicFlow | null > ( null )
39
+ useEffect ( ( ) => {
40
+ if ( ! lfRef . current ) {
41
+ lfRef . current = new LogicFlow ( {
42
+ container : containerRef . current ! ,
43
+ ...config ,
44
+ } )
45
+
46
+ lfRef . current . register ( Uml )
47
+
48
+ lfRef . current . setPatternItems ( [
49
+ {
50
+ type : 'circle' ,
51
+ text : '开始' ,
52
+ label : '开始节点' ,
53
+ icon : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAAnBJREFUOBGdVL1rU1EcPfdGBddmaZLiEhdx1MHZQXApraCzQ7GKLgoRBxMfcRELuihWKcXFRcEWF8HBf0DdDCKYRZpnl7p0svLe9Zzbd29eQhTbC8nv+9zf130AT63jvooOGS8Vf9Nt5zxba7sXQwODfkWpkbjTQfCGUd9gIp3uuPP8bZ946g56dYQvnBg+b1HB8VIQmMFrazKcKSvFW2dQTxJnJdQ77urmXWOMBCmXM2Rke4S7UAW+/8ywwFoewmBps2tu7mbTdp8VMOkIRAkKfrVawalJTtIliclFbaOBqa0M2xImHeVIfd/nKAfVq/LGnPss5Kh00VEdSzfwnBXPUpmykNss4lUI9C1ga+8PNrBD5YeqRY2Zz8PhjooIbfJXjowvQJBqkmEkVnktWhwu2SM7SMx7Cj0N9IC0oQXRo8xwAGzQms+xrB/nNSUWVveI48ayrFGyC2+E2C+aWrZHXvOuz+CiV6iycWe1Rd1Q6+QUG07nb5SbPrL4426d+9E1axKjY3AoRrlEeSQo2Eu0T6BWAAr6COhTcWjRaYfKG5csnvytvUr/WY4rrPMB53Uo7jZRjXaG6/CFfNMaXEu75nG47X+oepU7PKJvvzGDY1YLSKHJrK7vFUwXKkaxwhCW3u+sDFMVrIju54RYYbFKpALZAo7sB6wcKyyrd+aBMryMT2gPyD6GsQoRFkGHr14TthZni9ck0z+Pnmee460mHXbRAypKNy3nuMdrWgVKj8YVV8E7PSzp1BZ9SJnJAsXdryw/h5ctboUVi4AFiCd+lQaYMw5z3LGTBKjLQOeUF35k89f58Vv/tGh+l+PE/wG0rgfIUbZK5AAAAABJRU5ErkJggg==' ,
54
+ } ,
55
+ {
56
+ type : 'rect' ,
57
+ label : '用户任务' ,
58
+ icon : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==' ,
59
+ className : 'important-node' ,
60
+ } ,
61
+ {
62
+ type : 'rect' ,
63
+ label : '系统任务' ,
64
+ icon : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAEFVwZaAAAABGdBTUEAALGPC/xhBQAAAqlJREFUOBF9VM9rE0EUfrMJNUKLihGbpLGtaCOIR8VjQMGDePCgCCIiCNqzCAp2MyYUCXhUtF5E0D+g1t48qAd7CCLqQUQKEWkStcEfVGlLdp/fm3aW2QQdyLzf33zz5m2IsAZ9XhDpyaaIZkTS4ASzK41TFao88GuJ3hsr2pAbipHxuSYyKRugagICGANkfFnNh3HeE2N0b3nN2cgnpcictw5veJIzxmDamSlxxQZicq/mflxhbaH8BLRbuRwNtZp0JAhoplVRUdzmCe/vO27wFuuA3S5qXruGdboy5/PRGFsbFGKo/haRtQHIrM83bVeTrOgNhZReWaYGnE4aUQgTJNvijJFF4jQ8BxJE5xfKatZWmZcTQ+BVgh7s8SgPlCkcec4mGTmieTP4xd7PcpIEg1TX6gdeLW8rTVMVLVvb7ctXoH0Cydl2QOPJBG21STE5OsnbweVYzAnD3A7PVILuY0yiiyDwSm2g441r6rMSgp6iK42yqroI2QoXeJVeA+YeZSa47gZdXaZWQKTrG93rukk/l2Al6Kzh5AZEl7dDQy+JjgFahQjRopSxPbrbvK7GRe9ePWBo1wcU7sYrFZtavXALwGw/7Dnc50urrHJuTPSoO2IMV3gUQGNg87IbSOIY9BpiT9HV7FCZ94nPXb3MSnwHn/FFFE1vG6DTby+r31KAkUktB3Qf6ikUPWxW1BkXSPQeMHHiW0+HAd2GelJsZz1OJegCxqzl+CLVHa/IibuHeJ1HAKzhuDR+ymNaRFM+4jU6UWKXorRmbyqkq/D76FffevwdCp+jN3UAN/C9JRVTDuOxC/oh+EdMnqIOrlYteKSfadVRGLJFJPSB/ti/6K8f0CNymg/iH2gO/f0DwE0yjAFO6l8JaR5j0VPwPwfaYHqOqrCI319WzwhwzNW/aQAAAABJRU5ErkJggg==' ,
65
+ className : 'import_icon' ,
66
+ } ,
67
+ {
68
+ type : 'diamond' ,
69
+ label : '条件判断' ,
70
+ icon : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAAHeEJUAAAAABGdBTUEAALGPC/xhBQAAAvVJREFUOBGNVEFrE0EU/mY3bQoiFlOkaUJrQUQoWMGePLX24EH0IIoHKQiCV0G8iE1covgLiqA/QTzVm1JPogc9tIJYFaQtlhQxqYjSpunu+L7JvmUTU3AgmTfvffPNN++9WSA1DO182f6xwILzD5btfAoQmwL5KJEwiQyVbSVZ0IgRyV6PTpIJ81E5ZvqfHQR0HUOBHW4L5Et2kQ6Zf7iAOhTFAA8s0pEP7AXO1uAA52SbqGk6h/6J45LaLhO64ByfcUzM39V7ZiAdS2yCePPEIQYvTUHqM/n7dgQNfBKWPjpF4ISk8q3J4nB11qw6X8l+FsF3EhlkEMfrjIer3wJTLwS2aCNcj4DbGxXTw00JmAuO+Ni6bBxVUCvS5d9aa04+so4pHW5jLTywuXAL7jJ+D06sl82Sgl2JuVBQn498zkc2bGKxULHjCnSMadBKYDYYHAtsby1EQ5lNGrQd4Y3v4Zo0XdGEmDno46yCM9Tk+RiJmUYHS/aXHPNTcjxcbTFna000PFJHIVZ5lFRqRpJWk9/+QtlOUYJj9HG5pVFEU7zqIYDVsw2s+AJaD8wTd2umgSCCyUxgGsS1Y6TBwXQQTFuZaHcd8gAGioE90hlsY+wMcs30RduYtxanjMGal8H5dMW67dmT1JFtYUEe8LiQLRsPZ6IIc7A4J5tqco3T0pnv/4u0kyzrYUq7gASuEyI8VXKvB9Odytv6jS/PNaZBln0nioJG/AVQRZvApOdhjj3Jt8QC8Im09SafwdBdvIpztpxWxpeKCC+EsFdS8DCyuCn2munFpL7ctHKp+Xc5cMybeIyMAN33SPL3ZR9QV1XVwLyzHm6Iv0/yeUuUb7PPlZC4D4HZkeu6dpF4v9j9MreGtMbxMMRLIcjJic9yHi7WQ3yVKzZVWUr5UrViJvn1FfUlwe/KYVfYyWRLSGNu16hR01U9IacajXPei0wx/5BqgInvJN+MMNtNme7ReU9SBbgntovn0kKHpFg7UogZvaZiOue/q1SBo9ktHzQAAAAASUVORK5CYII=' ,
71
+ } ,
72
+ {
73
+ type : 'circle' ,
74
+ text : '结束' ,
75
+ label : '结束节点' ,
76
+ icon : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAABGdBTUEAALGPC/xhBQAAA1BJREFUOBFtVE1IVUEYPXOf+tq40Y3vPcmFIdSjIorWoRG0ERWUgnb5FwVhYQSl72oUoZAboxKNFtWiwKRN0M+jpfSzqJAQclHo001tKkjl3emc8V69igP3znzfnO/M9zcDcKT67azmjYWTwl9Vn7Vumeqzj1DVb6cleQY4oAVnIOPb+mKAGxQmKI5CWNJ2aLPatxWa3aB9K7/fB+/Z0jUF6TmMlFLQqrkECWQzOZxYGjTlOl8eeKaIY5yHnFn486xBustDjWT6dG7pmjHOJd+33t0iitTPkK6tEvjxq4h2MozQ6WFSX/LkDUGfFwfhEZj1Auz/U4pyAi5Sznd7uKzznXeVHlI/Aywmk6j7fsUsEuCGADrWARXXwjxWQsUbIupDHJI7kF5dRktg0eN81IbiZXiTESic50iwS+t1oJgL83jAiBupLDCQqwziaWSoAFSeIR3P5Xv5az00wyIn35QRYTwdSYbz8pH8fxUUAtxnFvYmEmgI0wYXUXcCCSpeEVpXlsRhBnCEATxWylL9+EKCAYhe1NGstUa6356kS9NVvt3DU2fd+Wtbm/+lSbylJqsqkSm9CRhvoJVlvKPvF1RKY/FcPn5j4UfIMLn8D4UYb54BNsilTDXKnF4CfTobA0FpoW/LSp306wkXM+XaOJhZaFkcNM82ASNAWMrhrUbRfmyeI1FvRBTpN06WKxa9BK0o2E4Pd3zfBBEwPsv9sQBnmLVbLEIZ/Xe9LYwJu/Er17W6HYVBc7vmuk0xUQ+pqxdom5Fnp55SiytXLPYoMXNM4u4SNSCFWnrVIzKG3EGyMXo6n/BQOe+bX3FClY4PwydVhthOZ9NnS+ntiLh0fxtlUJHAuGaFoVmttpVMeum0p3WEXbcll94l1wM/gZ0Ccczop77VvN2I7TlsZCsuXf1WHvWEhjO8DPtyOVg2/mvK9QqboEth+7pD6NUQC1HN/TwvydGBARi9MZSzLE4b8Ru3XhX2PBxf8E1er2A6516o0w4sIA+lwURhAON82Kwe2iDAC1Watq4XHaGQ7skLcFOtI5lDxuM2gZe6WFIotPAhbaeYlU4to5cuarF1QrcZ/lwrLaCJl66JBocYZnrNlvm2+MBCTmUymPrYZVbjdlr/BxlMjmNmNI3SAAAAAElFTkSuQmCC' ,
77
+ } ,
78
+ ] )
79
+ lfRef . current . render ( data )
80
+ lfRef . current . translateCenter ( )
81
+
82
+ lfRef . current . extension . snapshot . useGlobalRules = false
83
+ lfRef . current . extension . snapshot . customCssRules = `
84
+ .uml-wrapper {
85
+ line-height: 1.2;
86
+ text-align: center;
87
+ color: blue;
88
+ }
89
+ `
90
+ }
44
91
} , [ ] )
45
92
93
+ // 下载
46
94
const downLoad = ( ) => {
47
- lf . getSnapshot ( )
95
+ lfRef . current &&
96
+ lfRef . current . getSnapshot ( fileName , {
97
+ fileType,
98
+ height : height ,
99
+ padding : padding ,
100
+ backgroundColor : 'yellow' ,
101
+ partialElement : true ,
102
+ ...( width ? { width } : { } ) ,
103
+ ...( height ? { height } : { } ) ,
104
+ ...( padding ? { padding } : { } ) ,
105
+ } )
48
106
}
49
107
108
+ // 预览
50
109
const preview = ( ) => {
51
- lf . getSnapshotBlob ( '#FFFFFF' ) . then ( ( { data, width, height } : Snapshot ) => {
52
- // imgRef.current && imgRef.current.src = window.URL.createObjectURL(data);
53
- console . log ( width , height , data )
54
- } )
110
+ lfRef . current &&
111
+ lfRef . current
112
+ . getSnapshotBlob ( '#FFFFFF' , fileType )
113
+ . then ( ( { data } : SnapshotResponse ) => {
114
+ if ( imgRef . current ) {
115
+ imgRef . current . width = 500
116
+ imgRef . current . height = 400
117
+ imgRef . current . src = window . URL . createObjectURL ( data )
118
+ }
119
+ } )
55
120
}
56
121
122
+ // 打印base64地址
57
123
const logBase64 = ( ) => {
58
- lf . getSnapshotBase64 ( ) . then ( ( { data, width, height } : Snapshot ) => {
59
- // document.getElementById('img').src = data
60
- console . log ( width , height , data )
61
- } )
62
- }
63
-
64
- const downloadXml = ( ) => {
65
- const data = lf . getGraphData ( )
66
- console . log ( lfJson2Xml ( data ) )
67
- download ( 'logicflow.xml' , lfJson2Xml ( data ) )
68
-
69
- function download ( filename , text ) {
70
- const element = document . createElement ( 'a' )
71
- element . setAttribute (
72
- 'href' ,
73
- 'data:text/plain;charset=utf-8,' + encodeURIComponent ( text ) ,
74
- )
75
- element . setAttribute ( 'download' , filename )
76
-
77
- element . style . display = 'none'
78
- document . body . appendChild ( element )
79
-
80
- element . click ( )
81
-
82
- document . body . removeChild ( element )
83
- }
124
+ lfRef . current &&
125
+ lfRef . current
126
+ . getSnapshotBase64 ( undefined , fileType )
127
+ . then ( ( { data, width, height } : SnapshotResponse ) => {
128
+ // document.getElementById('img').src = data
129
+ console . log ( width , height , data )
130
+ } )
84
131
}
85
132
86
133
return (
87
134
< Card title = "LogicFlow Extension - Snapshot" >
135
+ < div style = { { marginBottom : '10px' } } >
136
+ < Space >
137
+ < span > 文件名:</ span >
138
+ < Input
139
+ placeholder = "文件名"
140
+ value = { fileName }
141
+ onChange = { ( e ) => setFileName ( e . target . value ) }
142
+ />
143
+ < span > 文件类型(默认png):</ span >
144
+ < Select
145
+ defaultValue = { fileType }
146
+ style = { { width : 120 } }
147
+ onChange = { ( value ) => setFileType ( value ) }
148
+ options = { [
149
+ { value : 'png' , label : 'png' } ,
150
+ { value : 'jpeg' , label : 'jpeg' } ,
151
+ { value : 'webp' , label : 'webp' } ,
152
+ { value : 'gif' , label : 'gif' } ,
153
+ ] }
154
+ />
155
+ < span > 宽度</ span >
156
+ < Input
157
+ placeholder = "width"
158
+ value = { width }
159
+ onChange = { ( e ) => setWidth ( e . target . value ) }
160
+ />
161
+ < span > 高度</ span >
162
+ < Input
163
+ placeholder = "height"
164
+ value = { height }
165
+ onChange = { ( e ) => setHeight ( e . target . value ) }
166
+ />
167
+ < span > padding</ span >
168
+ < Input
169
+ placeholder = "padding"
170
+ value = { padding }
171
+ onChange = { ( e ) => setPaddding ( e . target . value ) }
172
+ />
173
+ < Button id = "download" onClick = { downLoad } >
174
+ 下载快照
175
+ </ Button >
176
+ </ Space >
177
+ </ div >
178
+ < Divider />
88
179
< Space >
89
- < Button id = "download" onClick = { downLoad } >
90
- 下载快照
91
- </ Button >
92
180
< Button id = "preview" onClick = { preview } >
93
181
预览
94
182
</ Button >
95
183
< Button id = "base64" onClick = { logBase64 } >
96
184
打印base64
97
185
</ Button >
98
- < Button id = "downloadXml" onClick = { downloadXml } >
186
+ { /* <Button id="downloadXml" onClick={downloadXml}>
99
187
获取xml
100
- </ Button >
188
+ </Button> */ }
101
189
</ Space >
102
190
< Divider />
103
191
< div ref = { containerRef } id = "graph" > </ div >
0 commit comments