agentsclimarketplace

D3 color legend

Skill cxcscmu/SkillLearnBench/skills/b1-one-shot-claude-sonnet-4-6/stock-data-visualization/d3-color-legend

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.From its SKILL.md

Install
npx -y skills add cxcscmu/SkillLearnBench --skill d3-color-legend

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

SKILL.md

3.1 KB, 825 tokens by cl100k_base, as published. Nobody here has run it

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

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:

<div class="legend-container" id="chart-legend"></div>
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:

.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

// 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)

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).

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.