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

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.xdnf.cn/news/18681.html

相关文章:

  • Vue 2 中的 v-model和Vue3中的v-model
  • 大数据毕业设计选题推荐-基于大数据的超市销售数据统计分析系统-Hadoop-Spark-数据可视化-BigData
  • 企业在做广告前,需要明确哪些问题?
  • 销售额和营业收入的区别在哪?哪个值应该更大一些?
  • 《零基础入门AI:循环神经网络(Recurrent Neural Networks)(从原理到实现)》
  • Java中的反射机制
  • MyBatis 从入门到精通:一篇就够的实战指南(Java)
  • 3-3〔OSCP ◈ 研记〕❘ WEB应用攻击▸WEB应用安全评估工具
  • 火山引擎配置CDN
  • 【Linux | 网络】多路转接IO之poll
  • 计算机网络课堂笔记
  • AutoCAD Electrical缺少驱动程序“AceRedist“解决方法
  • C++ Core Guidelines 核心理念
  • 关于单片机串口通讯的多机操作说明---单片机串口通讯如何实现多机操作?
  • 16-day13强化学习和训练大模型
  • 怎么把iphone文件传输到windows电脑?分场景选方法
  • jasperreports 使用
  • 解锁处暑健康生活
  • 企业级监控可视化系统 Prometheus + Grafana
  • LoRA(低秩适应,Low-Rank Adaptation)的 alpha 参数解析(54)
  • 雷卯针对香橙派Orange 4G-IOT开发板防雷防静电方案
  • kafka 原理详解
  • 【OpenAI】ChatGPT-4o-latest 真正的多模态、长文本模型的详细介绍+API的使用教程!
  • 深入理解 Python Scapy 库:网络安全与协议分析的瑞士军刀
  • ES6/ES2015 - ES16/ES2025
  • 在压力测试中如何确定合适的并发用户数?
  • 挖币与区块链技术有怎样的联系?
  • 基于 Prometheus+Alertmanager+Grafana 打造监控报警后台(一)-Prometheus介绍及安装
  • DMP-Net:面向脑组织术中成像的深度语义先验压缩光谱重建方法|文献速递-深度学习人工智能医疗图像
  • PyTorch实战(1)——深度学习概述