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
相关产品推荐
相关产品推荐

