mcpField
D
d3js-visualization

d3js-visualization

github.com/autumnsgrove数据与数据库3743 次安装53 周前更新
代码仓库

关于 d3js-visualization

面向需要在浏览器中构建定制交互式可视化的开发者,提供 D3.js 实践指南,涵盖图表、数据处理、响应式设计与无障碍等内容。

主要功能

  1. 01定制 SVG 与 Canvas 可视化
  2. 02数据绑定、比例尺与坐标轴
  3. 03提示框、事件与过渡动画
  4. 04响应式图表模式
  5. 05无障碍与性能建议
  6. 06示例与详细参考资料

适用场景

  1. 01为网页数据构建定制图表
  2. 02为可视化添加交互和动画
  3. 03让图表适配不同容器尺寸
  4. 04选择图表类型并调整渲染性能

安装

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

$npx skills add https://github.com/autumnsgrove/claudeskills --skill d3js-visualization

安装后在 Claude Code 中输入/d3js-visualization确认已加载。

包含的文件

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

README.md
examples/
bar-chart.html
line-chart.html
network-graph.html
references/
advanced-patterns.md
chart-types.md
common-pitfalls.md
d3-fundamentals.md
data-transformation.md
integration-patterns.md
paths-and-shapes.md
scales-and-axes.md
scripts/
chart-templates.js
data-helpers.js

详细介绍

D3.js 数据可视化技能

什么是 D3.js

D3.js(Data-Driven Documents,数据驱动文档)是一个 JavaScript 库,用于在 Web 浏览器中制作动态交互式数据可视化。它使用 HTML、SVG 和 CSS 标准将数据绑定到 DOM,并应用数据驱动的转换。

何时使用 D3.js

以下情况适合使用 D3.js:

  • 需要图表库无法提供的自定义独特可视化
  • 需要精细控制每个可视元素
  • 需要复杂交互和动画
  • 需要进行图表以外的数据驱动 DOM 操作
  • 需要处理大型数据集时获得良好性能(使用 Canvas)
  • 需要基于 Web 标准构建可视化

以下情况可考虑其他方案:

  • 简单的标准图表即可满足需求(使用 Chart.js、Plotly)
  • 优先考虑快速原型设计(使用 Observable、Vega-Lite)
  • 需要用于印刷或报告的静态图表(使用 matplotlib、ggplot2)
  • 需要 3D 可视化(使用 Three.js、WebGL 库)
D3.js 与其他库的对比
库最适合学习曲线自定义能力
D3.js自定义可视化陡峭完全
Chart.js标准图表简单有限
Plotly科学绘图中等良好
Highcharts业务仪表板简单良好
Three.js3D 图形陡峭完全

核心工作流

1. 项目设置

选项 1:CDN(快速开始)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>D3 Visualization</title>
  <style>
    body { margin: 0; font-family: sans-serif; }
    svg { display: block; }
  </style>
</head>
<body>
  <div id="chart"></div>
  <script src="https://d3js.org/d3.v7.min.js"></script>
  <script>
    // Your code here
  </script>
</body>
</html>

选项 2:NPM(生产环境)

npm install d3
// Import all of D3
import * as d3 from "d3";

// Or import specific modules
import { select, selectAll } from "d3-selection";
import { scaleLinear, scaleTime } from "d3-scale";
2. 创建基本图表
// Set up dimensions and margins
const margin = {top: 20, right: 30, bottom: 40, left: 50};
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;

