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

Angular中使用D3.js绘制堆叠柱状图仅显示空图问题求解

问题排查与修复方案

核心错误点

  • x轴比例尺domain赋值错误:代码中x.domain(data.map(d => d.groups))写错了属性名,原数据行的分组字段是group而非groups,正确写法应为x.domain(groups),或者x.domain(data.map(d => d.group)),否则x轴比例尺没有有效值,矩形的x坐标返回undefined无法正常定位。
  • Y轴值域设置完全错误:当前Y轴domain硬编码为[5.75, 9],但你的CSV数据单字段最大值就达到33,堆叠后总和更高,所有数值都超出了Y轴范围,自然无法渲染。需要根据堆叠数据动态计算最大值,设置Y轴domain从0到堆叠数据的最大值。
  • 矩形数据绑定错误:在为堆叠分组绑定stackedData后,子元素rect的绑定写了.data(data)重新绑定了原始数据,应该改为.data(d => d)绑定当前堆叠分组的数值,才能拿到每个堆叠段的上下界d[0]和d[1],原始数据里并没有这两个属性,所以原代码拿不到高度计算的参数。
  • CSV数据未做类型转换:d3.csv默认读取的所有字段都是字符串类型,数值字段需要手动转换为数字,否则堆叠计算会出错。

修复后的完整drawBars代码

drawBars(data: any[]): void {
  // 转换数值字段类型
  data.forEach(d => {
    d.Nitrogen = Number(d.Nitrogen);
    d.normal = Number(d.normal);
    d.stress = Number(d.stress);
  });

  const subgroups = data.columns.slice(1)
  const groups = data.map(d => d.group)

  // 修复x轴domain
  const x = d3.scaleBand()
  .range([0, this.width])
  .domain(groups)
  .padding(0.2);

  this.svg.append("g")
  .attr("transform", "translate(0," + this.height + ")")
  .call(d3.axisBottom(x).tickSizeOuter(0))
  
  // 先计算堆叠数据,再动态设置Y轴domain
  const stackedData = d3.stack()
  .keys(subgroups)(data)

  const yMax = d3.max(stackedData, d => d3.max(d, item => item[1])) || 0;
  const y = d3.scaleLinear()
  .domain([0, yMax])
  .range([this.height, 0]);

  this.svg.append("g")
  .call(d3.axisLeft(y));

  const color = d3.scaleOrdinal()
  .domain(subgroups)
  .range(['#e41a1c','#377eb8','#4daf4a'])

  // 修复rect的数据绑定
  this.svg.append("g")
  .selectAll("g")
  .data(stackedData)
  .join("g")
  .attr("fill", d => color(d.key))
  .selectAll("rect")    
  .data(d => d)
  .join("rect")
  .attr("x", d => x(d.data.group))
  .attr("y", d => y(d[1]))
  .attr("height", d => y(d[0]) - y(d[1]))
  .attr("width",x.bandwidth())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 14:18:02