亲宝软件园·资讯

展开

D3.js实现树形图的绘制教程详解

FinGet 人气:0

数据

const data = {
  "name": "中国",
  "children": [
    {"name": "北京"},
    {"name": "陕西",
      "children": [
        {"name": "宝鸡"},
        {"name": "西安"}
      ]
    },
    {"name": "上海"},
    {"name": "浙江",
      "children": [
        {"name": "杭州"},
        {"name": "温州"}
      ]
    },
  ]
}

层次化

d3.hierarchy

const dataSet = d3.hierarchy(data)
console.log(dataSet)

返回的节点和每一个后代会被附加如下属性:

d3.hierarchy默认子节点取得是children属性,当然也可以自定义: d3.hierarchy(data, d => d.child)

d3.stratify

对于扁平数据,我们可以用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是反着来的,如果不反着赋值,效果如下图,还有水平和垂直,大家都可以动手试试效果。

最后

树形图的绘制可以总结为:

加载全部内容

相关教程
猜你喜欢
用户评论