vue项目中使用d3实现树结构
1. vue.js
安装vue.js
最新稳定版本
$ npm install vue
最新稳定 CSP 兼容版本
$ npm install vue@csp
2. d3
安装d3
$ npm i d3 --save
vue中引入
import * as d3 from 'd3'
3. 代码部分
(1)生成树实现
参考:https://www.jianshu.com/p/4e517d4c3885
参考文章里实现了点击节点会收起子节点功能,由于我的需求里没有用到就删除了那部分,如果有需要的去原文章里看哦~
(在实现中根据需求我将树的圆形结点改为了矩形结点,需要圆形结点可将)
nodeEnter.append("rect")
改为
nodeEnter.append("circle")
生成树部分代码
<script>
const dataset = {
name:"标题1",
children:[
{
name:"标题2标题2标题2标",
children:[
{
name:"标题3",
children:[
{
name:"标题4",value:100},
]
},
{
name:"标题3",value:100},
{
name:"标题3",value:100},
]
},
{
name:"标题2标题2标",
children:[
{
name:"标题3" ,value:100},
{
name:"标题3",value:100},
{
name:"标题3",value:100},
]
}
]
}
import * as d3 from 'd3'
export default {
name: 'Scale',
data() {
return {
id: '',
zoom: null,
index: 0,
duration: 750,
root: null,
nodes: [],
links: [],
dTreeData: null,
transform: null,
margin: {
top: 0, right: 90, bottom: 30, left: 180 }
}
},
methods: {
uuid () {
function s4 () {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1)
}
return (
s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4()
)
},
/**
* @description 获取构造根节点
*/
getRoot () {
let root = d3.hierarchy(dataset, d => {
return d.children
})
root.x0 = this.height / 2
root.y0 = 0
return root
},
clicktext (d) {
this.$alert(d.data.name, '标题名称', {
confirmButtonText: '确定',
});
},
diagonal (s, d) {
return `M ${
s.y} ${
s.x}
C ${
(s.y + d.y) / 2} ${
s.x},
${
(s.y + d.y) / 2} ${
d.x},
${
d.y} ${
d.x}`
},
/**
* @description 获取构造的node数据和link数据
*/
getNodesAndLinks () {
// 树状图根据根节点生成新的x、y坐标,
// 所以不能使用vue的计算螺旋桨
this.dTreeData = this.treemap(this.root)
this.nodes = this.dTreeData.descendants()
this.links = this.dTreeData.descendants().slice(1)
},
/**
* @description 数据与Dom进行绑定
*/
update (source) {
this.getNodesAndLinks()
this.nodes.forEach(d => {
d.y = d.depth * 140
})
// *************************** Nodes section *************************** //
// 更新节点
const svg = d3.select(this.$el).select('svg.d3-tree')
const container = svg.select('g.container')
let node = container.selectAll('g.node')
.data(this.nodes, d => {
return d.id || (d.id = ++this.index)
})
// 在父级之前的位置输入任何新源
let nodeEnter = node.enter().append('g')
.attr('class', 'node')
//.on('click', this.clickNode)
.attr('transform', d => {