D3.js v7柱状图height属性返回NaN问题排查求助
问题
在Django项目中使用D3.js v7绘制基础动画柱状图,数据来自views.py,但页面仅显示坐标轴及标签,控制台报错:Error: <rect> attribute height: Expected length, "NaN"。已设置绝对高度值,仍无法解决该NaN错误。
相关HTML模板代码
<div id="chart-container"></div> <script src="https://d3js.org/d3.v7.min.js"></script> <script type="text/javascript"> const data = JSON.parse('{{ assign_levels|safe }}'); const margin = {top: 10, right: 30, bottom: 140, left: 60}; const width = 400 - margin.left - margin.right; const height = 500 - margin.top - margin.bottom; const svg = d3.select("#chart-container") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left}, ${margin.top})`); const x = d3.scaleBand() .range([0, width]) .domain(data.map(d => d.level_assign)) .padding(0.3); const y = d3.scaleLinear() .range([height, 0]) .domain([0, d3.max(data, d => d.count)]); svg.append("g") .call(d3.axisLeft(y)); svg.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", "bar") .attr("x", d => x(d.level_assign)) .attr("width", x.bandwidth()) .attr("y", height) .attr("height", 0) .attr("fill", "#5F9EA0") .transition() .duration(1000) .delay((d, i) => i * 100) .attr("y", d => y(d.count)) .attr("height", d => height - y(d.count)); svg.append("g") .attr("transform", `translate(0, ${height})`) .call(d3.axisBottom(x)) .selectAll("text") .attr("transform", "rotate(-45)") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em"); svg.append("text") .attr("transform", "rotate(-90)") .attr("y", 0 - margin.left) .attr("x",0 - (height / 2)) .attr("dy", "1em") .style("text-anchor", "middle") .text("Study Count"); svg.append("text") .attr("x", (width + margin.left + margin.right) / 2) .attr("y", margin.top / 2) .attr("text-anchor", "middle") .style("font-size", "16px") .text("Level of Assignment"); </script>
传入的数据格式
[["Class", 36], ["School - cluster", 6], ["Individual", 20], ["N", 1], ["School - multi-site", 9], ["Not provided/ not available", 4], ["Region or district", 1]]
解决方案
问题根源
传入的数据是二维数组格式(每个元素为[标签, 数值]),但前端D3代码中尝试访问不存在的对象属性d.level_assign和d.count,导致比例尺无法正确映射数值,最终计算柱状图高度时出现NaN。
修复步骤
前端转换数据格式:将二维数组转为对象数组,让每个元素包含代码所需的属性:
const data = JSON.parse('{{ assign_levels|safe }}').map(item => ({ level_assign: item[0], count: item[1] }));可选:后端直接传递对象数组:若能修改Django的views.py,可直接在后端将数据处理为对象数组再传递,省去前端转换步骤:
assign_levels = [ {"level_assign": "Class", "count": 36}, {"level_assign": "School - cluster", "count": 6}, {"level_assign": "Individual", "count": 20}, {"level_assign": "N", "count": 1}, {"level_assign": "School - multi-site", "count": 9}, {"level_assign": "Not provided/ not available", "count": 4}, {"level_assign": "Region or district", "count": 1} ]
修复后关键代码示例
// 核心修改:转换数据结构 const data = JSON.parse('{{ assign_levels|safe }}').map(item => ({ level_assign: item[0], count: item[1] })); // 后续比例尺、柱状图绘制代码保持不变即可
内容的提问来源于stack exchange,提问作者Beatdown
相关产品推荐
相关产品推荐

