前言: 我是在vue里开发的, 根据文档: 在vue里面使用除了安装'@antv/x6', 需要额外安装'@antv/x6-vue-shape'。
这是用x6 画的简易关系图。 原型图还有蓝色tag 和灰色tag 首尾相连。
直接上代码:
<template>
<div class="custom-node" :style="node.data.style">
{{ node.data.label }}
</div>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
node: {
type: Object,
required: true
}
});
const node = computed(() => {
return props.node;
});
// console.log(node.value);
</script>
<style lang="less" scoped>
.custom-node {
width: fit-content;
text-align: center;
padding: 5px 18px;
z-index: 12999;
position: relative;
}
</style>
<template>
<div ref="container" class="x6-container"></div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { Graph } from "@antv/x6";
import { register } from "@antv/x6-vue-shape";
import NodeComponent from "./node.vue";
import { cloneDeep } from "lodash";
// 注册节点类型
register({
shape: "vue-node",
// shape 表示节点的类型,在创建addNode节点的时候,shape 属性对应就表示使用改类型节点
component: NodeComponent
// component 表示使用自定义节点
// propHooks: (metadata) => ({
// t: console.log(metadata),
// data: metadata.data || {} // 确保传递 data 字段
// })
});
const container = ref(null);
const graph = ref(null);
onMounted(() => {
// 表示创建画布
graph.value = new Graph({
container: container.value,
width: 1100,
height: 400,
grid: false,
connecting: {
router: "orth",
connector: "rounded"
}
});
const arr1 = [1, 1, 1];
const arr2 = [2, 2];
// 发出dash line
const fromConfig = {
shape: "vue-node", // 自定义节点type
x: 50, // 在画布中的位置
y: 130,
width: 185,
// 宽度
// 最重要的点: 往自定义节点组件中传数据一定需要放到data中!!! 传入style 可以到时候动态绑定style
data: {
label: "http://swodjee.kn/c...",
style: {
minWidth: "185px",
backgroundColor: "#4080FF",
border: "1px solid #edd",
borderRadius: "15px",
color: "#fff"
}
},
// ports 表示在节点上添加连接桩
// 所谓的连接桩就是 两个节点连接线的首尾点。
ports: {
groups: {
group1: {
attrs: {
circle: {
r: 1, // 连接点的半径
magnet: true,
stroke: "#4080FF",
strokeWidth: 2,
fill: "#4080FF"
}
},
position: { // 表示绝对定位
name: "absolute"
}
}
},
// 所有连接点的集合
items: [
{
id: "port1",
group: "group1",
// 通过 args 指定绝对位置
// 待补充args
args: { // 表示连接点相对于节点的位置
x: 170,
y: 20
},
attrs: {
text: { text: "" }
}
}
]
}
};
//接收dash line
const toConfig = {
shape: "vue-node",
x: 285,
y: 130,
width: 85,
data: {
label: "关系",
style: {
minWidth: "85px",
border: "1px solid #edd",
backgroundColor: "rgb(0,0,0,.05)",
borderRadius: "15px"
}
},
ports: {
groups: {
group1: {
attrs: {
circle: {
r: 1,
magnet: true,
stroke: "#f2f2f2",
strokeWidth: 2,
fill: "#f2f2f2"
}
},
position: {
name: "absolute"
}
}
},
items: [
{
id: "port2",
group: "group1",
// 通过 args 指定绝对位置
args: {
x: "-1",
y: "20"
},
// 这里是连接点的文字!
attrs: {
text: { text: "" }
}
}
]
}
};
const step = 365;
function handleAddNode(config, index, Y = false) {
const temp = cloneDeep(config);
const nodeConfig = { ...temp };
nodeConfig.x = nodeConfig.x + index * step;
if (Y) {
nodeConfig.y = 230;
}
// 创建节点
graph.value.addNode(nodeConfig);
}
arr1.forEach((_, index) => {
handleAddNode(fromConfig, index);
handleAddNode(fromConfig, index, true);
});
arr2.forEach((_, index) => {
handleAddNode(toConfig, index);
handleAddNode(toConfig, index, true);
});
// 公共边节点
const node4_4 = graph.value.addNode({
shape: "vue-node",
x: 980,
y: 180,
width: 85,
data: {
label: "关系",
style: {
border: "1px solid #edd",
backgroundColor: "rgb(0,0,0,.05)",
borderRadius: "15px"
}
},
ports: {
groups: {
group1: {
attrs: {
circle: {
r: 1,
magnet: true,
stroke: "#f2f2f2",
strokeWidth: 2,
fill: "#f2f2f2"
}
},
position: {
name: "absolute"
}
}
},
items: [
{
id: "port11",
group: "group1",
// 通过 args 指定绝对位置
// 待补充args
args: {
x: 40,
y: 0
},
attrs: {
text: { text: "" }
}
},
{
id: "port22",
group: "group1",
// 通过 args 指定绝对位置
// 待补充args
args: {
x: 40,
y: 40
},
attrs: {
text: { text: "" }
}
}
]
}
});
// 这里到时候需要给出各个节点之前的关系 每个节点需要有唯一的nodeName。然后给出各个节点之间的关联关系 通过nodeName 关联!!
// // 创建边(关键配置)
// const edge1 = graph.value.addEdge({
// source: {
// port: "port1",
// cell: node1
// },
// target: {
// port: "port2",
// cell: node2
// },
// router: "orth", // 正交路由
// connector: "rounded", // 圆角连接器
// attrs: {
// line: {
// stroke: "#4080FF",
// strokeDasharray: 5,
// // 隐藏箭头必须设置null 删除这个属性不行!
// targetMarker: null
// }
// }
// });
// console.log(graph.value.toJSON());
// 导出数据
// const test = graph.value.toJSON();
// test.cells.map((item) => {
// item.ports.items[0].id = item.id;
// });
// console.log(test);
// graph.value.fromJSON(test);
// 导入节点数据
// console.log(graph.value.toJSON());
});
</script>
<style>
.x6-container {
border: 1px solid #eaeaea;
margin: 20px;
}
.custom-node {
border-radius: 200px;
border: 2px solid #fff;
box-shadow: 0px 4px 16px 0px rgba(0, 0, 0, 0.16);
.test {
background-color: #4080ff;
color: #fff;
}
.test1 {
background-color: #fff;
color: var(---1, #242933);
}
}
</style>