d3js v7版本 超简洁树形结构图实现
可根据此简单图进行定制化结构图修改
有具体注释
实现效果如下图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://d3js.org/d3.v7.min.js"></script>
<title>v7版本d3 树形结构图</title>
</head>
<body>
<div>树形结构图</div>
<div id="tree"></div>
</body>
<script>
// 准备数据,要是树型结构
var root = {
name: "地区1",
children: [
{
name: "地区2",
children: [
{
name: "地区3",
},
],
},
{
name: "地区2",
children: [
{
name: "地区3",
},
],
},
{
name: "地区2",
children: [
{
name: "地区3",
},
],
},
{
name: "地区2",
children: [
{
name: "地区3",
},
],
},
],
};
var width = 1000;
var height = 800;
var cluster = d3.tree().size([height - 100, width - 300]); // 设置绘制范围
var hierachyData = d3.hierarchy(root); //对数据进行层级划分标记加工
var nodes = cluster(hierachyData); //对数据添加x,y坐标
var svg = d3
.select("#tree")
.append("svg")
.attr("width", "80%")
.attr("viewBox", `0 0 ${width} ${height + 20}`) //加上这个后,图形才可以成比例缩放
.append("g")
.attr("transform", "translate(50,50)");
// 这个是定义箭头
d3.select("#tree>svg")
.append("defs")
.append("marker")
.attr("id", "arrowhead")
.attr("refX", 0)
.attr("refY", 10)
.attr("markerWidth", 100)
.attr("markerHeight", 100)
.attr("orient", "auto") // 这个属性设置后可以根据线条方向进行旋转
.append("path")
.attr("d", "M10,0 L10,20 L0,10 Z")
.attr('fill','red')
drawLink(); //绘制线条
drawNode(); //绘制节点
function drawLink() {
svg
.selectAll(".link")
.data(nodes.descendants()) // nodes.decendtants() 把数据格式进行平铺成了数字,以便在这里遍历
.enter()
.append("path")
.attr("class", "link")
.attr("d", (d) => {
if (d.depth !== 0) {
return `M ${d.x} ${d.y} L ${d.parent.x} ${d.parent.y}`; // 这里根据需求可以画贝塞尔曲线或折线
}
})
.attr("stroke", "black")
.attr("marker-start", "url(#arrowhead)"); //把箭头加在这里
}
function drawNode() {
var myNode = svg
.selectAll("nodes")
.data(nodes.descendants())
.enter()
.append("g");
// 添加方框
myNode
.append("rect")
.attr("width", 100)
.attr("height", 30)
.attr("stroke", "red")
.attr("fill", "white")
.attr("x", (d) => {
return d.x - 50;
})
.attr("y", (d) => {
return d.y;
});
// 添加文本
myNode
.append("text")
.attr("dx", (d) => {
return d.x - 30;
})
.attr("dy", (d) => {
return d.y + 20;
})
.text((d) => {
return d.data.name;
});
}
</script>
</html>