mcpField
D
data-viz-2025

data-viz-2025

github.com/curiositech数据与数据库257305 次安装2 天前更新
代码仓库

关于 data-viz-2025

面向构建交互式图表、仪表板和数据故事的可视化指导技能,适用于开发者与数据团队。涵盖图表库选型、设计原则、响应式实现、无障碍和测试。

主要功能

  1. 01图表库选型与比较
  2. 02清晰、准确的图表设计
  3. 03动画与交互模式
  4. 04响应式与无障碍实践
  5. 05可视化测试策略
  6. 06数据故事叙述方法

适用场景

  1. 01为业务仪表板选择图表库
  2. 02构建交互式或实时数据展示
  3. 03检查图表的准确性与无障碍性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/curiositech/some_claude_skills --skill data-viz-2025

安装后在 Claude Code 中输入/data-viz-2025确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.claude-plugin/
plugin.json
assets/
example-chart.tsx
references/
data-storytelling.md
library-comparison.md
testing-strategies.md
animation-patterns.md
tufte-principles.md
scripts/
chart-test-helpers.ts
data-transform.ts

详细介绍

数据可视化 2025:视觉传播的艺术与科学

创建让 Seaborn 用户、Tufte 读者和所有人都喜爱的可视化。融合 NYT Graphics 的严谨、MoMA 的美学、Nike 的活力和 On Kawara 的精准。

何时使用此技能

✅ 适用于:

  • 构建交互式图表、仪表板和数据故事
  • 复杂可视化(弦图、桑基图、网络图)
  • 带动画的实时数据显示
  • 移动端响应式数据组件
  • 用于生产环境、易于访问且经过测试的可视化

❌ 不适用于:

  • 无交互的静态 PNG/SVG 导出(使用设计工具)
  • 基础 HTML 表格(使用语义化标记)
  • 仅用于印刷的图形(约束条件不同)
  • 简单的图标展示(使用图标库)

核心理念:三大支柱

1. 清晰(Tufte 的数据墨水比)

每个视觉元素都必须有存在的理由。去除图表垃圾,最大化信噪比。

2. 美感(审美标准)

可视化是艺术。运用弹簧物理效果、用心设计的配色和高品质设计系统。

3. 真实(图形完整性)

数据呈现必须诚实。严格测试、记录假设、保留上下文。

快速决策树

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)

数据可视化技术栈(2025)

推荐的软件包
{
  "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 />)
  • 文档和社区都很出色
  • 内置 TypeScript 支持
  • 学习曲线最平缓

Nivo - 想要视觉效果惊艳的结果

  • 提供 20 多种图表类型,默认样式精美
  • 支持 Canvas、SVG 和 HTML 渲染
  • 支持服务端渲染(独特功能)
  • 可通过 props 深度自定义

Visx - 想使用 React 模式获得最大控制力

  • 底层构件(比例尺、坐标轴、形状)
  • 自行组合图表类型
  • Airbnb 的 D3 + React 工具包
  • 最适合新颖的可视化

D3.js - 想要无限的能力(也要承担相应责任)

  • 完全控制每个像素
  • 学习曲线最陡峭
  • 最适合高级定制工作
  • 在 React 中与 useEffect 和 useRef 配合使用

Tufte 检查清单

发布任何可视化之前,请确认:

  • 最大化数据墨水比 - 移除网格线、装饰、3D 效果和阴影
  • 图形完整性 - 视觉呈现与数据值成比例
  • 标签清晰 - 直接标注数据(而非需要对照颜色的图例)
  • 没有图表垃圾 - 不添加不必要的装饰或莫尔条纹干扰
  • 信息分层 - 使用小多图,而非信息过载的单一图表
  • 展示数据变化,而非设计变化 - 保持视觉编码一致

阅读 references/tufte-principles.md 深入了解。

NYT Graphics 工作流

《纽约时报》图形团队的流程:

  1. 绘制 500 张图表 → 选出信息展示效果最佳的一张
  2. 合理简化 → 去除噪声和杂乱元素
  3. 添加见解注释 → 文字应突出模式,而不只是描述数据
  4. 与真实用户测试 → 观察人们如何交互,找出困惑之处
  5. 默认支持响应式 → 移动优先,渐进增强

阅读 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"
];
无障碍要求
  • 对比度 ≥4.5:1:文本与背景之间
  • 不要仅依赖颜色:使用形状、图案和标签
  • 使用色觉障碍友好型调色板:通过模拟器测试
  • 考虑深色模式:确保颜色在两种主题下都适用

