data-viz-2025 by erichowens/some_claude_skills
npx skills add https://github.com/erichowens/some_claude_skills --skill data-viz-2025创建 Seaborn 用户、Tufte 读者以及所有人都会喜爱的可视化作品。融合《纽约时报》图形的严谨性、MoMA 的美学、Nike 的活力以及 On Kawara 的精确性。
✅ 适用于:
❌ 不适用于:
每个视觉元素都必须有其存在的价值。移除图表垃圾,最大化信噪比。
可视化是艺术。运用弹簧物理、深思熟虑的色彩和优质的设计系统。
数据表示必须诚实。严格测试,记录假设,保留上下文。
What are you building?
├─ Exploratory analysis / many iterations
│ └─ → Observable Plot (grammar-of-graphics)
│
├─ Standard business charts (bars, lines, pies)
│ ├─ Simple React integration needed
│ │ └─ → Recharts (easiest, most popular)
│ └─ Premium aesthetics + theming
│ └─ → Nivo (beautiful out of the box)
│
├─ Custom, one-of-a-kind visualizations
│ ├─ Need low-level control
│ │ └─ → Visx (React + D3 primitives)
│ └─ Full D3 power
│ └─ → D3.js directly (steeper learning curve)
│
└─ Dashboard with Tailwind design system
├─ → Tremor (purpose-built for dashboards)
└─ → shadcn-ui Charts (Recharts + shadcn styling)
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
{
"dependencies": {
"@observablehq/plot": "^0.6.0", // Exploratory, grammar-of-graphics
"recharts": "^2.12.0", // React charts, simple & popular
"@nivo/core": "^0.87.0", // Beautiful, themeable charts
"@visx/visx": "^3.10.0", // Low-level D3 + React primitives
"d3": "^7.9.0", // Direct D3 for custom work
"@tremor/react": "^3.15.0", // Tailwind dashboard components
"framer-motion": "^11.0.0" // Smooth animations
},
"devDependencies": {
"@percy/cli": "^1.29.0", // Visual regression testing
"@testing-library/react": "^14.2.0", // Component testing
"@storybook/react": "^7.6.0" // Component playground
}
}
Observable Plot - 你希望在 JavaScript 中使用 ggplot2/Vega-Lite
Recharts - 你希望它在 React 中“开箱即用”
<Component />)Nivo - 你希望获得视觉上令人惊叹的结果
Visx - 你希望使用 React 模式获得最大控制权
D3.js - 你希望获得无限的力量(和责任)
useEffect 和 useRef 一起使用在发布任何可视化之前,请验证:
阅读 references/tufte-principles.md 深入了解。
《纽约时报》图形团队流程:
阅读 references/nyt-workflow.md 获取案例研究。
数据可视化不是静态的。运动传达信息:
// Use spring physics, not linear easing
const springConfig = {
type: "spring",
stiffness: 300,
damping: 30
};
// Stagger for multiple elements
const staggerChildren = {
delayChildren: 0.1,
staggerChildren: 0.05
};
// Respect prefers-reduced-motion
const shouldAnimate = !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
阅读 references/animation-patterns.md 获取完整的模式库。
// Qualitative (categorical data)
const categorical = [
"#d97706", "#7c3aed", "#059669", "#dc2626", "#2563eb"
];
// Sequential (ordered data, low to high)
const sequential = [
"#fef3c7", "#fcd34d", "#f59e0b", "#d97706", "#92400e"
];
// Diverging (data with meaningful center)
const diverging = [
"#dc2626", "#f87171", "#fef2f2", "#c7d2fe", "#6366f1"
];
# Percy - Automated visual testing
npx percy snapshot ./storybook-static
# Chromatic - For Storybook
npx chromatic --project-token=<token>
// Verify rendered elements match data
test('bar chart renders correct number of bars', () => {
const data = [{ x: 'A', y: 10 }, { x: 'B', y: 20 }];
render(<BarChart data={data} />);
const bars = screen.getAllByTestId('bar');
expect(bars).toHaveLength(2);
});
// Verify scale accuracy
test('bar heights proportional to values', () => {
const data = [{ x: 'A', y: 10 }, { x: 'B', y: 20 }];
render(<BarChart data={data} />);
const bars = screen.getAllByTestId('bar');
const heights = bars.map(b => parseInt(b.style.height));
expect(heights[1]).toBe(heights[0] * 2); // B is 2x A
});
阅读 references/testing-strategies.md 获取全面的测试套件。
// Desktop: Show everything
// Tablet: Simplify axes, reduce labels
// Mobile: Minimal chart, key insights only
const ChartResponsive = ({ data }: Props) => {
const isMobile = useMediaQuery('(max-width: 640px)');
return (
<ResponsiveContainer width="100%" height={isMobile ? 200 : 400}>
<LineChart data={data}>
{!isMobile && <CartesianGrid strokeDasharray="3 3" />}
<XAxis
dataKey="date"
tick={isMobile ? { fontSize: 10 } : undefined}
interval={isMobile ? 'preserveStartEnd' : 'auto'}
/>
<YAxis tick={isMobile ? false : undefined} />
<Tooltip />
<Line type="monotone" dataKey="value" stroke="#d97706" />
</LineChart>
</ResponsiveContainer>
);
};
每个可视化都在讲述一个故事。遵循叙事弧线:
阅读 references/data-storytelling.md 获取叙事框架。
问题: 12 种颜色,极小的扇区,图例在侧面 解决方案: 最多 5 个类别,直接标签,考虑改用条形图
问题: Y 轴不从零开始,夸大了差异 解决方案: 条形图始终从零开始(折线图可以变化)
问题: 两个 Y 轴使用不同的比例尺,误导观看者 解决方案: 使用单独的图表或归一化到相同的比例尺
问题: 3D 效果扭曲了数据感知 解决方案: 坚持使用 2D,用颜色/大小表示第三维度
问题: 空白屏幕显示旋转器超过 2 秒 解决方案: 骨架屏加载,立即显示图表结构
阅读 references/antipatterns.md 获取详尽目录。
# Use Observable Plot for rapid iteration
npm install @observablehq/plot
# Create throwaway prototypes, iterate fast
# When you find the right chart, implement in production library
// Use Recharts for standard charts
// Use Nivo for beautiful, themeable charts
// Use Visx/D3 for custom visualizations
// Always wrap in error boundaries
// Always show skeleton loading state
// Always handle empty/loading/error states
# Visual regression testing
npx percy snapshot
# Component testing
npm test -- --coverage
# Accessibility testing
npx axe-core src/components/charts
// Storybook for component playground
// Props documentation with TypeScript
// Usage examples for each chart type
const generateInsight = async (data: DataPoint[]) => {
const response = await fetch('/api/claude', {
method: 'POST',
body: JSON.stringify({
model: 'claude-haiku',
prompt: `Analyze this data and provide ONE key insight (max 15 words): ${JSON.stringify(data)}`
})
});
return response.text(); // "Sales peaked in Q3, driven by mobile conversions"
};
定期研究这些:
// ❌ DON'T import entire library
import { LineChart } from 'recharts';
// ✅ DO tree-shake where possible
import LineChart from 'recharts/lib/chart/LineChart';
// Use dynamic imports for heavy charts
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <ChartSkeleton />,
ssr: false // Disable SSR for client-only charts
});
对于大型数据集,仅渲染可见部分:
// Use react-window or react-virtualized for long lists
// Aggregate/sample data for chart display
// Store full dataset separately for export
prefers-reduced-motion: reduce<figure role="img" aria-labelledby="chart-title chart-desc">
<h2 id="chart-title">Sales Over Time</h2>
<p id="chart-desc">
Line chart showing sales increased 45% from Q1 to Q4,
peaking in November at $2.3M.
</p>
<LineChart data={data} />
{/* Provide data table alternative */}
<details>
<summary>View data table</summary>
<table>...</table>
</details>
</figure>
此技能包含全面的参考文档:
references/tufte-principles.md - Edward Tufte 的数据可视化原则及示例references/library-comparison.md - 深入探讨 Observable Plot、Recharts、Nivo、Visx、D3references/testing-strategies.md - 视觉回归、组件测试、无障碍测试references/animation-patterns.md - 图表的动效设计模式references/data-storytelling.md - 叙事技巧和滚动叙事模式references/antipatterns.md - 常见错误及如何避免references/nyt-workflow.md - 《纽约时报》图形团队最佳实践scripts/data-transform.ts - 常见数据转换(汇总、透视、归一化)scripts/chart-test-helpers.ts - 验证图表准确性的测试工具scripts/color-palette-generator.ts - 生成无障碍调色板scripts/performance-benchmark.ts - 基准测试图表渲染性能// 1. Install dependencies
// npm install recharts framer-motion
// 2. Create a simple line chart
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
import { motion } from 'framer-motion';
const data = [
{ month: 'Jan', value: 400 },
{ month: 'Feb', value: 300 },
{ month: 'Mar', value: 600 },
];
export const SalesChart = () => (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Line
type="monotone"
dataKey="value"
stroke="#d97706"
strokeWidth={2}
dot={{ fill: '#d97706', r: 4 }}
/>
</LineChart>
</ResponsiveContainer>
</motion.div>
);
// 3. Test it
// 4. Ship it with confidence
记住: 最好的可视化是让洞察变得显而易见的那一个。如有疑问,就简化。如果感到困惑,就制作 10 个选项的原型。发布时,要无情地测试。
此技能指导:图表选择 | 库集成 | 测试策略 | 动画模式 | 无障碍合规 | 性能优化
每周安装量
94
代码仓库
GitHub 星标数
76
首次出现
2026 年 1 月 23 日
安全审计
安装于
opencode80
gemini-cli79
codex79
cursor75
github-copilot70
cline64
Create visualizations that Seaborn users, Tufte readers, and everyone else will love. Marry NYT Graphics rigor with MoMA aesthetics, Nike energy, and On Kawara precision.
✅ Use for:
❌ NOT for:
Every visual element must earn its place. Remove chart junk, maximize signal-to-noise.
Visualizations are art. Use spring physics, thoughtful color, and premium design systems.
Data representation must be honest. Test rigorously, document assumptions, preserve context.
What are you building?
├─ Exploratory analysis / many iterations
│ └─ → Observable Plot (grammar-of-graphics)
│
├─ Standard business charts (bars, lines, pies)
│ ├─ Simple React integration needed
│ │ └─ → Recharts (easiest, most popular)
│ └─ Premium aesthetics + theming
│ └─ → Nivo (beautiful out of the box)
│
├─ Custom, one-of-a-kind visualizations
│ ├─ Need low-level control
│ │ └─ → Visx (React + D3 primitives)
│ └─ Full D3 power
│ └─ → D3.js directly (steeper learning curve)
│
└─ Dashboard with Tailwind design system
├─ → Tremor (purpose-built for dashboards)
└─ → shadcn-ui Charts (Recharts + shadcn styling)
{
"dependencies": {
"@observablehq/plot": "^0.6.0", // Exploratory, grammar-of-graphics
"recharts": "^2.12.0", // React charts, simple & popular
"@nivo/core": "^0.87.0", // Beautiful, themeable charts
"@visx/visx": "^3.10.0", // Low-level D3 + React primitives
"d3": "^7.9.0", // Direct D3 for custom work
"@tremor/react": "^3.15.0", // Tailwind dashboard components
"framer-motion": "^11.0.0" // Smooth animations
},
"devDependencies": {
"@percy/cli": "^1.29.0", // Visual regression testing
"@testing-library/react": "^14.2.0", // Component testing
"@storybook/react": "^7.6.0" // Component playground
}
}
Observable Plot - You want ggplot2/Vega-Lite in JavaScript
Recharts - You want it to "just work" in React
<Component />)Nivo - You want visually stunning results
Visx - You want maximum control with React patterns
D3.js - You want unlimited power (and responsibility)
useEffect and useRef in ReactBefore shipping any visualization, verify:
Read references/tufte-principles.md for deep dive.
The New York Times graphics team process:
Read references/nyt-workflow.md for case studies.
Data viz isn't static. Movement communicates:
// Use spring physics, not linear easing
const springConfig = {
type: "spring",
stiffness: 300,
damping: 30
};
// Stagger for multiple elements
const staggerChildren = {
delayChildren: 0.1,
staggerChildren: 0.05
};
// Respect prefers-reduced-motion
const shouldAnimate = !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
Read references/animation-patterns.md for complete patterns library.
// Qualitative (categorical data)
const categorical = [
"#d97706", "#7c3aed", "#059669", "#dc2626", "#2563eb"
];
// Sequential (ordered data, low to high)
const sequential = [
"#fef3c7", "#fcd34d", "#f59e0b", "#d97706", "#92400e"
];
// Diverging (data with meaningful center)
const diverging = [
"#dc2626", "#f87171", "#fef2f2", "#c7d2fe", "#6366f1"
];
# Percy - Automated visual testing
npx percy snapshot ./storybook-static
# Chromatic - For Storybook
npx chromatic --project-token=<token>
// Verify rendered elements match data
test('bar chart renders correct number of bars', () => {
const data = [{ x: 'A', y: 10 }, { x: 'B', y: 20 }];
render(<BarChart data={data} />);
const bars = screen.getAllByTestId('bar');
expect(bars).toHaveLength(2);
});
// Verify scale accuracy
test('bar heights proportional to values', () => {
const data = [{ x: 'A', y: 10 }, { x: 'B', y: 20 }];
render(<BarChart data={data} />);
const bars = screen.getAllByTestId('bar');
const heights = bars.map(b => parseInt(b.style.height));
expect(heights[1]).toBe(heights[0] * 2); // B is 2x A
});
Read references/testing-strategies.md for comprehensive test suites.
// Desktop: Show everything
// Tablet: Simplify axes, reduce labels
// Mobile: Minimal chart, key insights only
const ChartResponsive = ({ data }: Props) => {
const isMobile = useMediaQuery('(max-width: 640px)');
return (
<ResponsiveContainer width="100%" height={isMobile ? 200 : 400}>
<LineChart data={data}>
{!isMobile && <CartesianGrid strokeDasharray="3 3" />}
<XAxis
dataKey="date"
tick={isMobile ? { fontSize: 10 } : undefined}
interval={isMobile ? 'preserveStartEnd' : 'auto'}
/>
<YAxis tick={isMobile ? false : undefined} />
<Tooltip />
<Line type="monotone" dataKey="value" stroke="#d97706" />
</LineChart>
</ResponsiveContainer>
);
};
Every visualization tells a story. Follow the narrative arc:
Read references/data-storytelling.md for narrative frameworks.
Problem: 12 colors, tiny slices, legend on the side Solution: Max 5 categories, direct labels, consider bar chart instead
Problem: Y-axis doesn't start at zero, exaggerates differences Solution: Always start at zero for bar charts (lines can vary)
Problem: Two Y-axes with different scales mislead viewers Solution: Use separate charts or normalize to same scale
Problem: 3D effects distort data perception Solution: Stick to 2D, use color/size for third dimension
Problem: Empty screen with spinner for 2+ seconds Solution: Skeleton loading that shows chart structure immediately
Read references/antipatterns.md for exhaustive catalog.
# Use Observable Plot for rapid iteration
npm install @observablehq/plot
# Create throwaway prototypes, iterate fast
# When you find the right chart, implement in production library
// Use Recharts for standard charts
// Use Nivo for beautiful, themeable charts
// Use Visx/D3 for custom visualizations
// Always wrap in error boundaries
// Always show skeleton loading state
// Always handle empty/loading/error states
# Visual regression testing
npx percy snapshot
# Component testing
npm test -- --coverage
# Accessibility testing
npx axe-core src/components/charts
// Storybook for component playground
// Props documentation with TypeScript
// Usage examples for each chart type
const generateInsight = async (data: DataPoint[]) => {
const response = await fetch('/api/claude', {
method: 'POST',
body: JSON.stringify({
model: 'claude-haiku',
prompt: `Analyze this data and provide ONE key insight (max 15 words): ${JSON.stringify(data)}`
})
});
return response.text(); // "Sales peaked in Q3, driven by mobile conversions"
};
Study these regularly:
// ❌ DON'T import entire library
import { LineChart } from 'recharts';
// ✅ DO tree-shake where possible
import LineChart from 'recharts/lib/chart/LineChart';
// Use dynamic imports for heavy charts
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <ChartSkeleton />,
ssr: false // Disable SSR for client-only charts
});
For large datasets, render only visible portion:
// Use react-window or react-virtualized for long lists
// Aggregate/sample data for chart display
// Store full dataset separately for export
prefers-reduced-motion: reduce<figure role="img" aria-labelledby="chart-title chart-desc">
<h2 id="chart-title">Sales Over Time</h2>
<p id="chart-desc">
Line chart showing sales increased 45% from Q1 to Q4,
peaking in November at $2.3M.
</p>
<LineChart data={data} />
{/* Provide data table alternative */}
<details>
<summary>View data table</summary>
<table>...</table>
</details>
</figure>
This skill includes comprehensive reference documentation:
references/tufte-principles.md - Edward Tufte's data visualization principles with examplesreferences/library-comparison.md - Deep dive on Observable Plot, Recharts, Nivo, Visx, D3references/testing-strategies.md - Visual regression, component testing, accessibility testingreferences/animation-patterns.md - Motion design patterns for chartsreferences/data-storytelling.md - Narrative techniques and scrollytelling patternsreferences/antipatterns.md - Common mistakes and how to avoid themreferences/nyt-workflow.md - New York Times graphics team best practicesscripts/data-transform.ts - Common data transformations (rollup, pivot, normalize)scripts/chart-test-helpers.ts - Testing utilities for verifying chart accuracyscripts/color-palette-generator.ts - Generate accessible color palettesscripts/performance-benchmark.ts - Benchmark chart rendering performance// 1. Install dependencies
// npm install recharts framer-motion
// 2. Create a simple line chart
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
import { motion } from 'framer-motion';
const data = [
{ month: 'Jan', value: 400 },
{ month: 'Feb', value: 300 },
{ month: 'Mar', value: 600 },
];
export const SalesChart = () => (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Line
type="monotone"
dataKey="value"
stroke="#d97706"
strokeWidth={2}
dot={{ fill: '#d97706', r: 4 }}
/>
</LineChart>
</ResponsiveContainer>
</motion.div>
);
// 3. Test it
// 4. Ship it with confidence
Remember: The best visualization is the one that makes the insight obvious. When in doubt, simplify. When confused, prototype 10 options. When shipping, test ruthlessly.
This skill guides: Chart selection | Library integration | Testing strategies | Animation patterns | Accessibility compliance | Performance optimization
Weekly Installs
94
Repository
GitHub Stars
76
First Seen
Jan 23, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode80
gemini-cli79
codex79
cursor75
github-copilot70
cline64
Vue 3 调试指南:解决响应式、计算属性与监听器常见错误
11,900 周安装
Motion动画库指南:高性能JavaScript/TypeScript网页动效开发与性能优化
123 周安装
Node.js开发专家指南:TypeScript、Payload CMS、Next.js与Vue.js全栈实战
122 周安装
Tailwind CSS 最佳实践指南:29条规则构建响应式、可维护界面(含v4迁移)
120 周安装
产品需求文档(PRD)创建指南与模板 - SDD工作流第2层产物,含双重评分标准
127 周安装
KPI仪表盘设计指南:业务指标可视化框架、布局原则与最佳实践
129 周安装
Solidity智能合约开发专家 | 安全模式与Gas优化最佳实践指南
127 周安装