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

D3散点图图例创建失败:页面无显示问题排查求助

D3-legend模块创建散点图图例无显示问题排查

我编写了以下代码片段,想用Susie Lu的D3-legend模块为散点图创建图例,但网页完全没有显示图例内容。请问我遗漏了什么?哪里出错了?


HTML代码

<html>

<head>
    <title>D3 Legend</title>

    <link rel="stylesheet" href="style-sheet.css">
</head>

<body>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.25.6/d3-legend.min.js"></script>

    <script src="data-script.js"></script>

    <svg id="scatterplot"></svg>
    <div id="legend"></div>
</body>

</html>

CSS代码

#legend {
    font-family: Arial, sans-serif;
    font-size: 12px;
}

JavaScript代码

// Set up the scatter plot.
var margin = { top: 20, right: 20, bottom: 30, left: 40 };
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;

var x = d3.scaleLinear()
    .range([0, width]);

var y = d3.scaleLinear()
    .range([height, 0]);

var color = d3.scaleSequential(d3.interpolateViridis);

var svg = d3.select("#scatterplot")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv("data.csv").then(function (data, error) {
    if (error) throw error;

    data.forEach(function (d) {
        d.x = +d.x;
        d.y = +d.y;
    });

    x.domain(d3.extent(data, function (d) { return d.x; })).nice();
    y.domain(d3.extent(data, function (d) { return d.y; })).nice();
    color.domain(d3.extent(data, function (d) { return d.z; }));

    svg.selectAll(".dot")
        .data(data)
        .enter().append("circle")
        .attr("class", "dot")
        .attr("r", 3.5)
        .attr("cx", function (d) { return x(d.x); })
        .attr("cy", function (d) { return y(d.y); })
        .style("fill", function (d) { return color(d.z); });

    // Set up the legend.
    var legend = d3.legendColor()
        .labelFormat(d3.format(".2f"))
        .title("Z Value")
        .scale(color);

    svg.append("g")
        .attr("class", "legend")
        .call(legend);
});

问题排查与修复方案

  • 版本兼容问题:你使用的d3-legend 2.25.6是针对旧版D3设计的,和D3 v7不兼容。需要替换为适配D3 v7的版本,比如d3-svg-legend@4.1.0。
  • 数据处理遗漏:在数据转换时,仅将x、y转为数值,但未处理z字段,导致颜色比例尺无法正确获取数据范围,影响图例生成。
  • 图例位置问题:你将图例添加到了散点图SVG内部,但未设置位置偏移,图例可能被挤出可视区域或与散点重叠;同时HTML中预留的<div id="legend">未被使用。

关键修复代码示例

  1. 更新d3-legend引用
<script src="https://cdn.jsdelivr.net/npm/d3-svg-legend@4.1.0/dist/d3-svg-legend.min.js"></script>
  1. 补全z字段数值转换
data.forEach(function (d) {
    d.x = +d.x;
    d.y = +d.y;
    d.z = +d.z; // 新增该行,确保z为数值类型
});
  1. 调整图例容器与位置
    如果要使用HTML中预留的<div id="legend">,可单独创建图例SVG:
// 在预留的legend容器中创建SVG
var legendSvg = d3.select("#legend")
    .append("svg")
    .attr("width", 120)
    .attr("height", height + margin.top + margin.bottom);

// 生成并添加图例
var legend = d3.legendColor()
    .labelFormat(d3.format(".2f"))
    .title("Z Value")
    .scale(color);

legendSvg.append("g")
    .attr("transform", "translate(10,20)")
    .call(legend);

或者保留在主SVG中,调整位置并预留空间:

// 调整主图表宽度,给图例留出空间
var width = 600 - margin.left - margin.right - 120;

// ...其他代码不变...

// 添加图例并设置位置到图表右侧
svg.append("g")
    .attr("class", "legend")
    .attr("transform", "translate(" + (width + 10) + ",0)")
    .call(legend);

内容的提问来源于stack exchange,提问作者Reem Al-Assaf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:17:20