d3绘制树状图
使用d3中提供的d3.tree()
API。
const data = {
name: '中国',
children: [
{
name: '浙江',
children: [
{ name: '杭州', value: 100 },
{ name: '宁波', value: 100 },
{ name: '温州', value: 100 },
{ name: '绍兴', value: 100 }
]
},
{
name: '广西',
children: [
{
name: '桂林',
children: [
{ name: '秀峰区', value: 100 },
{ name: '叠彩区', value: 100 },
{ name: '象山区', value: 100 },
{ name: '七星区', value: 100 }
]
},
{ name: '南宁', value: 100 },
{ name: '柳州', value: 100 },
{ name: '防城港', value: 100 }
]
},
{
name: '黑龙江',
children: [
{ name: '哈尔滨', value: 100 },
{ name: '齐齐哈尔', value: 100 },
{ name: '牡丹江', value: 100 },
{ name: '大庆', value: 100 }
]
},
{
name: '新疆',
children:
[
{ name: '乌鲁木齐' },
{ name: '克拉玛依' },
{ name: '吐鲁番' },
{ name: '哈密' }
]
}
]
}
const marge = { top: 50, bottom: 0, left: 10, right: 0 };
const width = window.innerWidth,
height = window.innerHeight,
svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
const g = svg.append('g').attr('transform', `translate(${marge.top}, ${marge.left})`)
//指定树的层次数据结构
const hierarchyData = d3.hierarchy(data).sum(d => d.value)
//创建一个树布局
const tree = d3.tree().size([width / 2, height / 2]).separation((a, b) => (a.parent === b.parent ? 1 : 2) / a.depth)
//使用指定的hierarchy进行布局,并附加node.x和node.y两个属性
const treeData = tree(hierarchyData)
const nodes = treeData.descendants(),
links = treeData.links()
//贝塞尔曲线生成器
const bezier_curve_generator = d3.linkHorizontal().x(d => d.y).y(d => d.x)
//连线
g.append('g').selectAll('path').data(links).enter()
.append('path').attr('d', d => {
const start = { x: d.source.x, y: d.source.y }
const end = { x: d.target.x, y: d.target.y }
return bezier_curve_generator({ source: start, target: end })
})
.attr('fill', 'none')
.attr('stroke', '#444')
.attr('stroke-width', 1)
//节点和对应文字分组
const gs = g.append('g').selectAll('g').data(nodes).enter().append('g')
.attr('transform', d => `translate(${d.y}, ${d.x})`)
//绘制节点
gs.append('circle').attr('r', 6).attr('fill', 'white').attr('stroke', '#555').attr('stroke-width', 1)
.on('click', nodeClick)
gs.append('circle').attr('r', 2).attr('fill', 'white').attr('stroke', '#555').attr('stroke-width', 1)
.on('click', nodeClick)
//文字
gs.append('text').attr('x', d => d.children ? -40 : 8).attr('y', -5).attr('dy', 10).text(d => d.data.name)
function nodeClick() {
d3.select(this).transition().attr('r', 8)
}
运行效果如下
See the Pen JaLbXm by Leevare (@leevare) on CodePen.
代码实现参考自:https://blog.csdn.net/qq_34414916/article/details/80038989
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=1385