D3.js:使用数据集中的列为散点图点着色时无点显示的问题
解决D3.js散点图着色后无点显示的问题
嘿,刚从ggplot2转D3.js确实会遇到一些逻辑差异的小坑,我来帮你排查下问题:
核心问题分析
你的代码里有两个关键错误导致点无法正常渲染:
- 颜色样式的回调函数写法错误:你直接调用了
d3.interpolateRdGy(d[1]),但此时d还没有被D3传入(只有在回调函数内部才能拿到每个数据点对应的d对象),这会触发JavaScript报错,进而中断后续的点绘制流程。 - 数据访问与数据源不匹配:你提到自己添加了
Color列,但代码里既没有用d.Color来访问这个列,而且读取的还是原始无Color列的CSV链接;同时d[1]这种索引访问方式不适用D3处理后的CSV数据(CSV数据是键值对对象,不是数组)。
修正后的完整代码
我标注了关键修改点,你可以直接参考:
<!DOCTYPE html> <meta charset="utf-8"> <!-- Load d3.js --> <script src="https://d3js.org/d3.v4.js"></script> <!-- Create a div where the graph will take place --> <div id="my_dataviz"></div> <script> // set the dimensions and margins of the graph var margin = {top: 10, right: 30, bottom: 30, left: 60}, width = 460 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; // append the svg object to the body of the page var svg = d3.select("#my_dataviz") .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 + ")"); //Read the data - 替换成你自己修改后包含Color列的CSV链接 d3.csv("你的修改后数据集链接", function(data) { // 可选:将Color列转换为数字类型(CSV读取默认是字符串格式) data.forEach(function(d) { d.Color = +d.Color; }); // Add X axis var x = d3.scaleLinear() .domain([0, 4000]) .range([ 0, width ]); svg.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); // Add Y axis var y = d3.scaleLinear() .domain([0, 500000]) .range([ height, 0]); svg.append("g") .call(d3.axisLeft(y)); // Add dots - 关键修改区域 svg.append('g') .selectAll("circle") // 建议用circle代替dot,更符合SVG语义 .data(data) .enter() .append("circle") .attr("cx", function (d) { return x(d.GrLivArea); } ) .attr("cy", function (d) { return y(d.SalePrice); } ) .attr("r", 1.5) // 包装成回调函数,用d.Color访问你的颜色列 .style("fill", function(d) { return d3.interpolateRdGy(d.Color); }) }) </script>
额外测试小技巧
如果你暂时还没上传修改后的数据集,可以先在代码里模拟Color列测试效果:
data.forEach(function(d) { // 生成0-1之间的随机值作为Color列数据 d.Color = Math.random(); });
和ggplot2的映射逻辑不同,D3里所有和数据绑定的视觉属性(颜色、位置等)都需要通过回调函数实现,每个数据点都会触发一次这个函数,拿到对应的d对象来计算属性值。
内容的提问来源于stack exchange,提问作者Hoops
相关产品推荐
相关产品推荐

