d3数据可视化实践-横向树状图

23 阅读2分钟

效果如图所示:

image.png

使用 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>