PS: 这玩意是收费的,后面换antv-G6使用了
仅按自身需求做了简单的封装操作,
- 继承ana模板,修改了node样式和大小,去除了img显示
- 使用tag动态标记不同类型的node边框样式
- 向父组件暴露需求使用到的方法
<!--封装OrgChart功能-->
<template>
<div id="tree" ref="tree"></div>
</template>
<script>
import OrgChart from '@balkangraph/orgchart.js/orgchart'
export default {
name: 'OrgChart',
props: {
nodes: {
type: Array,
default: () => []
},
handleClick: {
type: Function,
default: () => false
},
unCheckNodeIds: {
type: Array,
default: () => []
},
checkNodeIds: {
type: Array,
default: () => []
}
},
data() {
return {
chart: null,
currentId: null,
orientation: {
'top': OrgChart.orientation.top,
'bottom': OrgChart.orientation.bottom,
'left': OrgChart.orientation.left,
'right': OrgChart.orientation.right
}
}
},
watch: {
unCheckNodeIds: {
handler(newValue, oldValue) {
//console.log('------------unCheckNodeIds-----------')
//去除class
for (let i = 0; i < oldValue.length; i++) {
this.removeNodeTag(oldValue[i], "error")
}
//添加class
for (let i = 0; i < newValue.length; i++) {
this.addNodeTag(oldValue[i], "error")
}
this.draw()
},
deep: true
},
checkNodeIds: {
handler(newValue, oldValue) {
//去除class
for (let i = 0; i < oldValue.length; i++) {
this.removeNodeTag(oldValue[i], "success")
}
//添加class
for (let i = 0; i < newValue.length; i++) {
this.addNodeTag(oldValue[i], "success")
}
this.draw()
},
deep: true
}
},
methods: {
oc: function(domEl, x) {
console.log('--------------oc draw-------------')
console.log(x)
var that = this;
this.customTemplate()
this.chart = new OrgChart(domEl, {
template: 'myTemplate',
nodes: x,
//默认合并级别
collapse: {
level: 2,
allChildren: true
},
nodeBinding: {
field_0: "name",
field_1: "id",
//img_0: "img"
},
orientation: OrgChart.orientation.left,
toolbar: {
layout: false,
zoom: true,
fit: true,
expandAll: false,
fullScreen: false
},
/*nodeMenu: {
details: { text: "Details" },
add: { text: "Add New" },
edit: { text: "Edit" },
remove: { text: "Remove" },
pdf: { text: "Export PDF" },
png: { text: "Export PNG" },
svg: { text: "Export SVG" },
csv: { text: "Export CSV" }
},*/
});
this.chart.on('click', this.onNodeClick);
this.chart.on('add', function (sender, node) {
// your code goes here
// return false; to cancel the operation
debugger
});
//拖动事件
this.chart.on('drop', function (sender, draggedNodeId, droppedNodeId) {
console.log('drop------move---' + draggedNodeId + '---to father-----' + droppedNodeId)
if (draggedNodeId == 1){
return false;
}
//TODO 暴露回调方法给外部
})
},
/**
* 自定义显示外观模板
*/
customTemplate() {
//继承ana外观
OrgChart.templates.myTemplate = Object.assign({}, OrgChart.templates.ana);
//node位置,同node的width和height
OrgChart.templates.myTemplate.size = [140, 60];
//node外形
OrgChart.templates.myTemplate.node =
'<rect x="0" y="0" height="60" width="140" fill="#039BE5" stroke-width="1" stroke="#aeaeae" rx="5" ry="5"></rect>';
//node显示字段显示
OrgChart.templates.myTemplate.field_0 =
'<text width="130" class="field_0" style="font-size: 14px;" fill="#ffffff" x="64" y="40" text-anchor="middle">{val}</text>';
OrgChart.templates.myTemplate.field_1 =
'<text width="60" text-overflow="multiline" class="field_1" style="font-size: 10px;" fill="#ffffff" x="130" y="20" text-anchor="end">{val}</text>';
//不要图片显示
OrgChart.templates.myTemplate.img_0 = '';
//menu菜单按钮显示
OrgChart.templates.myTemplate.nodeMenuButton = '<g style="cursor:pointer;" transform="matrix(1,0,0,1,225,105)" control-node-menu-id="{id}"><rect x="-4" y="-10" fill="#000000" fill-opacity="0" width="22" height="22"></rect><circle cx="-105" cy="-52" r="2" fill="#ffffff"></circle><circle cx="-98" cy="-52" r="2" fill="#ffffff"></circle><circle cx="-91" cy="-52" r="2" fill="#ffffff"></circle></g>';
//节点显示
//节点位置
OrgChart.templates.myTemplate.expandCollapseSize = 20;
//节点十字
OrgChart.templates.myTemplate.plus = '<circle cx="10" cy="10" r="10" fill="#ffffff" stroke="#aeaeae" stroke-width="1"></circle><line x1="-1" y1="10" x2="21" y2="10" stroke-width="1" stroke="#aeaeae"></line><line x1="10" y1="-1" x2="10" y2="21" stroke-width="1" stroke="#aeaeae"></line>';
//节点形状
OrgChart.templates.myTemplate.minus =
'<circle cx="10" cy="10" r="10" fill="#ffffff" stroke="#aeaeae" stroke-width="1"></circle><line x1="-1" y1="10" x2="21" y2="10" stroke-width="1" stroke="#aeaeae"></line>';
},
/**
* chart.addNode({ id: 4, pid: 2, name: "Name 1", title: "Title 1" });
* @param nodeData
*/
addNode(nodeData) {
this.chart.addNode(nodeData)
},
/**
* chart.removeNode(5);
* @param id
*/
removeNode(id) {
this.chart.removeNode(id)
},
/**
* 只更新有效值字段
* chart.updateNode({ id: 4, pid: 2, name: "Updated Name", title: "Updated Title" });
* @param nodeData
*/
updateNode(nodeData) {
if (!nodeData.id) {
console.error('update error not id')
return
}
var nodeDetail = this.chart.get(nodeData.id)
if (nodeDetail && nodeData.pid) {
nodeDetail.pid = nodeData.pid
}
if (nodeDetail && nodeData.name) {
nodeDetail.name = nodeData.name
}
if (nodeDetail && nodeData.dmId) {
nodeDetail.dmId = nodeData.dmId
}
this.chart.updateNode(nodeDetail)
},
onNodeClick(sender, args) {
var chart = this.chart;
if (this.currentId == null) {
this.currentId = args.node.id
chart.addNodeTag(args.node.id, "selected");
} else {
chart.removeNodeTag(this.currentId, "selected");
this.currentId = args.node.id
chart.addNodeTag(args.node.id, "selected");
}
chart.draw()
var nodeDetail = chart.get(args.node.id)
if (this.handleClick(nodeDetail)) {
//afterClick
}
return false
},
changeDirection(orientation) {
var chart = this.chart
if (orientation && this.orientation[orientation]) {
chart.config.orientation = this.orientation[orientation]
} else {
if (chart.config.orientation == OrgChart.orientation.top) {
chart.config.orientation = OrgChart.orientation.left
} else {
chart.config.orientation = OrgChart.orientation.top
}
}
chart.draw()
},
addNodeTag(id, tag) {
this.chart.addNodeTag(id, tag);
},
removeNodeTag(id, tag) {
this.chart.removeNodeTag(id, tag)
},
draw() {
this.chart.draw()
},
get(id) {
if (id) {
return this.chart.get(id)
}
return null
}
},
mounted(){
this.oc(this.$refs.tree, this.nodes)
}
}
</script>
<style type="text/css">
/*partial*/
.node.selected rect {
fill: #F57C00;
}
.node.error rect {
stroke-width: 3;
stroke: red;
}
.node.success rect {
stroke-width: 3;
stroke: green;
}
</style>