vue + d3.js(v6) 绘制【树状图/思维导图】_数据

<template>
<div class="d3Chart"></div>
</template>
<script>
import * as d3 from 'd3';

export default {
mounted() {
// 源数据
let data = {
"name": "中国",
"children":
[
{
"name": "浙江",
"children":
[
{"name": "杭州"},
{"name": "宁波"},
{"name": "温州"},
{"name": "绍兴"}
]
},
{
"name": "广西",
"children":
[
{
"name": "桂林",
"children":
[
{"name": "秀峰区"},
{"name": "叠彩区"},
{"name": "象山区"},
{"name": "七星区"}
]
},
{"name": "南宁"},
{"name": "柳州"},
{"name": "防城港"}
]
},
{
"name": "黑龙江",
"children":
[
{"name": "哈尔滨"},
{"name": "齐齐哈尔"},
{"name": "牡丹江"},
{"name": "大庆"}
]
},
{
"name": "新疆",
"children":
[
{"name": "乌鲁木齐"},
{"name": "克拉玛依"},
{"name": "吐鲁番"},
{"name": "哈密"}
]
}
]
}
// 画布的参数
let mapWidth = 600;
let mapHeight = 600;
let mapPadding = 20
// 定义画布—— 外边距 10px
let svgMap = d3.select(".d3Chart").append('svg').attr("width", mapWidth).attr("height", mapHeight).style("margin", "10px")
// 定义树状图画布
let treeMap = svgMap.append("g").attr("transform", "translate(" + mapPadding + "," + mapPadding + ")");
// 将源数据转换为可以生成树状图的数据(有节点 nodes 和连线 links )
let treeData = d3.tree()
// 设置树状图的尺寸
.size([mapWidth - 3 * mapPadding, mapHeight - 6 * mapPadding])
// 设置树状图节点之间的间隔
.separation(function (a, b) {
return (a.parent == b.parent ? 1 : 2) / a.depth;
})(
// 创建层级布局,对源数据进行数据转换
d3.hierarchy(data).sum(function (d) {
return d.value;
})
)
// 贝塞尔曲线生成器
let Bézier_curve_generator = d3.linkHorizontal()
.x(function (d) {
return d.y;
})
.y(function (d) {
return d.x;
});
//绘制边
treeMap.selectAll("path")
// 节点的关系 links
.data(treeData.links())
.enter()
.append("path")
.attr("d", function (d) {
// 根据name值的长度调整连线的起点
var start = {x: d.source.x, y: d.source.y + d.source.data.name.length * 16 + 12};
var end = {x: d.target.x, y: d.target.y};
return Bézier_curve_generator({source: start, target: end});
})
.attr("fill", "none")
.attr("stroke", "blue")
.attr("stroke-width", 1);
// 创建分组——节点+文字
let groups = treeMap.selectAll("g")
// 节点 nodes
.data(treeData.descendants())
.enter()
.append("g")
.attr("transform", function (d) {
var cx = d.x;
var cy = d.y;
return "translate(" + cy + "," + cx + ")";
});
//绘制节点
groups.append("circle")
.attr("r", 2)
.attr("fill", "white")
.attr("stroke", "red")
.attr("stroke-width", 1);
//绘制文字
groups.append("text")
.attr("x", function (d) {
return 8
})
.attr("y", -5)
.attr("dy", 10)
.text(function (d) {
return d.data.name;
})
}
}
</script>
<style scoped>
</style>