D3.js柱状图切换学校筛选数据时渲染异常问题咨询
解决方法
你需要做三处核心调整即可实现效果统一:
- 固定X轴域为
0-20的所有整数,不要动态取当前学校存在的成绩值,保证两个学校的X轴分段完全一致 - 统计成绩人数时给所有0-20分值默认填充0,避免缺失分值导致X轴缩短
- 补充多余柱子的退场逻辑,切换学校时清除旧数据残留的柱子
以下是修改后的完整update函数代码:
function update(selectedVar) { var arr = []; // 解析数据 d3.csv("student-mat.csv", function(data) { data = data.filter(function(row) { return row['school'] == selectedVar; }) data.map(function(d){ arr.push(+d.G3); }); var counts = {}; // 先给0-20所有分值默认赋值0 for(let i=0;i<=20;i++){ counts[i] = 0; } // 再统计对应成绩的实际人数 for (var i = 0; i < arr.length; i++) { var num = arr[i]; counts[num] = counts[num] + 1; } var test = []; for (const [key, value] of Object.entries(counts)) { test.push({name:key,score:value}); } // 按成绩数字升序排序,保证X轴顺序正确 test.sort((a,b) => +a.name - +b.name) // X轴用0-20的所有值做域,两个学校完全一致 x.domain(test.map(function(d) { return d.name; })) xAxis.transition().duration(1000).call(d3.axisBottom(x)) // Y轴默认动态适配当前学校最大值,如需和GP学校Y轴完全统一,可固定为[0, GP学校的最大人数] y.domain([0, d3.max(test, function(d) { return d.score}) ]); yAxis.transition().duration(1000).call(d3.axisLeft(y)); // 绑定数据到现有柱子 var u = svg.selectAll("rect") .data(test) // 移除旧数据多余的柱子 u.exit().remove() // 更新柱子状态 u .enter() .append("rect") .merge(u) .transition() .duration(1000) .attr("x", function(d) { return x(d.name); }) .attr("y", function(d) { return y(d.score); }) .attr("width", x.bandwidth()) .attr("height", function(d) { return height - y(d.score); }) .attr("fill", "#69b3a2") }) }
内容的提问来源于stack exchange,提问作者shell12
相关产品推荐
相关产品推荐

