xiaohongshu
xiaohongshu
d3-shapes-paths
Use when creating SVG shapes, paths, or generators for charts. Invoke for line/area/arc generators, curves, symbols, pie/donut charts, stacks, ribbons, or path manipulation operations.
Full skill instructions
Expert knowledge of D3's shape generators and path manipulation. Covers line, area, arc, pie, symbol, stack, ribbon generators, curve interpolation, and SVG path construction.
Invoke this skill when:
Location: /Users/zach/Documents/cc-skills/docs/d3/
Coverage (203 files):
Shapes (146 files):
Paths (12 files):
Contours (17 files):
Chords (22 files):
Polygons (6 files):
Question: "How do I create a multi-series line chart?"
Response:
import * as d3 from 'd3';
// Sample data
const data = [
{ date: new Date('2024-01-01'), series1: 30, series2: 20 },
{ date: new Date('2024-01-02'), series1: 45, series2: 35 },
{ date: new Date('2024-01-03'), series1: 40, series2: 30 },
{ date: new Date('2024-01-04'), series1: null, series2: 40 }, // Gap in series1
{ date: new Date('2024-01-05'), series1: 60, series2: 50 },
];
// Create scales
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, 800]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => Math.max(d.series1 || 0, d.series2))])
.range([400, 0])
.nice();
// Create line generator
const line = d3.line()
.x(d => xScale(d.date))
.y(d => yScale(d.value))
.curve(d3.curveMonotoneX) // Smooth curve
.defined(d => d.value != null); // Skip null values
// Transform data for each series
const series1Data = data.map(d => ({ date: d.date, value: d.series1 }));
const series2Data = data.map(d => ({ date: d.date, value: d.series2 }));
// Generate path data
const path1 = line(series1Data);
const path2 = line(series2Data);
// Create SVG
const svg = d3.create('svg')
.attr('width', 800)
.attr('height', 400);
// Add lines
svg.append('path')
.attr('d', path1)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 2);
svg.append('path')
.attr('d', path2)
.attr('fill', 'none')
.attr('stroke', 'orange')
.attr('stroke-width', 2);
// Add axes
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
svg.append('g')
.attr('transform', 'translate(0, 400)')
.call(xAxis);
svg.append('g')
.call(yAxis);
Curve Types:
curveLinear - Straight lines (default)curveMonotoneX - Smooth, no overshootcurveCatmullRom - Smooth, passes through pointscurveBasis - Smooth B-splinecurveStep - Step functionReferences:
docs/d3/shape/line.mddocs/d3/shape/curve.mdQuestion: "How do I create an area chart with gradient fill?"
Response:
import * as d3 from 'd3';
const data = [
{ x: 0, y0: 0, y1: 30 },
{ x: 1, y0: 0, y1: 45 },
{ x: 2, y0: 0, y1: 40 },
{ x: 3, y0: 0, y1: 60 },
{ x: 4, y0: 0, y1: 50 },
];
// Create scales
const xScale = d3.scaleLinear()
.domain([0, 4])
.range([0, 800]);
const yScale = d3.scaleLinear()
.domain([0, 60])
.range([400, 0]);
// Create area generator
const area = d3.area()
.x(d => xScale(d.x))
.y0(d => yScale(d.y0)) // Baseline
.y1(d => yScale(d.y1)) // Top line
.curve(d3.curveMonotoneX);
// Create SVG
const svg = d3.create('svg')
.attr('width', 800)
.attr('height', 400);
// Define gradient
const gradient = svg.append('defs')
.append('linearGradient')
.attr('id', 'area-gradient')
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '0%')
.attr('y2', '100%');
gradient.append('stop')
.attr('offset', '0%')
.attr('stop-color', 'steelblue')
.attr('stop-opacity', 0.8);
gradient.append('stop')
.attr('offset', '100%')
.attr('stop-color', 'steelblue')
.attr('stop-opacity', 0.1);
// Add area
svg.append('path')
.datum(data)
.attr('d', area)
.attr('fill', 'url(#area-gradient)');
// Add top line
const line = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y1))
.curve(d3.curveMonotoneX);
svg.append('path')
.datum(data)
.attr('d', line)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 2);
Radial Area (for circular charts):
const radialArea = d3.areaRadial()
.angle(d => angleScale(d.angle))
.innerRadius(d => radiusScale(d.inner))
.outerRadius(d => radiusScale(d.outer));
References:
docs/d3/shape/area.mddocs/d3/shape/radial.mdQuestion: "How do I create a pie chart with labels?"
Response:
import * as d3 from 'd3';
const data = [
{ category: 'A', value: 30 },
{ category: 'B', value: 80 },
{ category: 'C', value: 45 },
{ category: 'D', value: 60 },
];
// Create pie layout
const pie = d3.pie()
.value(d => d.value)
.sort(null) // Keep original order
.padAngle(0.02); // Spacing between slices
// Create arc generator
const arc = d3.arc()
.innerRadius(0) // Use innerRadius > 0 for donut
.outerRadius(150);
// Arc for labels (slightly outside)
const labelArc = d3.arc()
.innerRadius(170)
.outerRadius(170);
// Color scale
const color = d3.scaleOrdinal()
.domain(data.map(d => d.category))
.range(d3.schemeCategory10);
// Create SVG
const svg = d3.create('svg')
.attr('width', 400)
.attr('height', 400);
const g = svg.append('g')
.attr('transform', 'translate(200, 200)'); // Center
// Generate pie data
const pieData = pie(data);
// Add arcs
g.selectAll('path')
.data(pieData)
.join('path')
.attr('d', arc)
.attr('fill', d => color(d.data.category))
.attr('stroke', 'white')
.attr('stroke-width', 2);
// Add labels
g.selectAll('text')
.data(pieData)
.join('text')
.attr('transform', d => `translate(${labelArc.centroid(d)})`)
.attr('text-anchor', 'middle')
.text(d => d.data.category);
// Add percentage labels
g.selectAll('.percentage')
.data(pieData)
.join('text')
.attr('class', 'percentage')
.attr('transform', d => `translate(${arc.centroid(d)})`)
.attr('text-anchor', 'middle')
.attr('fill', 'white')
.attr('font-weight', 'bold')
.text(d => {
const percent = ((d.endAngle - d.startAngle) / (2 * Math.PI) * 100).toFixed(1);
return `${percent}%`;
});
Donut Chart (add inner radius):
const arc = d3.arc()
.innerRadius(80) // Creates donut hole
.outerRadius(150);
Corner Radius (rounded corners):
const arc = d3.arc()
.innerRadius(80)
.outerRadius(150)
.cornerRadius(5);
References:
docs/d3/shape/pie.mddocs/d3/shape/arc.mdQuestion: "How do I create a stacked area chart?"
Response:
import * as d3 from 'd3';
const data = [
{ date: new Date('2024-01-01'), apples: 30, bananas: 20, oranges: 10 },
{ date: new Date('2024-01-02'), apples: 45, bananas: 35, oranges: 15 },
{ date: new Date('2024-01-03'), apples: 40, bananas: 30, oranges: 20 },
{ date: new Date('2024-01-04'), apples: 60, bananas: 40, oranges: 25 },
];
// Define stack keys (series)
const keys = ['apples', 'bananas', 'oranges'];
// Create stack layout
const stack = d3.stack()
.keys(keys)
.order(d3.stackOrderNone) // Keep original order
.offset(d3.stackOffsetNone); // Start from zero
// Generate stack data
const stackedData = stack(data);
// [
// [[0, 30], [0, 45], ...], // apples layer
// [[30, 50], [45, 80], ...], // bananas layer
// [[50, 60], [80, 95], ...], // oranges layer
// ]
// Create scales
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, 800]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(stackedData[stackedData.length - 1], d => d[1])])
.range([400, 0])
.nice();
// Create area generator
const area = d3.area()
.x(d => xScale(d.data.date))
.y0(d => yScale(d[0])) // Bottom of stack
.y1(d => yScale(d[1])) // Top of stack
.curve(d3.curveMonotoneX);
// Color scale
const color = d3.scaleOrdinal()
.domain(keys)
.range(d3.schemeCategory10);
// Create SVG
const svg = d3.create('svg')
.attr('width', 800)
.attr('height', 400);
// Add layers
svg.selectAll('path')
.data(stackedData)
.join('path')
.attr('d', area)
.attr('fill', d => color(d.key))
.attr('stroke', 'white')
.attr('stroke-width', 1);
// Add legend
const legend = svg.append('g')
.attr('transform', 'translate(700, 20)');
legend.selectAll('rect')
.data(keys)
.join('rect')
.attr('y', (d, i) => i * 25)
.attr('width', 20)
.attr('height', 20)
.attr('fill', d => color(d));
legend.selectAll('text')
.data(keys)
.join('text')
.attr('x', 25)
.attr('y', (d, i) => i * 25 + 15)
.text(d => d);
Stack Orders:
stackOrderNone - Original orderstackOrderAscending - Smallest on topstackOrderDescending - Largest on topstackOrderInsideOut - Largest in middleStack Offsets:
stackOffsetNone - Zero baselinestackOffsetExpand - Normalize to [0, 1]stackOffsetSilhouette - Center around zerostackOffsetWiggle - Minimize changes in slopeReferences:
docs/d3/shape/stack.mdQuestion: "How do I use D3 symbols for scatter plots?"
Response:
import * as d3 from 'd3';
const data = [
{ x: 30, y: 20, type: 'A' },
{ x: 50, y: 80, type: 'B' },
{ x: 80, y: 50, type: 'A' },
{ x: 120, y: 90, type: 'C' },
];
// Create scales
const xScale = d3.scaleLinear()
.domain([0, 150])
.range([0, 800]);
const yScale = d3.scaleLinear()
.domain([0, 100])
.range([400, 0]);
// Symbol types
const symbolTypes = [
d3.symbolCircle,
d3.symbolSquare,
d3.symbolTriangle,
d3.symbolStar,
d3.symbolDiamond,
d3.symbolCross,
];
// Symbol scale
const symbolScale = d3.scaleOrdinal()
.domain(['A', 'B', 'C'])
.range([d3.symbolCircle, d3.symbolSquare, d3.symbolTriangle]);
// Create symbol generator
const symbol = d3.symbol()
.size(200); // Area in square pixels
// Create SVG
const svg = d3.create('svg')
.attr('width', 800)
.attr('height', 400);
// Add symbols
svg.selectAll('path')
.data(data)
.join('path')
.attr('d', d => {
symbol.type(symbolScale(d.type));
return symbol();
})
.attr('transform', d => `translate(${xScale(d.x)}, ${yScale(d.y)})`)
.attr('fill', 'steelblue')
.attr('stroke', 'white')
.attr('stroke-width', 2);
Available Symbol Types:
symbolCircle - CirclesymbolSquare - SquaresymbolTriangle - Upward trianglesymbolStar - Five-pointed starsymbolDiamond - DiamondsymbolCross - Plus signsymbolWye - Y shapeCustom Symbol:
const customSymbol = {
draw(context, size) {
const r = Math.sqrt(size / 5) / 2;
context.moveTo(-3 * r, -r);
context.lineTo(-r, -r);
context.lineTo(-r, -3 * r);
context.lineTo(r, -3 * r);
context.lineTo(r, -r);
context.lineTo(3 * r, -r);
context.lineTo(3 * r, r);
context.lineTo(r, r);
context.lineTo(r, 3 * r);
context.lineTo(-r, 3 * r);
context.lineTo(-r, r);
context.lineTo(-3 * r, r);
context.closePath();
},
};
const symbol = d3.symbol()
.type(customSymbol)
.size(200);
References:
docs/d3/shape/symbol.mdconst line = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
.curve(d3.curveMonotoneX);
svg.append('path')
.datum(data)
.attr('d', line)
.attr('fill', 'none')
.attr('stroke', 'steelblue')
.attr('stroke-width', 2);
const arc = d3.arc()
.innerRadius(80)
.outerRadius(150);
const arcHover = d3.arc()
.innerRadius(80)
.outerRadius(160); // Larger
svg.selectAll('path')
.on('mouseenter', function() {
d3.select(this).transition()
.attr('d', arcHover);
})
.on('mouseleave', function() {
d3.select(this).transition()
.attr('d', arc);
});
const link = d3.linkHorizontal()
.x(d => d.x)
.y(d => d.y);
const linkData = {
source: { x: 0, y: 100 },
target: { x: 200, y: 150 },
};
svg.append('path')
.attr('d', link(linkData))
.attr('fill', 'none')
.attr('stroke', 'black');
# Find line/area docs
grep -r "line\|area\|curve" /Users/zach/Documents/cc-skills/docs/d3/shape/
# Find pie/arc docs
grep -r "pie\|arc\|donut" /Users/zach/Documents/cc-skills/docs/d3/shape/
# Find stack docs
grep -r "stack\|layer" /Users/zach/Documents/cc-skills/docs/d3/shape/
# Find symbol docs
grep -r "symbol\|scatter" /Users/zach/Documents/cc-skills/docs/d3/shape/
# Find path operations
grep -r "path\|serialize" /Users/zach/Documents/cc-skills/docs/d3/path/
# List shape generators
ls /Users/zach/Documents/cc-skills/docs/d3/shape/
Path not rendering: Check scale domains match data range
Area chart inverted: Y scale range is backwards
Pie chart off-center: Missing transform translate
transform="translate(cx, cy)" to groupGaps in line: Null/undefined values in data
.defined(d => d.value != null)Stack negative values: stackOffsetNone doesn't handle negatives
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience