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

Ir para a instalação

Informações da origem

Repositório
reason-machines/claude-code-skills
Última atividade na origem
3 de junho de 2026 às 03:12
Idioma detectado do SKILL.md
inglês
Estrelas
4
Forks
1

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
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')
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub