D3.js新手求助:散点图数据显示位置不符合预期的问题排查
嘿,刚看到你的问题,这绝对是D3新手最容易踩的基础坑之一,咱们一步步拆解问题,很快就能搞定!
核心问题1:你没用到D3的比例尺来转换数据
你已经定义了x和y的比例尺,但在绘制圆点的时候,直接把原始数据值(d[0]、d[1])当成了像素坐标用!D3的比例尺核心作用就是把你的数据范围(domain)映射到画布的像素范围(range),跳过这一步的话,你的100-200的原始数据会被直接当成像素值,再加上你把坐标轴的domain设成了0-10000,自然会出现点挤在坐标轴角落的情况。
核心问题2:比例尺的domain和数据不匹配
你的测试数据x/y都是100-200,但你把比例尺的domain设成了[0,10000],这就相当于把一个小范围的数据硬塞进一个超大的坐标轴里,所有点自然会挤在一起。
额外小问题:无用的CSV读取
你代码里写了d3.csv("DataFile.csv"),但实际完全没用到这个文件里的数据,反而依赖dataExample。如果这个CSV文件不存在,你的整个绘图逻辑都不会执行,所以可以直接去掉这部分。
修正后的完整代码
<!DOCTYPE html> <meta charset="utf-8"> <!-- Load d3.js --> <script src="d3.v6.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 const margin = {top: 10, right: 30, bottom: 30, left: 60}, width = 920 - margin.left - margin.right, height = 800 - margin.top - margin.bottom; // append the svg object to the body of the page const 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})`); let dataExample = []; for (let i = 0; i < 10000; i++) { const x = Math.floor(Math.random() * 100) + 100; const y = Math.floor(Math.random() * 100) + 100; dataExample.push([x, y]); } // Add X axis const xScale = d3.scaleLinear() .domain(d3.extent(dataExample, d => d[0])) // 自动计算数据的最小/最大值 .range([0, width]); svg.append("g") .attr("transform", `translate(0, ${height})`) .call(d3.axisBottom(xScale)); // Add Y axis const yScale = d3.scaleLinear() .domain(d3.extent(dataExample, d => d[1])) .range([height, 0]); svg.append("g") .call(d3.axisLeft(yScale)); // Add dots svg.append('g') .selectAll("circle") .data(dataExample) .join("circle") .attr("cx", d => xScale(d[0])) // 用比例尺转换数据到像素坐标 .attr("cy", d => yScale(d[1])) .attr("r", 1.5) .style("fill", "#69b3a2") </script>
后续排查的通用线索
- 永远记得:D3的比例尺是函数,必须调用它来转换数据,比如
xScale(d[0])而不是d[0] - 用
d3.extent()自动计算数据的范围,避免手动设置domain出错;如果手动设置,一定要和实际数据的最小值/最大值匹配 - 检查坐标轴的方向:D3的y轴像素坐标是从顶部开始的,所以scale的range要设成
[height, 0],这样数据值越大,点越靠上,符合常规图表逻辑 - 可以用
console.log()输出转换后的坐标值,比如console.log(xScale(d[0])),看看是否符合预期的像素范围
内容的提问来源于stack exchange,提问作者Argus
相关产品推荐
相关产品推荐

