You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在D3.js树图中根据问卷数据调整节点间连线宽度

实现D3可折叠树图的比例化连线宽度

1. 扩展数据结构

首先给每个子节点添加代表受访者比例的字段(比如proportion,取值0-1),让D3能读取到比例数据:

{
  "name": "Question 1",
  "children": [
    { "name": "Yes", "proportion": 0.65 }, // 65%受访者选Yes
    { "name": "No", "proportion": 0.35 }   // 35%受访者选No
  ]
}

如果是多层嵌套的问卷(比如Yes选项下还有后续问题),每个子节点都需要添加该字段。

2. 创建连线宽度比例尺

用D3的比例尺将0-1的比例转换为合适的像素宽度,可选线性或平方根比例尺(后者能放大高比例的视觉差异):

// 线性比例尺:比例0对应1px,比例1对应10px,可按需调整
const linkWidthScale = d3.scaleLinear()
  .domain([0, 1])
  .range([1, 10]);

// 可选:用平方根比例尺强化高比例的视觉表现
// const linkWidthScale = d3.scaleSqrt()
//   .domain([0, 1])
//   .range([1, 15]);

3. 修改连线绘制逻辑

在树图的连线生成代码中,绑定数据后通过stroke-width属性应用比例尺:

// 初始绘制连线
const link = svg.selectAll(".link")
  .data(links)
  .enter().append("path")
  .attr("class", "link")
  .attr("d", diagonal) // 原树图的对角线生成函数
  .attr("stroke-width", d => linkWidthScale(d.target.proportion));

D3树布局生成的links数组中,每个元素包含source(父节点)和target(子节点),所以直接取子节点的proportion值即可。

4. 处理折叠/展开的更新逻辑

当树节点折叠或展开时,需要在连线更新代码中重新设置宽度:

// 在update函数的连线更新部分添加
link.attr("d", diagonal)
    .attr("stroke-width", d => linkWidthScale(d.target.proportion));

5. 可选:添加比例图例

为让用户直观理解线宽对应的比例,可以在SVG中添加简单图例:

// 在SVG右上角绘制图例
const legend = svg.append("g")
  .attr("transform", `translate(${width - 120}, 20)`);

// 0% 标记
legend.append("line")
  .attr("x1", 0).attr("x2", 60)
  .attr("y1", 0).attr("y2", 0)
  .attr("stroke", "#777")
  .attr("stroke-width", linkWidthScale(0));
legend.append("text")
  .attr("x", 70).attr("y", 5)
  .style("font-size", "12px")
  .text("0%");

// 50% 标记
legend.append("line")
  .attr("x1", 0).attr("x2", 60)
  .attr("y1", 25).attr("y2", 25)
  .attr("stroke", "#777")
  .attr("stroke-width", linkWidthScale(0.5));
legend.append("text")
  .attr("x", 70).attr("y", 30)
  .style("font-size", "12px")
  .text("50%");

// 100% 标记
legend.append("line")
  .attr("x1", 0).attr("x2", 60)
  .attr("y1", 50).attr("y2", 50)
  .attr("stroke", "#777")
  .attr("stroke-width", linkWidthScale(1));
legend.append("text")
  .attr("x", 70).attr("y", 55)
  .style("font-size", "12px")
  .text("100%");

内容的提问来源于stack exchange,提问作者creekjumper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:55:06