入门
¥Getting started
D3 可在任何 JavaScript 环境中运行。
¥D3 works in any JavaScript environment.
在线试用 D3
¥Try D3 online
最快开始使用 D3(并获得帮助)的方法就是使用 Observable!D3 默认在注意本中作为 Observable 标准库的一部分提供。使用 D3 创建对象,请从单元格返回生成的 DOM 元素。这里有一个空白图表可以帮助你入门:
¥The fastest way to get started (and get help) with D3 is on Observable! D3 is available by default in notebooks as part of Observable’s standard library. To create something with D3, return the generated DOM element from a cell. Here is a blank chart to get you started:
{
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Return the SVG element.
return svg.node();
}
作为一个更完整的示例,请尝试以下入门模板之一:
¥As a more complete example, try one of these starter templates:
有关更多可分叉示例,请参阅 D3 图库。
¥See the D3 gallery for more forkable examples.
Observable 包含一些 D3 代码片段,点击“+”按钮添加单元格时(单元格菜单打开时输入“d3”),以及便捷的 示例数据集 来试用 D3 功能。或者上传 CSV 或 JSON 文件开始处理你的数据。你还可以 fork 我们发布的任何 数百个注意本 以抢占先机。
¥Observable includes a few D3 snippets when you click + to add a cell (type “d3” when the cell menu is open to filter), as well as convenient sample datasets to try out D3 features. Or upload a CSV or JSON file to start playing with your data. You can also fork any of the hundreds of notebooks we’ve published for a head start.
Observable 可供公众免费使用。注册 专业账户 以连接到私有数据库、在私有注意本上协作等等。
¥Observable is free for public use. Sign up for a Pro account to connect to private databases, collaborate on private notebooks, and more.
原生 HTML 中的 D3
¥D3 in vanilla HTML
在原生 HTML 中,你可以从 CDN(例如 jsDelivr)加载 D3,也可以将其下载到本地。我们建议使用 CDN 托管的 ES 模块包。但对于那些需要帮助的人,我们还提供了一个 UMD 包,当以纯脚本加载时,它会导出 d3
全局变量。
¥In vanilla HTML, you can load D3 from a CDN such as jsDelivr or you can download it locally. We recommend using the CDN-hosted ES module bundle. But for those who need it, we also provide a UMD bundle that exports the d3
global when loaded as a plain script.
<!DOCTYPE html>
<div id="container"></div>
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append the SVG element.
container.append(svg.node());
</script>
<!DOCTYPE html>
<div id="container"></div>
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script type="module">
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append the SVG element.
container.append(svg.node());
</script>
<!DOCTYPE html>
<div id="container"></div>
<script src="d3.js"></script>
<script type="module">
// Declare the chart dimensions and margins.
const width = 640;
const height = 400;
const marginTop = 20;
const marginRight = 20;
const marginBottom = 30;
const marginLeft = 40;
// Declare the x (horizontal position) scale.
const x = d3.scaleUtc()
.domain([new Date("2023-01-01"), new Date("2024-01-01")])
.range([marginLeft, width - marginRight]);
// Declare the y (vertical position) scale.
const y = d3.scaleLinear()
.domain([0, 100])
.range([height - marginBottom, marginTop]);
// Create the SVG container.
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
// Add the x-axis.
svg.append("g")
.attr("transform", `translate(0,${height - marginBottom})`)
.call(d3.axisBottom(x));
// Add the y-axis.
svg.append("g")
.attr("transform", `translate(${marginLeft},0)`)
.call(d3.axisLeft(y));
// Append the SVG element.
container.append(svg.node());
</script>
你还可以像这样导入和解构单个 D3 模块:
¥You can also import and destructure individual D3 modules like so:
<script type="module">
import {forceSimulation, forceCollide, forceX} from "https://cdn.jsdelivr.net/npm/d3-force@3/+esm";
const nodes = [{}, {}];
const simulation = forceSimulation(nodes)
.force("x", forceX())
.force("collide", forceCollide(5))
.on("tick", () => console.log(nodes[0].x));
</script>
如果你希望在本地(或离线)运行 D3,你可以在此处下载 D3 的 UMD 软件包:
¥If you’d prefer to run D3 locally (or offline), you can download the UMD bundles of D3 here:
然后,在 UMD + 本地选项卡中创建一个如上所示的 index.html
文件。Use the non-minified bundle for debugging, and the minified bundle for faster performance in production.
¥Then, create an index.html
file as shown above in the UMD + local tab. Use the non-minified bundle for debugging, and the minified bundle for faster performance in production.
从 npm 安装
¥Installing from npm
如果你正在使用 Node 开发 Web 应用,你可以通过 yarn、npm、pnpm 或你喜欢的包管理器安装 D3。
¥If you’re developing a web application using Node, you can install D3 via yarn, npm, pnpm, or your preferred package manager.
yarn add d3
npm install d3
pnpm add d3
然后,你可以将 D3 加载到你的应用中:
¥You can then load D3 into your app as:
import * as d3 from "d3";
如果你愿意,也可以导入特定的符号:
¥You can instead import specific symbols if you prefer:
import {select, selectAll} from "d3";
或者,你可以安装并导入 D3 子模块:
¥Alternatively you can install and import from D3 submodules:
import {mean, median} from "d3-array";
TypeScript declarations are available via DefinitelyTyped。
React 中的 D3
¥D3 in React
大多数 D3 模块(包括 d3-scale、d3-array、d3-interpolate 和 d3-format)不与 DOM 交互,因此在 React 中使用它们时没有区别。你可以在 JSX 中使用它们进行纯声明式可视化,例如下面的折线图。
¥Most D3 modules (including d3-scale, d3-array, d3-interpolate, and d3-format) don’t interact with the DOM, so there is no difference when using them in React. You can use them in JSX for purely declarative visualization, such as the line plot below.
import * as d3 from "d3";
export default function LinePlot({
data,
width = 640,
height = 400,
marginTop = 20,
marginRight = 20,
marginBottom = 20,
marginLeft = 20
}) {
const x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
const y = d3.scaleLinear(d3.extent(data), [height - marginBottom, marginTop]);
const line = d3.line((d, i) => x(i), y);
return (
<svg width={width} height={height}>
<path fill="none" stroke="currentColor" strokeWidth="1.5" d={line(data)} />
<g fill="white" stroke="currentColor" strokeWidth="1.5">
{data.map((d, i) => (<circle key={i} cx={x(i)} cy={y(d)} r="2.5" />))}
</g>
</svg>
);
}
操作 selections(包括 d3-selection、d3-transition 和 d3-axis)的 D3 模块确实会操作 DOM,这与 React 的虚拟 DOM 存在竞争关系。在这种情况下,你可以将 ref 附加到元素,并在 useEffect hook 中将其传递给 D3。
¥D3 modules that operate on selections (including d3-selection, d3-transition, and d3-axis) do manipulate the DOM, which competes with React’s virtual DOM. In those cases, you can attach a ref to an element and pass it to D3 in a useEffect hook.
import * as d3 from "d3";
import {useRef, useEffect} from "react";
export default function LinePlot({
data,
width = 640,
height = 400,
marginTop = 20,
marginRight = 20,
marginBottom = 30,
marginLeft = 40
}) {
const gx = useRef();
const gy = useRef();
const x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
const y = d3.scaleLinear(d3.extent(data), [height - marginBottom, marginTop]);
const line = d3.line((d, i) => x(i), y);
useEffect(() => void d3.select(gx.current).call(d3.axisBottom(x)), [gx, x]);
useEffect(() => void d3.select(gy.current).call(d3.axisLeft(y)), [gy, y]);
return (
<svg width={width} height={height}>
<g ref={gx} transform={`translate(0,${height - marginBottom})`} />
<g ref={gy} transform={`translate(${marginLeft},0)`} />
<path fill="none" stroke="currentColor" strokeWidth="1.5" d={line(data)} />
<g fill="white" stroke="currentColor" strokeWidth="1.5">
{data.map((d, i) => (<circle key={i} cx={x(i)} cy={y(d)} r="2.5" />))}
</g>
</svg>
);
}
有关在 React 中使用 D3 的更多指导,请参阅 Amelia Wattenberger 的帖子。
¥For more guidance using D3 in React, see Amelia Wattenberger’s post.
Svelte 中的 D3
¥D3 in Svelte
与 使用 React 一样,你可以根据需要专门使用 Svelte 进行渲染,并且只使用不操作 DOM 的 D3 模块。这是使用 d3-shape 和 d3-scale 绘制的数字数组的线图。
¥As with React, you can use Svelte exclusively for rendering if you like, and only use D3 modules that don’t manipulate the DOM. Here is a line plot of an array of numbers that uses d3-shape and d3-scale.
<script>
import * as d3 from 'd3';
export let data;
export let width = 640;
export let height = 400;
export let marginTop = 20;
export let marginRight = 20;
export let marginBottom = 20;
export let marginLeft = 20;
$: x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
$: y = d3.scaleLinear(d3.extent(data), [height - marginBottom, marginTop]);
$: line = d3.line((d, i) => x(i), y);
</script>
<svg width={width} height={height}>
<path fill="none" stroke="currentColor" stroke-width="1.5" d={line(data)} />
<g fill="white" stroke="currentColor" stroke-width="1.5">
{#each data as d, i}
<circle key={i} cx={x(i)} cy={y(d)} r="2.5" />
{/each}
</g>
</svg>
Svelte 的反应式语句 ($:
) 与 D3 数据连接 完美搭配,可实现高效更新。下面,我们将使用它们来渲染数据变化时的动态轴。
¥Svelte’s reactive statements ($:
) pair nicely with D3 data joins for efficient updates. Below, we use them to render dynamic axes as the data changes.
<script>
import * as d3 from 'd3';
export let data;
export let width = 640;
export let height = 400;
export let marginTop = 20;
export let marginRight = 20;
export let marginBottom = 30;
export let marginLeft = 40;
let gx;
let gy;
$: x = d3.scaleLinear([0, data.length - 1], [marginLeft, width - marginRight]);
$: y = d3.scaleLinear(d3.extent(data), [height - marginBottom, marginTop]);
$: line = d3.line((d, i) => x(i), y);
$: d3.select(gy).call(d3.axisLeft(y));
$: d3.select(gx).call(d3.axisBottom(x));
</script>
<svg width={width} height={height}>
<g bind:this={gx} transform="translate(0,{height - marginBottom})" />
<g bind:this={gy} transform="translate({marginLeft},0)" />
<path fill="none" stroke="currentColor" stroke-width="1.5" d={line(data)} />
<g fill="white" stroke="currentColor" stroke-width="1.5">
{#each data as d, i}
<circle key={i} cx={x(i)} cy={y(d)} r="2.5" />
{/each}
</g>
</svg>