Skip to content

Commit 7369231

Browse files
committed
feat: 添加画布一件美化
1 parent 2722b5a commit 7369231

File tree

10 files changed

+134
-17
lines changed

10 files changed

+134
-17
lines changed

ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"@ctrl/tinycolor": "^4.1.0",
1818
"@logicflow/core": "^1.2.27",
1919
"@logicflow/extension": "^1.2.27",
20+
"@antv/layout": "^0.3.1",
2021
"@vueuse/core": "^10.9.0",
2122
"@wecom/jssdk": "^2.1.0",
2223
"axios": "^0.28.0",

ui/src/components/dynamics-form/items/table/TableCheckbox.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const props = defineProps<{
7272
modelValue?: Array<any>
7373
}>()
7474
const rowTemp = ref<any>()
75-
const evalF = (text: string, row: any) => {
75+
const evalF: (text: string, row: any) => string = (text: string, row: any) => {
7676
rowTemp.value = row
7777
return eval(text)
7878
}
@@ -167,8 +167,8 @@ watch(
167167
168168
const activeText = computed(() => {
169169
if (props.modelValue) {
170-
const rows = option_list.value.filter(
171-
(f: any) => props.modelValue?.includes(f[valueField.value])
170+
const rows = option_list.value.filter((f: any) =>
171+
props.modelValue?.includes(f[valueField.value])
172172
)
173173
if (rows) {
174174
if (rows.length > 3) {

ui/src/components/icons/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,28 @@ export const iconMap: any = {
12281228
])
12291229
}
12301230
},
1231+
1232+
'app-beautify': {
1233+
iconReader: () => {
1234+
return h('i', [
1235+
h(
1236+
'svg',
1237+
{
1238+
style: { height: '100%', width: '100%' },
1239+
viewBox: '0 0 1024 1024',
1240+
version: '1.1',
1241+
xmlns: 'http://www.w3.org/2000/svg'
1242+
},
1243+
[
1244+
h('path', {
1245+
d: 'M739.6864 689.92l4.2496 3.584 136.4992 135.936a34.1504 34.1504 0 0 1-43.9296 51.968l-4.1984-3.584-136.5504-135.936a34.1504 34.1504 0 0 1 43.9296-51.968zM663.4496 151.552a34.1504 34.1504 0 0 1 51.2512 30.464l-5.9392 216.6272 156.4672 146.1248a34.1504 34.1504 0 0 1-8.6528 55.808l-4.8128 1.792-202.8032 61.0816-87.4496 197.12a34.1504 34.1504 0 0 1-56.32 9.216l-3.2768-4.096-119.5008-178.432-209.9712-24.064a34.1504 34.1504 0 0 1-26.1632-50.176l2.7648-4.3008 129.28-171.7248-42.5472-212.3776a34.1504 34.1504 0 0 1 40.448-40.1408l4.6592 1.3312 198.912 72.3456z m-18.6368 89.7536l-144.5376 83.968a34.1504 34.1504 0 0 1-28.8256 2.56L314.5728 270.592l33.792 167.8848c1.4848 7.68 0.3584 15.5136-3.1744 22.3232l-3.072 4.9152-102.656 136.2944 166.4 19.1488c8.2944 0.9216 15.872 4.864 21.4016 10.9568l3.072 3.9424 93.8496 140.032 68.7104-154.7776a34.1504 34.1504 0 0 1 16.7936-17.0496l4.608-1.792 160.9216-48.4864-124.2624-116.0192a34.1504 34.1504 0 0 1-10.4448-20.0704l-0.3584-5.7856 4.6592-170.9056z',
1246+
fill: 'currentColor'
1247+
})
1248+
]
1249+
)
1250+
])
1251+
}
1252+
}
12311253
// 'app-history-outlined': {
12321254
// iconReader: () => {
12331255
// return h('i', [

ui/src/components/markdown/EchartsRander.vue

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@
77
import { onMounted, nextTick, watch, onBeforeUnmount, ref } from 'vue'
88
import * as echarts from 'echarts'
99
const tmp = ref()
10-
const props = defineProps({
11-
option: {
12-
type: String,
13-
required: true
14-
}
15-
})
10+
const props = defineProps<{ option: string }>()
1611
const chartsRef = ref()
1712
1813
const style = ref({

ui/src/components/markdown/FormRander.vue

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { computed, ref } from 'vue'
2020
import DynamicsForm from '@/components/dynamics-form/index.vue'
2121
const props = defineProps<{
2222
form_setting: string
23-
sendMessage: (question: string, type: 'old' | 'new', other_params_data?: any) => void
23+
sendMessage?: (question: string, type: 'old' | 'new', other_params_data?: any) => void
2424
}>()
2525
const form_setting_data = computed(() => {
2626
if (props.form_setting) {
@@ -68,11 +68,13 @@ const submit = () => {
6868
dynamicsFormRef.value?.validate().then(() => {
6969
_submit.value = true
7070
const setting = JSON.parse(props.form_setting)
71-
props.sendMessage('', 'old', {
72-
runtime_node_id: setting.runtime_node_id,
73-
chat_record_id: setting.chat_record_id,
74-
node_data: form_data.value
75-
})
71+
if (props.sendMessage) {
72+
props.sendMessage('', 'old', {
73+
runtime_node_id: setting.runtime_node_id,
74+
chat_record_id: setting.chat_record_id,
75+
node_data: form_data.value
76+
})
77+
}
7678
})
7779
}
7880
</script>

ui/src/components/markdown/MdRenderer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
:option="item.content"
1616
></EchartsRander>
1717
<FormRander
18-
:sendMessage="sendMessage"
18+
:send-message="sendMessage"
1919
v-else-if="item.type === 'form_rander'"
2020
:form_setting="item.content"
2121
></FormRander>

ui/src/workflow/common/NodeControl.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<el-button link @click="fitView">
1212
<AppIcon iconName="app-fitview" title="适应"></AppIcon>
1313
</el-button>
14+
<el-button link @click="layout">
15+
<AppIcon iconName="app-beautify" title="美化"></AppIcon>
16+
</el-button>
1417
</el-card>
1518
</template>
1619

@@ -30,5 +33,8 @@ function fitView() {
3033
props.lf?.resetTranslate()
3134
props.lf?.fitView()
3235
}
36+
const layout = () => {
37+
props.lf?.extension.dagre.layout()
38+
}
3339
</script>
3440
<style scoped></style>

ui/src/workflow/common/app-node.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,26 @@ class AppNode extends HtmlResize.view {
137137
}
138138

139139
class AppNodeModel extends HtmlResize.model {
140+
refreshDeges() {
141+
// 更新节点连接边的path
142+
this.incoming.edges.forEach((edge: any) => {
143+
// 调用自定义的更新方案
144+
edge.updatePathByAnchor()
145+
})
146+
this.outgoing.edges.forEach((edge: any) => {
147+
edge.updatePathByAnchor()
148+
})
149+
}
150+
set_position(position: { x?: number; y?: number }) {
151+
const { x, y } = position
152+
if (x) {
153+
this.x = x
154+
}
155+
if (y) {
156+
this.y = y
157+
}
158+
this.refreshDeges()
159+
}
140160
getResizeOutlineStyle() {
141161
const style = super.getResizeOutlineStyle()
142162
style.stroke = 'none'

ui/src/workflow/index.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
</template>
66
<script setup lang="ts">
77
import LogicFlow from '@logicflow/core'
8-
import { ref, onMounted, computed } from 'vue'
8+
import { ref, onMounted, computed, nextTick } from 'vue'
99
import AppEdge from './common/edge'
1010
import Control from './common/NodeControl.vue'
1111
import { baseNodes } from '@/workflow/common/data'
1212
import '@logicflow/extension/lib/style/index.css'
1313
import '@logicflow/core/dist/style/index.css'
1414
import { initDefaultShortcut } from '@/workflow/common/shortcut'
15+
import Dagre from '@/workflow/plugins/dagre'
1516
const nodes: any = import.meta.glob('./nodes/**/index.ts', { eager: true })
1617
1718
defineOptions({ name: 'WorkFlow' })
@@ -61,6 +62,7 @@ const renderGraphData = (data?: any) => {
6162
const container: any = document.querySelector('#container')
6263
if (container) {
6364
lf.value = new LogicFlow({
65+
plugins: [Dagre],
6466
textEdit: false,
6567
adjustEdge: false,
6668
adjustEdgeStartAndEnd: false,

ui/src/workflow/plugins/dagre.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { DagreLayout, type DagreLayoutOptions } from '@antv/layout'
2+
3+
export default class Dagre {
4+
static pluginName = 'dagre'
5+
lf: any
6+
option: DagreLayoutOptions | any
7+
render(lf: any) {
8+
this.lf = lf
9+
}
10+
11+
/**
12+
* option: {
13+
* rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
14+
* align: undefined, // 节点对齐方式,可选 UL, UR, DL, DR
15+
* nodeSize: undefined, // 节点大小
16+
* nodesepFunc: undefined, // 节点水平间距(px)
17+
* ranksepFunc: undefined, // 每一层节点之间间距
18+
* nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
19+
* ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
20+
* controlPoints: false, // 是否保留布局连线的控制点
21+
* radial: false, // 是否基于 dagre 进行辐射布局
22+
* focusNode: null, // radial 为 true 时生效,关注的节点
23+
* };
24+
*/
25+
layout(option = {}) {
26+
const { nodes, edges, gridSize } = this.lf.graphModel
27+
// 为了保证生成的节点在girdSize上,需要处理一下。
28+
let nodesep = 40
29+
let ranksep = 40
30+
if (gridSize > 20) {
31+
nodesep = gridSize * 2
32+
ranksep = gridSize * 2
33+
}
34+
this.option = {
35+
type: 'dagre',
36+
rankdir: 'LR',
37+
// align: 'UL',
38+
// align: 'UR',
39+
align: 'DR',
40+
nodesep,
41+
ranksep,
42+
begin: [120, 120],
43+
...option
44+
}
45+
const layoutInstance = new DagreLayout(this.option)
46+
const layoutData = layoutInstance.layout({
47+
nodes: nodes.map((node: any) => ({
48+
id: node.id,
49+
size: {
50+
width: node.width,
51+
height: node.height
52+
},
53+
model: node
54+
})),
55+
edges: edges.map((edge: any) => ({
56+
source: edge.sourceNodeId,
57+
target: edge.targetNodeId,
58+
model: edge
59+
}))
60+
})
61+
62+
layoutData.nodes?.forEach((node: any) => {
63+
// @ts-ignore: pass node data
64+
const { model } = node
65+
model.set_position({ x: node.x, y: node.y })
66+
})
67+
this.lf.fitView()
68+
}
69+
}

0 commit comments

Comments
 (0)