当前位置: 首页 > news >正文

Vue3使用 DAG 图(AntV X6)

参考文档

  • AntV X6 文档

可自定义设置以下属性

  • 容器宽度(width),类型:number | string,默认 ‘100%’
  • 容器高度(height),类型:number | string,默认 ‘100%’

效果如下图:

在这里插入图片描述

安装插件

pnpm add @antv/x6

创建DAG组件DAGChart.vue

<script setup lang="ts">
import type { Edge, Graph as X6Graph, Node } from '@antv/x6'
import { Graph } from '@antv/x6'
import { useResizeObserver, debounce } from 'vue-amazing-ui'interface Props {width?: string | number // 容器宽度height?: string | number // 容器高度
}
const props = withDefaults(defineProps<Props>(), {width: '100%',height: '100%'
})
const chartWidth = computed(() => {if (typeof props.width === 'number') {return `${props.width}px`}return props.width
})
const chartHeight = computed(() => {if (typeof props.height === 'number') {return `${props.height}px`}return props.height
})const chartRef = useTemplateRef('chartRef')
let graph: X6Graph | null = nulltype DagNodeData = {label: stringtype: 'source' | 'transform' | 'sink' | 'hello' | string
}function getDefaultNodePorts() {return {groups: {in: {position: 'left',zIndex: 1,attrs: {circle: { r: 4, magnet: false, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff' }}},out: {position: 'right',zIndex: 1,attrs: {circle: { r: 4, magnet: false, stroke: '#52c41a', strokeWidth: 1, fill: '#fff' }}}},items: [{ id: 'in-1', group: 'in' },{ id: 'out-1', group: 'out' }]}
}function getGraphData() {const nodes: Node.Metadata[] = [{id: 'source-1',shape: 'rect', // 节点图形 'rect' | 'circle' | 'ellipse' | 'polygon' | 'polyline' | 'path' | 'image' | 'html' (HTML 节点,使用 foreignObject 渲染 HTML 片段)x: 80, // 节点位置 x 坐标,单位为 pxy: 140, // 节点位置 y 坐标,单位为 pxwidth: 140, // 节点宽度,单位为 pxheight: 42, // 节点高度,单位为 pxangle: 0, // 节点旋转角度,单位为度data: { label: 'Source: Kafka', type: 'source' } as DagNodeData,attrs: {body: { fill: '#e6f4ff', stroke: '#91caff', rx: 6, ry: 6 },label: { text: 'Source: Kafka', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'transform-1',shape: 'rect',x: 340,y: 120,width: 160,height: 42,data: { label: 'Transform: Clean', type: 'transform' } as DagNodeData,attrs: {body: { fill: '#f6ffed', stroke: '#b7eb8f', rx: 6, ry: 6 },label: { text: 'Transform: Clean', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'transform-2',shape: 'rect',x: 340,y: 200,width: 160,height: 42,data: { label: 'Transform: Enrich', type: 'transform' } as DagNodeData,attrs: {body: { fill: '#f6ffed', stroke: '#b7eb8f', rx: 6, ry: 6 },label: { text: 'Transform: Enrich', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'sink-1',shape: 'rect',x: 620,y: 160,width: 140,height: 42,data: { label: 'Sink: ClickHouse', type: 'sink' } as DagNodeData,attrs: {body: { fill: '#fff7e6', stroke: '#ffadd2', rx: 6, ry: 6 },label: { text: 'Sink: ClickHouse', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'hello-1',shape: 'rect',x: 880,y: 60,width: 140,height: 42,data: { label: 'Hello: World', type: 'hello' } as DagNodeData,attrs: {body: { fill: '#fff0f6', stroke: '#ffadd2', rx: 6, ry: 6 },label: { text: 'Hello: World', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'hello-2',shape: 'rect',x: 880,y: 160,width: 140,height: 42,data: { label: 'Hello: Forest', type: 'hello' } as DagNodeData,attrs: {body: { fill: '#fff0f6', stroke: '#ffadd2', rx: 6, ry: 6 },label: { text: 'Hello: Forest', fill: '#1f1f1f' }},ports: getDefaultNodePorts()},{id: 'hello-3',shape: 'rect',x: 880,y: 260,width: 140,height: 42,data: { label: 'Hello: Sea', type: 'hello' } as DagNodeData,attrs: {body: { fill: '#fff0f6', stroke: '#ffadd2', rx: 6, ry: 6 },label: { text: 'Hello: Sea', fill: '#1f1f1f' }},ports: getDefaultNodePorts()}]const edges: Edge.Metadata[] = [{id: 'edge-1',source: { cell: 'source-1', port: 'out-1' },target: { cell: 'transform-1', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-2',source: { cell: 'source-1', port: 'out-1' },target: { cell: 'transform-2', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-3',source: { cell: 'transform-1', port: 'out-1' },target: { cell: 'sink-1', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-4',source: { cell: 'transform-2', port: 'out-1' },target: { cell: 'sink-1', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-5',source: { cell: 'sink-1', port: 'out-1' },target: { cell: 'hello-1', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-6',source: { cell: 'sink-1', port: 'out-1' },target: { cell: 'hello-2', port: 'in-1' },connector: { name: 'smooth' }},{id: 'edge-7',source: { cell: 'sink-1', port: 'out-1' },target: { cell: 'hello-3', port: 'in-1' },connector: { name: 'smooth' }}]return { nodes, edges }
}function initGraph() {if (!chartRef.value) returngraph = new Graph({container: chartRef.value,grid: {visible: true, // 绘制网格,默认绘制 dot 类型网格size: 10, // 网格大小,单位 pxtype: 'dot', // 网格类型,可选 'dot' | 'fixedDot' | 'mesh' | 'doubleMesh' | ''args: {color: '#ddd', // 网点颜色thickness: 1 // 网点大小}},background: { color: '#fafafa' }, // 背景panning: true, // 是否可以拖拽平移mousewheel: true, // 鼠标滚轮缩放interacting: { nodeMovable: true, edgeMovable: false, vertexMovable: false, edgeLabelMovable: false },autoResize: true // 监听容器大小改变,并自动更新画布大小})// 点击事件graph.on('node:click', ({ node }) => {const data = (node.getData ? node.getData() : node.getData) as DagNodeData | undefinedconsole.log(`节点被点击:${data?.label}`)})const data = getGraphData()graph.fromJSON(data) // 渲染元素fitView()centerView()useResizeObserver(chartRef,debounce(() => {console.log('centerView')fitView()centerView()}, 100) as ResizeObserverCallback)
}
// 将画布缩放级别增加 0.1
function zoomIn() {graph?.zoom(0.1)
}
// 将画布缩放级别减少 0.1
function zoomOut() {graph?.zoom(-0.1)
}
// 将画布中元素缩小或者放大一定级别,让画布正好容纳所有元素,可以通过 maxScale 配置最大缩放级别
function fitView() {graph?.zoomToFit({ padding: 20, maxScale: 1 })
}
// 将画布中元素居中展示
function centerView() {graph?.centerContent()
}
onMounted(() => {initGraph()
})
onBeforeUnmount(() => {graph?.dispose()graph = null
})
</script>
<template><div class="dag-container"><divref="chartRef"class="graph-container":style="`--chart-width: ${chartWidth}; --chart-height: ${chartHeight};`"></div></div>
</template>
<style lang="less" scoped>
.dag-container {.graph-container {width: var(--chart-width) !important;height: var(--chart-height) !important;padding: 16px 24px;border-radius: 4px;}
}
</style>

在要使用的页面引入

<script setup lang="ts">
import DAGChart from './DAGChart.vue'
</script>
<template><div><h1>DAGChart 参考文档</h1><ul class="m-list"><li><a class="u-file" href="https://x6.antv.antgroup.com/tutorial/about" target="_blank">AntV X6 文档</a></li></ul><DAGChart :height="500" /></div>
</template>
http://www.dtcms.com/a/350825.html

相关文章:

  • 2024年12月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • Spring Boot 3.5 新特性
  • C++ namespace
  • 国内外大模型体验与评测:洞察智能时代的核心驱动力一、引言
  • DataX HdfsWriter 插件文档
  • 实现自己的AI视频监控系统-第二章-AI分析模块2
  • Java全栈开发面试实战:从基础到微服务的完整技术解析
  • Oracle数据库如何修改字段中的两个字符
  • CF2133C 下界(The Nether)
  • 敏捷价值实证:亚马逊如何用敏捷破解技术项目的“价值迷雾”?
  • 学习做动画3.八方移动
  • SW - 增加导出STL数据中的三角面数,增加别人逆向建模的难度
  • Excel比较两列的值是否相同
  • ViT系列网络系统性分析:从架构创新到未来趋势
  • SSH 反向隧道:快速解决服务器网络限制
  • Frida JavaScript API 总结
  • 【数据库】dbeaver 查询clickhouse,表内时间与真实时间差8小时
  • 基于Springboot + vue3实现的宿舍管理系统
  • [pilot智驾系统] docs | 用户界面状态(UIState)
  • 第十八节:骨骼动画 - 角色动画控制
  • 时间序列异常检测实战:HMM与LSTM方法解析
  • 在华为云服务器上使用Ansible部署LNMP环境【玩转华为云】
  • Ubuntu22.04 解决eth0未托管问题
  • golang 基础类 八股文400题
  • Redis面试精讲 Day 30:Redis面试真题解析与答题技巧
  • 蓝牙AOA定位方案:重塑精准定位新纪元,赋能行业智能化升级
  • 16-day13强化学习和训练大模型
  • 深入理解 Roo Code 的自动批准功能
  • Node.js(1)—— Node.js介绍与入门
  • 从0开始学习Java+AI知识点总结-25.web实战(AOP)