前言
Relation-Graph 是一个开源的免费关系图谱组件,支持 Vue2、Vue3 和 React 框架。它提供开箱即用的体验,配置简单,文档清晰,并支持通过插槽自定义节点样式。文章详细介绍了在 Vue2、Vue3 和 React 中的安装和使用方法,包含完整的代码示例和运行效果图。该组件具有高度可定制性,支持节点点击事件等交互功能,适用于构建各种关系图谱应用。
官网地址
relation-graph - A Relationship Graph Component
推荐原因
- 超级容易上手,基本开箱即用
- 官方文档清晰明了,有在线示例、可自定义配置,配置完可直接复制配置的代码
- 完全支持 Vue2、Vue3、React 三种框架
- 关系节点可通过插槽完全自定义定制
- 免费
使用方法
1. Vue2 使用
1.1 安装 relation-graph
npm install --save relation-graph
1.2 可直接复制到 Vue 文件中运行使用
<template>
<div>
<div>
<RelationGraph ref="graphRef" :options="graphOptions" :on-node-click="onNodeClick" :on-line-click="onLineClick" />
</div>
</div>
</template>
<script>
// relation-graph 也支持在 main.js 文件中使用 Vue.use(RelationGraph);这样,你就不需要下面这一行代码来引入了。
import RelationGraph from 'relation-graph'
export default {
name: 'Demo',
components: { RelationGraph },
data() {
return {
graphOptions: {
defaultJunctionPoint: 'border'
// 这里可以参考"Graph 图谱"中的参数进行设置 https://www.relation-graph.com/#/docs/graph
}
}
},
mounted() {
this.showGraph()
},
methods: {
showGraph() {
const jsonData = {
rootId: 'a',
nodes: [
{ id: 'a', text: 'A', borderColor: 'yellow' },
{ id: 'b', text: 'B', color: '#43a2f1', fontColor: 'yellow' },
{ id: 'c', text: 'C', nodeShape: 1, width: 80, height: 60 },
{ id: 'e', text: 'E', nodeShape: 0, width: 150, height: 150 }
],
lines: [
{ from: 'a', to: 'b', text: '关系 1', color: '#43a2f1' },
{ from: 'a', to: 'c', text: '关系 2' },
{ from: 'a', to: 'e', text: '关系 3' },
{ from: 'b', to: 'e', color: '#67C23A' }
]
}
// 以上数据中的 node 和 link 可以参考"Node 节点"和"Link 关系"中的参数进行配置
this.$refs.graphRef.setJsonData(jsonData, (graphInstance) => {
// Called when the relation-graph is completed
})
},
onNodeClick(nodeObject, $event) {
console.log('onNodeClick:', nodeObject)
},
onLineClick(lineObject, $event) {
console.log('onLineClick:', lineObject)
}
}
}
</script>
2. Vue3 使用
2.1 安装 relation-graph
npm install --save relation-graph-vue3
2.2 可直接复制到 Vue 文件中运行使用
<template>
<div>
<div>
<relation-graph ref="graphRef$" :options="options" />
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import RelationGraph from 'relation-graph-vue3'
const graphRef$ = ref<RelationGraph>()
const options = {
defaultExpandHolderPosition: 'right'
}
onMounted(() => {
const jsonData = {
rootId: 'a',
nodes: [
{ id: 'a', text: 'a', },
{ id: 'b', text: 'b', },
{ id: 'c', text: 'c', },
{ id: 'd', text: 'd', },
{ id: 'e', text: 'e', },
{ id: 'f', text: 'f', },
],
lines: [
{ from: 'a', to: 'b', },
{ from: 'a', to: 'c', },
{ from: 'a', to: 'd', },
{ from: 'a', to: 'e', },
{ from: 'a', to: 'f', },
],
}
// The node and line in the above data can refer to the options in "Node" and "Link & Line" for configuration.
// Node: https://www.relation-graph.com/#/docs/node
// Link & Line: https://www.relation-graph.com/#/docs/link
graphRef$.value.setJsonData(jsonData)
// The graphRef$.value.setJsonData(jsonData, callback) method is a convenient method that is equivalent to the following code:
// const graphInstance = graphRef$.value.getInstance();
// graphInstance.addNodes(jsonData.nodes);
// graphInstance.addLines(jsonData.lines);
// graphInstance.rootNode = graphInstance.getNodeById(jsonData.rootId);
// await graphInstance.doLayout(); // Layout using the layouter set in graphOptions
// await graphInstance.moveToCenter(); // Find the center based on node distribution and center the view
// await graphInstance.zoomToFit(); // Zoom to fit, so that all nodes can be displayed in the visible area
})
</script>
3. React 使用
3.1 安装 relation-graph
npm install --save relation-graph-react
3.2 可直接复制到文件中运行使用
import React, { useEffect, useRef } from 'react'
import RelationGraph, { RelationGraphInstance } from 'relation-graph-react'
import type { MutableRefObject } from 'react'
import type {
RGLine,
RGLink,
RGNode,
RGNodeSlotProps,
RGOptions,
RelationGraphExpose
} from 'relation-graph-react'
const staticJsonData = {
rootId: '2',
nodes: [
{ id: '1', text: '节点 -1', myicon: 'el-icon-star-on' },
{ id: '2', text: '节点 -2', myicon: 'el-icon-setting', width: 100, height: 100 },
{ id: '3', text: '节点 -3', myicon: 'el-icon-setting' },
{ id: '4', text: '节点 -4', myicon: 'el-icon-star-on' },
{ id: , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : }
],
: [
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : },
{ : , : , : }
]
}
: .<> = {
.()
(node. === ) {
(
)
}
(
)
}
: . = {
graphRef = () <>
( {
()
}, [])
= () => {
graphRef..(staticJsonData, {
})
}
: = {
: ,
: ,
: {
: ,
:
},
:
}
= () => {
.(, node.)
}
= () => {
.(, line., line., line.)
}
(
)
}
运行结果
因为我是 Vue2 项目,所以下面展示的是我在 Vue2 项目中的代码,可直接复制运行,需要注意的是我使用了 less。
<template>
<div>
<div>
<h3>设备联动图</h3>
</div>
<div>
<RelationGraph ref="graphRef" :options="graphOptions" :on-node-click="onNodeClick" :on-line-click="onLineClick">
<template #node="{ node }">
<div>
<div>
<div>
<span></span>
<strong>声光</strong>
<div>离线</div>
</div>
<div>
<span>4</span>
</div>
</div>
<div>
办公室 1
</div>
</div>
</template>
</RelationGraph>
</div>
</div>
</template>
<script>
import RelationGraph from 'relation-graph'
export default {
name: "DevLinkageDiagram",
components: { RelationGraph },
props: {},
data() {
return {
graphOptions: {
defaultJunctionPoint: 'border',
allowShowDownloadButton: false,
defaultFocusRootNode: false,
defaultNodeWidth: 1,
defaultNodeHeight: 1,
defaultShowLineLabel: false,
allowShowRefreshButton: true,
// 这里可以参考"Graph 图谱"中的参数进行设置 https://www.relation-graph.com/#/docs/graph
}
}
},
computed: {},
created() {},
mounted() {
this.showGraph()
},
methods: {
showGraph() {
const jsonData = {
rootId: 'a',
nodes: [
{ id: 'a', text: 'A', },
{ id: 'b', text: 'B', },
{ id: 'c', text: 'C', },
{ id: 'e', text: 'E', }
],
lines: [
{ from: 'a', to: 'b', },
{ from: 'a', to: 'c', },
{ from: 'a', to: 'e', },
]
}
// 以上数据中的 node 和 link 可以参考"Node 节点"和"Link 关系"中的参数进行配置
this.$refs.graphRef.setJsonData(jsonData, (graphInstance) => {
// Called when the relation-graph is completed
})
},
onNodeClick(nodeObject, $event) {
// console.log('onNodeClick:', nodeObject)
},
onLineClick(lineObject, $event) {
// console.log('onLineClick:', lineObject)
}
},
};
</script>
<style scoped lang="less">
.dev-linkage-diagram {
padding: 15px;
background-color: #ffffff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.graphRefBox {
height: 580px;
background-color: #cfcece;
}
.rel-node-peel {
position: relative;
.c-my-rg-node {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
.nodeBox {
width: 200px;
border-radius: 20px;
overflow: hidden;
>div {
padding: 0 16px;
}
.top {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 40px;
background-color: #deb922;
.left {
display: flex;
align-items: center;
color: #fff;
.state {
padding: 1px 4px;
margin-left: 4px;
background-color: rgba(245, 245, 245, 0.3);
border-radius: 4px;
}
}
.num {
display: flex;
justify-content: center;
align-items: center;
width: 24px;
height: 24px;
background-color: rgba(226, 226, 226, 0.5);
border: 1px solid #fff;
border-radius: 50%;
color: #fff;
font-weight: 700;
font-size: 14px;
}
}
.bottom {
display: flex;
align-items: center;
width: 100%;
height: 40px;
background-color: #72716d;
font-size: 14px;
}
}
}
</style>
运行成果图

该组件表现良好,推荐使用。


