const data = { "name": "中国", "children": [ {"name": "北京"}, {"name": "陕西", "children": [ {"name": "宝鸡"}, {"name": "西安"} ] }, {"name": "上海"}, {"name": "浙江", "children": [ {"name": "杭州"}, {"name": "温州"} ] }, ] }
const dataSet = d3.hierarchy(data) console.log(dataSet)
返回的节点和每一个后代会被附加如下属性:
0
.0
.null
.undefined
.d3.hierarchy
默认子节点取得是children
属性,当然也可以自定义: d3.hierarchy(data, d => d.child)
。
对于扁平数据,我们可以用d3.stratify
来实现数据的层次化:
let data = [ {"name": "Eve", "parent": ""}, {"name": "Cain", "parent": "Eve"}, {"name": "Seth", "parent": "Eve"}, {"name": "Enos", "parent": "Seth"}, {"name": "Noam", "parent": "Seth"}, {"name": "Abel", "parent": "Eve"}, {"name": "Awan", "parent": "Eve"}, {"name": "Enoch", "parent": "Awan"}, {"name": "Azura", "parent": "Eve"} ] const dataSet = d3.stratify() .id(function(d) { return d.name; }) .parentId(function(d) { return d.parent; }) (data)
//创建树布局 const tree = d3.tree().size([300, 300]) console.log(tree) //所有的节点 const nodes = tree(dataSet) console.log(nodes) console.log(nodes.descendants()) // 返回所有节点
d3.tree
对 hierarchy 进行布局,并为 root 以及它的每一个后代附加两个属性:
经过布局之后,我们就可以获取到对应的节点(node
)信息和连线(link
)信息:
const node = group.selectAll('.node') .data(nodes.descendants()) .enter() .append('g') .attr('class', function(d) { return 'node' + (d.children ? ' node--internal' : ' node--leaf'); }) .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; }) node.append('circle') .attr('r', 20) .attr('fill', (d, i) => color(i))
node.append('text') .attr("dy", ".33em") .attr("font-size","12px") .attr("text-anchor", "middle") // 文字居中 .attr('fill', '#fff') .text(d => d.tata.name)
const link = group.selectAll('.link') .data(nodes.links()) .enter() .append('path') .attr('class', 'link') .attr('d', d3.linkHorizontal() // linkVertical() 垂直 linkHorizontal() 水平 .x(function(d) { return d.y; }) .y(function(d) { return d.x; }) ) .attr('fill', 'none') .attr('stroke', '#ccc')
需要注意下的是,x和y是反着来的,如果不反着赋值,效果如下图,还有水平和垂直,大家都可以动手试试效果。
树形图的绘制可以总结为: