Skip to content

D3.js - SVG 介绍

SVG,全称为 Scalable Vector Graphics(可伸缩矢量图形),是创建基于 Web 的数据可视化的关键技术。SVG 是一种基于 XML 的标记语言,用于描述二维矢量图形。与基于像素的栅格图形(raster graphics)(如 JPEG 或 PNG)不同,矢量图形(vector graphics)由数学方程定义。这使得它们可以在不失清晰度或质量的情况下缩放到任何尺寸,因此非常适合响应式设计(responsive designs)和高分辨率显示(high-resolution displays)。D3.js 大量使用 SVG 来渲染可视化元素。

理解这些 SVG 特性将有助于你使用 D3.js:

  • 基于矢量和文本: SVG 图像在 XML 文本文件中定义,这意味着它们是人类可读的,并且可以使用代码或文本编辑器进行操作。
  • 可伸缩且与分辨率无关: SVG 在任何缩放级别或屏幕分辨率下都看起来清晰锐利。
  • 可进行 DOM 操作: SVG 元素与 HTML 元素一样,会成为文档对象模型(DOM)的一部分。这使得 D3.js 和 JavaScript 可以动态地与其交互和修改。
  • 可用 CSS 设置样式: 你可以对 SVG 元素应用 CSS 样式来控制其表现(颜色、字体、描边等)。
  • 坐标系: SVG 通常使用左上角为 (0,0) 的坐标系。位置是相对于其父级 SVG 容器或变换后的坐标空间的绝对位置。
  • 可嵌入 HTML: SVG 标记可以直接嵌入到 HTML 文档中。

一个最小的 SVG 示例(不使用 D3.js)

Section titled “一个最小的 SVG 示例(不使用 D3.js)”

让我们首先看一个直接嵌入 HTML 中的基本 SVG 图像。

步骤 1:创建一个 SVG 画布(canvas)。<svg> 元素定义了绘图区域。它的 width 和 height 属性设置了其尺寸。

<!-- 在 HTML 的 body 中 -->
<svg width="300" height="300">
<!-- SVG 形状将放在这里 -->
</svg>

默认情况下,如果未另行指定单位,则单位为像素。

步骤 2:绘制一个形状,例如一条线。<line> 元素绘制一条直线。

<svg width="300" height="300">
<line x1="100" y1="100" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>

<line> 属性解释:

  • x1, y1: 线的起始点坐标。
  • x2, y2: 线的结束点坐标。
  • style: 定义线外观的行内样式(inline style)。也可以使用 CSS 类(CSS classes)。
  • stroke: 线的颜色(这里是红色)。
  • stroke-width: 线的粗细(这里是 2 像素)。

让我们将其整合到一个完整的 HTML 文档中:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SVG Line Example</title>
<style>
body { font-family: Arial, sans-serif; }
svg {
border: 1px solid #ccc; /* 可选:查看 SVG 边界 */
}
</style>
</head>
<body>
<div id="svgcontainer">
<svg width="300" height="300">
<line x1="100" y1="100" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>
</div>
<p>上面的 SVG 显示了一条红色的对角线。</p>
</body>
</html>

当你在浏览器中打开此 HTML 文件时,你将在一个 300x300 像素的区域内看到一条红色的对角线。

D3.js 擅长根据数据创建和操作 SVG 元素。让我们使用 D3.js 重现上面的线示例。

步骤 1:在你的 HTML 中创建一个容器,D3 将在其中放置 SVG。

<!-- 在 HTML 的 body 中 -->
<div id="d3svgcontainer"></div>

步骤 2:使用 D3 选择容器,附加(append)一个 <svg> 元素,然后在其中附加一个 <line> 元素,并设置其属性(attribute)。

// JavaScript 代码(例如,在 <script> 标签内)
const width = 300;
const height = 300;
// 选择容器 div
const svgContainer = d3.select("#d3svgcontainer");
// 向容器附加一个 SVG 元素
const svg = svgContainer.append("svg")
.attr("width", width)
.attr("height", height);
// 向 SVG 附加一个线元素
svg.append("line")
.attr("x1", 100)
.attr("y1", 100)
.attr("x2", 200)
.attr("y2", 200)
.style("stroke", "blue") // 我们把这条线设为蓝色
.style("stroke-width", 2);

包含 D3.js 的完整 HTML 文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SVG Line with D3.js</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body { font-family: Arial, sans-serif; }
svg {
border: 1px solid #ccc; /* 可选 */
}
</style>
</head>
<body>
<div id="d3svgcontainer"></div>
<p>下方由 D3.js 创建的 SVG 显示了一条蓝色的对角线。</p>
<script>
const width = 300;
const height = 300;
const svgContainer = d3.select("#d3svgcontainer");
const svg = svgContainer.append("svg")
.attr("width", width)
.attr("height", height);
svg.append("line")
.attr("x1", 100)
.attr("y1", 100)
.attr("x2", 200)
.attr("y2", 200)
.style("stroke", "blue")
.style("stroke-width", 2);
</script>
</body>
</html>

此代码将生成一条蓝色的对角线,展示了 D3.js 如何通过编程动态生成 SVG 内容。

除了 <line> 之外,SVG 还提供了其他各种形状元素(shape elements),D3.js 可以创建和操作它们:

矩形由其左上角的坐标(x、y)、其 width 和 height 定义。

矩形的 SVG 代码:

<rect x="20" y="20" width="200" height="100" fill="green" />

<rect> 的主要属性:

  • x: 左上角的 x 坐标。
  • y: 左上角的 y 坐标。
  • width: 矩形的宽度。
  • height: 矩形的高度。
  • fill: 矩形的填充颜色(例如,“绿色”)。

使用 D3.js 创建矩形:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SVG Rectangle with D3.js</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div id="svgcontainer"></div>
<script>
const svgWidth = 300;
const svgHeight = 200;
const svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
svg.append("rect")
.attr("x", 20)
.attr("y", 20)
.attr("width", 200)
.attr("height", 100)
.attr("fill", "green");
</script>
</body>
</html>

这将在 SVG 画布中渲染一个绿色的矩形。

圆形由其中心点的坐标(cx、cy)和其半径(r)定义。

圆形的 SVG 代码:

<circle cx="150" cy="100" r="40" fill="purple" />

<circle> 的主要属性:

  • cx: 圆心的 x 坐标。
  • cy: 圆心的 y 坐标。
  • r: 圆的半径。

使用 D3.js 创建圆形:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SVG Circle with D3.js</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div id="svgcontainer"></div>
<script>
const svgWidth = 300;
const svgHeight = 200;
const svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
svg.append("circle")
.attr("cx", 150)
.attr("cy", 100)
.attr("r", 40)
.attr("fill", "purple");
</script>
</body>
</html>

这将渲染一个紫色的圆形。

椭圆由其中心点(cx、cy)和两个半径定义:rx(水平半径)和 ry(垂直半径)。

椭圆的 SVG 代码:

<ellipse cx="150" cy="100" rx="100" ry="50" fill="orange" />

<ellipse> 的主要属性:

  • cx: 椭圆中心的 x 坐标。
  • cy: 椭圆中心的 y 坐标。
  • rx: 椭圆的水平半径。
  • ry: 椭圆的垂直半径。

使用 D3.js 创建椭圆:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SVG Ellipse with D3.js</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<div id="svgcontainer"></div>
<script>
const svgWidth = 300;
const svgHeight = 200;
const svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
svg.append("ellipse")
.attr("cx", 150)
.attr("cy", 100)
.attr("rx", 100)
.attr("ry", 50)
.attr("fill", "orange");
</script>
</body>
</html>

这将渲染一个橙色的椭圆。理解这些基本的 SVG 形状对于使用 D3.js 构建更复杂的视图至关重要。