Skip to main content Skills Marketplace Descubre y explora habilidades de IA creadas por la comunidad.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Copiar promptMostrar detalles del prompt Un comando directo omite el prompt de revisión. Revisa el origen antes de ejecutarlo.
npx skills add https://github.com/InugamiDev/ultrathink-oss --skill d3El comando permanece en una sola línea. Desplázate horizontalmente para revisarlo antes de copiarlo.
¿Prefieres una copia local? Descarga los archivos que SkillsMP tiene disponibles ahora.
Descargar Zip Descargando... Más de este repositorio Unified design foundations — design system architecture, tokens, component specs, visual principles, creative vision, figma integration, plus brand design system loader (66 real brands via DESIGN.md). Absorbs design, design-system, design-systems, design-principles, design-router, creative-vision, figma, design-md.
Render, summarize, and present markdown documents and structured content in multiple output modes
Ultra UI skill - combines Google's DESIGN.md spec (machine-readable design tokens) with the ui-ux-pro-max knowledge base (91 styles, 161 palettes, 73 font pairings, 161 products, 104 UX guidelines, 25 chart types). Generates lint-clean DESIGN.md files, validates token references and WCAG contrast, exports Tailwind/DTCG tokens, and diffs design systems version-over-version.
Ocupaciones relacionadas SOC
Basado en la clasificación ocupacional SOC
name d3 description D3.js data visualization — scales, axes, SVG rendering, force layouts, transitions, geo projections, and idiomatic React integration patterns layer domain-specialist category visualization triggers ["d3 chart","data visualization","svg chart","force layout","d3 scales","bar chart","line chart","scatter plot","d3 transition","d3 react"] inputs ["Data shape (array of objects, nested, time series)","Chart type (bar, line, scatter, force, geo, treemap, etc.)","Interaction requirements (tooltips, zoom, brush, drag)","Target framework (vanilla, React, Svelte)"] outputs ["Complete chart component with scales, axes, and rendering","Responsive SVG layout with proper viewBox handling","Transition and animation code","Accessibility attributes (aria-label, role, desc)"] linksTo ["react","animation","responsive-design","css-variables"] linkedFrom ["ui-ux-pro","design-systems"] preferredNextSkills ["animation","responsive-design"] fallbackSkills ["threejs"] riskLevel low memoryReadPolicy selective memoryWritePolicy selective sideEffects ["Adds d3 dependencies to project","May add SVG elements to DOM"]
D3.js Data Visualization Skill
Purpose
D3 (Data-Driven Documents) binds data to DOM elements and applies data-driven transformations. This skill covers idiomatic D3 v7 patterns, React integration (letting D3 handle math, React handle DOM), and production-quality chart architecture.
Key Concepts
D3's Role: Math, Not DOM
In modern apps, D3 should compute — scales, layouts, paths, projections — while the framework (React, Svelte) owns the DOM. Only use D3's DOM manipulation (select, append, enter/exit) in vanilla JS or when D3 transitions are essential.
D3 Responsibility Split:
D3 owns: Scales, axes generators, path generators, layouts, transitions
React owns: DOM rendering, event handling, state, lifecycle
Core Primitives
Primitive Purpose Example Scales Map data domain to visual range scaleLinear().domain([0, 100]).range([0, 500])Axes Generate tick marks and labels axisBottom(xScale).ticks(5)Shapes Generate SVG path strings line().x(d => xScale(d.date)).y(d => yScale(d.value))Layouts Compute positions from data forceSimulation(nodes).force('charge', forceManyBody())Selections Bind data to DOM elements selectAll('rect').data(data).join('rect')Transitions Animate between states select(el).transition().duration(300).attr('y', newY)
Workflow
Step 1: Define the Data Contract
Always type your data before building:
interface DataPoint {
date : Date ;
value : number ;
category : string ;
}
interface {
: ;
: ;
: { : ; : ; : ; : };
}
( ): & {
: ;
: ;
} {
width = ;
height = ;
{
width,
height,
margin,
: width - margin. - margin. ,
: height - margin. - margin. ,
};
}
ChartDimensions
width
number
height
number
margin
top
number
right
number
bottom
number
left
number
function
useDimensions
margin : ChartDimensions ['margin' ]
ChartDimensions
innerWidth
number
innerHeight
number
const
800
const
400
return
innerWidth
left
right
innerHeight
top
bottom
Step 2: Build Scales import { scaleLinear, scaleTime, scaleBand, scaleOrdinal, extent, schemeTableau10 } from 'd3' ;
const yScale = scaleLinear ()
.domain ([0 , Math .max (...data.map (d => d.value ))])
.range ([innerHeight, 0 ])
.nice ();
const xScale = scaleTime ()
.domain (extent (data, d => d.date ) as [Date , Date ])
.range ([0 , innerWidth]);
const xBand = scaleBand<string >()
.domain (data.map (d => d.category ))
.range ([0 , innerWidth])
.padding (0.2 );
const colorScale = scaleOrdinal<string >()
.domain (categories)
.range (schemeTableau10);
Step 3: React Integration Pattern (Recommended) import { useRef, useEffect, useMemo } from 'react' ;
import {
scaleLinear, scaleBand, axisBottom, axisLeft,
select, max, line, curveMonotoneX,
} from 'd3' ;
interface BarChartProps {
data : { label : string ; value : number }[];
width ?: number ;
height ?: number ;
}
export function BarChart ({ data, width = 600 , height = 400 }: BarChartProps ) {
const margin = { top : 20 , right : 20 , bottom : 40 , left : 50 };
const innerWidth = width - margin.left - margin.right ;
const innerHeight = height - margin.top - margin.bottom ;
const xScale = useMemo (
() => scaleBand<string >()
.domain (data.map (d => d.label ))
.range ([0 , innerWidth])
.padding (0.2 ),
[data, innerWidth]
);
const yScale = useMemo (
() => scaleLinear ()
.domain ([0 , max (data, d => d.value ) ?? 0 ])
.range ([innerHeight, 0 ])
.nice (),
[data, innerHeight]
);
const xAxisRef = useRef<SVGGElement >(null );
const yAxisRef = useRef<SVGGElement >(null );
useEffect (() => {
if (xAxisRef.current ) {
select (xAxisRef.current ).call (axisBottom (xScale));
}
if (yAxisRef.current ) {
select (yAxisRef.current ).call (axisLeft (yScale).ticks (5 ));
}
}, [xScale, yScale]);
return (
<svg
width ={width}
height ={height}
viewBox ={ `0 0 ${width } ${height }`}
role ="img"
aria-label ={ `Bar chart with ${data.length } items `}
>
<g transform ={ `translate (${margin.left },${margin.top })`}>
{/* Bars — React renders, D3 computes positions */}
{data.map(d => (
<rect
key ={d.label}
x ={xScale(d.label)}
y ={yScale(d.value)}
width ={xScale.bandwidth()}
height ={innerHeight - yScale (d.value )}
fill ="var(--color-primary, #6366f1)"
rx ={4}
>
<title > {`${d.label}: ${d.value}`}</title >
</rect >
))}
{/* Axes — D3 renders via refs (imperative) */}
<g ref = = ` ( ,${ })`} />
);
}
Step 4: Line Chart with Transitions import { line, curveMonotoneX, select, transition } from 'd3' ;
function AnimatedLine ({
data,
xScale,
yScale,
}: {
data: DataPoint[];
xScale: d3.ScaleTime<number , number >;
yScale: d3.ScaleLinear<number , number >;
} ) {
const pathRef = useRef<SVGPathElement >(null );
const lineGenerator = useMemo (
() => line<DataPoint >()
.x (d => xScale (d.date ))
.y (d => yScale (d.value ))
.curve (curveMonotoneX),
[xScale, yScale]
);
const pathD = lineGenerator (data) ?? '' ;
useEffect (() => {
if (!pathRef.current ) return ;
const path = select (pathRef.current );
const length = path.node ()!.getTotalLength ();
path
.attr ('stroke-dasharray' , `${length} ${length} ` )
.attr ('stroke-dashoffset' , length)
.transition ()
.duration (800 )
.attr ('stroke-dashoffset' , 0 );
}, [pathD]);
return (
<path
ref ={pathRef}
d ={pathD}
fill ="none"
stroke ="var(--color-primary, #6366f1)"
strokeWidth ={2}
/>
);
}
Step 5: Force Layout import {
forceSimulation, forceLink, forceManyBody,
forceCenter, forceCollide, SimulationNodeDatum ,
} from 'd3' ;
interface Node extends SimulationNodeDatum {
id : string ;
group : number ;
}
interface Link {
source : string ;
target : string ;
value : number ;
}
function useForceLayout (nodes : Node [], links : Link [], width : number , height : number ) {
const [simulatedNodes, setSimulatedNodes] = useState<Node []>([]);
useEffect (() => {
const simulation = forceSimulation (nodes)
.force ('link' , forceLink<Node , Link >(links).id (d => d.id ).distance (80 ))
.force ('charge' , forceManyBody ().strength (-200 ))
.force ('center' , forceCenter (width / 2 , height / 2 ))
.force ('collision' , forceCollide ().radius (20 ));
simulation.on ('tick' , () => {
setSimulatedNodes ([...simulation.nodes ()]);
});
return () => { simulation.stop (); };
}, [nodes, links, width, height]);
return simulatedNodes;
}
Step 6: Responsive Charts function useResizeObserver (ref : React .RefObject <HTMLDivElement > ) {
const [dimensions, setDimensions] = useState ({ width : 0 , height : 0 });
useEffect (() => {
const el = ref.current ;
if (!el) return ;
const observer = new ResizeObserver (entries => {
const { width, height } = entries[0 ].contentRect ;
setDimensions ({ width, height });
});
observer.observe (el);
return () => observer.disconnect ();
}, [ref]);
return dimensions;
}
function ResponsiveChart ({ data }: { data: DataPoint[] } ) {
const containerRef = useRef<HTMLDivElement >(null );
const { width, height } = useResizeObserver (containerRef);
return (
<div ref ={containerRef} style ={{ width: '100 %', aspectRatio: '16 /9 ' }}>
{width > 0 && (
<BarChart data ={data} width ={width} height ={height} />
)}
</div >
);
}
Common Pitfalls
D3 fighting React for DOM control — Never use d3.select().append() inside React components for elements React should own. Use D3 for math only; let React render SVG elements. Exception: axes (use refs).
Missing key prop on mapped SVG elements — D3's join() handles enter/update/exit, but React needs key. Always add unique keys to mapped <rect>, <circle>, etc.
Not using viewBox — Hardcoded width/height without viewBox breaks responsive behavior. Always set viewBox and let CSS control the actual size.
Forgetting .nice() on scales — Domain [0, 97] produces ugly axis ticks. .nice() rounds to [0, 100].
Importing all of D3 — import * as d3 from 'd3' bundles ~500KB. Import specific modules: d3-scale, d3-shape, d3-axis.
Transition memory leaks — D3 transitions on unmounted elements throw. Always clean up simulations and cancel transitions in useEffect cleanup.
Examples
Example 1: Dashboard Sparkline (Minimal) function Sparkline ({ data, width = 120 , height = 32 }: {
data: number [];
width?: number ;
height?: number ;
} ) {
const xScale = scaleLinear ().domain ([0 , data.length - 1 ]).range ([0 , width]);
const yScale = scaleLinear ().domain (extent (data) as [number , number ]).range ([height - 2 , 2 ]);
const pathD = line<number >()
.x ((_, i ) => xScale (i))
.y (d => yScale (d))
.curve (curveMonotoneX)(data);
return (
<svg width ={width} height ={height} aria-label ="Sparkline trend" >
<path d ={pathD ?? ''} fill ="none" stroke ="currentColor" strokeWidth ={1.5} />
</svg >
);
}
Example 2: Donut Chart import { pie, arc, PieArcDatum } from 'd3' ;
function DonutChart ({ data }: { data: { label: string ; value: number }[] } ) {
const size = 200 ;
const radius = size / 2 ;
const innerRadius = radius * 0.6 ;
const pieGen = pie<{ label : string ; value : number }>().value (d => d.value ).sort (null );
const arcGen = arc<PieArcDatum <{ label : string ; value : number }>>()
.innerRadius (innerRadius)
.outerRadius (radius)
.cornerRadius (4 )
.padAngle (0.02 );
return (
<svg width ={size} height ={size} viewBox ={ `0 0 ${size } ${size }`}>
<g transform ={ `translate (${radius },${radius })`}>
{pieGen(data).map((d, i) => (
<path
key ={d.data.label}
d ={arcGen(d) ?? ''}
fill ={schemeTableau10[i % 10 ]}
>
<title > {`${d.data.label}: ${d.data.value}`}</title >
</path >
))}
</g >
</svg >
);
}
Example 3: Geo/Map Projection import { geoMercator, geoPath, GeoPermissibleObjects } from 'd3' ;
const projection = geoMercator ()
.center ([-98 , 39 ])
.scale (800 )
.translate ([width / 2 , height / 2 ]);
const pathGenerator = geoPath ().projection (projection);
Best Practices
Tree-shake imports : import { scaleLinear } from 'd3-scale' not from 'd3'
Memoize generators : Wrap useMemo around scale/line/arc generators that depend on data/dimensions
Accessibility : Add role="img", aria-label, <title> on SVG, <desc> for complex charts
Color : Use d3-scale-chromatic for perceptually uniform palettes; test with colorblindness simulators
Performance : For >10K elements, use Canvas (d3 can compute positions, draw to <canvas> instead of SVG)
{xAxisRef}
transform
{
translate
0
innerHeight
<g ref ={yAxisRef} />
</g >
</svg >