Skip to content

feat: 添加画布一件美化 #1618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@ctrl/tinycolor": "^4.1.0",
"@logicflow/core": "^1.2.27",
"@logicflow/extension": "^1.2.27",
"@antv/layout": "^0.3.1",
"@vueuse/core": "^10.9.0",
"@wecom/jssdk": "^2.1.0",
"axios": "^0.28.0",
Expand Down
6 changes: 3 additions & 3 deletions ui/src/components/dynamics-form/items/table/TableCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const props = defineProps<{
modelValue?: Array<any>
}>()
const rowTemp = ref<any>()
const evalF = (text: string, row: any) => {
const evalF: (text: string, row: any) => string = (text: string, row: any) => {
rowTemp.value = row
return eval(text)
}
Expand Down Expand Up @@ -167,8 +167,8 @@ watch(

const activeText = computed(() => {
if (props.modelValue) {
const rows = option_list.value.filter(
(f: any) => props.modelValue?.includes(f[valueField.value])
const rows = option_list.value.filter((f: any) =>
props.modelValue?.includes(f[valueField.value])
)
if (rows) {
if (rows.length > 3) {
Expand Down
22 changes: 22 additions & 0 deletions ui/src/components/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,28 @@ export const iconMap: any = {
])
}
},

'app-beautify': {
iconReader: () => {
return h('i', [
h(
'svg',
{
style: { height: '100%', width: '100%' },
viewBox: '0 0 1024 1024',
version: '1.1',
xmlns: 'http://www.w3.org/2000/svg'
},
[
h('path', {
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',
fill: 'currentColor'
})
]
)
])
}
}
// 'app-history-outlined': {
// iconReader: () => {
// return h('i', [

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个代码中的一个主要问题是样式重复使用(style和class重叠)。例如,两个div都有相同的style部分:height: 100%; width: 100%,所以应该只在第一个出现一次。另一个问题是没有明确地将这些内容分块或归类为不同的组件文件。

对于优化,可以创建一个单独的CSS文件来集中处理这些图标和其他元素的样式,并且尽量减少标签的选择器长度以提高性能。此外,考虑重构并按逻辑模块进行组织结构,以清晰展示每个任务的功能和状态。

Expand Down
7 changes: 1 addition & 6 deletions ui/src/components/markdown/EchartsRander.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
import { onMounted, nextTick, watch, onBeforeUnmount, ref } from 'vue'
import * as echarts from 'echarts'
const tmp = ref()
const props = defineProps({
option: {
type: String,
required: true
}
})
const props = defineProps<{ option: string }>()
const chartsRef = ref()

const style = ref({
Expand Down
14 changes: 8 additions & 6 deletions ui/src/components/markdown/FormRander.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { computed, ref } from 'vue'
import DynamicsForm from '@/components/dynamics-form/index.vue'
const props = defineProps<{
form_setting: string
sendMessage: (question: string, type: 'old' | 'new', other_params_data?: any) => void
sendMessage?: (question: string, type: 'old' | 'new', other_params_data?: any) => void
}>()
const form_setting_data = computed(() => {
if (props.form_setting) {
Expand Down Expand Up @@ -68,11 +68,13 @@ const submit = () => {
dynamicsFormRef.value?.validate().then(() => {
_submit.value = true
const setting = JSON.parse(props.form_setting)
props.sendMessage('', 'old', {
runtime_node_id: setting.runtime_node_id,
chat_record_id: setting.chat_record_id,
node_data: form_data.value
})
if (props.sendMessage) {
props.sendMessage('', 'old', {
runtime_node_id: setting.runtime_node_id,
chat_record_id: setting.chat_record_id,
node_data: form_data.value
})
}
})
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/markdown/MdRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
:option="item.content"
></EchartsRander>
<FormRander
:sendMessage="sendMessage"
:send-message="sendMessage"
v-else-if="item.type === 'form_rander'"
:form_setting="item.content"
></FormRander>
Expand Down
6 changes: 6 additions & 0 deletions ui/src/workflow/common/NodeControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
<el-button link @click="fitView">
<AppIcon iconName="app-fitview" title="适应"></AppIcon>
</el-button>
<el-button link @click="layout">
<AppIcon iconName="app-beautify" title="美化"></AppIcon>
</el-button>
</el-card>
</template>

Expand All @@ -30,5 +33,8 @@ function fitView() {
props.lf?.resetTranslate()
props.lf?.fitView()
}
const layout = () => {
props.lf?.extension.dagre.layout()
}
</script>
<style scoped></style>
20 changes: 20 additions & 0 deletions ui/src/workflow/common/app-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ class AppNode extends HtmlResize.view {
}

class AppNodeModel extends HtmlResize.model {
refreshDeges() {
// 更新节点连接边的path
this.incoming.edges.forEach((edge: any) => {
// 调用自定义的更新方案
edge.updatePathByAnchor()
})
this.outgoing.edges.forEach((edge: any) => {
edge.updatePathByAnchor()
})
}
set_position(position: { x?: number; y?: number }) {
const { x, y } = position
if (x) {
this.x = x
}
if (y) {
this.y = y
}
this.refreshDeges()
}
getResizeOutlineStyle() {
const style = super.getResizeOutlineStyle()
style.stroke = 'none'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我发现了两个问题:

  1. 第一个问题是类AppNode在HtmlResize中继承了view。
  2. 第二个问题是class AppNodeModel在.HtmlResize模型上是被继承的。

对于第一个问题和第二个问题,可以采取两种解决方案:

对第一个人而言:你可以将它转换为子类别或实现自己的功能,并将其放在HTMLResizer组件内;

其次,对第二个人而言:你可以创建一个新的父类别或改变结构来管理整个系统的布局。

Expand Down
4 changes: 3 additions & 1 deletion ui/src/workflow/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
</template>
<script setup lang="ts">
import LogicFlow from '@logicflow/core'
import { ref, onMounted, computed } from 'vue'
import { ref, onMounted, computed, nextTick } from 'vue'
import AppEdge from './common/edge'
import Control from './common/NodeControl.vue'
import { baseNodes } from '@/workflow/common/data'
import '@logicflow/extension/lib/style/index.css'
import '@logicflow/core/dist/style/index.css'
import { initDefaultShortcut } from '@/workflow/common/shortcut'
import Dagre from '@/workflow/plugins/dagre'
const nodes: any = import.meta.glob('./nodes/**/index.ts', { eager: true })

defineOptions({ name: 'WorkFlow' })
Expand Down Expand Up @@ -61,6 +62,7 @@ const renderGraphData = (data?: any) => {
const container: any = document.querySelector('#container')
if (container) {
lf.value = new LogicFlow({
plugins: [Dagre],
textEdit: false,
adjustEdge: false,
adjustEdgeStartAndEnd: false,
Expand Down
69 changes: 69 additions & 0 deletions ui/src/workflow/plugins/dagre.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { DagreLayout, type DagreLayoutOptions } from '@antv/layout'

export default class Dagre {
static pluginName = 'dagre'
lf: any
option: DagreLayoutOptions | any
render(lf: any) {
this.lf = lf
}

/**
* option: {
* rankdir: "TB", // layout 方向, 可选 TB, BT, LR, RL
* align: undefined, // 节点对齐方式,可选 UL, UR, DL, DR
* nodeSize: undefined, // 节点大小
* nodesepFunc: undefined, // 节点水平间距(px)
* ranksepFunc: undefined, // 每一层节点之间间距
* nodesep: 40, // 节点水平间距(px) 注意:如果有grid,需要保证nodesep为grid的偶数倍
* ranksep: 40, // 每一层节点之间间距 注意:如果有grid,需要保证ranksep为grid的偶数倍
* controlPoints: false, // 是否保留布局连线的控制点
* radial: false, // 是否基于 dagre 进行辐射布局
* focusNode: null, // radial 为 true 时生效,关注的节点
* };
*/
layout(option = {}) {
const { nodes, edges, gridSize } = this.lf.graphModel
// 为了保证生成的节点在girdSize上,需要处理一下。
let nodesep = 40
let ranksep = 40
if (gridSize > 20) {
nodesep = gridSize * 2
ranksep = gridSize * 2
}
this.option = {
type: 'dagre',
rankdir: 'LR',
// align: 'UL',
// align: 'UR',
align: 'DR',
nodesep,
ranksep,
begin: [120, 120],
...option
}
const layoutInstance = new DagreLayout(this.option)
const layoutData = layoutInstance.layout({
nodes: nodes.map((node: any) => ({
id: node.id,
size: {
width: node.width,
height: node.height
},
model: node
})),
edges: edges.map((edge: any) => ({
source: edge.sourceNodeId,
target: edge.targetNodeId,
model: edge
}))
})

layoutData.nodes?.forEach((node: any) => {
// @ts-ignore: pass node data
const { model } = node
model.set_position({ x: node.x, y: node.y })
})
this.lf.fitView()
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

该代码存在一些问题和不规则的部分:

  1. render 方法应作为类的成员而不是函数来定义,在 JavaScript 中,方法通常被声明为静态属性或类变量。
  2. 错误地导入了 package.json 文件中的 module.exports 块,并将它导出为 DagreLayout. 应将 @antv/layout/Dagre 导入并使用这个版本。
  3. 不正确地设置了布局方向。对于单层图形(如饼图),可能不需要改变方向即可工作。但对于多层级结构,则需要设置正确的方向以获得预期的效果。

根据这些发现进行调整:

import { DAGRE_LAYOUT_OPTIONS, LayoutOptions } from '@antv/dagre-plugin'

const layoutInstance = new DAGRE_LAYOUT_OPTIONS(options).layout()

// ...

Loading