1.安装X6组件库
npm install @antv/x6 –save
2.页面引入X6
import { Graph, Cell, Node, Color, Dom, Shape } from '@antv/x6';
3.实现自定义节点 组织树代码
<template>
<div class="app-container home">
<div class="leighhs">
<div class="glydgs">
<div v-show="Steps === 1" id="container"></div>
<glydInfo :getNode="getNode" v-show="Steps === 2"></glydInfo>
</div>
<div class="back" @click="back">
<img src="../../assets/images/home_glyd/back.png" alt="">
</div>
</div>
</div>
</template>
<script>
import { Graph, Cell, Node, Color, Dom, Shape } from '@antv/x6';
import { selectClassRelePoi, selectPointDeta } from '@/http/index';
import glydInfo from './glydInfo.vue';
export default {
name: 'demo5',
components:{
glydInfo
},
data() {
return {
getNode:undefined,//父传子数据
Steps:1,//页面切换
containerWidth: 0, //容器宽
containerHeight: 0, //容器高
childNodeWidth: 218, //子节点款
childNodeHeight: 71, //子节点高
level2Right: 0,
topY: 0, //画布最低的Y值,即在视图中最上面的Y值
HorizontalMargin:200, //node左右之间的间距
VerticalMargin: 15, //node上下之间的间距
level: 3, //层级
};
},
mounted() {
//Container的宽高
this.$nextTick(() => {
this.containerWidth = window.innerWidth;
this.containerHeight = window.innerHeight;
});
this.initGraph();
},
beforeDestroy() {
},
methods: {
back(){
if(this.Steps>1){
this.Steps -= 1;
}
},
initGraph() {
//自定义节点
Graph.registerNode(
'root-node',
{
width: 365,
height: 365,
markup: [
{
tagName: 'image',
attrs: {
class: 'image'
}
},
{
tagName: 'text',
attrs: {
class: 'name'
}
}
],
attrs: {
//设置 image样式
'.image': {
x: 0,
y: 0,
width: 365,
height: 365,
opacity: 1.0
},
//设置 text样式
'.name': {
refX: 0.5,
refY: 0.5,
textAnchor: 'middle',
textVerticalAnchor: 'middle',
fill: '#fff',
fontFamily: 'Arial',
fontSize:48,
fontWeight: '600'
}
}
},
true
);
Graph.registerNode(
'second-node',
{
width: this.childNodeWidth,
height: this.childNodeHeight,
markup: [
{
tagName: 'image',
attrs: {
class: 'image'
}
},
{
tagName: 'text',
attrs: {
class: 'name'
}
}
],
attrs: {
'.image': {
x: 0,
y: 0,
width: this.childNodeWidth,
height: this.childNodeHeight,
opacity: 1.0
},
'.name': {
refX: 0.5,
refY: 0.5,
textAnchor: 'middle',
textVerticalAnchor: 'middle',
fill: '#fff',
fontFamily: 'Arial',
fontSize:28,
fontWeight: '600'
}
}
},
true
);
Graph.registerNode(
'third-node',
{
width: 220,
height: 58,
markup: [
{
tagName: 'image',
attrs: {
class: 'image'
}
},
{
tagName: 'text',
attrs: {
class: 'name'
}
}
],
attrs: {
'.image': {
x: 0,
y: 0,
width: 220,
height: 58,
opacity: 1.0
},
'.name': {
refX: 0.5,
refY: 0.5,
textAnchor: 'middle',
textVerticalAnchor: 'middle',
fill: '#fff',
fontFamily: 'Arial',
fontSize:24
}
},
},
true
);
// 自定义边
Graph.registerEdge(
'org-edge',
{
zIndex: -1,
attrs: {
line: {
strokeWidth: 1,
stroke: '#A2B1C3',
sourceMarker: null,
targetMarker: null
}
}
},
true
);
// 创建画布
this.graph = new Graph({
container: document.getElementById('container'),
scroller: false, //是否滚动
interacting: false,
panning:true, //画布拖拽
});
//调用数据
this.initData();
},
//获取数据
initData() {
selectClassRelePoi({ type: '2' }).then(res => {
if (res?.code && res?.code == 200) {
let treeData = {
isRoot: true,
name: '管理要点',
img: require(`../../assets/images/home_glyd/class_a.png`),
level: 0,
id: 'root',
code: 'root',
content: null,
parentId: '',
children: res.data
};
//设置节点
this.setNodes(treeData);
//监听自定义事件
this.setup();
} else {
this.$message.warning('没有获取到管理要点信息');
}
});
},
// 监听自定义事件
setup() {
this.graph.on('node:click', ({ e, node }) => {
if (e.type == 'click') {
let level = node.data.level;
if (level >= 2) {
if(node.data.children){
this.getNode = node.data;
this.$message.success('跳转新页面');
this.Steps = 2;
return;
}else{
this.$message.success('没有子节点了');
return;
}
}
let parent = node.getParent();
if (parent) {
let children = parent.children.filter(item => {
return this.graph.isNode(item);
});
//点击删除 上次展示的节点
if (children && children.length > 0) {
children.forEach(item => {
if (item.children && item.children.length > 0) {
item.children.forEach(cell => {
//判断是否节点
if (this.graph.isNode(cell)) {
//删除节点
this.graph.removeNode(cell);
}
//判断是否线条
if (this.graph.isEdge(cell)) {
//判断是否线条
this.graph.removeEdge(cell);
}
});
}
});
}
}
if (node.data.children && node.data.children.length > 0) {
this.level = node.data.level + 1;
//设置子级的节点
this.setChildrenNodes(node.data.children, { x: node.getBBox().x, y: node.getBBox().y });
} else {
//没有子节点了,如果level>=4,可以直接跳转详情页面
if (node.data.level >= 4) {
this.$message.success('跳转详情页面');
} else {
this.$message.success('没有子节点了');
}
}
}
});
this.graph.on('node:show', ({ e, node }) => {
if (e.type == 'touchstart') {
if (node.data.content) {
}
} else {
this.$message.warning('该节点没有可查看的详细内容');
}
});
},
//设置第一级节点
setNodes(data) {
let children = data.children;
let totalHeight = (children.length - 1) * (this.childNodeHeight + this.VerticalMargin) + this.childNodeHeight; //子节点总高度
let position = { x:80, y: totalHeight / 2 -100 };
//第一级节点
this.createNode(data.isRoot, 'root-node', data.id, data.name, data.img, data, position);
this.setChildrenNodes(children, position);
},
//设置子级节点
setChildrenNodes(nodes, position) {
let nodesFromPoint = this.graph.getNodesFromPoint(position.x, position.y);
let parentNode = nodesFromPoint[0];
let parentBBox = parentNode.getBBox();
let totalHeight = (nodes.length - 1) * (this.childNodeHeight + this.VerticalMargin) + this.childNodeHeight; //子节点总高度
let Y = parentBBox.center.y - totalHeight / 2;
// y轴 小于0 进行削正
if(Y<15){
Y = 15;
}
//大于935 超出屏幕 进行削正
let size = nodes.length;
if((Y + size * (this.childNodeHeight + this.VerticalMargin))>=800){
let difference = (Y + (nodes.length-1) * (this.childNodeHeight + this.VerticalMargin)) - 800;
//差 相减
Y = Y-difference;
}
//便利
for (let i = 0; i < nodes.length; i++) {
let childNode = nodes[i];
let level = childNode.level;
childNode['img'] = require(level == 1 ? `../../assets/images/home_glyd/class_b.png` : `../../assets/images/home_glyd/class_c.png`);
if(level >= 2){
this.$set(childNode,'lineColor','#00E5F5')
}
if (childNode.level > this.level) {
break;
}
let childX;
//第一级 节点 定位 X轴坐标
if (level == 1) {
let centerPosition = 0;
let cnt = 0;
if (size % 2 === 0) {
//偶数
centerPosition = size / 2;
} else {
//奇数
centerPosition = (size - 1) / 2;
if (centerPosition === i) {
cnt = 1;
} else {
cnt = Math.abs(centerPosition - i) + 1;
}
}
childX = parentBBox.x + parentBBox.width + this.HorizontalMargin + (cnt - 1) * (this.HorizontalMargin / 5);
if (i == 0) {
this.level2Right = childX + this.childNodeWidth;
}
} else {
childX = this.level2Right + this.HorizontalMargin;
}
let childY = Y + i * (this.childNodeHeight + this.VerticalMargin);
let node = this.createNode(childNode.isRoot, level >= 2 ? 'third-node' : 'second-node', parentNode.id + childNode.id, childNode.name, childNode.img, childNode, {
x: childX,
y: childY
});
node.addTo(parentNode);
// 添加线条
this.createEdge(parentNode, node, parentNode.data.lineColor);
}
},
//将节点添加到 画布
createNode(isRoot, nodeType, id, name, bg, data, position) {
if (isRoot) {
//根节点
return this.graph.addNode({
shape: nodeType,
id: id,
position: position,
data: data,
attrs: {
//xlinkHref 自定义图标
'.image': { xlinkHref: bg },
'.name': {
//breakText 设置宽度 超出换行
text: Dom.breakText(name, { width: 160, height: 45 })
}
}
});
} else {
//非跟节点
if (nodeType == 'second-node') {
return this.graph.addNode({
shape: nodeType,
id: id,
position: position,
data: data,
attrs: {
//xlinkHref 自定义图标
'.image': { xlinkHref: bg },
'.name': {
//breakText 设置宽度 超出换行
text: Dom.breakText(name, { width: 160, height: 35 })
}
}
});
} else {
return this.graph.addNode({
shape: nodeType,
id: id,
position: position,
data: data,
attrs: {
'.image': { xlinkHref: bg },
'.name': {
text: Dom.breakText(name, { width: 90, height: 35 })
}
}
});
}
}
},
// 设置线条
createEdge(source, target, lineColor) {
let sourceBBox = source.getBBox();
let targetBBox = target.getBBox();
let x;
let vertices = [];
if (sourceBBox.y !== targetBBox.y) {
if (target.data.level == 1) {
x = sourceBBox.x + sourceBBox.width + this.HorizontalMargin / 2;
} else {
x = targetBBox.x - this.HorizontalMargin / 2;
}
vertices = [{ x, y: sourceBBox.center.y }, { x, y: targetBBox.center.y }];
}
//将线条添加到画布
return this.graph.addEdge({
shape: 'org-edge',
source: { cell: source.id },
target: { cell: target.id },
vertices: vertices,
router: { name: 'orth' },
connector: { name: 'rounded' },
attrs: {
line: {
//箭头
targetMarker: {
name: 'classic',
size: 10
},
//颜色
stroke: target.data.lineColor? target.data.lineColor:'#0BE1CB'
}
}
});
}
}
};
</script>
<style scoped lang="scss">
.home {
width: 100%;
height: 100%;
.leighhs {
width: 100%;
height: 100%;
padding: 17px;
background: #fff;
background-color: #008b87;
position: relative;
.glydgs {
width: 100%;
height: 100%;
background: url('~@/assets/images/home_glyd/glyd_bg.png') no-repeat;
background-size: 100% 100%;
#container {
width: 100%;
height: 100%;
overflow: hidden;
}
}
.back{
background: url("../../assets/images/home_glyd/bg.png") no-repeat;
background-size: 100% 100%;
width: 40px;
height: 40px;
position: absolute;
left: 60px;
bottom: 40px;
z-index: 9999;
img{
margin-top: 9px;
margin-left: 5px;
width: 30px;
height: 22px;
cursor: pointer;
}
}
}
}
</style>
最终效果
版权声明:本文为weixin_45792972原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。