一、relation-graph 的使用案例
1、可展开收起的关系图
先看效果:
上代码:
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div style="width: 100%; height: 100%" class="relationGraph">
<RelationGraph
ref="relationGraphRef"
:options="graphOptions"
@on-node-click="onNodeClick"
@on-line-click="onLineClick"
@on-node-drag-end="onNodeDragEnd"
@on-node-expand="onNodeExpand"
@on-node-collapse="onNodeCollapse"
/>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue'
import RelationGraph from 'relation-graph-vue3'
import type {
RGJsonData,
RGNode,
RGOptions,
RGUserEvent
} from 'relation-graph-vue3'
// 获取关系图实例的引用
const relationGraphRef: any = ref(null)
const resizeTimer = ref()
// 设置图表的基本选项
const graphOptions = ref<any>({
allowShowMiniToolBar: true, // 允许显示迷你工具栏
allowShowZoomMenu: true, // 允许显示缩放菜单
allowShowDownloadButton: false, // 禁止显示下载按钮
allowAutoLayoutIfSupport: false, // 允许自动布局
defaultExpandHolderPosition: 'right', // 默认展开方向为右
defaultJunctionPoint: 'border', // 默认连线点为边框
debug: false, // 禁止调试模式
showDebugPanel: false, // 不显示调试面板
moveToCenterWhenRefresh: false, // 禁止刷新时移动到中心
zoomToFitWhenRefresh: false, // 禁止刷新时自动缩放以适应屏幕
useAnimationWhenRefresh: true, // 刷新时使用动画
layout: {
layoutName: 'force', // 自动布局
from: 'left', // 默认left——从左到右
maxLayoutTimes: 10000, // 最大布局次数,默认300
force_node_repulsion: 1,
force_line_elastic: 1
}
})
// 定义默认的关系数据
const graphJsonData: RGJsonData = {
rootId: 'root',
nodes: [
{
id: 'root',
text: '根节点',
expanded: true,
children: []
}
],
lines: []
}
onMounted(async () => {
const graphInstance = relationGraphRef.value!.getInstance()
// 停止自动布局
await graphInstance.stopAutoLayout()
// 渲染关系图
await renderGraph(graphInstance)
// 初始渲染后缩放设置为100%
await graphInstance.setZoom(100)
// 1.5s后自动将视图调整到充满画布
resizeTimer.value = setInterval(async () => {
const graphInstance = relationGraphRef.value!.getInstance()
await graphInstance.zoomToFit()
}, 1500)
})
onUnmounted(() => {
clearInterval(resizeTimer.value)
})
// 渲染关系图
const renderGraph = async graphInstance => {
await getGraphJsonList()
await graphInstance.setJsonData(graphJsonData)
}
// 获取关系图数据
const getGraphJsonList = async () => {
// 调接口获取关系图的节点数据(这里就用假数据代替了)
const graphJsonList = [
{
id: 'a',
name: 'a'
},
{
id: 'b',
name: 'b',
children: [
{
id: 'b1',
name: 'b1',
children: [
{ id: 'b1-1', name: 'b1-1' },
{ id: 'b1-2', name: 'b1-2' },
{ id: 'b1-3', name: 'b1-3' },
{ id: 'b1-4', name: 'b1-4' },
{ id: 'b1-5', name: 'b1-5' },
{ id: 'b1-6', name: 'b1-6' }
]
},
{
id: 'b2',
name: 'b2',
children: [
{ id: 'b2-1', name: 'b2-1' },
{ id: 'b2-2', name: 'b2-2' }
]
}
]
},
{
id: 'c',
text: 'c',
children: [
{ id: 'c1', name: 'c1' },
{ id: 'c2', name: 'c2' },
{ id: 'c3', name: 'c3' }
]
}
]
// 获取子节点数据
const graphJsonDataNode = getChildNodeData(graphJsonList)
// 添加子节点数据
graphJsonData.nodes[0].children = graphJsonDataNode || []
}
// 获取子节点数据
const getChildNodeData = (list: any[]): any[] => {
// 过滤掉无效的数据
let newList = list.filter(item => item.name)
// 递归遍历数据,指定要渲染前几层数据
newList = extractLayers(newList, 3)
// 添加子节点
return newList.map((item: any) => {
const row: any = {
id: item.id,
text: item.name,
expanded: false
}
if (item.children && item.children[0]) {
row.children = getChildNodeData(item.children)
}
return row
})
}
/**
* 递归遍历数据的指定前几层
* @data 数据
* @level 指定的层级
* @currentLevel 当前层级
*/
const extractLayers = (data: any[], level: number, currentLevel = 1): any[] => {
// 递归终止条件:如果当前层级大于指定层级,则不再递归
if (currentLevel > level) {
return []
}
return data.map(item => {
// 复制当前节点
const newItem = { ...item }
// 如果当前节点有子节点,并且当前层级小于等于指定层级
if (newItem.children) {
// 递归处理子节点
newItem.children = extractLayers(
newItem.children,
level,
currentLevel + 1
)
} else {
// 没有子节点时,确保删除 children 属性
delete newItem.children
}
return newItem
})
}
// 点击节点事件
const onNodeClick = (node: RGNode, e: RGUserEvent) => {
// console.log('onNodeClick:', node.id)
return true
}
// 点击线条事件
const onLineClick = (line: RGNode, e: RGUserEvent) => {
// console.log('onLineClick:', line.id, '0000')
return true
}
// 当节点拖动结束时
const onNodeDragEnd = (node: RGNode, e: RGUserEvent) => {}
// 节点展开事件处理函数
const onNodeExpand = async (node: RGNode, e: RGUserEvent) => {
// console.log('onNodeExpand:', node.id)
const graphInstance = relationGraphRef.value!.getInstance()
// 在节点展开时,更新其状态
node.expanded = true
// 这里可以添加代码来处理展开节点的子节点数据
// 开启自动布局
await graphInstance.startAutoLayout()
}
// 节点收缩事件处理函数
const onNodeCollapse = async (node: RGNode, e: RGUserEvent) => {
// console.log('onNodeCollapse:', node.id)
const graphInstance = relationGraphRef.value!.getInstance()
// 在节点收缩时,更新其状态
node.expanded = false
// 这里可以添加代码来处理收缩节点的子节点数据
// 开启自动布局
await graphInstance.startAutoLayout()
}
</script>