D3 v4 网格数据绑定问题:仅渲染单个黑色方块、d.x/d.y定位失效如何解决
问题根因与修复方案
核心问题
代码存在4处错误,导致方块无法正常排布:
- 变量定义顺序错误,计算坐标时依赖的变量均为undefined,生成的
d.x、d.y为NaN,所有方块堆叠在同一位置 - TSV读取的
platform_medium为字符串类型,判断时用严格等于匹配数字,永远返回false,填充色无效显示默认黑色 - 线性渐变ID大小写不匹配,无法正常加载渐变资源
- SVG的g元素添加了不必要的居中平移,大部分方块偏移到可视区域外
修复步骤
- 调整变量定义顺序,保证调用
getWords前所有依赖的变量都完成赋值 - 将
platform_medium转换为数字类型,保证判断逻辑生效 - 修正渐变ID的大小写,保持定义和使用的ID一致
- 移除g元素的居中平移属性,保证方块从SVG左上角开始排布
修复后的核心代码片段
d3.tsv("platform.tsv", function(data) { for (var i = 0; i < data.length; i++) { console.log(data[i].report_num); console.log(data[i].platform_medium); } // 调整变量定义顺序,所有依赖项提前定义 var margin = {top: 10, right: 30, bottom: 30, left: 60}; var width = 750 - margin.left - margin.right; var height = 520 - margin.top - margin.bottom; var squareSize = 20; var squarePad =5; var numPerRow = Math.floor(width / (squareSize + squarePad)); // 取整避免出现半格 var platformData = getWords(data); function getWords(data) { return data.map(function (d, i) { // 转换为数字类型 d.platform_medium = +d.platform_medium; d.report_num = +d.report_num; d.col = i % numPerRow; d.x = d.col * (squareSize + squarePad); d.row = Math.floor(i / numPerRow); d.y = d.row * (squareSize + squarePad); return d; }); } // 移除不必要的居中平移 var gridvis = d3.select("#chart2") .append("svg") .attr("width", width) .attr("height", height) .append("g"); var gridFill7 = gridvis.append("defs") .append("linearGradient") .attr("id", "gridFill7") .attr("x1", "0%") .attr("x2", "0%") .attr("y1", "100%") .attr("y2", "0%"); gridFill7.append("stop") .attr("offset", "50%") .style("stop-color", "#0652DD"); gridFill7.append("stop") .attr("offset", "50%") .style("stop-color", "#C4E538"); var gridFill8 = gridvis.append("defs") .append("linearGradient") .attr("id", "gridFill8") .attr("x1", "0%") .attr("x2", "0%") .attr("y1", "100%") .attr("y2", "0%"); gridFill8.append("stop") .attr("offset", "50%") .style("stop-color", "#0652DD"); gridFill8.append("stop") .attr("offset", "50%") .style("stop-color", "#EE5A24"); var squares = gridvis.selectAll('.square').data(platformData, function (d) { return d.report_num; }); var squaresE = squares.enter() .append('rect') .classed('square', true); var squares = squares.merge(squaresE) .attr('width', squareSize) .attr('height', squareSize) .attr('fill', '#fff') .classed('fill-square', function (d) { return d.platform_medium; }) .attr('x', function (d) { return d.x;}) .attr('y', function (d) { return d.y;}) .attr('opacity', 0); function highlightGrid() { gridvis.selectAll('.fill-square') .transition() .duration(800) .attr('opacity', 1.0) .attr('fill', function (d) { if (d.platform_medium===1) {return "#0652DD";} else if (d.platform_medium===2) {return "#9980FA";} else if (d.platform_medium===3) {return "#C4E538";} else if (d.platform_medium===4) {return "#ED4C67";} else if (d.platform_medium===5) {return "#F79F1F";} else if (d.platform_medium===6) {return "#EE5A24";} else if (d.platform_medium===7) {return "url(#gridFill7)";} // 修正ID大小写 else if (d.platform_medium===8) {return "url(#gridFill8)";} // 修正ID大小写 }); } highlightGrid(); });
内容的提问来源于stack exchange,提问作者cynichole
相关产品推荐
相关产品推荐

