在数据可视化项目中,图例(Legend)是帮助观众理解图表含义的重要说明工具,D3.js作为专业的JavaScript可视化库,虽然未直接提供图例API,但开发者可通过灵活的SVG操作实现高度定制化的图例系统,以下是实现图例的完整方案和最佳实践:
适用场景:分类颜色映射(如不同国家GDP颜色区分)
// 创建颜色比例尺 const colorScale = d3.scaleOrdinal() .domain(["亚洲", "欧洲", "美洲"]) .range(["#4e79a7", "#f28e2c", "#e15759"]); // 生成图例容器 const legend = svg.append("g") .attr("class", "legend") .attr("transform", "translate(20,20)"); // 绘制图例项 legend.selectAll("rect") .data(colorScale.domain()) .join("rect") .attr("x", 0) .attr("y", (d,i) => i*25) .attr("width", 18) .attr("height", 18) .attr("fill", d => colorScale(d)); // 添加文本标签 legend.selectAll("text") .data(colorScale.domain()) .join("text") .attr("x", 24) .attr("y", (d,i) => i*25 + 14) .text(d => d) .style("font-size", "12px") .style("dominant-baseline", "middle");
适用场景:连续型数据映射(如温度热力图)
// 创建渐变对象 const gradient = svg.append("defs") .append("linearGradient") .attr("id", "gradient") .attr("x1", "0%").attr("y1", "0%") .attr("x2", "100%").attr("y2", "0%"); // 定义颜色断点 gradient.selectAll("stop") .data([ {offset: "0%", color: "#fff7fb"}, {offset: "100%", color: "#034e7b"} ]) .join("stop") .attr("offset", d => d.offset) .attr("stop-color", d => d.color); // 绘制渐变条 svg.append("rect") .attr("x", 20) .attr("y", 100) .attr("width", 200) .attr("height", 20) .style("fill", "url(#gradient)"); // 添加刻度标记 const scaleAxis = d3.axisBottom(d3.scaleLinear().domain([0, 100])) .ticks(5) .tickSize(6); svg.append("g") .attr("transform", "translate(20,120)") .call(scaleAxis);
最佳实践方案:
状态同步:通过事件监听实现图例点击与图表元素的联动
legend.selectAll("rect") .on("click", function(event, d) { const isActive = d3.select(this).classed("active"); d3.select(this).classed("active", !isActive); // 联动图表元素 svg.selectAll(".data-element") .filter(datum => datum.category === d) .transition() .style("opacity", isActive ? 1 : 0.3); });
视觉反馈:添加CSS过渡效果
.legend rect { transition: opacity 0.3s; cursor: pointer; } .legend rect.active { opacity: 0.5; stroke: #333; stroke-width: 2px; }
function updateLegendPosition() { const chartWidth = svg.node().getBoundingClientRect().width; legend.attr("transform", `translate(${chartWidth-220},20)`); }
window.addEventListener(“resize”, updateLegendPosition);
2. **无障碍访问**
```javascript
legend.selectAll("rect")
.attr("role", "button")
.attr("aria-label", d => `切换${d}类别显示`);
<symbol>
复用图形元素注:代码示例采用D3.js v7+语法,建议在现代浏览器环境下运行,实现方案可根据实际项目需求进行扩展和优化。