关于 d3-visualization
d3-visualization 是面向可视化开发者的 D3.js 技能,帮助构建定制数据图形。它提供按任务组织的流程和参考,涵盖图表、动态更新、高级布局、动画与交互。
主要功能
- 01基础图表分步工作流
- 02数据绑定、比例尺与坐标轴指导
- 03网络图、层级图和地图布局
- 04动态数据更新与过渡动画
- 05缩放、拖拽等交互
- 06可复用模式与代码模板
适用场景
- 01构建定制柱状图、折线图或散点图
- 02数据变化时刷新可视化
- 03创建网络图、层级图或地图
- 04为图表添加动画和交互控件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lyndonkl/ claude --skill d3-visualization安装后在 Claude Code 中输入/d3-visualization确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
resources/advanced-layouts.mdcommon-patterns.mdevaluation-rubric.jsongetting-started.mdscales-axes.mdselections-datajoins.mdshapes-layouts.mdtransitions-interactions.mdworkflows.md详细介绍
D3.js 数据可视化
目录
概述
D3 提供了用于数据驱动的 DOM 操作、视觉编码、布局算法和交互的底层构建模块,可实现图表库无法提供的定制化可视化。
适用场景: 图表库无法满足特定设计需求,需要完全自定义,正在构建网络图/层级结构/地图,或需要平滑地为数据变化添加动画。
优先选择更简单的工具: 简单的柱状图/折线图即可满足需求(Chart.js、Highcharts),需要 3D(Three.js、WebGL),或数据集超过 10K 个点且未进行聚合。
核心概念: 数据连接(将数组绑定到 DOM 元素)、比例尺(将数据值映射为视觉值)、形状(生成 SVG 路径)、布局(计算网络/树/地图中的位置)、过渡(对状态变化进行动画处理)、交互(缩放/平移/拖动/框选)。
技能结构
- 入门指南:设置、前提条件、第一个可视化
- 选择集与数据连接:DOM 操作、数据绑定
- 比例尺与坐标轴:数据转换、坐标轴生成
- 形状与布局:路径生成器、基础布局
- 高级布局:力导向模拟、层级结构、地理地图
- 过渡与交互:动画、缩放/平移/拖动/框选
- 工作流:常见图表类型的分步指南
- 常见模式:可复用代码模板
工作流
根据当前任务选择工作流:
创建基础图表工作流
适用场景: 从头开始构建柱状图、折线图或散点图
耗时: 1-2 小时
复制此清单并跟踪进度:
Basic Chart Progress:
- [ ] Step 1: Set up SVG container with margins
- [ ] Step 2: Load and parse data
- [ ] Step 3: Create scales (x, y)
- [ ] Step 4: Generate axes
- [ ] Step 5: Bind data and create visual elements
- [ ] Step 6: Style and add interactivity
步骤 1:设置带边距的 SVG 容器
创建具有适当尺寸的 SVG 元素。为坐标轴定义边距:{top: 20, right: 20, bottom: 30, left: 40}。计算内部宽度/高度:width - margin.left - margin.right。参见入门。
步骤 2:加载并解析数据
使用 d3.csv('data.csv') 加载外部文件,或直接定义数据数组。对于时间序列,使用 d3.timeParse('%Y-%m-%d') 解析日期。对于 CSV 数据,使用转换函数将字符串转换为数字。参见入门。
步骤 3:创建比例尺
根据数据选择比例尺类型:scaleBand(分类)、scaleTime(时间)、scaleLinear(定量)。使用 d3.extent()、d3.max() 或手动指定范围来设置定义域。根据 SVG 尺寸设置值域。参见比例尺与坐标轴。
步骤 4:生成坐标轴
创建坐标轴生成器:d3.axisBottom(xScale)、d3.axisLeft(yScale)。添加 g 元素,并通过变换定位。调用坐标轴生成器:.call(axis)。使用 .ticks()、.tickFormat() 自定义刻度。参见比例尺与坐标轴。
步骤 5:绑定数据并创建可视元素
使用数据连接模式:svg.selectAll(type).data(array).join(type)。使用比例尺和访问器函数设置属性:.attr('x', d => xScale(d.category))。对于折线图,使用 d3.line() 生成器。对于散点图,创建带有 cx、cy、r 属性的圆形。参见选择集与数据连接和形状与布局。
步骤 6:设置样式并添加交互
应用颜色:.attr('fill', ...)、.attr('stroke', ...)。添加悬停效果:使用工具提示实现 .on('mouseover', ...)。添加点击处理程序以进行下钻。可选择为初始动画应用过渡效果。参见过渡与交互和常见模式。
使用新数据更新可视化
适用场景: 使用新数据刷新图表(实时更新、筛选、用户交互)
耗时: 30 分钟 - 1 小时
复制此检查清单:
Update Progress:
- [ ] Step 1: Encapsulate visualization in update function
- [ ] Step 2: Update scale domains if needed
- [ ] Step 3: Re-bind data with key function
- [ ] Step 4: Add transitions to join
- [ ] Step 5: Update attributes with new values
- [ ] Step 6: Trigger update on data change
步骤 1:将可视化封装在更新函数中
将基础图表工作流的步骤 3-5 包装在 function update(newData) { ... } 中。这样可让可视化适用于任何数据集。参见 工作流。
步骤 2:更新比例尺定义域
当数据范围变化时重新计算定义域:yScale.domain([0, d3.max(newData, d => d.value)])。通过过渡更新坐标轴:svg.select('.y-axis').transition().duration(500).call(yAxis)。参见 选择集与数据绑定。
步骤 3:使用键函数重新绑定数据
使用键函数保持对象恒定:.data(newData, d => d.id)。这可确保元素与数据项关联,而不是与数组位置关联。这对正确的过渡效果至关重要。参见 选择集与数据绑定。
步骤 4:为数据关联添加过渡
在属性更新前插入 .transition().duration(500)。使用 .ease(d3.easeCubicOut) 指定缓动效果。若要自定义进入/退出效果,请在 .join() 中使用进入/退出函数。参见 过渡与交互。
步骤 5:使用新值更新属性
使用更新后的比例尺设置位置/尺寸:.attr('y', d => yScale(d.value))、.attr('height', d => height - yScale(d.value))。过渡会将旧值平滑地变化到新值。参见 常见模式。
步骤 6:在数据变化时触发更新
在数据变化时调用 update(newData):例如点击按钮、定时器(setInterval)、WebSocket 消息或 API 响应。对于实时数据,可使用滑动窗口限制数据点数量。参见 工作流。
创建高级布局工作流
适用场景: 构建网络图、层级结构或地理地图
耗时: 2-4 小时
复制此清单:
Advanced Layout Progress:
- [ ] Step 1: Choose appropriate layout type
- [ ] Step 2: Prepare and structure data
- [ ] Step 3: Create and configure layout
- [ ] Step 4: Apply layout to data
- [ ] Step 5: Bind computed properties to elements
- [ ] Step 6: Add interactions (drag, zoom)
步骤 1:选择合适的布局类型
力导向模拟:网络图、有机聚类。层级布局:树形图、集群图(节点-链接)、矩形式树图、圆形打包图、分区图(填充空间)。地理布局:使用投影的地图。弦图:流向图。有关选择建议,请参阅 高级布局。
步骤 2:准备并组织数据
力导向布局:nodes = [{id, group}]、links = [{source, target}]。层级布局:使用包含子节点数组的嵌套对象,通过 d3.hierarchy(data) 转换。地理布局:GeoJSON 要素。请参阅 高级布局。
步骤 3:创建并配置布局
力导向布局:d3.forceSimulation(nodes).force('link', d3.forceLink(links)).force('charge', d3.forceManyBody())。层级布局:d3.treemap().size([width, height])。地理布局:d3.geoMercator().fitExtent([[0,0], [width,height]], geojson)。有关各布局类型,请参阅 高级布局。
步骤 4:将布局应用于数据
力导向布局:模拟会自动运行,并在每个 tick 更新节点位置。层级布局:对根节点调用布局:treemap(root)。地理布局:无需应用,投影会用于路径生成器。请参阅 应用布局。
步骤 5:将计算出的属性绑定到元素
力导向布局:在 tick 处理函数中更新 cx、cy:node.attr('cx', d => d.x)。层级布局:使用 d.x0、d.x1、d.y0、d.y1 绘制矩形。地理布局:使用 path(feature) 设置 d 属性。有关特定布局的示例,请参阅 工作流。
步骤 6:添加交互
对力导向网络使用拖拽:node.call(d3.drag().on('drag', dragHandler))。对地图或大型网络使用缩放:svg.call(d3.zoom().on('zoom', zoomHandler))。对层级结构使用点击进行下钻。请参阅 过渡与交互。
路径选择菜单
您想做什么?
-
我是 D3 新手 - 配置环境、了解前置条件、创建第一个可视化
-
构建基础图表 - 按步骤创建柱状图、折线图或散点图
-
使用比例转换数据 - 将数据值映射为视觉属性(位置、颜色、大小)
-
将数据绑定到元素 - 将数组关联到 DOM 元素,并处理动态更新
-
创建网络图/层级图/地图 - 力导向图、矩形式树图、地理可视化
-
添加动画 - 在图表状态之间平滑过渡
-
添加交互性 - 缩放、平移、拖拽、画笔选择、工具提示
-
使用新数据更新图表 - 处理实时数据、筛选器和用户交互
-
获取代码模板 - 复制、粘贴并修改常见模式的模板
-
了解 D3 概念 - 深入了解数据连接、比例、生成器和布局
快速参考
数据连接模式(D3 核心工作流)
// 1. Select container
const svg = d3.select('svg');
// 2. Bind data
svg.selectAll('circle')
.data(dataArray)
.join('circle') // Create/update/remove elements automatically
.attr('cx', d => d.x) // Use accessor functions (d = datum, i = index)
.attr('cy', d => d.y)
.attr('r', 5);
创建比例(数据 → 视觉转换)
// For quantitative data
const xScale = d3.scaleLinear()
.domain([0, 100]) // Data range
.range([0, 500]); // Pixel range
// For categorical data
const xScale = d3.scaleBand()
.domain(['A', 'B', 'C'])
.range([0, 500])
.padding(0.1);
// For temporal data
const xScale = d3.scaleTime()
.domain([new Date(2020, 0, 1), new Date(2020, 11, 31)])
.range([0, 500]);
形状生成器(创建 SVG 路径)
// Line chart
const line = d3.line()
.x(d => xScale(d.date))
.y(d => yScale(d.value));
svg.append('path')
.datum(data) // Use .datum() for single data item
.attr('d', line) // Line generator creates path data
.attr('fill', 'none')
.attr('stroke', 'steelblue');
过渡(动画)
// Add transition before attribute updates
svg.selectAll('rect')
.data(newData)
.join('rect')
.transition() // Everything after this is animated
.duration(500) // Milliseconds
.attr('height', d => yScale(d.value));
常见比例尺类型
| 数据类型 | 任务 | 比例尺 |
|---|---|---|
| 定量(线性) | 位置、大小 | scaleLinear() |
| 定量(指数) | 压缩范围 | scaleLog()、scalePow() |
| 定量 → 圆面积 | 设置圆形大小 | scaleSqrt() |
| 分类 | 条形、分组 | scaleBand()、scalePoint() |
| 分类 → 颜色 | 颜色编码 | scaleOrdinal() |
| 时间 | 时间序列 | scaleTime() |
| 定量 → 颜色 | 热力图 | scaleSequential() |
D3 模块导入(ES6)
// Specific functions
import { select, selectAll } from 'd3-selection';
import { scaleLinear, scaleBand } from 'd3-scale';
import { line, area } from 'd3-shape';
// Entire D3 namespace
import * as d3 from 'd3';
按任务分类的关键资源
- 设置与第一个图表:入门指南
- 数据绑定:选择与数据联结
- 比例尺与坐标轴:比例尺与坐标轴
- 图表类型:工作流 + 常见模式
- 网络与树:高级布局 + 高级布局
- 地图:高级布局
- 动画:过渡与交互
- 交互性:过渡与交互