d3-color-legend · git:20260424.d50cf5a · 2026-04-24 · sha256 7aa1e81344690c1d
d3-color-legend git:20260424.d50cf5aA
Immutable. This exact content never changes and is served at /api/v1/blob/7aa1e81344690c1d.
---
name: d3-color-legend
description: Add a categorical color legend to a D3 chart using colored rectangles or circles with text labels, supporting both SVG-inline and HTML overlay styles.
---
# D3 v6 Categorical Color Legend
## Overview
A color legend maps category names to colors, placed either inside the SVG or as an HTML overlay. Use this whenever a chart uses a categorical color scale.
## SVG Inline Legend
```javascript
const legend = svg.append('g')
.attr('class', 'legend')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const legendItems = legend.selectAll('.legend-item')
.data(categories)
.join('g')
.attr('class', 'legend-item')
.attr('transform', (d, i) => `translate(0, ${i * 22})`);
// Color swatch (circle or rect)
legendItems.append('circle')
.attr('r', 7)
.attr('cx', 7)
.attr('cy', 0)
.attr('fill', d => colorScale(d));
// Label
legendItems.append('text')
.attr('x', 18)
.attr('y', 4)
.style('font-size', '13px')
.text(d => d);
```
## HTML Overlay Legend
Place outside the SVG for more flexible layout:
```html
<div class="legend-container" id="chart-legend"></div>
```
```javascript
const legendDiv = d3.select('#chart-legend');
legendDiv.selectAll('.legend-item')
.data(categories)
.join('div')
.attr('class', 'legend-item')
.html(d => `
<span class="legend-swatch" style="background:${colorScale(d)}"></span>
<span class="legend-label">${d}</span>
`);
```
CSS:
```css
.legend-container {
display: flex;
flex-wrap: wrap;
gap: 10px 20px;
margin: 8px 0;
}
.legend-item {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
}
.legend-swatch {
width: 14px;
height: 14px;
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
```
## Recommended Color Scales
```javascript
// Tableau10 (10 distinguishable categorical colors)
const colorScale = d3.scaleOrdinal(d3.schemeTableau10);
// Custom palette for specific categories
const colorScale = d3.scaleOrdinal()
.domain(['ETF', 'Energy', 'Financial', 'Industry', 'Information Technology'])
.range(['#6baed6', '#fd8d3c', '#74c476', '#9e9ac8', '#f768a1']);
// Safe for colorblind users (Wong palette)
const WONG = ['#E69F00','#56B4E9','#009E73','#F0E442','#0072B2','#D55E00','#CC79A7','#000000'];
const colorScale = d3.scaleOrdinal().range(WONG);
```
## Interactive Legend (Hover to Highlight)
```javascript
legendItems
.style('cursor', 'pointer')
.on('mouseover', function(event, cat) {
// Dim all bubbles not in this category
d3.selectAll('circle.bubble')
.style('opacity', d => d.category === cat ? 1 : 0.2);
})
.on('mouseout', function() {
d3.selectAll('circle.bubble').style('opacity', 1);
});
```
## Placement Tips
- For a vertical legend, position at `(width - legendWidth, margin.top)`.
- For a horizontal legend under the chart, use flex-wrap HTML layout.
- Keep legend items 20–24px apart vertically for readability.
- Use consistent font-size (12–14px) and color contrast (dark text on light background).