Skip to main content

tufte-chart-design

Apply Edward Tufte's visualization principles to produce data-honest, high data-ink ratio charts with minimal chartjunk

Zur Installation springen

Quellinformationen

Repository
reason-machines/claude-code-skills
Letzte Quellaktivität
3. Juni 2026 um 03:12
Erkannte Sprache von SKILL.md
Englisch
Sterne
4
Forks
1

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
tufte-chart-design
description
Apply Edward Tufte's visualization principles to produce data-honest, high data-ink ratio charts with minimal chartjunk
triggers
["make a chart","create a visualization","design a dashboard","improve this chart","what chart should I use","apply Tufte principles","visualize this data","build a graph"]
# Tufte Chart Design Skill > Skill by [ara.so](https://ara.so) — Claude Code Skills collection. This skill teaches you to create charts following Edward Tufte's principles from his three foundational books: *The Visual Display of Quantitative Information*, *Envisioning Information*, and *Visual Explanations*. It turns "make me a chart" into a Tufte-compliant visualization with maximum data-ink ratio and zero chartjunk. ## What This Skill Does - **Activates automatically** when you're asked to create, improve, or critique any chart or visualization - **Applies ten core principles** distilled from Tufte's work - **Chooses the right chart type** based on data shape and analytical goal - **Removes chartjunk** — 3D effects, unnecessary gridlines, redundant legends, pie charts, dual axes - **Produces clean output** as inline SVG, React (Recharts), or D3-in-React - **Enforces graphical integrity** — lie factor between 0.95 and 1.05, bars always start at zero ## The Ten Principles 1. **Show the data** — Above all else. Every decision asks "does this help see the data?" 2. **Maximize data-ink ratio** — Ink that changes when data changes is data-ink. Everything else is overhead. 3. **Erase non-data-ink** — Remove frame boxes, gridlines, tick marks at minor units. 4. **Erase redundant data-ink** — One encoding per quantity. Don't show "37" as a bar + number + gridline + tick. 5. **Graphical integrity** — Bars start at zero. Never use area for 1D quantities. Lie factor = (size of effect shown) / (size of effect in data). 6. **Small multiples** — N small charts on shared scales beats one chart with N overlapping lines. 7. **Layering and separation** — Data on top, labels next, scaffolding faintest. Avoid 1+1=3 visual noise. 8. **Micro/macro readings** — One shape from across the room, every point legible up close. 9. **Smallest effective difference** — Gray for context, one accent for focus. Subtle but clear. 10. **Word-data integration** — Sparklines in sentences. Numbers next to visuals. Tables are charts. ## When This Skill Activates Auto-triggers on: - "Make a chart of...", "visualize...", "graph...", "plot..." - "Build a dashboard", "design a KPI tile" - "Improve this chart", "critique this visual" - "What chart should I use for...?" - `/tufte` command or mentioning Tufte by name - Any code editing session involving chart/visualization code Does NOT trigger for: - Logos, illustrations, decorative graphics - Flowcharts, architecture diagrams, wireframes - Pure typography or layout without quantitative data ## Chart Selection Guide | Data Shape | Goal | Use | NOT | |---|---|---|---| | One time series | Show trend | Sparkline or line chart | Area chart, bar chart | | Multiple time series | Compare trends | Small multiples (separate charts) | Multi-line spaghetti | | Categories (≤10) | Compare values | Sorted dot plot or bar chart | Pie, donut, 3D bars | | Categories (>10) | Show distribution | Strip plot or histogram | Rainbow color scales | | Two time points | Show change | Slopegraph | Clustered bars | | Part-to-whole | Show composition | Sorted table with percentages | Pie, donut, stacked bars | | Process stages | Show flow | Horizontal bars + percentages | 3D funnel | | Correlation | Show relationship | Scatterplot | Dual-axis line chart | | Cohorts over time | Show retention | Sequential heatmap + sparklines | Rainbow heatmap | | Geographic | Show regional pattern | Choropleth (single-hue sequential) | Rainbow choropleth | ## Kill List — Never Use ❌ **3D effects** — distort area perception, add no information ❌ **Pie charts** — humans can't compare angles; use sorted table instead ❌ **Donut charts** — same problem as pie, worse ❌ **Dual-axis charts** — viewer can't tell if correlation is real or axis-manipulation ❌ **Rainbow color scales** — perceptually non-uniform; use sequential single-hue ❌ **Gradient fills** — decorative ink, not data-ink ❌ **Drop shadows, glows** — chartjunk ❌ **Chart frames/boxes** — erase, data should float ❌ **Heavy gridlines** — if you need them, print values instead ❌ **Redundant legends** — direct-label instead ## HTML/SVG Output Pattern When asked for inline SVG or given no preference, use this pattern: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: 11px; color: #1a1a1a; background: white; padding: 40px; } .label { font-size: 10px; fill: #666; } .value { font-size: 13px; fill: #1a1a1a; font-weight: 500; } .data-point { fill: #1a1a1a; } .data-line { stroke: #1a1a1a; stroke-width: 1.5; fill: none; } .reference-line { stroke: #e0e0e0; stroke-width: 1; } .accent { fill: #d73027; } </style> </head> <body> <svg width="600" height="200" viewBox="0 0 600 200"> <!-- Data visualization here --> </svg> </body> </html> ``` ### Sparkline Example ```html <div style="font-family: sans-serif; padding: 20px;"> <div style="font-size: 11px; color: #666; margin-bottom: 4px;">Monthly Active Users</div> <div style="display: flex; align-items: baseline; gap: 12px;"> <span style="font-size: 24px; font-weight: 500; color: #1a1a1a;">247K</span> <svg width="120" height="24" style="display: block;"> <polyline points="0,18 10,15 20,16 30,14 40,12 50,13 60,10 70,9 80,11 90,8 100,6 110,4 120,3" stroke="#1a1a1a" stroke-width="1.5" fill="none" /> <text x="0" y="24" font-size="9" fill="#999">Jan</text> <text x="110" y="24" font-size="9" fill="#999" text-anchor="end">Dec</text> </svg> </div> </div> ``` ### Dot Plot Example ```html <svg width="400" height="180" viewBox="0 0 400 180"> <!-- Sorted by value, descending --> <circle cx="320" cy="20" r="4" fill="#1a1a1a"/> <text x="330" y="24" font-size="11" fill="#1a1a1a">Product A</text> <text x="310" y="24" font-size="11" fill="#666" text-anchor="end">$247K</text> <circle cx="280" cy="45" r="4" fill="#1a1a1a"/> <text x="290" y="49" font-size="11" fill="#1a1a1a">Product B</text> <text x="270" y="49" font-size="11" fill="#666" text-anchor="end">$213K</text> <circle cx="190" cy="70" r="4" fill="#1a1a1a"/> <text x="200" y="74" font-size="11" fill="#1a1a1a">Product C</text> <text x="180" y="74" font-size="11" fill="#666" text-anchor="end">$145K</text> <!-- Scale reference at bottom --> <line x1="0" y1="160" x2="320" y2="160" stroke="#e0e0e0" stroke-width="1"/> <text x="0" y="175" font-size="9" fill="#999">$0</text> <text x="320" y="175" font-size="9" fill="#999" text-anchor="end">$250K</text> </svg> ``` ## React/Recharts Output Pattern When asked for React or Recharts: ```jsx import { LineChart, Line, ResponsiveContainer, XAxis, YAxis } from 'recharts'; const data = [ { month: 'Jan', value: 180 }, { month: 'Feb', value: 195 }, { month: 'Mar', value: 205 }, { month: 'Apr', value: 198 }, { month: 'May', value: 215 }, { month: 'Jun', value: 247 }, ]; export default function RevenueChart() { return ( <div style={{ fontFamily: 'system-ui, sans-serif' }}> <div style={{ fontSize: 11, color: '#666', marginBottom: 4 }}> Monthly Revenue (thousands) </div> <ResponsiveContainer width="100%" height={120}> <LineChart data={data} margin={{ top: 5, right: 5, bottom: 5, left: 5 }}> <XAxis dataKey="month" axisLine={false} tickLine={false} tick={{ fontSize: 10, fill: '#999' }} interval="preserveStartEnd" /> <YAxis hide={true} /> <Line type="monotone" dataKey="value" stroke="#1a1a1a" strokeWidth={1.5} dot={false} /> </LineChart> </ResponsiveContainer> <div style={{ fontSize: 20, fontWeight: 500, color: '#1a1a1a' }}> $247K </div> </div> ); } ``` ### Recharts Theme Config Apply these props to strip chartjunk: ```jsx // Universal settings const tufteTheme = { xAxis: { axisLine: false, tickLine: false, tick: { fontSize: 10, fill: '#999' }, }, yAxis: { axisLine: false, tickLine: false, tick: { fontSize: 10, fill: '#999' }, // Often better to hide Y-axis and direct-label instead }, grid: { strokeDasharray: '3 3', stroke: '#f0f0f0', // very faint if you must show }, // NO tooltip by default — print values on chart // NO legend — direct label instead }; ``` ## D3-in-React Pattern (for Custom Charts) For slopegraphs, custom dot plots, small multiples: ```jsx import { useEffect, useRef } from 'react'; import * as d3 from 'd3'; export default function Slopegraph({ data }) { const svgRef = useRef(); useEffect(() => { const svg = d3.select(svgRef.current); const width = 400; const height = 300; const margin = { top: 20, right: 80, bottom: 20, left: 80 }; // Clear previous render svg.selectAll('*').remove(); const y = d3.scaleLinear() .domain([0, d3.max(data, d => Math.max(d.q2, d.q3))]) .range([height - margin.bottom, margin.top]); // Draw lines svg.selectAll('line.slope') .data(data) .join('line') .attr('class', 'slope') .attr('x1', margin.left) .attr('x2', width - margin.right) .attr('y1', d => y(d.q2)) .attr('y2', d => y(d.q3)) .attr('stroke', d => d.q3 < d.q2 ? '#d73027' : '#ccc') .attr('stroke-width', 1.5); // Left labels + values svg.selectAll('text.left-label') .data(data) .join('text') .attr('class', 'left-label') .attr('x', margin.left - 8) .attr('y', d => y(d.q2)) .attr('text-anchor', 'end') .attr('alignment-baseline', 'middle') .attr('font-size', 11) .attr('fill', '#1a1a1a') .text(d => `${d.team} ${d.q2}`); // Right values svg.selectAll('text.right-label') .data(data) .join('text') .attr('class', 'right-label') .attr('x', width - margin.right + 8) .attr('y', d => y(d.q3)) .attr('text-anchor', 'start') .attr('alignment-baseline', 'middle') .attr('font-size', 11) .attr('fill', '#1a1a1a') .text(d => d.q3); // Column headers svg.append('text') .attr('x', margin.left) .attr('y', 10) .attr('text-anchor', 'middle') .attr('font-size', 10) .attr('fill', '#666') .text('Q2'); svg.append('text')
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen