效果如图所示:
使用 D3.js 的 d3.tree()
和 d3.stratify()
来创建树布局
实现步骤:
1、SVG
创建svg容器
<svg id="tree"></svg>
定义容器的宽高
const width = 800;
const height = 400;
// 创建 SVG 元素
const svg = d3.select("#tree")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(40,0)");
2、使用 d3.hierarchy 转换数据为层次结构
const root = d3.hierarchy(data);
3、定义树布局,设置节点间距
const treeLayout = d3.tree()
.size([height, width - 160]);
应用树布局到根节点
treeLayout(root);
4、绘制连线
// 定义连线生成器
const linkGenerator = d3.linkHorizontal()
.x(d => d.y)
.y(d => d.x);
// 绘制连线
const links = svg.selectAll(".link")
.data(root.links())
.enter().append("path")
.attr("class", "link")
.attr("d", linkGenerator);
5、绘制节点
// 绘制节点
const nodes = svg.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.y},${d.x})`);
// 为每个节点添加形状
nodes.append("rect")
.attr("width", 100)
.attr("height", 20)
.attr("y", -10)
.attr("stroke", "#ccc")
.attr("fill", "white")
// 为每个节点添加文本标签
nodes.append("text")
.attr("dy", ".35em")
.attr("x", 10)
.attr("text-anchor", "center")
.text(d => d.data.name);</script>
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Horizontal Tree Diagram</title>
<!-- 引入 D3.js 库 -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
/* 设置 SVG 容器的样式 */
svg {
font: 10px sans-serif;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
</style>
</head>
<body>
<!-- 用于显示树状图的 SVG 容器 -->
<svg id="tree"></svg>
<script>// 定义 SVG 容器的宽度和高度
const width = 800;
const height = 400;
// 创建 SVG 元素
const svg = d3.select("#tree")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(40,0)");
// 示例数据
const data = {
"name": "Top Level",
"children": [
{
"name": "Level 2: A",
"children": [
{ "name": "Son of A" },
{ "name": "Daughter of A" }
]
},
{ "name": "Level 2: B" },
{ "name": "Level 3: C" }
]
};
// 使用 d3.hierarchy 转换数据为层次结构
const root = d3.hierarchy(data);
// 定义树布局,设置节点间距
const treeLayout = d3.tree()
.size([height, width - 160]);
// 应用树布局到根节点
treeLayout(root);
// 定义连线生成器
const linkGenerator = d3.linkHorizontal()
.x(d => d.y)
.y(d => d.x);
// 绘制连线
const links = svg.selectAll(".link")
.data(root.links())
.enter().append("path")
.attr("class", "link")
.attr("d", linkGenerator);
// 绘制节点
const nodes = svg.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", "node")
.attr("transform", d => `translate(${d.y},${d.x})`);
// 为每个节点添加形状
nodes.append("rect")
.attr("width", 100)
.attr("height", 20)
.attr("y", -10)
.attr("stroke", "#ccc")
.attr("fill", "white")
// 为每个节点添加文本标签
nodes.append("text")
.attr("dy", ".35em")
.attr("x", 10)
.attr("text-anchor", "center")
.text(d => d.data.name);</script>
</body>
</html>