数据可视化大屏项目开发中,需要实现一个公司结构图效果,效果截图如下:
这里我们使用的是vue3开发的,所以使用的插件是vue3-tree-org
插件版本
"vue3-tree-org": "^4.2.2",
vue3-tree-org
Vue3 Tree Org 是一个基于 Vue 3.x 的插件库,专门用于创建和管理组织结构树。它提供了一种高效且灵活的方式来展示树形数据,具有良好的可维护性和扩展性。以下是该插件的一些主要功能和特点:
- 拖拽功能:支持通过拖拽节点来改变树结构。
- 缩放功能:支持通过鼠标滚轮进行缩放操作。
- 节点管理:支持新增和删除节点,以及编辑节点名称。
- 自定义右键菜单:允许用户自定义右键菜单,以便执行特定操作。
- Slot自定义节点:支持使用 slot 来自定义节点的渲染内容,提供更大的灵活性。
安装依赖
pnpm i vue3-tree-org
main.js引入
import vue3TreeOrg from 'vue3-tree-org';
import "vue3-tree-org/lib/vue3-tree-org.css";
use(vue3TreeOrg)
实例代码
<template>
<div class="treeBody">
<vue3-tree-org
:data="data"
center
:horizontal="horizontal"
:collapsable="collapsable"
:label-style="style"
:only-one-node="onlyOneNode"
:clone-node-drag="cloneNodeDrag"
:before-drag-end="beforeDragEnd"
:node-draggable="false"
@on-node-drag="nodeDragMove"
@on-node-drag-end="nodeDragEnd"
@on-contextmenu="onMenus"
@on-expand="onExpand"
/>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
name: "baseTree",
components: {
},
setup() {
const cloneNodeDrag = ref(false)
return {
cloneNodeDrag
}
},
data() {
return {
data: {
"id": 1, "label": "公司董事会",
"children": [
{
"id": 2, "pid": 1, "label": "科学技术委员会",
"children": [
{
"id": 5, "pid": 2, "label": "产品研发中心",
"children": [
{"id": 9, "pid": 5, "label": "产品研发中心1"},
{"id": 10, "pid": 5, "label": "产品研发中心2"},
{"id": 11, "pid": 5, "label": "产品研发中心3"}
]
},
{
"id": 6, "pid": 2, "label": "客户服务中心",
"children": [
{"id": 12, "pid": 6, "label": "产品研发中心1"},
{"id": 13, "pid": 6, "label": "产品研发中心2"},
{"id": 14, "pid": 6, "label": "产品研发中心3"}
]
},
{
"id": 7, "pid": 2, "label": "数据运营中心",
"children": [
{"id": 15, "pid": 7, "label": "产品研发中心1"},
{"id": 16, "pid": 7, "label": "产品研发中心2"},
{"id": 17, "pid": 7, "label": "产品研发中心3"}
]
},
{
"id": 8, "pid": 2, "label": "市场营销中心",
"children": [
{"id": 18, "pid": 8, "label": "产品研发中心1"},
{"id": 19, "pid": 8, "label": "产品研发中心2"},
{"id": 20, "pid": 8, "label": "产品研发中心3"}
]
}
]
},
{
"id": 3, "pid": 1, "label": "专家委员会",
"children": [
{
"id": 21, "pid": 3, "label": "产品研发中心",
"children": [
{"id": 25, "pid": 21, "label": "产品研发中心1"},
{"id": 26, "pid": 21, "label": "产品研发中心2"},
{"id": 27, "pid": 21, "label": "产品研发中心3"}
]
},
{
"id": 22, "pid": 3, "label": "客户服务中心",
"children": [
{"id": 28, "pid": 22, "label": "产品研发中心1"},
{"id": 29, "pid": 22, "label": "产品研发中心2"},
{"id": 30, "pid": 22, "label": "产品研发中心3"}
]
},
{
"id": 23, "pid": 3, "label": "数据运营中心",
"children": [
{"id": 31, "pid": 23, "label": "产品研发中心1"},
{"id": 32, "pid": 23, "label": "产品研发中心2"},
{"id": 33, "pid": 23, "label": "产品研发中心3"}
]
},
{
"id": 24, "pid": 3, "label": "市场营销中心",
"children": [
{"id": 34, "pid": 24, "label": "产品研发中心1"},
{"id": 35, "pid": 24, "label": "产品研发中心2"},
{"id": 36, "pid": 24, "label": "产品研发中心3"}
]
}
]
}
]
},
horizontal: false,
collapsable: false,
onlyOneNode: false,
expandAll: true,
disaled: true,
style: {
background: "rgba(41, 86, 131, 1)",
color: "#FFFFFF",
fontFamily: "MicrosoftYaHei",
fontWeight: 400,
fontSize: "14px",
},
};
},
methods: {
onMenus(event, data) {
event.preventDefault(); // 阻止默认右键菜单行为
event.stopPropagation(); // 阻止事件冒泡
console.log('右键菜单已被禁用', data);
},
onExpand(e, data) {
console.log(e, data);
},
nodeDragMove(data) {
console.log(data);
},
beforeDragEnd(node, targetNode) {
return new Promise((resolve, reject) => {
if (!targetNode) reject()
if (node.id === targetNode.id) {
reject()
} else {
resolve()
}
})
},
nodeDragEnd(data, isSelf) {
console.log(data, isSelf);
},
toggleExpand(data, val) {
if (Array.isArray(data)) {
data.forEach((item) => {
item.expand = val
if (item.children) {
this.toggleExpand(item.children, val);
}
});
} else {
data.expand = val
if (data.children) {
this.toggleExpand(data.children, val);
}
}
},
},
};
</script>
<style lang="scss">
.zm-tree-org {
background: none !important;
}
.treeBody {
position: relative;
width: 100%;
height: 100%;
}
.vue3-tree-org {
.tree-node {
.label-wrapper {
.label {
font-family: MicrosoftYaHei;
font-weight: 400;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(41, 86, 131, 1);
}
}
}
// 添加以下样式来更改连接线颜色
.lines {
.line {
stroke: rgba(41, 48, 72, 1) !important;
}
}
}
.zm-tree-contextmenu {
display: none !important;
}
.zm-tree-handle {
display: none !important;
}
</style>