测试数据可视化

视觉回归测试
# 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>
  );
};
便于触控的交互
  • 触控目标最小尺寸:44×44px:工具提示、按钮和交互元素
  • 滑动手势:浏览时间序列、切换视图
  • 双指缩放:用于密集图表(谨慎使用)
  • 长按上下文菜单:高级操作

数据叙事

每个可视化都在讲述一个故事。请遵循叙事结构:

  1. 引子:有什么令人惊讶的洞见?
  2. 背景:为什么值得关注?
  3. 证据:清晰地展示数据
  4. 结论:我们应该采取什么行动?
叙事技巧
  • 滚动叙事:用户滚动时,图表随之动态变化
  • 渐进式呈现:从简单内容开始,逐步揭示复杂信息
  • 注释:指出洞见,不要让用户自行寻找
  • 对比:展示之前与之后、我们与他们、预期与实际

请阅读 references/data-storytelling.md,了解叙事框架。

常见反模式

❌ “彩虹呕吐式”饼图

问题: 12 种颜色、切片很小、图例放在一旁
解决方案: 最多显示 5 个类别,直接添加标签,考虑改用条形图

❌ “误导性坐标轴”条形图

问题: Y 轴不从零开始,夸大差异
解决方案: 条形图的坐标轴始终从零开始(折线图可以有所不同)

❌ “双坐标轴混淆”折线图

问题: 两个比例不同的 Y 轴会误导读者
解决方案: 使用单独的图表,或将数据归一化到相同的比例

❌ “3D 透视”陷阱

问题: 3D 效果会扭曲数据感知
解决方案: 使用 2D 图表,并通过颜色或大小表示第三个维度

❌ “死亡转圈”加载状态

问题: 空白屏幕上只有加载转圈,持续 2 秒以上
解决方案: 使用骨架屏加载,立即显示图表结构

请阅读 references/antipatterns.md,查看完整目录。

实施工作流

1. 探索数据
# 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
2. 构建生产组件
// 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
3. 全面测试
# Visual regression testing
npx percy snapshot

# Component testing
npm test -- --coverage

# Accessibility testing
npx axe-core src/components/charts
4. 编写文档并部署
// Storybook for component playground
// Props documentation with TypeScript
// Usage examples for each chart type

AI 增强型可视化

何时使用 Claude/Haiku
  • 动态注释:根据数据生成洞见
  • 调色板建议:由 AI 提供的色彩协调建议
  • 图表类型建议:“展示这些数据的最佳方式是什么?”
  • 无障碍描述:自动生成替代文本
示例:AI 注释
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
});
Canvas 与 SVG
  • SVG:更适合 < 1000 个数据点、无障碍访问,并且在任何缩放比例下都清晰
  • Canvas:更适合 > 1000 个数据点、动画和高性能场景
  • WebGL:最适合 > 10,000 个数据点、3D 和游戏级性能场景
虚拟化

对于大型数据集,仅渲染可见部分:

// Use react-window or react-virtualized for long lists
// Aggregate/sample data for chart display
// Store full dataset separately for export

无障碍标准(WCAG AA)

要求
  • 键盘导航 - 所有交互元素均可通过 Tab 访问
  • 屏幕阅读器支持 - 提供数据表格作为替代方案
  • 焦点指示器 - 为交互元素提供清晰可见的焦点状态
  • 颜色对比度 - 小号文本 ≥4.5:1,大号文本 ≥3:1
  • 减少动态效果 - 遵循 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 和 D3
  • references/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 种方案的原型;准备发布时,就严格测试。

此技能涵盖:图表选择 | 库集成 | 测试策略 | 动效模式 | 无障碍合规 | 性能优化

评论

支持 Markdown