// Create SVG
const svg = d3.select("#chart")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left},${margin.top})`);

// Load and process data
d3.csv("data.csv", d => ({
  date: new Date(d.date),
  value: +d.value
})).then(data => {

  // Create scales
  const xScale = d3.scaleTime()
    .domain(d3.extent(data, d => d.date))
    .range([0, width]);

  const yScale = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.value)])
    .nice()
    .range([height, 0]);

  // Create and append axes
  svg.append("g")
    .attr("transform", `translate(0,${height})`)
    .call(d3.axisBottom(xScale));

  svg.append("g")
    .call(d3.axisLeft(yScale));

  // Create line generator
  const line = d3.line()
    .x(d => xScale(d.date))
    .y(d => yScale(d.value))
    .curve(d3.curveMonotoneX);

  // Draw line
  svg.append("path")
    .datum(data)
    .attr("d", line)
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-width", 2);
});
3. 添加交互性

工具提示:

const tooltip = d3.select("body")
  .append("div")
  .attr("class", "tooltip")
  .style("position", "absolute")
  .style("visibility", "hidden")
  .style("background", "white")
  .style("border", "1px solid #ddd")
  .style("padding", "10px")
  .style("border-radius", "4px");

circles
  .on("mouseover", function(event, d) {
    tooltip
      .style("visibility", "visible")
      .html(`<strong>${d.name}</strong><br/>Value: ${d.value}`);
  })
  .on("mousemove", function(event) {
    tooltip
      .style("top", (event.pageY - 10) + "px")
      .style("left", (event.pageX + 10) + "px");
  })
  .on("mouseout", function() {
    tooltip.style("visibility", "hidden");
  });

过渡效果:

circles
  .transition()
  .duration(300)
  .ease(d3.easeCubicOut)
  .attr("r", 8);
4. 实现响应式设计
function createChart() {
  const container = d3.select("#chart");
  const containerWidth = container.node().getBoundingClientRect().width;

  const margin = {top: 20, right: 30, bottom: 40, left: 50};
  const width = containerWidth - margin.left - margin.right;
  const height = Math.min(width * 0.6, 500);

  container.selectAll("*").remove(); // Clear previous

  // Create SVG...
}

// Initial render
createChart();

// Re-render on resize with debouncing
let resizeTimer;
window.addEventListener("resize", () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(createChart, 250);
});

核心原则

数据绑定
  • 使用 .data() 将数据绑定到 DOM 元素
  • 处理 enter、update 和 exit 选择集
  • 使用键函数确保元素与数据的匹配保持一致
  • 现代语法:使用 .join() 编写更简洁的代码
比例尺
  • 将数据值(domain)映射到视觉值(range)
  • 使用合适的比例尺类型(linear、time、band、ordinal)
  • 对比例尺应用 .nice(),使坐标轴数值更整齐
  • 反转 y 比例尺范围,以实现从下往上的坐标:[height, 0]
SVG 坐标系
  • 原点(0,0)位于左上角
  • y 轴向下递增(与笛卡尔坐标系相反)
  • 使用边距规范来设置合适的间距
  • 使用 <g> 标签对相关元素分组
性能
  • 少于 1,000 个元素时使用 SVG
  • 多于 1,000 个元素时使用 Canvas
  • 对大型数据集进行聚合或抽样
  • 对调整大小事件处理函数进行防抖

图表选择指南

时间序列数据? → 折线图或面积图

比较类别? → 柱状图(垂直或水平)

展示关系? → 散点图或气泡图

展示部分与整体? → 环形图或堆叠柱状图(类别数限制在 5-7 个)

网络数据? → 力导向图

展示分布? → 直方图或箱线图

有关详细的图表选择标准和最佳实践,请参阅 references/chart-types.md。


常见模式

快速加载数据
// Load CSV with type conversion
d3.csv("data.csv", d => ({
  date: new Date(d.date),
  value: +d.value,
  category: d.category
})).then(data => {
  createChart(data);
});
快速添加工具提示
selection
  .on("mouseover", (event, d) => {
    tooltip.style("visibility", "visible").html(`Value: ${d.value}`);
  })
  .on("mousemove", (event) => {
    tooltip.style("top", event.pageY + "px").style("left", event.pageX + "px");
  })
  .on("mouseout", () => tooltip.style("visibility", "hidden"));
快速创建响应式 SVG
svg
  .attr("viewBox", `0 0 ${width} ${height}`)
  .attr("preserveAspectRatio", "xMidYMid meet")
  .style("width", "100%")
  .style("height", "auto");

质量标准

视觉质量
  • 根据数据选择合适的图表类型
  • 使用一致的配色方案
  • 添加清晰的坐标轴标签和图例
  • 使用边距规范设置适当的间距
  • 使用合适的比例尺类型和范围
交互质量
  • 添加有意义的工具提示
  • 使用平滑过渡效果(持续 300-500ms)
  • 提供悬停反馈
  • 为无障碍访问提供键盘导航
  • 实现缩放和平移,以便详细探索
代码质量
  • 在数据连接中使用键函数
  • 正确处理 enter、update 和 exit
  • 更新前清理之前的渲染结果
  • 使用可复用的图表模式实现模块化
  • 对开销较大的操作进行防抖
无障碍访问
  • 添加 ARIA 标签和描述
  • 提供键盘导航
  • 使用适合色盲人士的调色板
  • 为屏幕阅读器提供文本替代内容
  • 确保足够的颜色对比度

辅助资源

可用脚本
  • data-helpers.js:数据加载、解析和转换工具
  • chart-templates.js:适用于常见可视化的可复用图表模板

实现请参阅 scripts/ 目录。

可运行示例
  • line-chart.html:带工具提示的时间序列可视化
  • bar-chart.html:分组和堆叠条形图
  • network-graph.html:力导向网络可视化

完整实现请参阅 examples/ 目录。

详细参考

故障排除

图表没有显示?

  • 检查浏览器控制台是否有错误
  • 确认数据已正确加载
  • 确保 SVG 设置了宽度和高度
  • 检查比例尺的定义域和值域

元素位置不正确?

  • 确认比例尺定义域与数据范围匹配
  • 检查 y 比例尺的值域是否反转:[height, 0]
  • 确认边距变换已应用于 <g> 元素
  • 检查 SVG 坐标系(左上角为原点)

过渡效果不起作用?

  • 确保时长设置合理(300-500ms)
  • 检查过渡效果是否应用于选择集,而非数据
  • 确认缓动函数有效
  • 确认元素在过渡开始前已存在

性能不佳?

  • 减少 DOM 元素数量(超过 1,000 个时使用 Canvas)
  • 聚合或抽样数据
  • 对调整大小处理程序进行防抖
  • 尽量减少重绘

外部资源

官方文档
学习资源
配色工具
灵感来源

此技能全面介绍了如何使用 D3.js 创建专业的交互式数据可视化。可将核心工作流作为起点,针对具体主题查阅详细参考,并根据需要自定义示例。

评论

支持 Markdown