You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3.js散点图无显示问题求助:附多变量数据集与代码

问题排查与修复方案

核心错误点

  • 重复创建SVG+宽高初始化错误:页面已存在<svg>元素,代码中又append("svg")创建新SVG,且新SVG未设置初始宽高,导致parseInt(svg.attr('width'))返回NaN,后续所有尺寸设置全部失效。
  • 轴容器创建错误:d3.append("g")是直接向文档根节点添加元素,而非添加到目标SVG中,正确写法应为svg.append("g")。
  • Scale与Axis绑定逻辑错误:D3中需先独立创建比例尺函数,再将其绑定到轴组件,而非直接在<g>元素上链式调用比例尺方法。
  • 脚本标签语法错误:引入D3的<script>标签未闭合,导致后续自定义代码无法被浏览器解析执行。
  • X轴Domain处理不当:直接用data.map(d => d.year)会生成大量重复年份值,ScaleBand要求Domain是唯一值集合。

修正后的核心代码示例

<!DOCTYPE html>
<html lang="en">
<body>
<!-- 保留页面初始SVG,不再重复创建 -->
<svg width="1000" height="1000"></svg>

<!-- 先闭合引入D3的script标签,再开启新标签编写自定义代码 -->
<script src="https://d3js.org/d3.v4.js" charset="utf-8"></script>
<script>
var margin = {top:100, right:80, bottom:80, left:80};

// 选择页面已有的SVG元素
var svg = d3.select("svg");

// 获取初始宽高并计算带边距的总尺寸
var width = parseInt(svg.attr('width'));
var height = parseInt(svg.attr("height"));

svg.attr("width", width + margin.left + margin.right);
svg.attr("height", height + margin.top + margin.bottom);

// 加载数据并处理
d3.csv("data/programmingassignment1data.csv", function(error, data){
   if (error) throw error;

   data.forEach(function(d){
      d.year = +d.year;
      d.percentile = +d.percentile;
      d.avg_welfare = +d.avg_welfare;
      d.pop_share = +d.pop_share;
      d.welfare_share = +d.welfare_share;
   });

   // 1. 创建X轴比例尺(提取去重年份作为Domain)
   var xScale = d3.scaleBand()
     .domain(d3.map(data, d => d.year).keys())
     .range([margin.left, width - margin.right])
     .padding(0.4);

   // 2. 创建X轴容器并绑定比例尺
   var xAxis = svg.append("g")
     .attr("transform", `translate(0, ${height - margin.bottom})`)
     .call(d3.axisBottom(xScale));

   // 3. 以avg_welfare为例创建Y轴比例尺与轴容器
   var yScaleAvg = d3.scaleLinear()
     .domain([0, d3.max(data, d => d.avg_welfare)])
     .range([height - margin.bottom, margin.top]);

   var yAxisAvg = svg.append("g")
     .attr("transform", `translate(${margin.left}, 0)`)
     .call(d3.axisLeft(yScaleAvg));

   // 4. 绘制avg_welfare对应的散点
   svg.selectAll(".avg-point")
     .data(data)
     .enter()
     .append("circle")
     .attr("class", "avg-point")
     .attr("cx", d => xScale(d.year))
     .attr("cy", d => yScaleAvg(d.avg_welfare))
     .attr("r", 3)
     .attr("fill", "steelblue");

   // 可重复上述Y轴+散点逻辑,实现welfare_share、pop_share的区域展示
});
</script>
</body>
</html>

额外说明

  • 针对Y轴三个区域的需求,需分别为avg_welfare、welfare_share、pop_share创建独立的Y轴比例尺,将每个变量的散点映射到对应的Y轴范围。
  • 若要在X轴同时展示年份与百分位数,可将year+'-'+percentile作为组合值传入ScaleBand的Domain,或采用分组轴的方式实现层级展示。

内容的提问来源于stack exchange,提问作者Esther

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:05:20