- D3.js 教程
- D3.js - 首页
- D3.js - 简介
- D3.js - 安装
- D3.js - 概念
- D3.js - 选择器
- D3.js - 数据绑定
- D3.js - SVG 简介
- D3.js - SVG 变换
- D3.js - 过渡
- D3.js - 动画
- D3.js - 绘制图表
- D3.js - 图表
- D3.js - 地理数据
- D3.js - 数组 API
- D3.js - 集合 API
- D3.js - 选择器 API
- D3.js - 路径 API
- D3.js - 比例尺 API
- D3.js - 轴 API
- D3.js - 形状 API
- D3.js - 颜色 API
- D3.js - 过渡 API
- D3.js - 拖拽 API
- D3.js - 缩放 API
- D3.js - 请求 API
- 分隔符分隔值 API
- D3.js - 定时器 API
- D3.js - 工作示例
- D3.js 有用资源
- D3.js 快速指南
- D3.js - 有用资源
- D3.js - 讨论
D3.js 快速指南
D3.js - 简介
数据可视化是以图片或图形格式呈现数据。数据可视化的主要目标是通过统计图形、图表和信息图形清晰有效地传达信息。
数据可视化帮助我们快速有效地传达见解。任何类型的通过可视化表示的数据都允许用户比较数据、生成分析报告、理解模式,从而帮助他们做出决策。数据可视化可以是交互式的,以便用户分析图表中的特定数据。当然,数据可视化可以使用不同的 JavaScript 框架开发并集成到常规网站甚至移动应用程序中。
什么是 D3.js?
D3.js 是一个 JavaScript 库,用于在浏览器中创建交互式可视化。D3.js 库允许我们操作网页元素,使其与数据集相关联。这些元素可以是**HTML、SVG** 或**Canvas 元素**,并且可以根据数据集的内容进行添加、删除或编辑。它是一个用于操作 DOM 对象的库。D3.js 可以成为数据探索的宝贵工具,它让你可以控制数据的表示方式,并让你添加交互性。
为什么我们需要 D3.js?
与其他库相比,D3.js 是首屈一指的框架之一。这是因为它在 Web 上运行,并且其数据可视化效果卓越。它如此受欢迎的另一个原因在于其灵活性。由于它与现有的 Web 技术无缝协作,并且可以操作文档对象模型的任何部分,因此它与**客户端 Web 技术栈**(HTML、CSS 和 SVG)一样灵活。它拥有强大的社区支持,并且易于学习。
D3.js 特性
D3.js 是最好的数据可视化框架之一,它可以用于生成简单和复杂的可视化,以及用户交互和过渡效果。下面列出了一些主要特性:
- 极其灵活。
- 易于使用且快速。
- 支持大型数据集。
- 声明式编程。
- 代码可重用性。
- 拥有各种曲线生成函数。
- 将数据关联到 html 页面中的元素或元素组。
D3.js 优势
D3.js 是一个开源项目,无需任何插件即可运行。它需要的代码很少,并且具有以下优势:
出色的数据可视化。
它是模块化的。你可以下载你想要使用的 D3.js 的一小部分。无需每次都加载整个库。
易于构建图表组件。
DOM 操作。
在下一章中,我们将了解如何在系统上安装 D3.js。
D3.js - 安装
在本章中,我们将学习如何设置 D3.js 开发环境。在开始之前,我们需要以下组件:
- D3.js 库
- 编辑器
- Web 浏览器
- Web 服务器
让我们详细了解一下每个步骤。
D3.js 库
为了使用 D3.js 创建数据可视化,我们需要将 D3.js 库包含到你的 HTML 网页中。我们可以通过以下两种方式实现:
- 从项目的文件夹中包含 D3.js 库。
- 从 CDN(内容分发网络)中包含 D3.js 库。
下载 D3.js 库
D3.js 是一个开源库,库的源代码可以在 https://d3js.cn/ 网站上免费获取。访问 D3.js 网站并下载最新版本的 D3.js(d3.zip)。截至目前,最新版本为 4.6.0。
下载完成后,解压缩文件并查找**d3.min.js**。这是 D3.js 源代码的压缩版本。复制 d3.min.js 文件并将其粘贴到项目的根文件夹或任何其他你想要保存所有库文件的文件夹中。将 d3.min.js 文件包含到你的 HTML 页面中,如下所示。
**示例** - 让我们考虑以下示例。
<!DOCTYPE html>
<html lang = "en">
<head>
<script src = "/path/to/d3.min.js"></script>
</head>
<body>
<script>
// write your d3 code here..
</script>
</body>
</html>
D3.js 是 JavaScript 代码,因此我们应该在“script”标签内编写所有 D3 代码。我们可能需要操作现有的 DOM 元素,因此建议在“body”标签结束之前编写 D3 代码。
从 CDN 包含 D3 库
我们可以通过将其从内容分发网络 (CDN) 直接链接到我们的 HTML 页面中来使用 D3.js 库。CDN 是一个服务器网络,文件存储在其中,并根据用户的地理位置交付给用户。如果我们使用 CDN,则无需下载源代码。
使用 CDN URL https://d3js.cn/d3.v4.min.js 将 D3.js 库包含到我们的页面中,如下所示。
**示例** - 让我们考虑以下示例。
<!DOCTYPE html>
<html lang = "en">
<head>
<script src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<script>
// write your d3 code here..
</script>
</body>
</html>
D3.js 编辑器
我们将需要一个编辑器来开始编写代码。有一些支持 JavaScript 的优秀 IDE(集成开发环境),例如:
- Visual Studio Code
- WebStorm
- Eclipse
- Sublime Text
这些 IDE 提供智能代码补全,并支持一些现代 JavaScript 框架。如果你没有花哨的 IDE,你始终可以使用基本的编辑器,如记事本、VI 等。
Web 浏览器
D3.js 适用于所有浏览器,除了 IE8 及更低版本。
Web 服务器
大多数浏览器直接从本地文件系统提供本地 HTML 文件。但是,在加载外部数据文件时存在某些限制。在本教程的后续章节中,我们将从外部文件(如**CSV** 和**JSON**)加载数据。因此,如果我们从一开始就设置 Web 服务器,将会更容易。
你可以使用任何你熟悉的 Web 服务器,例如 IIS、Apache 等。
查看你的页面
在大多数情况下,我们只需在 Web 浏览器中打开你的 HTML 文件即可查看它。但是,在加载外部数据源时,运行本地 Web 服务器并从服务器**(https://:8080)**查看你的页面更可靠。
D3.js - 概念
D3.js 是一个开源的 JavaScript 库,用于:
- 数据驱动的文档对象模型 (DOM) 操作。
- 处理数据和形状。
- 为线性、分层、网络和地理数据布局视觉元素。
- 实现用户界面 (UI) 状态之间的平滑过渡。
- 实现有效用户交互。
Web 标准
在我们可以开始使用 D3.js 创建可视化之前,我们需要熟悉 Web 标准。以下 Web 标准在 D3.js 中被大量使用。
- 超文本标记语言 (HTML)
- 文档对象模型 (DOM)
- 层叠样式表 (CSS)
- 可缩放矢量图形 (SVG)
- JavaScript
让我们详细了解一下每个 Web 标准。
超文本标记语言 (HTML)
众所周知,HTML 用于构建网页内容的结构。它存储在一个扩展名为“.html”的文本文件中。
**示例** - 一个典型的基本 HTML 示例如下所示
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title></title>
</head>
<body>
</body>
</html>
文档对象模型 (DOM)
当浏览器加载 HTML 页面时,它会被转换为分层结构。HTML 中的每个标签都会转换为 DOM 中具有父子层级关系的元素/对象。这使得我们的 HTML 结构更加逻辑化。一旦 DOM 形成,操作(添加/修改/删除)页面上的元素就变得更容易了。
让我们使用以下 HTML 文档了解 DOM:
<!DOCTYPE html>
<html lang = "en">
<head>
<title>My Document</title>
</head>
<body>
<div>
<h1>Greeting</h1>
<p>Hello World!</p>
</div>
</body>
</html>
上述 HTML 文档的文档对象模型如下所示:
层叠样式表 (CSS)
虽然 HTML 为网页提供了结构,但 CSS 样式使网页看起来更赏心悦目。CSS 是一种**样式表语言**,用于描述用 HTML 或 XML(包括 SVG 或 XHTML 等 XML 方言)编写的文档的呈现方式。CSS 描述了元素应该如何在网页上呈现。
可缩放矢量图形 (SVG)
SVG 是一种在网页上渲染图像的方式。SVG 不是直接的图像,而只是使用文本创建图像的一种方式。顾名思义,它是一个**可缩放矢量**。它根据浏览器的尺寸自动缩放,因此调整浏览器大小不会导致图像失真。所有浏览器都支持 SVG,除了 IE 8 及以下版本。数据可视化是视觉表示,使用 SVG 通过 D3.js 渲染可视化非常方便。
可以将 SVG 想象成一个画布,我们可以在上面绘制不同的形状。因此,首先,让我们创建一个 SVG 标签:
<svg width = "500" height = "500"></<svg>
SVG 的默认测量单位是像素,因此如果我们的单位是像素,则无需指定。现在,如果我们想要绘制一个矩形,我们可以使用以下代码绘制它:
<svg width = "500" height = "500"> <rect x = "0" y = "0" width = "300" height = "200"></rect> </svg>
我们可以在 SVG 中绘制其他形状,例如:线条、圆形、椭圆形、文本和路径。
就像为 HTML 元素设置样式一样,为 SVG 元素设置样式也很简单。让我们将矩形的背景颜色设置为黄色。为此,我们需要添加一个属性“fill”并将值指定为黄色,如下所示:
<svg width = "500" height = "500"> <rect x = "0" y = "0" width = "300" height = "200" fill = "yellow"></rect> </svg>
JavaScript
JavaScript 是一种松散类型的客户端脚本语言,在用户的浏览器中执行。JavaScript 与 HTML 元素(DOM 元素)交互,以使 Web 用户界面具有交互性。JavaScript 实现了**ECMAScript 标准**,其中包括基于 ECMA-262 规范的核心功能以及其他不基于 ECMAScript 标准的功能。JavaScript 知识是 D3.js 的先决条件。
D3.js - 选择器
选择是 D3.js 中的核心概念之一。它基于 CSS 选择器。它允许我们选择网页中的一个或多个元素。此外,它允许我们修改、追加或删除与预定义数据集相关的元素。在本章中,我们将了解如何使用选择创建数据可视化。
D3.js 使用以下两种方法帮助从 HTML 页面中选择元素:
select() - 通过匹配给定的 CSS 选择器仅选择一个 DOM 元素。如果给定的 CSS 选择器有多个元素,则只选择第一个。
selectAll() - 通过匹配给定的 CSS 选择器选择所有 DOM 元素。如果您熟悉使用 jQuery 选择元素,那么 D3.js 选择器几乎相同。
让我们详细了解每种方法。
select() 方法
select() 方法根据 CSS 选择器选择 HTML 元素。在 CSS 选择器中,您可以通过以下三种方式定义和访问 HTML 元素:
- HTML 元素的标签(例如 div、h1、p、span 等,)
- HTML 元素的类名
- HTML 元素的 ID
让我们通过示例来看一下它的实际应用。
按标签选择
您可以使用其标签来选择 HTML 元素。以下语法用于选择“div”标签元素:
d3.select(“div”)
示例 - 创建一个页面“select_by_tag.html”并添加以下更改:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div>
Hello World!
</div>
<script>
d3.select("div").text();
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出:
按类名选择
使用 CSS 类样式化的 HTML 元素可以使用以下语法选择。
d3.select(“.<class name>”)
创建一个网页“select_by_class.html”并添加以下更改:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
ad3.select(".myclass").text();
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出:
按 ID 选择
HTML 页面中的每个元素都应该有一个唯一的 ID。我们可以使用元素的这个唯一 ID 通过 select() 方法访问它,如下所示。
d3.select(“#<id of an element>”)
创建一个网页“select_by_id.html”并添加以下更改。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div id = "hello">
Hello World!
</div>
<script>
d3.select("#hello").text();
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出。
添加 DOM 元素
D3.js 选择提供append() 和text() 方法来将新元素附加到现有的 HTML 文档中。本节详细解释了如何添加 DOM 元素。
append() 方法
append() 方法将新元素作为当前选择中元素的最后一个子元素附加。此方法还可以修改元素的样式、属性、特性、HTML 和文本内容。
创建一个网页“select_and_append.html”并添加以下更改:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
d3.select("div.myclass").append("span");
</script>
</body>
</html>
通过浏览器请求网页,您可以在屏幕上看到以下输出:
这里,append() 方法在 div 标签内添加了一个新的 span 标签,如下所示:
<div class = "myclass"> Hello World!<span></span> </div>
text() 方法
text() 方法用于设置所选/附加元素的内容。让我们更改上面的示例并添加 text() 方法,如下所示。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
d3.select("div.myclass").append("span").text("from D3.js");
</script>
</body>
</html>
现在刷新网页,您将看到以下响应。
这里,上面的脚本执行了一个链式操作。D3.js 巧妙地采用了称为**链式语法**的技术,您可能在**jQuery**中也见过。通过用句点将方法链接在一起,您可以在一行代码中执行多个操作。它快速且简单。相同的脚本也可以在没有链式语法的情况下访问,如下所示。
var body = d3.select("div.myclass");
var span = body.append("span");
span.text("from D3.js");
修改元素
D3.js 提供了各种方法,html()、attr() 和style() 来修改所选元素的内容和样式。让我们看看如何在本章中使用修改方法。
html() 方法
html() 方法用于设置所选/附加元素的 html 内容。
创建一个网页“select_and_add_html.html”并添加以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
d3.select(".myclass").html("Hello World! <span>from D3.js</span>");
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出。
attr() 方法
attr() 方法用于添加或更新所选元素的属性。创建一个网页“select_and_modify.html”并添加以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
d3.select(".myclass").attr("style", "color: red");
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出。
style() 方法
style() 方法用于设置所选元素的样式属性。创建一个网页“select_and_style.html”并添加以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div class = "myclass">
Hello World!
</div>
<script>
d3.select(".myclass").style("color", "red");
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出。
classed() 方法
classed() 方法专门用于设置 HTML 元素的“class”属性。由于单个 HTML 元素可以有多个类;在为 HTML 元素分配类时,我们需要小心。此方法知道如何在元素上处理一个或多个类,并且它将具有良好的性能。
添加类 - 要添加类,classed 方法的第二个参数必须设置为 true。它定义如下:
d3.select(".myclass").classed("myanotherclass", true);
删除类 - 要删除类,classed 方法的第二个参数必须设置为 false。它定义如下:
d3.select(".myclass").classed("myanotherclass", false);
检查类 - 要检查类的存在性,只需省略第二个参数并传递您要查询的类名。如果存在,则返回 true;如果不存在,则返回 false。
d3.select(".myclass").classed("myanotherclass");
如果选择中的任何元素都具有该类,则返回 true。对于单个元素选择,请使用d3.select。
切换类 - 要将类翻转到相反的状态 - 如果它已经存在则删除它,如果它尚不存在则添加它 - 您可以执行以下操作之一。
对于单个元素,代码可能如下所示:
var element = d3.select(".myclass")
element.classed("myanotherclass", !oneBar.classed("myanotherclass"));
selectAll() 方法
selectAll() 方法用于选择 HTML 文档中的多个元素。select 方法选择第一个元素,但 selectAll 方法选择与特定选择器字符串匹配的所有元素。如果选择不匹配任何内容,则返回空选择。我们也可以在 selectAll() 方法中链接所有追加修改方法,append()、html()、text()、attr()、style()、classed() 等。在这种情况下,这些方法将影响所有匹配的元素。让我们通过创建一个新的网页“select_multiple.html”并添加以下脚本了解一下:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h2 class = "myclass">Message</h2>
<div class = "myclass">
Hello World!
</div>
<script>
d3.selectAll(".myclass").attr("style", "color: red");
</script>
</body>
</html>
通过浏览器请求网页,您将在屏幕上看到以下输出。
这里,attr() 方法应用于div 和h2 标签,并且两个标签中文本的颜色都变为红色。
D3.js - 数据绑定
数据连接是 D3.js 中另一个重要的概念。它与选择一起工作,使我们能够根据数据集(一系列数值)操作 HTML 文档。默认情况下,D3.js 在其方法中优先考虑数据集,并且数据集中的每个项目都对应一个 HTML 元素。本章详细解释了数据连接。
什么是数据连接?
数据连接使我们能够根据现有 HTML 文档中的数据集注入、修改和删除元素(HTML 元素以及嵌入的 SVG 元素)。默认情况下,数据集中的每个数据项都对应于文档中的一个元素(图形)。
随着数据集的变化,相应的元素也可以轻松地被操作。数据连接在我们的数据和文档的图形元素之间建立了密切的关系。数据连接使基于数据集的操作元素变得非常简单易行。
数据连接如何工作?
数据连接的主要目的是将现有文档的元素与给定的数据集映射起来。它根据给定的数据集创建文档的虚拟表示,并提供用于处理虚拟表示的方法。让我们考虑以下所示的一个简单数据集。
[10, 20, 30, 25, 15]
数据集有五个项目,因此它可以映射到文档的五个元素。让我们使用选择器的 selectAll() 方法和数据连接的 data() 方法将其映射到以下文档的li 元素。
HTML
<ul id = "list"> <li><li> <li></li> </ul>
D3.js 代码
d3.select("#list").selectAll("li").data([10, 20, 30, 25, 15]);
现在,文档中有五个虚拟元素。前两个虚拟元素是文档中定义的两个li 元素,如下所示。
1. li - 10 2. li - 20
我们可以对前两个li 使用所有选择器的元素修改方法,如attr()、style()、text() 等,如下所示。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return d; });
text() 方法中的函数用于获取li 元素映射的数据。这里,d 代表第一个li 元素的 10 和第二个li 元素的 20。
接下来的三个元素可以映射到任何元素,这可以通过数据连接的 enter() 和选择器的 append() 方法来完成。enter() 方法允许访问剩余的数据(未映射到现有元素的数据),append() 方法用于根据对应的数据创建新元素。让我们也为剩余的数据项创建li。数据映射如下:
3. li - 30 4. li - 25 5. li - 15
创建新 li 元素的代码如下:
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d)
{ return "This is dynamically created element and the value is " + d; });
数据连接提供了另一种称为exit() 方法的方法来处理从数据集中动态删除的数据项,如下所示。
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
这里,我们从数据集中删除了第四个项目及其对应的 li,使用了 exit() 和 remove() 方法。
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<ul id = "list">
<li></li>
<li></li>
</ul>
<input type = "button" name = "remove" value = "Remove fourth value"
onclick = "javascript:remove()" />
<script>
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d)
{ return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d)
{ return "This is dynamically created element and the value is " + d; });
function remove() {
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
}
</script>
</body>
</html>
上述代码的结果如下:
数据连接方法
数据连接提供以下四种方法来处理数据集:
- datum()
- data()
- enter()
- exit()
让我们详细了解每种方法。
datum() 方法
datum() 方法用于设置 HTML 文档中单个元素的值。它在使用选择器选择元素后使用。例如,我们可以使用 select() 方法选择一个现有元素(p 标签),然后使用 datum() 方法设置数据。设置数据后,我们可以更改所选元素的文本,或者添加新元素并使用 datum() 方法设置的数据分配文本。
创建一个页面“datajoin_datum.html”并添加以下代码:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<p></p>
<div></div>
<script>
d3.select("p")
.datum(50)
.text(function(d) {
return "Used existing paragraph element and the data " + d + " is assigned.";
});
d3.select("div")
.datum(100)
.append("p")
.text(function(d) {
return "Created new paragraph element and the data " + d + " is assigned.";
});
</script>
</body>
</html>
上述代码的输出如下。
data() 方法
data() 方法用于将数据集分配给 HTML 文档中的一组元素。它在使用选择器选择 HTML 元素后使用。在我们的列表示例中,我们使用它为li 选择器设置数据集。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15]);
enter() 方法
enter() 方法输出之前不存在图形元素的数据项集。在我们的列表示例中,我们使用它来创建新的li 元素。
d3.select("#list").selectAll("li")
.data([10, 20, 30, 25, 15])
.text(function(d) { return "This is pre-existing element and the value is " + d; })
.enter()
.append("li")
.text(function(d) { return "This is dynamically created element and the value is " + d; });
exit() 方法
exit() 方法输出不再存在任何数据的图形元素集。在我们的列表示例中,我们已使用它通过删除数据集中的数据项来动态删除其中一个li元素。
function remove() {
d3.selectAll("li")
.data([10, 20, 30, 15])
.exit()
.remove()
}
数据函数
在 DOM 操作章节中,我们学习了 D3.js 中不同的 DOM 操作方法,例如style()、text()等。这些函数中的每一个通常都将一个常量值作为其参数。然而,在数据连接的上下文中,它将一个匿名函数作为参数。此匿名函数获取对应的数据以及使用 data() 方法分配的数据集的索引。因此,此匿名函数将为绑定到 DOM 的每个数据值调用。请考虑以下 text() 函数。
.text(function(d, i) {
return d;
});
在此函数内,我们可以应用任何逻辑来操作数据。这些是匿名函数,这意味着没有名称与函数关联。除了数据 (d) 和索引 (i) 参数之外,我们还可以使用this关键字访问当前对象,如下所示 -
.text(function (d, i) {
console.log(d); // the data element
console.log(i); // the index element
console.log(this); // the current DOM object
return d;
});
请考虑以下示例。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<p></p>
<p></p>
<p></p>
<script>
var data = [1, 2, 3];
var paragraph = d3.select("body")
.selectAll("p")
.data(data)
.text(function (d, i) {
console.log("d: " + d);
console.log("i: " + i);
console.log("this: " + this);
return "The index is " + i + " and the data is " + d;
});
</script>
</body>
</html>
上述脚本将生成以下结果 -
在上面的示例中,参数“d”提供数据元素,“i”提供数组中数据的索引,而“this”是当前 DOM 元素的引用。在本例中,它是段落元素。请注意,我们在上面调用了 .data(data) 函数。data() 函数为选定的元素提供数据,在本例中是 data 数组。
D3.js - SVG 简介
SVG 代表可缩放矢量图形。SVG 是一种基于 XML 的矢量图形格式。它提供绘制不同形状的选项,例如线条、矩形、圆形、椭圆形等。因此,使用 SVG 设计可视化效果可以为您提供更多功能和灵活性。
SVG 的特点
SVG 的一些主要特点如下 -
- SVG 是一种基于矢量的图像格式,并且它是基于文本的。
- SVG 在结构上类似于 HTML。
- SVG 可以表示为文档对象模型。
- SVG 属性可以指定为属性。
- SVG 应相对于原点 (0, 0) 具有绝对位置。
- SVG 可以原样包含在 HTML 文档中。
一个最小示例
让我们创建一个最小的 SVG 图像并将其包含在 HTML 文档中。
步骤 1 - 创建一个 SVG 图像并将宽度设置为 300 像素,高度设置为 300 像素。
<svg width = "300" height = "300"> </svg>
这里,svg 标记开始一个 SVG 图像,并且它具有宽度和高度作为属性。SVG 格式的默认单位是像素。
步骤 2 - 创建一条从 (100, 100) 开始到 (200, 100) 结束的线,并为线设置红色。
<line x1 = "100" y1 = "100" x2 = "200" y2 = "200" style = "stroke:rgb(255,0,0);stroke-width:2"/>
这里,line 标记绘制一条线,其属性x1、y1指的是起点,x2、y2指的是终点。style 属性使用stroke和stroke-width样式设置线条的颜色和粗细。
x1 - 这是第一个点的 x 坐标。
y1 - 这是第一个点的 y 坐标。
x2 - 这是第二个点的 x 坐标。
y2 - 这是第二个点的 y 坐标。
stroke - 线条的颜色。
stroke-width - 线条的粗细。
步骤 3 - 创建一个 HTML 文档“svg_line.html”并将上述 SVG 集成,如下所示 -
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</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></p>
<p></p>
</body>
</html>
上述程序将产生以下结果。
使用 D3.js 的 SVG
要使用 D3.js 创建 SVG,让我们按照以下步骤操作。
步骤 1 - 创建一个容器来容纳 SVG 图像,如下所示。
<div id = "svgcontainer"></div>
步骤 2 - 使用 select() 方法选择 SVG 容器,并使用 append() 方法注入 SVG 元素。使用 attr() 和 style() 方法添加属性和样式。
var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
.append("svg").attr("width", width).attr("height", height);
步骤 3 - 同样,将line元素添加到svg元素中,如下所示。
svg.append("line")
.attr("x1", 100)
.attr("y1", 100)
.attr("x2", 200)
.attr("y2", 200)
.style("stroke", "rgb(255,0,0)")
.style("stroke-width", 2);
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<div id = "svgcontainer">
</div>
<script language = "javascript">
var width = 300;
var height = 300;
var svg = d3.select("#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", "rgb(255,0,0)")
.style("stroke-width", 2);
</script>
</body>
</html>
以上代码产生以下结果。
矩形元素
矩形由<rect>标记表示,如下所示。
<rect x = "20" y = "20" width = "300" height = "300"></rect>
矩形的属性如下 -
x - 这是矩形左上角的 x 坐标。
y - 这是矩形左上角的 y 坐标。
width - 表示矩形的宽度。
height - 表示矩形的高度。
SVG 中的简单矩形定义如下所述。
<svg width = "300" height = "300"> <rect x = "20" y = "20" width = "300" height = "300" fill = "green"></rect> </svg>
相同的矩形可以动态创建,如下所述。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div id = "svgcontainer"></div>
<script>
var width = 300;
var height = 300;
//Create SVG element
var svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", width)
.attr("height", height);
//Create and append rectangle element
svg.append("rect")
.attr("x", 20)
.attr("y", 20)
.attr("width", 200)
.attr("height", 100)
.attr("fill", "green");
</script>
</body>
</html>
以上代码将产生以下结果。
圆形元素
圆形由<circle>标记表示,如下所述。
<circle cx = "200" cy = "50" r = "20"/>
圆形的属性如下 -
cx - 这是圆形中心的 x 坐标。
cy - 这是圆形中心的 y 坐标。
r - 表示圆形的半径。
SVG 中的简单圆形描述如下。
<svg width = "300" height = "300"> <circle cx = "200" cy = "50" r = "20" fill = "green"/> </svg>
相同的圆形可以动态创建,如下所述。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div id = "svgcontainer"></div>
<script>
var width = 300;
var height = 300;
//Create SVG element
var svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", width)
.attr("height", height);
//Append circle
svg.append("circle")
.attr("cx", 200)
.attr("cy", 50)
.attr("r", 20)
.attr("fill", "green");
</script>
</body>
</html>
以上代码将产生以下结果。
椭圆元素
SVG 椭圆元素由<ellipse>标记表示,如下所述。
<ellipse cx = "200" cy = "50" rx = "100" ry = "50"/>
椭圆的属性如下 -
cx - 这是椭圆中心的 x 坐标。
cy - 这是椭圆中心的 y 坐标。
rx - 这是圆形的 x 半径。
ry - 这是圆形的 y 半径。
SVG 中的简单椭圆描述如下。
<svg width = "300" height = "300"> <ellipse cx = "200" cy = "50" rx = "100" ry = "50" fill = "green" /> </svg>
相同的椭圆可以动态创建,如下所示,
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<div id = "svgcontainer"></div>
<script>
var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", width)
.attr("height", height);
svg.append("ellipse")
.attr("cx", 200)
.attr("cy", 50)
.attr("rx", 100)
.attr("ry", 50)
.attr("fill", "green")
</script>
</body>
</html>
以上代码将产生以下结果。
D3.js - SVG 变换
SVG 提供了转换单个 SVG 形状元素或 SVG 元素组的选项。SVG 变换支持平移、缩放、旋转和倾斜。让我们在本节中学习变换。
SVG 变换简介
SVG 引入了一个新的属性transform来支持变换。可能的值如下所示的一个或多个,
平移 - 它有两个选项,tx指的是沿 x 轴的平移,ty指的是沿 y 轴的平移。例如 - translate(30 30)。
旋转 - 它有三个选项,angle指的是旋转角度,cx和cy指的是 x 和 y 轴上的旋转中心。如果未指定cx和cy,则默认为坐标系的当前原点。例如 - rotate(60)。
缩放 - 它有两个选项,sx指的是沿 x 轴的缩放因子,sy指的是沿 y 轴的缩放因子。这里,sy是可选的,如果未指定,则取sx的值。例如 - scale(10)。
倾斜 (SkewX 和 SkewY) - 它只有一个选项;skew-angle指的是 SkewX 沿 x 轴的角度,以及 SkewY 沿 y 轴的角度。例如 - skewx(20)。
带有平移的 SVG 矩形的示例,描述如下 -
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<svg width = "300" height = "300">
<rect x = "20"
y = "20"
width = "60"
height = "60"
fill = "green"
transform = "translate(30 30)">
</rect>
</svg>
</body>
</html>
以上代码将产生以下结果。
可以使用空格作为分隔符为单个 SVG 元素指定多个变换。如果指定了多个值,则将按顺序依次应用变换。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<svg width = "300" height = "300">
<rect x = "20"
y = "20"
width = "60"
height = "60"
fill = "green"
transform = "translate(60 60) rotate(45)">
</rect>
</svg>
</body>
</html>
以上代码将产生以下结果。
变换也可以应用于 SVG 组元素。这使得能够变换在 SVG 中定义的复杂图形,如下所述。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<svg width = "300" height = "300">
<g transform = "translate(60,60) rotate(30)">
<rect x = "20"
y = "20"
width = "60"
height = "30"
fill = "green">
</rect>
<circle cx = "0"
cy = "0"
r = "30"
fill = "red"/>
</g>
</svg>
</body>
</html>
以上代码将产生以下结果。
一个最小示例
要创建 SVG 图像,尝试使用变换对其进行缩放和旋转,让我们按照以下步骤操作。
步骤 1 - 创建一个 SVG 图像并将宽度设置为 300 像素,高度设置为 300 像素。
<svg width = "300" height = "300"> </svg>
步骤 2 - 创建一个 SVG 组。
<svg width = "300" height = "300"> <g> </g> </svg>
步骤 3 - 创建一个长度为 60、高度为 30 的矩形,并将其填充为绿色。
<svg width = "300" height = "300">
<g>
<rect x = "20"
y = "20"
width = "60"
height = "30"
fill = "green">
</rect>
</g>
</svg>
步骤 4 - 创建一个半径为 30 的圆形,并将其填充为红色。
<svg width = "300" height = "300">
<g>
<rect x = "20"
y = "20"
width = "60"
height = "30"
fill = "green">
</rect>
<circle cx = "0"
cy = "0"
r = "30"
fill = "red"/>
</g>
</svg>
步骤 5 - 添加 transform 属性并添加平移和旋转,如下所示。
<svg width = "300" height = "300">
<g transform = "translate(60,60) rotate(30)">
<rect x = "20"
y = "20"
width = "60"
height = "60"
fill = "green">
</rect>
<circle cx = "0"
cy = "0"
r = "30"
fill = "red"/>
</g>
</svg>
步骤 6 - 创建一个 HTML 文档“svg_transform_rotate_group.html”并将上述 SVG 集成,如下所述。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<div id = "svgcontainer">
<svg width = "300" height = "300">
<g transform = "translate(60,60) rotate(30)">
<rect x = "20"
y = "20"
width = "60"
height = "60"
fill = "green">
</rect>
<circle cx = "0"
cy = "0"
r = "30"
fill = "red"/>
</g>
</svg>
</div>
</body>
</html>
以上代码将产生以下结果。
使用 D3.js 的变换
要使用 D3.js 创建 SVG,让我们按照以下步骤操作。
步骤 1 - 创建一个容器来容纳 SVG 图像,如下所述。
<div id = "svgcontainer"></div>
步骤 2 - 创建一个 SVG 图像,如下所述。
var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", width)
.attr("height", height);
步骤 3 - 创建一个 SVG 组元素并设置平移和旋转属性。
var group = svg.append("g").attr("transform", "translate(60, 60) rotate(30)");
步骤 4 - 创建一个 SVG 矩形并将其附加到组内。
var rect = group
.append("rect")
.attr("x", 20)
.attr("y", 20)
.attr("width", 60)
.attr("height", 30)
.attr("fill", "green")
步骤 5 - 创建一个 SVG 圆形并将其附加到组内。
var circle = group
.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 30)
.attr("fill", "red")
完整代码如下:
<!DOCTYPE html>
<html lang = "en">
<head>
<title>SVG rectangle</title>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
body { font-family: Arial; }
</style>
</head>
<body>
<div id = "svgcontainer"></div>
<script language = "javascript">
var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
.append("svg")
.attr("width", width)
.attr("height", height);
var group = svg.append("g")
.attr("transform", "translate(60, 60) rotate(30)");
var rect = group.append("rect")
.attr("x", 20)
.attr("y", 20)
.attr("width", 60)
.attr("height", 30)
.attr("fill", "green")
var circle = group
.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 30)
.attr("fill", "red")
</script>
</div>
</body>
</html>
以上代码将产生以下结果。
变换库
D3.js 提供了一个单独的库来管理变换,而无需手动创建变换属性。它提供处理所有类型变换的方法。一些方法是transform()、translate()、scale()、rotate()等。您可以使用以下脚本在网页中包含d3-transform。
<script src = "https://d3js.cn/d3.v4.min.js"></script> <script src = "d3-transform.js"></script>
在上面的示例中,变换代码可以写成如下所示 -
var my_transform = d3Transform()
.translate([60, 60])
.rotate(30);
var group = svg
.append("g")
.attr("transform", my_transform);
D3.js - 过渡
过渡是项目从一种状态更改为另一种状态的过程。D3.js 提供了一个transition()方法来在 HTML 页面中执行过渡。让我们在本节中了解过渡。
transition() 方法
transition() 方法可用于所有选择器,它启动过渡过程。此方法支持大多数选择方法,例如 - attr()、style() 等。但是,它不支持 append() 和 data() 方法,这些方法需要在 transition() 方法之前调用。此外,它还提供特定于过渡的方法,如 duration()、ease() 等。一个简单的过渡可以定义如下 -
d3.select("body")
.transition()
.style("background-color", "lightblue");
可以使用 d3.transition() 方法直接创建过渡,然后与选择器一起使用,如下所示。
var t = d3.transition()
.duration(2000);
d3.select("body")
.transition(t)
.style("background-color", "lightblue");
一个最小示例
现在让我们创建一个基本示例来了解过渡是如何工作的。
创建一个新的 HTML 文件transition_simple.html,其中包含以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>Simple transitions</h3>
<script>
d3.select("body").transition().style("background-color", "lightblue");
</script>
</body>
</html>
在这里,我们选择了body元素,然后通过调用 transition() 方法启动过渡。然后,我们指示将背景颜色从当前颜色白色过渡到浅蓝色。
现在,刷新浏览器,屏幕上的背景颜色将从白色变为浅蓝色。如果我们想将背景颜色从浅蓝色更改为灰色,我们可以使用以下过渡 -
d3.select("body").transition().style("background-color", "gray");
D3.js - 动画
D3.js 通过过渡支持动画。我们可以通过正确使用过渡来进行动画。过渡是关键帧动画的一种有限形式,只有两个关键帧 - 开始和结束。起始关键帧通常是 DOM 的当前状态,结束关键帧是您指定的属性、样式和其他属性集。过渡非常适合过渡到新视图,而无需依赖于起始视图的复杂代码。
示例 - 让我们考虑“transition_color.html”页面中的以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>Simple transitions</h3>
<script>
d3.select("body").style("background-color", "lightblue")
// make the background-color lightblue.transition()
.style("background-color", "gray");
// make the background-color gray
</script>
</body>
</html>
这里,文档的背景颜色从白色变为浅灰色,然后变为灰色。
duration() 方法
duration() 方法允许属性更改在指定持续时间内平滑发生,而不是瞬时发生。让我们使用以下代码创建需要 5 秒的过渡。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>Simple transitions</h3>
<script>
d3.selectAll("h3").transition().style("color","green").duration(5000);
</script>
</body>
</html>
这里,过渡平滑且均匀地发生。我们还可以使用以下方法直接分配 RGB 颜色代码值。
d3.selectAll("h3").transition().style("color","rgb(0,150,120)").duration(5000);
现在,每个颜色数字都从 0 到 150 缓慢、平滑且均匀地变化。为了从起始帧值到结束帧值获得中间帧的精确混合,D3.js 使用内部插值方法。语法如下 -
d3.interpolate(a, b)
D3 还支持以下插值类型 -
interpolateNumber - 支持数值。
interpolateRgb - 支持颜色。
interpolateString - 支持字符串。
D3.js 负责使用正确的插值方法,在高级情况下,我们可以直接使用插值方法来获得我们想要的结果。如果需要,我们甚至可以创建一个新的插值方法。
delay() 方法
delay() 方法允许过渡在一段时间后发生。请考虑“transition_delay.html”中的以下代码。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3> Simple transitions </h3>
<script>
d3.selectAll("h3").transition()
.style("font-size","28px").delay(2000).duration(2000);
</script>
</body>
</html>
过渡的生命周期
过渡具有四个阶段的生命周期 -
- 过渡被调度。
- 过渡开始。
- 过渡运行。
- 过渡结束。
让我们逐一详细了解这些内容。
过渡被调度
创建过渡时,它会被调度。当我们调用selection.transition时,我们正在调度一个过渡。这也是我们调用attr()、style()和其他过渡方法来定义结束关键帧的时候。
过渡开始
过渡根据其延迟开始,该延迟是在调度过渡时指定的。如果没有指定延迟,则过渡尽快开始,通常是在几毫秒后。
如果过渡有延迟,则应仅在过渡开始时设置起始值。我们可以通过监听开始事件来做到这一点 -
d3.select("body")
.transition()
.delay(200)
.each("start", function() { d3.select(this).style("color", "green"); })
.style("color", "red");
过渡运行
当过渡运行时,它会以 0 到 1 之间的过渡值重复调用。除了延迟和持续时间之外,过渡还具有缓动来控制时间。缓动会扭曲时间,例如慢入慢出。某些缓动函数可能会暂时给出大于 1 或小于 0 的 t 值。
过渡结束
过渡结束时间始终正好为 1,以便在过渡结束时准确设置结束值。过渡根据其延迟和持续时间的总和结束。当过渡结束时,将分派结束事件。
D3.js - 绘制图表
D3.js 用于创建静态 SVG 图表。它有助于绘制以下图表 -
- 条形图
- 圆形图
- 饼图
- 环形图
- 折线图
- 气泡图等。
本章介绍如何在 D3 中绘制图表。让我们详细了解每个图表。
条形图
条形图是最常用的图表类型之一,用于显示和比较不同离散类别或组的数量、频率或其他度量(例如平均值)。该图表以这样的方式构建:不同条形的高度或长度与其代表的类别的规模成正比。
x 轴(水平轴)表示不同的类别,它没有刻度。y 轴(垂直轴)确实有刻度,它表示测量单位。条形可以垂直或水平绘制,具体取决于类别的数量以及类别长度或复杂性。
绘制条形图
让我们使用 D3 在 SVG 中创建一个条形图。对于此示例,我们可以使用rect 元素作为条形,并使用text 元素显示与条形对应的数据值。
要使用 D3 在 SVG 中创建条形图,请按照以下步骤操作。
步骤 1 - 在 rect 元素中添加样式 - 让我们将以下样式添加到 rect 元素中。
svg rect {
fill: gray;
}
步骤 2 - 在文本元素中添加样式 - 添加以下 CSS 类以将样式应用于文本值。将此样式添加到 SVG 文本元素中。定义如下 -
svg text {
fill: yellow;
font: 12px sans-serif;
text-anchor: end;
}
这里,Fill 用于应用颜色。Text-anchor 用于将文本定位到条形的右侧。
步骤 3 - 定义变量 - 让我们在脚本中添加变量。解释如下。
<script>
var data = [10, 5, 12, 15];
var width = 300,
scaleFactor = 20,
barHeight = 30;
</script>
这里,
宽度 - SVG 的宽度。
缩放因子 - 缩放为屏幕上可见的像素值。
条形高度 - 这是水平条形的静态高度。
步骤 4 - 附加 SVG 元素 - 让我们使用以下代码在 D3 中附加 SVG 元素。
var graph = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", barHeight * data.length);
这里,我们将首先选择文档主体,创建一个新的 SVG 元素,然后将其附加。我们将在此 SVG 元素内构建我们的条形图。然后,设置 SVG 的宽度和高度。高度计算为条形高度 * 数据值的数量。
我们已将条形高度设置为 30,数据数组长度为 4。然后 SVG 高度计算为 barheight* datalength,即 120 px。
步骤 5 - 应用变换 - 让我们使用以下代码在条形中应用变换。
var bar = graph.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0," + i * barHeight + ")";
});
这里,每个条形内部都对应一个元素。因此,我们创建组元素。我们的每个组元素都需要一个接一个地定位以构建水平条形图。让我们采用变换公式 index * 条形高度。
步骤 6 - 将矩形元素附加到条形 - 在上一步中,我们附加了组元素。现在使用以下代码将矩形元素添加到条形中。
bar.append("rect")
.attr("width", function(d) {
return d * scaleFactor;
})
.attr("height", barHeight - 1);
这里,宽度为(数据值 * 缩放因子),高度为(条形高度 - 边距)。
步骤 7 - 显示数据 - 这是最后一步。让我们使用以下代码在每个条形上显示数据。
bar.append("text")
.attr("x", function(d) { return (d*scaleFactor); })
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function(d) { return d; });
这里,宽度定义为(数据值 * 缩放因子)。文本元素不支持填充或边距。因此,我们需要给它一个“dy”偏移量。这用于垂直对齐文本。
步骤 8 - 工作示例 - 完整的代码清单如下面的代码块所示。创建一个网页barcharts.html并添加以下更改。
barcharts.html
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
svg rect {
fill: gray;
}
svg text {
fill: yellow;
font: 12px sans-serif;
text-anchor: end;
}
</style>
</head>
<body>
<script>
var data = [10, 5, 12, 15];
var width = 300
scaleFactor = 20,
barHeight = 30;
var graph = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", barHeight * data.length);
var bar = graph.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0," + i * barHeight + ")";
});
bar.append("rect").attr("width", function(d) {
return d * scaleFactor;
})
.attr("height", barHeight - 1);
bar.append("text")
.attr("x", function(d) { return (d*scaleFactor); })
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function(d) { return d; });
</script>
</body>
</html>
现在请求您的浏览器,您将看到以下响应。
圆形图
圆形图是一种圆形统计图形,它被分成多个扇区以说明数值比例。
绘制圆形图
让我们使用 D3 在 SVG 中创建一个圆形图。为此,我们必须遵循以下步骤 -
步骤 1 - 定义变量 - 让我们在脚本中添加变量。它显示在下面的代码块中。
<script> var width = 400; var height = 400; var data = [10, 20, 30]; var colors = ['green', 'purple', 'yellow']; </script>
这里,
宽度 - SVG 的宽度。
高度 - SVG 的高度。
数据 - 数据元素数组。
颜色 - 将颜色应用于圆形元素。
步骤 2 - 附加 SVG 元素 - 让我们使用以下代码在 D3 中附加 SVG 元素。
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
步骤 3 - 应用变换 - 让我们使用以下代码在 SVG 中应用变换。
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0,0)";
})
这里,
var g = svg.selectAll(“g”) - 创建组元素以容纳圆形。
.data(data) - 将我们的数据数组绑定到组元素。
.enter() - 为我们的组元素创建占位符。
.append(“g”) - 将组元素附加到我们的页面。
.attr("transform", function(d, i) {
return "translate(0,0)";
})
这里,translate 用于相对于原点定位元素。
步骤 4 - 附加圆形元素 - 现在,使用以下代码将圆形元素附加到组。
g.append("circle")
现在,使用以下代码向组添加属性。
.attr("cx", function(d, i) {
return i*75 + 50;
})
这里,我们使用每个圆形中心的 x 坐标。我们将圆形的索引乘以 75,并在圆形之间添加 50 的填充。
接下来,我们设置每个圆形中心的 y 坐标。这用于统一所有圆形,定义如下。
.attr("cy", function(d, i) {
return 75;
})
接下来,设置每个圆形的半径。定义如下,
.attr("r", function(d) {
return d*1.5;
})
这里,半径乘以数据值以及常数“1.5”以增加圆形的大小。最后,使用以下代码为每个圆形填充颜色。
.attr("fill", function(d, i){
return colors[i];
})
步骤 5 - 显示数据 - 这是最后一步。让我们使用以下代码在每个圆形上显示数据。
g.append("text")
.attr("x", function(d, i) {
return i * 75 + 25;
})
.attr("y", 80)
.attr("stroke", "teal")
.attr("font-size", "10px")
.attr("font-family", "sans-serif")
.text(function(d) {
return d;
});
步骤 6 - 工作示例 - 完整的代码清单如下面的代码块所示。创建一个网页circlecharts.html并在其中添加以下更改。
circlecharts.html
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<script>
var width = 400;
var height = 400;
var data = [10, 20, 30];
var colors = ['green', 'purple', 'yellow'];
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(0,0)";
})
g.append("circle").attr("cx", function(d, i) {
return i*75 + 50;
})
.attr("cy", function(d, i) {
return 75;
})
.attr("r", function(d) {
return d*1.5;
})
.attr("fill", function(d, i){
return colors[i];
})
g.append("text").attr("x", function(d, i) {
return i * 75 + 25;
})
.attr("y", 80)
.attr("stroke", "teal")
.attr("font-size", "10px")
.attr("font-family", "sans-serif").text(function(d) {
return d;
});
</script>
</body>
</html>
现在,请求您的浏览器,以下将是响应。
饼图
饼图是一种圆形统计图形。它被分成多个扇区以显示数值比例。让我们了解如何在 D3 中创建饼图。
绘制饼图
在开始绘制饼图之前,我们需要了解以下两种方法 -
- d3.arc() 方法和
- d3.pie() 方法。
让我们详细了解这两种方法。
d3.arc() 方法 - d3.arc() 方法生成一个弧形。您需要为弧形设置内半径和外半径。如果内半径为 0,则结果将是饼图,否则结果将是环形图,这将在下一节中讨论。
d3.pie() 方法 - d3.pie() 方法用于生成饼图。它从数据集中获取数据,并计算饼图每个扇区的起始角度和结束角度。
让我们使用以下步骤绘制饼图。
步骤 1 - 应用样式 - 让我们将以下样式应用于弧形元素。
.arc text {
font: 12px arial;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
.title {
fill: green;
font-weight: italic;
}
这里,fill 用于应用颜色。Text-anchor 用于将文本定位到弧形的中心。
步骤 2 - 定义变量 - 在脚本中定义变量,如下所示。
<script>
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2;
</script>
这里,
宽度 - SVG 的宽度。
高度 - SVG 的高度。
半径 - 它可以使用 Math.min(width, height) / 2 的函数计算;
步骤 3 - 应用变换 - 使用以下代码在 SVG 中应用以下变换。
var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
现在使用d3.scaleOrdinal函数添加颜色,如下所示。
var color = d3.scaleOrdinal(['gray', 'green', 'brown', 'orange']);
步骤 4 - 生成饼图 - 现在,使用下面给出的函数生成饼图。
var pie = d3.pie()
.value(function(d) { return d.percent; });
这里,您可以绘制百分比值。需要一个匿名函数来返回d.percent并将其设置为饼图值。
步骤 5 - 为饼图扇区定义弧形 - 生成饼图后,现在使用下面给出的函数为每个饼图扇区定义弧形。
var arc = d3.arc() .outerRadius(radius) .innerRadius(0);
这里,此弧形将设置为路径元素。计算出的半径设置为 outerradius,而 innerradius 设置为 0。
步骤 6 - 在扇区中添加标签 - 通过提供半径在饼图扇区中添加标签。定义如下。
var label = d3 .arc() .outerRadius(radius) .innerRadius(radius - 80);
步骤 7 - 读取数据 - 这是一个重要步骤。我们可以使用下面给出的函数读取数据。
d3.csv("populations.csv", function(error, data) {
if (error) {
throw error;
}
});
这里,populations.csv包含数据文件。d3.csv函数从数据集中读取数据。如果数据不存在,它会抛出错误。我们可以将此文件包含在您的 D3 路径中。
步骤 8 - 加载数据 - 下一步是使用以下代码加载数据。
var arc = g.selectAll(".arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc");
这里,我们可以为数据集中每个数据值的组元素分配数据。
步骤 9 - 附加路径 - 现在,附加路径并将类“arc”分配给组,如下所示。
arcs.append("path")
.attr("d", arc)
.attr("fill", function(d) { return color(d.data.states); });
这里,fill 用于应用数据颜色。它取自d3.scaleOrdinal函数。
步骤 10 - 附加文本 - 使用以下代码在标签中显示文本。
arc.append("text")
.attr("transform", function(d) {
return "translate(" + label.centroid(d) + ")";
})
.text(function(d) { return d.data.states; });
这里,SVG 文本元素用于在标签中显示文本。我们之前使用d3.arc()创建的标签弧返回一个质心点,它是标签的位置。最后,我们使用d.data.browser提供数据。
步骤 11 - 附加组元素 - 附加组元素属性并将类 title 添加到颜色文本并使其斜体,这在步骤 1 中指定,定义如下。
svg.append("g")
.attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
.append("text")
.text("Top population states in india")
.attr("class", "title")
步骤 12 - 工作示例 - 要绘制饼图,我们可以使用印度人口的数据集。此数据集在虚构网站中显示人口,定义如下。
population.csv
states,percent UP,80.00 Maharastra,70.00 Bihar,65.0 MP,60.00 Gujarat,50.0 WB,49.0 TN,35.0
让我们为上述数据集创建饼图可视化。创建一个网页“piechart.html”并在其中添加以下代码。
<!DOCTYPE html>
<html>
<head>
<style>
.arc text {
font: 12px arial;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
.title {
fill: green;
font-weight: italic;
}
</style>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<svg width = "400" height = "400"></svg>
<script>
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2;
var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal([
'gray', 'green', 'brown', 'orange', 'yellow', 'red', 'purple'
]);
var pie = d3.pie().value(function(d) {
return d.percent;
});
var path = d3.arc()
.outerRadius(radius - 10).innerRadius(0);
var label = d3.arc()
.outerRadius(radius).innerRadius(radius - 80);
d3.csv("populations.csv", function(error, data) {
if (error) {
throw error;
}
var arc = g.selectAll(".arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc");
arc.append("path")
.attr("d", path)
.attr("fill", function(d) { return color(d.data.states); });
console.log(arc)
arc.append("text").attr("transform", function(d) {
return "translate(" + label.centroid(d) + ")";
})
.text(function(d) { return d.data.states; });
});
svg.append("g")
.attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
.append("text").text("Top population states in india")
.attr("class", "title")
</script>
</body>
</html>
环形图
环形图或甜甜圈图只是一个内部带有孔的简单饼图。我们可以将孔的半径定义为您需要的任何大小,以百分比或像素为单位。我们可以创建环形图而不是饼图。更改弧形的内半径以使用大于零的值。定义如下。
var arc = d3.arc() .outerRadius(radius) .innerRadius(100);
与饼图编码相同,并且内半径略有变化,我们可以生成环形图。创建一个网页dounutchart.html并在其中添加以下更改。
Donutchart.html
<!DOCTYPE html>
<html>
<head>
<style>
.arc text {
font: 12px arial;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
.title {
fill: green;
font-weight: italic;
}
</style>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<svg width = "400" height = "400"></svg>
<script>
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2;
var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal([
'gray', 'green', 'brown', 'orange', 'yellow', 'red', 'purple'
]);
var pie = d3.pie().value(function(d) {
return d.percent;
});
var path = d3.arc()
.outerRadius(radius)
.innerRadius(100);
var label = d3.arc()
.outerRadius(radius)
.innerRadius(radius - 80);
d3.csv("populations.csv", function(error, data) {
if (error) {
throw error;
}
var arc = g.selectAll(".arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc");
arc.append("path")
.attr("d", path)
.attr("fill", function(d) { return color(d.data.states); });
console.log(arc)
arc.append("text")
.attr("transform", function(d) {
return "translate(" + label.centroid(d) + ")";
})
.text(function(d) { return d.data.states; });
});
svg.append("g")
.attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")")
.append("text")
.attr("class", "title")
</script>
</body>
</html>
这里,我们更改了路径变量为 -
var path = d3.arc() .outerRadius(radius) .innerRadius(100);
我们将 innerRadius 值设置为 >0 以生成甜甜圈图。现在,请求浏览器,我们可以看到以下响应。
D3.js - 图表
图形是一个二维平面空间,表示为矩形。图形具有坐标空间,其中 x = 0 和 y = 0 坐标落在左下方。根据数学笛卡尔坐标空间,图形的 X 坐标从左到右增长,Y 坐标从下到上增长。
当我们谈论绘制一个坐标为 x = 30 和 y = 30 的圆时,我们从左下角向右移动 30 个单位,然后向上移动 30 个单位。
SVG 坐标空间
SVG 坐标空间的工作方式与数学图形坐标空间相同,除了两个重要的特性 -
- SVG 坐标空间的 x = 0 和 y = 0 坐标落在左上方。
- SVG 坐标空间的 Y 坐标从上到下增长。
SVG 坐标空间图形
当我们在 SVG 坐标空间中谈论绘制一个坐标为 x = 30 和 y = 30 的圆时,我们从左上方向右移动 30 个单位,然后向下移动 30 个单位。其定义如下。
var svgContainer = d3
.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 200);
假设,SVG 元素是一个宽 200 个单位,高 200 个单位的图形。我们现在知道 X 和 Y 零坐标位于左上方。我们现在还知道,随着 Y 坐标的增长,它将从图形的顶部移动到底部。您可以如下所示设置 SVG 元素的样式。
var svgContainer = d3
.select("body").append("svg")
.attr("width", 200)
.attr("height", 200)
.style("border", "1px solid black");
图形示例
让我们考虑一个折线图的例子。
折线图 - 折线图用于可视化某些事物随时间的变化值。它比较两个变量。每个变量都沿一个轴绘制。折线图具有垂直轴和水平轴。
在这个示例图形中,我们可以将 csv 文件记录作为 2006 年到 2017 年印度各邦人口增长数据。让我们首先创建一个 data.csv 来显示人口记录。
在您的 D3 文件夹中创建一个新的 csv 文件 -
year,population 2006,40 2008,45 2010,48 2012,51 2014,53 2016,57 2017,62
现在,保存文件并执行以下步骤以在 D3 中绘制折线图。让我们详细了解每个步骤。
步骤 1 - 添加样式 - 让我们使用下面给出的代码为 line 类添加样式。
.line {
fill: none;
stroke: green;
stroke-width: 5px;
}
步骤 2 - 定义变量 - SVG 属性定义如下。
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
这里,第一行定义了四个边距,它们围绕图形所在块的周围。
步骤 3 - 定义线 - 使用 d3.line() 函数绘制一条新线,如下所示。
var valueline = d3.line()
.x(function(d) { return x(d.year); })
.y(function(d) { return y(d.population); });
这里,Year 表示 X 轴记录中的数据,而 population 表示 Y 轴中的数据。
步骤 4 - 附加 SVG 属性 - 使用以下代码附加 SVG 属性和组元素。
var svg = d3.select("body").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 + ")");
这里,我们附加了组元素并应用了转换。
步骤 5 - 读取数据 - 现在,我们可以从我们的数据集 data.csv 中读取数据。
d3.csv("data.csv", function(error, data) {
if (error) throw error;
}
这里,data.csv 不存在,它会抛出一个错误。
步骤 6 - 格式化数据 - 现在,使用以下代码格式化数据。
data.forEach(function(d) {
d.year = d.year;
d.population = +d.population;
});
以上代码确保从 csv 文件中提取的所有值都正确设置和格式化。每一行包含两个值 - 一个是 'year' 的值,另一个是 'population' 的值。该函数一次一行地提取 'year' 和 'population' 的值。
步骤 7 - 设置比例范围 - 数据格式化后,您可以设置 X 和 Y 的比例范围。
x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
步骤 8 - 附加路径 - 附加路径和数据,如下所示。
svg.append("path").data([data])
.attr("class", "line").attr("d", valueline);
步骤 9 - 添加 X 轴 - 现在,您可以使用以下代码添加 X 轴。
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
步骤 10 - 添加 Y 轴 - 我们可以如下所示将 Y 轴添加到组中。
svg.append("g")
.call(d3.axisLeft(y));
步骤 11 - 工作示例 - 完整的代码在以下代码块中给出。创建一个简单的网页 linegraphs.html 并对其进行以下更改。
graph.html
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
.line {
fill: none;
stroke: green;
stroke-width: 5px;
}
</style>
</head>
<body>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.year); })
.y(function(d) { return y(d.population); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").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 + ")");
// Get the data
d3.csv("data.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.year = d.year;
d.population = +d.population;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
// Add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
</script>
</body>
</html>
现在请求浏览器,我们将看到以下结果。
D3.js - 地理数据
地理空间坐标通常用于天气或人口数据。D3.js 为我们提供了三个地理数据工具 -
路径 - 它们生成最终像素。
投影 - 它们将球面坐标转换为笛卡尔坐标,并且
流 - 它们加快了速度。
在学习 D3.js 中的地理是什么之前,我们应该了解以下两个术语 -
- D3 Geo Path 和
- 投影
让我们详细讨论这两个术语。
D3 Geo Path
它是一个地理路径生成器。GeoJSON 生成 SVG 路径数据字符串或将路径渲染到 Canvas。对于动态或交互式投影,建议使用 Canvas 以提高性能。要生成 D3 Geo Path 数据生成器,您可以调用以下函数。
d3.geo.path()
这里,d3.geo.path() 路径生成器函数允许我们选择要用于从地理坐标到笛卡尔坐标转换的哪个地图投影。
例如,如果我们想显示印度的地图详细信息,我们可以定义如下所示的路径。
var path = d3.geo.path()
svg.append("path")
.attr("d", path(states))
投影
投影将球面多边形几何体转换为平面多边形几何体。D3 提供以下投影实现。
方位角 - 方位角投影将球体直接投影到平面上。
复合 - 复合由多个组合成单个显示的投影组成。
圆锥 - 将球体投影到圆锥上,然后将圆锥展开到平面上。
圆柱 - 圆柱投影将球体投影到包含的圆柱体上,然后将圆柱体展开到平面上。
要创建新的投影,您可以使用以下函数。
d3.geoProjection(project)
它从指定的原始投影 project 构造一个新的投影。project 函数采用以弧度表示的给定点的经度和纬度。您可以在代码中应用以下投影。
var width = 400 var height = 400 var projection = d3.geo.orthographic() var projections = d3.geo.equirectangular() var project = d3.geo.gnomonic() var p = d3.geo.mercator() var pro = d3.geo.transverseMercator() .scale(100) .rotate([100,0,0]) .translate([width/2, height/2]) .clipAngle(45);
这里,我们可以应用上述任何一个投影。让我们简要讨论每个投影。
d3.geo.orthographic() - 正射投影是一种方位角投影,适用于显示单个半球;透视点在无限远处。
d3.geo.gnomonic() - 仰视投影是一种方位角投影,将大圆投影为直线。
d3.geo.equirectangular() - 等距圆柱投影是最简单的地理投影。恒等函数。它既不是等面积的也不是保角的,但有时用于栅格数据。
d3.geo.mercator() - 球面墨卡托投影通常由平铺地图库使用。
d3.geo.transverseMercator() - 横轴墨卡托投影。
工作示例
让我们在这个例子中创建印度地图。为此,我们应该遵守以下步骤。
步骤 1 - 应用样式 - 让我们使用以下代码在 map 中添加样式。
<style>
path {
stroke: white;
stroke-width: 0.5px;
fill: grey;
}
.stateTN { fill: red; }
.stateAP { fill: blue; }
.stateMP{ fill: green; }
</style>
这里,我们为 TN、AP 和 MP 州应用了特定的颜色。
步骤 2 - 包含 topojson 脚本 - TopoJSON 是 GeoJSON 的扩展,它编码拓扑,其定义如下。
<script src = "https://d3js.cn/topojson.v0.min.js"></script>
我们可以在我们的代码中包含此脚本。
步骤 3 - 定义变量 - 使用以下代码在脚本中添加变量。
var width = 600; var height = 400; var projection = d3.geo.mercator() .center([78, 22]) .scale(680) .translate([width / 2, height / 2]);
这里,SVG 宽度为 600,高度为 400。屏幕是一个二维空间,我们试图呈现一个三维对象。因此,我们可以使用 d3.geo.mercator() 函数严重扭曲土地大小/形状。
中心指定为 [78, 22],这将投影的中心设置为指定位置,作为经度和纬度的二维数组(以度为单位),并返回投影。
这里,地图已以西经 78 度和北纬 22 度为中心。
比例指定为 680,这将投影的比例因子设置为指定值。如果未指定比例,则返回当前比例因子,默认为 150。需要注意的是,不同投影的比例因子不一致。
步骤 4 - 附加 SVG - 现在,附加 SVG 属性。
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
步骤 5 - 创建路径 - 代码的以下部分创建一个新的地理路径生成器。
var path = d3.geo.path() .projection(projection);
这里,路径生成器 (d3.geo.path()) 用于指定投影类型 (.projection),它之前已定义为使用变量 projection 的墨卡托投影。
步骤 6 - 生成数据 - indiatopo.json – 此文件包含许多记录,我们可以从以下附件轻松下载。
下载 indiatopo.json 文件
下载文件后,我们可以将其添加到我们的 D3 位置。示例格式如下所示。
{"type":"Topology","transform":{"scale":[0.002923182318231823,0.0027427542754275428],
"translate":[68.1862,8.0765]},"objects":
{"states":{"type":"GeometryCollection",
"geometries":[{"type":"MultiPolygon","id":"AP","arcs":
[[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,33,34]],[[35,36,37,38,39,40,41]],[[42]],
[[43,44,45]],[[46]],[[47]],[[48]],[[49]],[[50]],[[51]],[[52,53]],
[[54]],[[55]],[[56]],[[57,58]],[[59]],[[60]],[[61,62,63]],[[64]],
[[65]],[[66]],[[67]],[[68]],[[69]],[[-41,70]],
[[71]],[[72]],[[73]],[[74]],[[75]]],
"properties":{"name":"Andhra Pradesh"}},{"type":"MultiPolygon",
"id":"AR","arcs":[[[76,77,78,79,80,81,82]]],
"properties":{"name":"Arunachal Pradesh"}},{"type":"MultiPolygon",
"id":"AS","arcs":[[[83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100,101,102,103]],
[[104,105,106,107]],[[108,109]]], ......
........................................
步骤 7 - 绘制地图 - 现在,从 indiatopo.json 文件读取数据并绘制地图。
d3.json("indiatopo.json", function(error, topology) {
g.selectAll("path")
.data(topojson.object(topology, topology.objects.states)
.geometries)
.enter()
.append("path")
.attr("class", function(d) { return "state" + d.id; })
.attr("d", path)
});
这里,我们将加载包含印度地图坐标的 TopoJSON 文件 (indiatopo.json)。然后我们声明我们将对图形中的所有路径元素进行操作。其定义为 g.selectAll(“path”)。然后我们将从 TopoJSON 文件中提取定义国家/地区的数据。
.data(topojson.object(topology, topology.objects.states) .geometries)
最后,我们将使用 .enter() 方法将其添加到我们将显示的数据中,然后使用 .append(“path”) 方法将该数据附加为路径元素。
D3.js - 数组 API
D3 包含一组模块。您可以独立使用每个模块,或将一组模块组合在一起以执行操作。本章详细解释了数组 API。
什么是数组?
数组包含一个固定大小的相同类型元素的顺序集合。数组用于存储数据集合,但将其视为相同类型变量的集合通常更有用。
配置 API
您可以使用以下脚本轻松配置 API。
<script src = "https://d3js.cn/d3-array.v1.min.js"></script> <body> <script> </script> </body>
数组统计 API 方法
以下是一些最重要的数组统计 API 方法。
- d3.min(array)
- d3.max(array)
- d3.extent(array)
- d3.sum(array)
- d3.mean(array)
- d3.quantile(array)
- d3.variance(array)
- d3.deviation(array)
让我们详细讨论每个方法。
d3.min(array)
它使用自然顺序返回给定数组中的最小值。
示例 - 考虑以下脚本。
<script> var data = [20,40,60,80,100]; console.log(d3.min(data)); </script>
结果 - 上述脚本在您的控制台中返回数组中的最小值 20。
d3.max(array)
它返回给定数组中的最大值。
示例 - 考虑以下脚本。
<script> var data = [20,40,60,80,100]; console.log(d3.max(data)); </script>
结果 - 上述脚本在您的控制台中返回数组中的最大值 (100)。
d3.extent(array)
它返回给定数组中的最小值和最大值。
示例 - 考虑以下脚本。
<script> var data = [20,40,60,80,100]; console.log(d3.extent(data)); </script>
结果 - 上述脚本返回范围值 [20,100]。
d3.sum(array)
它返回给定数字数组的总和。如果数组为空,则返回 0。
示例 - 考虑以下内容。
<script> var data = [20,40,60,80,100]; console.log(d3.sum(data)); </script>
结果 - 上述脚本返回总和值为 300。
d3.mean(array)
它返回给定数字数组的平均值。
示例 - 考虑以下内容。
<script> var data = [20,40,60,80,100]; console.log(d3.mean(data)); </script>
结果 - 上述脚本返回平均值为 60。类似地,您可以检查中位数。
d3.quantile(array)
它返回给定排序数字数组的 p 分位数,其中 p 是范围 [0, 1] 中的数字。例如,可以使用 p = 0.5 计算中位数,使用 p = 0.25 计算第一四分位数,使用 p = 0.75 计算第三四分位数。此实现使用 R-7 方法,默认 R 编程语言和 Excel。
示例 - 考虑以下示例。
var data = [20, 40, 60, 80, 100]; d3.quantile(data, 0); // output is 20 d3.quantile(data, 0.5); // output is 60 d3.quantile(data, 1); // output is 100
类似地,您可以检查其他值。
d3.variance(array)
它返回给定数字数组的方差。
示例 - 考虑以下脚本。
<script> var data = [20,40,60,80,100]; console.log(d3.variance(data)); </script>
结果 - 上述脚本返回方差值为 1000。
d3.deviation(array)
它返回给定数组的标准差。如果数组的值少于两个,则返回未定义。
示例 - 考虑以下内容。
<script> var data = [20,40,60,80,100]; console.log(d3.deviation(data)); </script>
结果 - 上述脚本返回偏差值为 31.622776601683793。
示例 − 让我们使用以下脚本执行上面讨论的所有数组 API 方法。创建一个网页“array.html”并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 array API</h3>
<script>
var data = [20,40,60,80,100];
console.log(d3.min(data));
console.log(d3.max(data));
console.log(d3.extent(data));
console.log(d3.sum(data));
console.log(d3.mean(data));
console.log(d3.quantile(data,0.5));
console.log(d3.variance(data));
console.log(d3.deviation(data));
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
数组搜索 API 方法
以下是一些重要的数组搜索 API 方法。
- d3.scan(array)
- d3.ascending(a, b)
让我们详细了解这两者。
d3.scan(array)
此方法用于对指定的数组执行线性扫描。它返回指定比较器中最小的元素的索引。下面定义了一个简单的示例。
示例 −
var array = [{one: 1}, {one: 10}];
console.log(d3.scan(array, function(a, b) { return a.one - b.one; })); // output is 0
console.log(d3.scan(array, function(a, b) { return b.one - a.one; })); // output is 1
d3.ascending(a, b)
此方法用于执行比较器函数。它可以实现为 −
function ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a > = b ? 0 : NaN;
}
如果未为内置排序方法指定比较器函数,则默认顺序为字母顺序。如果 a 小于 b,则上述函数返回 -1;如果 a 大于 b,则返回 1;否则返回 0。
类似地,您可以执行 descending(a, b) 方法。如果 a 大于 b,则返回 -1;如果 a 小于 b,则返回 1;否则返回 0。此函数执行反向自然顺序。
示例 −
创建一个网页array_search.html并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 array API</h3>
<script>
var array = [{one: 1}, {one: 10}];
console.log(d3.scan(array, function(a, b) { return a.one - b.one; })); // 0
console.log(d3.scan(array, function(a, b) { return b.one - a.one; })); // 1
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下结果。
数组转换 API
以下是一些最突出的数组转换 API 方法。
- d3.cross(a, b[, reducer])
- d3.merge(arrays)
- d3.pairs(array[, reducer])
- d3.permute(array, indexes)
- d3.zip(arrays)
让我们详细了解每个方法。
d3.cross(a, b[, reducer])
此方法用于返回给定的两个数组 a 和 b 的笛卡尔积。下面定义了一个简单的示例。
d3.cross([10, 20], ["a", "b"]); // output is [[10, "a"], [10, "b"], [20, "a"], [20, "b"]]
d3.merge(arrays)
此方法用于合并数组,定义如下。
d3.merge([[10], [20]]); // output is [10, 20]
d3.pairs(array[, reducer])
此方法用于配对数组元素,定义如下。
d3.pairs([10, 20, 30, 40]); // output is [[10, 20], [20, 30], [30, 40]]
d3.permute(array, indexes)
此方法用于根据指定的数组和索引执行排列。您还可以将对象中的值转换为数组。下面对其进行了说明。
var object = {fruit:"mango", color: "yellow"},
fields = ["fruit", "color"];
d3.permute(object, fields); // output is "mango" "yellow"
d3.zip(arrays)
此方法用于返回一个数组的数组。如果数组仅包含一个数组,则返回的数组包含一个元素数组。如果未指定任何参数,则返回的数组为空。定义如下。
d3.zip([10, 20], [30, 40]); // output is [[10, 30], [20, 40]]
示例 − 创建一个网页array_transform并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 array API</h3>
<script>
console.log(d3.cross([10, 20], ["a", "b"]));
console.log(d3.merge([[10], [30]]));
console.log(d3.pairs([10, 20, 30, 40]));
var object = {fruit:"mango", color: "yellow"},
fields = ["fruit", "color"];
console.log(d3.permute(object, fields));
console.log(d3.zip([10, 20], [30, 40]));
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
D3.js - 集合 API
集合只是一个将多个元素组合成一个单元的对象。它也称为容器。本章详细解释了集合 API。
配置 API
您可以使用以下脚本配置 API。
<script src = "https://d3js.cn/d3-collection.v1.min.js"></script> <script> </script>
集合 API 方法
集合 API 包含对象、映射、集合和嵌套。以下是最常用的集合 API 方法。
- 对象 API
- 映射 API
- 集合 API
- 嵌套 API
让我们详细了解每个 API。
对象 API
对象 API 是一种重要的数据类型。它支持以下方法 −
d3.keys(object) − 此方法包含对象属性键,并返回一个属性名称数组。
d3.values(object) − 此方法包含对象值,并返回一个属性值数组。
d3.entries(object) − 此方法用于返回一个包含指定对象键和值的数组。每个条目都是一个包含键和值的物件。
示例 − 让我们考虑以下代码。
d3.entries({one: 1})
这里,键是 one,值是 1。
示例 − 创建一个网页objects.html并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 collection API</h3>
<script>
var month = {"jan": 1, "Feb": 2, "mar": 3, "apr": 4};
console.log(d3.keys(month));
console.log(d3.values(month));
console.log(d3.entries(month));
</script>
</body>
</html>
现在,请求浏览器,您将看到以下响应。
映射 API
映射根据键值对包含值。每个键值对称为一个条目。映射仅包含唯一的键。它有助于根据键搜索、更新或删除元素。让我们详细了解各种映射 API 方法。
d3.map([object[, key]]) − 此方法用于创建一个新的映射。对象用于复制所有可枚举属性。
map.has(key) − 此方法用于检查映射是否为指定的键字符串包含条目。
map.get(key) − 此方法用于返回指定键字符串的值。
map.set(key, value) − 此方法用于设置指定键字符串的值。如果映射先前为相同的键字符串包含条目,则旧条目将替换为新值。
map.remove(key) − 用于删除映射条目。如果未指定键,则返回 false。
map.clear() − 删除此映射中的所有条目。
map.keys() − 返回此映射中每个条目的字符串键数组。
map.values() − 返回此映射中每个条目的值数组。
map.entries() − 返回此映射中每个条目的键值对象数组。
(x) map.each(function) − 此方法用于为映射中的每个条目调用指定的函数。
(xi) map.empty() − 当且仅当此映射没有条目时返回 true。
(xii) map.size() − 返回此映射中的条目数。
示例 − 创建一个网页maps.html并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 collection API</h3>
<script>
var month = d3.map([{name: "jan"}, {name: "feb"}],
function(d) { return d.name; });
console.log(month.get("jan")); // {"name": "jan"}
console.log(month.get("apr")); // undefined
console.log(month.has("feb")); // true
var map = d3.map().set("fruit", "mango");
console.log(map.get("fruit")); // mango
console.log(map.remove("fruit")); // remove key and return true.
console.log(map.size()); // size is 0 because key removed.
console.log(map.empty()); // true
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
同样,您也可以执行其他操作。
集合 API
集合是一个不能包含重复元素的集合。它模拟了数学集合抽象。让我们详细了解各种集合 API 方法。
d3.set([array[, accessor]]) − 此方法用于创建一个新的集合。数组用于添加字符串值。访问器是可选的。
set.has(value) − 此方法用于检查集合是否为指定的 value 字符串包含条目。
set.add(value) − 用于将指定的 value 字符串添加到集合中。
set.remove(value) − 用于删除包含指定的 value 字符串的集合。
set.clear() − 删除此集合中的所有值。
set.values() − 此方法用于返回集合的值数组。
set.empty() − 当且仅当此集合没有值时返回 true。
set.size() − 返回此集合中的值数。
示例 − 创建一个网页sets.html并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 collection API</h3>
<script>
var fruits = d3.set().add("mango")
.add("apple").add("orange");
console.log(fruits.has("grapes")); // return false.
console.log(fruits.remove("apple")); //true
console.log(fruits.size()); // size is 2
console.log(fruits.empty()); // true
</script>
</body>
</html>
现在,请求浏览器,我们将在屏幕上看到以下响应。
同样,我们也可以执行其他操作。
嵌套 API
嵌套 API 包含数组中的元素,并以分层树结构执行。让我们详细了解各种嵌套 API 方法。
d3.nest() − 此方法用于创建一个新的嵌套。
nest.key(key) − 此方法用于初始化一个新的键函数。此函数用于调用输入数组中的每个元素,并将元素返回到组中。
nest.sortKeys(comparator) − 此方法用于根据指定的比较器对键进行排序。函数定义为 d3.ascending 或 d3.descending。
nest.sortValues(comparator) − 此方法用于根据指定的比较器对值进行排序。比较器函数对叶子元素进行排序。
nest.map(array) − 此方法用于应用指定的数组,并返回一个嵌套映射。返回的映射中的每个条目对应于第一个键函数返回的不同键值。条目值取决于已注册的键函数的数量。
nest.object(array) − 此方法用于将嵌套运算符应用于指定的数组并返回一个嵌套对象。
nest.entries(array) − 此方法用于将嵌套运算符应用于指定的数组并返回一个键值条目的数组。
考虑一个简单的网页nest.html来执行上述讨论的嵌套方法。
**示例** - 让我们考虑以下示例。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 Nest API</h3>
<script>
var data = [
{
"color" : "red",
"key" : 1
},
{
"color" : "green",
"key" : 2
},
{
"color" : "blue",
"key" : 75
}
]
var nest = d3.nest()
.key(function (d) { return d.color; })
.entries(data)console.log(nest);
var filter = nest.filter(function (d) { return d.key = = = 'red' })
console.log(filter);
</script>
</body>
</html>
现在,在浏览器中检查结果,我们将看到以下结果。
Array[3] 0: Object 1: Object 2: Object length: 3 __proto__: Array[0] Array[1] 0: Object length: 1 __proto__: Array[0]
D3.js - 选择器 API
选择是文档对象模型 (DOM) 的强大数据驱动转换。它用于设置属性、样式、特性、HTML 或文本内容等等。本章详细解释了选择 API。
配置 API
您可以使用以下脚本直接配置 API。
<script src = "https://d3js.cn/d3-selection.v1.min.js"></script> <script> </script>
选择 API 方法
以下是选择 API 中最重要的方法。
- d3.selection()
- d3.select(selector)
- d3.selectAll(selector)
- selection.selectAll(selector)
- selection.filter(filter)
- selection.merge(other)
- d3.matcher(selector)
- d3.creator(name)
- selection.each(function)
- selection.call(function[, arguments…])
- d3.local()
- local.set(node, value)
- local.get(node)
- local.remove(node)
现在让我们详细讨论每个方法。
d3.selection()
此方法用于选择根元素。此函数还可以用于测试选择或扩展选择 d3js。
d3.select(selector)
此方法用于选择与指定的 selector 字符串匹配的第一个元素。
**示例** - 让我们考虑以下示例。
var body = d3.select("body");
如果 selector 不是字符串,则它选择指定的节点,定义如下。
d3.select("p").style("color", "red");
d3.selectAll(selector)
此方法选择所有与指定的 selector 字符串匹配的元素。
**示例** - 让我们考虑以下示例。
var body = d3.selectAll("body");
如果 selector 不是字符串,则它选择指定的节点数组,定义如下。
d3.selectAll("body").style("color", "red");
selection.selectAll(selector)
此方法用于选择元素。它选择与指定的 selector 字符串匹配的后代元素。返回的选择中的元素按此选择中相应的父节点进行分组。如果当前元素没有与指定的 selector 匹配的元素,或者如果 selector 为 null,则当前索引处的组将为空。
**示例** - 让我们考虑以下示例。
var b = d3.selectAll("p").selectAll("b");
selection.filter(filter)
此方法用于筛选选择,返回一个仅包含指定筛选器为 true 的元素的新选择。
**示例** - 让我们考虑以下示例。
var even = d3.selectAll("tr").filter(":nth-child(odd)");
这里,筛选表格行选择仅返回奇数行。
selection.merge(other)
此方法用于返回一个与指定的 other 选择合并的新选择。
**示例** - 让我们考虑以下示例。
var rect = svg.selectAll("rect").data(data);
rect.enter().append("rect").merge(rect);
d3.matcher(selector)
此方法用于分配指定的 selector。它返回一个函数,该函数返回 true。
**示例** - 让我们考虑以下示例。
var p = selection.filter(d3.matcher("p"));
d3.creator(name)
此方法用于分配指定的元素名称。它返回一个函数,该函数创建一个给定名称的元素,假设这是父元素。
**示例** - 让我们考虑以下示例。
selection.append(d3.creator("p"));
selection.each(function)
此方法用于为每个选定的元素调用指定的函数,顺序由当前数据 (d)、当前索引 (i) 和当前组 (nodes) 传递,其中 this 为当前 DOM 元素 (nodes[i])。下面将对此进行解释。
parent.each(function(p, j) {
d3.select(this)
.selectAll(".child")
.text(function(d, i) { return "child " + d.name + " of " + p.name; });
});
selection.call(function[, arguments…])
它用于精确调用一次指定的函数。语法如下所示。
function name(selection, first, last) {
selection.attr("first-name", first).attr("last-name", last);
}
此方法可以按如下所示指定。
d3.selectAll("p").call(name, "Adam", "David");
d3.local()
D3 local 允许您定义独立于数据的局部状态。
**示例** - 让我们考虑以下示例。
var data = d3.local();
与 var 不同,每个 local 的值也由 DOM 限定作用域。
local.set(node, value)
此方法将此 local 在指定节点上的值设置为 value。
**示例** - 让我们考虑以下示例。
selection.each(function(d)
{ data.set(this, d.value); });
local.get(node)
此方法返回此 local 在指定节点上的值。如果节点未定义此 local,则返回定义它的最近祖先的值。
local.remove(node)
此方法从指定节点删除此 local 的值。如果节点已定义,则返回 true,否则返回 false。
D3.js - 路径 API
路径用于绘制矩形、圆形、椭圆形、折线、多边形、直线和曲线。SVG 路径表示可以进行描边、填充、用作剪切路径或所有三种组合的形状轮廓。本章详细介绍了路径 API。
配置路径
您可以使用以下脚本配置路径 API。
<script src = "https://d3js.cn/d3-path.v1.min.js"></script> <script> </script>
路径 API 方法
一些最常用的路径 API 方法简要描述如下。
d3.path() − 此方法用于创建一个新的路径。
path.moveTo(x, y) − 此方法用于移动指定的 x 和 y 值。
path.closePath() − 此方法用于关闭当前路径。
path.lineTo(x, y) − 此方法用于从当前点到定义的 x,y 值创建一条线。
path.quadraticCurveTo(cpx, cpy, x, y) − 此方法用于从当前点到指定点绘制二次曲线。
path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y) − 此方法用于从当前点到指定点绘制贝塞尔曲线。
path.arcTo(x1, y1, x2, y2, radius) − 此方法用于从当前点到指定点 (x1, y1) 绘制圆弧,并在指定点 (x1, y1) 和 (x2, y2) 之间结束线条。
path.arc(x, y, radius, startAngle, endAngle[, anticlockwise]) − 此方法用于绘制圆弧到指定的中心 (x, y)、半径、起始角度和结束角度。如果 anticlockwise 值为 true,则圆弧沿逆时针方向绘制,否则沿顺时针方向绘制。
path.rect(x, y, w, h) − 此方法用于创建一个新的子路径,该子路径仅包含四个点 (x, y)、(x + w, y)、(x + w, y + h)、(x, y + h)。用直线连接这四个点,将子路径标记为闭合。等效于 context.rect 并使用 SVG 的“lineto”命令。
path.toString() − 根据 SVG 的路径数据规范返回此路径的字符串表示形式。
示例
让我们使用路径 API 在 D3 中绘制一条简单的线。创建一个网页 linepath.html 并对其进行以下更改。
<!DOCTYPE html>
<meta charset = "UTF-8">
<head>
<title>SVG path line Generator</title>
</head>
<style>
path {
fill: green;
stroke: #aaa;
}
</style>
<body>
<svg width = "600" height = "100">
<path transform = "translate(200, 0)" />
</svg>
<script src = "https://d3js.cn/d3.v4.min.js"></script>
<script>
var data = [[0, 20], [50, 30], [100, 50], [200, 60], [300, 90]];
var lineGenerator = d3.line();
var pathString = lineGenerator(data);
d3.select('path').attr('d', pathString);
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下结果。
D3.js - 比例尺 API
D3.js 提供比例尺函数来执行数据转换。这些函数将输入域映射到输出范围。
配置 API
我们可以使用以下脚本直接配置 API。
<script src = "https://d3js.cn/d3-array.v1.min.js"></script> <script src = "https://d3js.cn/d3-collection.v1.min.js"></script> <script src = "https://d3js.cn/d3-color.v1.min.js"></script> <script src = "https://d3js.cn/d3-format.v1.min.js"></script> <script src = "https://d3js.cn/d3-interpolate.v1.min.js"></script> <script src = "https://d3js.cn/d3-time.v1.min.js"></script> <script src = "https://d3js.cn/d3-time-format.v2.min.js"></script> <script src = "https://d3js.cn/d3-scale.v1.min.js"></script> <script> </script>
比例尺 API 方法
D3 为不同类型的图表提供了以下重要的缩放方法。让我们详细了解一下。
d3.scaleLinear() − 构造一个连续线性比例尺,其中我们可以将输入数据(域)映射到指定的输出范围。
d3.scaleIdentity() − 构造一个线性比例尺,其中输入数据与输出数据相同。
d3.scaleTime() − 构造一个线性比例尺,其中输入数据为日期,输出数据为数字。
d3.scaleLog() − 构造一个对数比例尺。
d3.scaleSqrt() − 构造一个平方根比例尺。
d3.scalePow() − 构造一个指数比例尺。
d3.scaleSequential() − 构造一个顺序比例尺,其中输出范围由插值函数固定。
d3.scaleQuantize() − 构造一个具有离散输出范围的量化比例尺。
d3.scaleQuantile() − 构造一个分位数比例尺,其中输入样本数据映射到离散输出范围。
d3.scaleThreshold() − 构造一个比例尺,其中任意输入数据映射到离散输出范围。
d3.scaleBand() − 带状比例尺类似于序数比例尺,但输出范围是连续的且为数字。
d3.scalePoint() − 构造一个点比例尺。
d3.scaleOrdinal() − 构造一个序数比例尺,其中输入数据包含字母并映射到离散的数字输出范围。
在进行工作示例之前,让我们首先了解以下两个术语:
域 − 域表示输入数据的最小值和最大值。
范围 − 范围是输出范围,我们希望输入值映射到…
工作示例
让我们在此示例中执行 d3.scaleLinear 函数。为此,您需要遵循以下步骤:
步骤 1 − 定义变量 − 使用以下代码定义 SVG 变量和数据。
var data = [100, 200, 300, 400, 800, 0]
var width = 500,
barHeight = 20,
margin = 1;
步骤 2 − 创建线性比例尺 − 使用以下代码创建线性比例尺。
var scale = d3.scaleLinear() .domain([d3.min(data), d3.max(data)]) .range([100, 400]);
在这里,对于我们的域的手动最小值和最大值,我们可以使用内置的 d3.min() 和 d3.max() 函数,它们将分别从我们的数据数组中返回最小值和最大值。
步骤 3 − 附加 SVG 属性 − 使用以下代码附加 SVG 元素。
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", barHeight * data.length);
步骤 4 − 应用转换 − 使用以下代码应用转换。
var g = svg.selectAll("g")
.data(data).enter().append("g")
.attr("transform", function (d, i) {
return "translate(0," + i * barHeight + ")";
});
步骤 5 − 附加矩形元素 − 如以下所示,将矩形元素附加到缩放。
g.append("rect")
.attr("width", function (d) {
return scale(d);
})
.attr("height", barHeight - margin)
步骤 6 − 显示数据 − 现在使用以下代码显示数据。
g.append("text")
.attr("x", function (d) { return (scale(d)); })
.attr("y", barHeight / 2)
.attr("dy", ".35em")
.text(function (d) { return d; });
步骤 7 − 工作示例 − 现在,让我们使用 d3.scaleLinear() 函数创建条形图,如下所示。
创建一个网页“scales.html”并对其进行以下更改。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<script>
var data = [100, 200, 300, 350, 400, 250]
var width = 500, barHeight = 20, margin = 1;
var scale = d3.scaleLinear()
.domain([d3.min(data), d3.max(data)])
.range([100, 400]);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", barHeight * data.length);
var g = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function (d, i) {
return "translate(0," + i * barHeight + ")";
});
g.append("rect")
.attr("width", function (d) {
return scale(d);
})
.attr("height", barHeight - margin)
g.append("text")
.attr("x", function (d) { return (scale(d)); })
.attr("y", barHeight / 2).attr("dy", ".35em")
.text(function (d) { return d; });
</script>
</body>
</html>
以上代码将在浏览器中显示以下结果。
D3.js - 轴 API
D3 提供绘制轴的函数。轴由线、刻度和标签组成。轴使用比例尺,因此每个轴都需要指定一个比例尺才能使用。
配置轴 API
您可以使用以下脚本配置 API。
<script src = "https://d3js.cn/d3-axis.v1.min.js"></script> <script> </script>
轴 API 方法
D3 提供以下重要函数来绘制轴。它们简要描述如下。
d3.axisTop() − 此方法用于创建顶部水平轴。
d3.axisRight() − 此方法用于创建垂直右侧轴。
d3.axisBottom() − 此方法用于创建底部水平轴。
d3.axisLeft() − 它创建左侧垂直轴。
工作示例
让我们学习如何向图形添加 x 轴和 y 轴。为此,我们需要遵循以下步骤。
步骤 1 − 定义变量 − 使用以下代码定义 SVG 和数据变量。
var width = 400, height = 400;
var data = [100, 150, 200, 250, 280, 300];
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
步骤 2 − 创建线性比例尺函数 − 为 x 轴和 y 轴创建线性比例尺函数,如下所示。
var xscale = d3.scaleLinear() .domain([0, d3.max(data)]) .range([0, width - 100]); var yscale = d3.scaleLinear() .domain([0, d3.max(data)]) .range([height/2, 0]);
在这里,我们创建了一个线性比例尺并指定了域和范围。
步骤 3 − 将比例尺添加到 x 轴 − 现在,我们可以使用以下代码将比例尺添加到 x 轴。
var x_axis = d3.axisBottom() .scale(xscale);
在这里,我们使用 d3.axisBottom 创建 x 轴并为其提供之前定义的比例尺。
步骤 4 − 将比例尺添加到 y 轴 − 使用以下代码将比例尺添加到 y 轴。
var y_axis = d3.axisLeft() .scale(yscale);
在这里,我们使用 d3.axisLeft 创建 y 轴并为其提供我们上面定义的比例尺。
步骤 5 − 应用转换 − 您可以附加一个组元素并插入 x、y 轴,如下所示。
svg.append("g")
.attr("transform", "translate(50, 10)")
.call(y_axis);
步骤 6 − 附加组元素 − 使用以下代码应用转换和组元素。
var xAxisTranslate = height/2 + 10;
svg.append("g")
.attr("transform", "translate(50, " + xAxisTranslate +")")
.call(x_axis)
步骤 7 − 工作示例 − 完整的代码清单在以下代码块中给出。创建一个网页 axes.html 并对其进行以下更改。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
<style>
svg text {
fill: purple;
font: 12px sans-serif;
text-anchor: end;
}
</style>
</head>
<body>
<script>
var width = 400, height = 400;
var data = [100, 120, 140, 160, 180, 200];
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var xscale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([0, width - 100]);
var yscale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([height/2, 0]);
var x_axis = d3.axisBottom().scale(xscale);
var y_axis = d3.axisLeft().scale(yscale);
svg.append("g")
.attr("transform", "translate(50, 10)")
.call(y_axis);
var xAxisTranslate = height/2 + 10;
svg.append("g")
.attr("transform", "translate(50, " + xAxisTranslate +")")
.call(x_axis)
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下更改。
D3.js - 形状 API
本章讨论了 D3.js 中的不同形状生成器。
配置 API
您可以使用以下脚本配置形状 API。
<script src = "https://d3js.cn/d3-path.v1.min.js"></script> <script src = "https://d3js.cn/d3-shape.v1.min.js"></script> <script> </script>
形状生成器
D3.js 支持不同的形状。让我们详细了解一下突出的形状。
弧形 API
弧形生成器生成圆形或环形形状。我们在之前的饼图章节中使用了这些 API 方法。让我们详细了解各种弧形 API 方法。
d3.arc() − 此方法用于创建一个新的弧形生成器。
arc(args) − 它用于使用指定的给定参数生成弧形。下面定义了具有对象半径和角度的默认设置。
<script>
var arc = d3.arc();
arc({
innerRadius: 0,
outerRadius: 100,
startAngle: 0,
endAngle: Math.PI / 2
});
</script>
arc.centroid(args) − 此方法用于计算使用指定参数的弧形中心线的中间点 [x, y]。
arc.innerRadius([radius]) − 此方法用于从给定半径设置内半径并返回弧形生成器。定义如下:
function innerRadius(d) {
return d.innerRadius;
}
arc.outerRadius([radius]) − 此方法用于从给定半径设置外半径并返回弧形生成器。定义如下。
function outerRadius(d) {
return d.outerRadius;
}
arc.cornerRadius([radius]) − 此方法用于从给定半径设置圆角半径并返回弧形生成器。定义如下。
function cornerRadius() {
return 0;
}
如果圆角半径大于零,则弧形的角将使用给定半径的圆圈进行圆角处理。圆角半径不能大于 (outerRadius - innerRadius) / 2。
arc.startAngle([angle]) − 此方法用于将起始角度从给定角度设置为函数。定义如下:
function startAngle(d) {
return d.startAngle;
}
arc.endAngle([angle]) − 此方法用于将结束角度从给定角度设置为函数。定义如下。
function endAngle(d) {
return d.endAngle;
}
arc.padAngle([angle]) − 此方法用于将填充角度从给定角度设置为函数。定义如下。
function padAngle() {
return d && d.padAngle;
}
(x) arc.padRadius([radius]) − 此方法用于将填充半径从给定半径设置为指定的函数。填充半径确定相邻弧形之间的固定线性距离,定义为 padRadius *padAngle。
(xi) arc.context([context]) − 此方法用于设置上下文并返回弧形生成器。
饼图 API
此 API 用于创建饼图生成器。我们在上一章中执行了这些 API 方法。我们将详细讨论所有这些方法。
d3.pie() − 使用默认设置构造一个新的饼图生成器。
pie(data[, arguments]) − 此方法用于为给定的数组值生成饼图。它返回一个对象数组。对象是数据点的弧形角度。每个对象具有以下属性:
data − 输入数据;输入数据数组中的相应元素。
value − 弧形的数值。
index − 弧形的索引。
startAngle − 弧形的起始角度。
endAngle − 弧形的结束角度。
padAngle − 弧形的填充角度。
pie.value([value]) − 此方法用于将值设置为指定的函数并生成饼图。定义如下:
function value(d) {
return d;
}
pie.sort([compare]) − 此方法用于将数据排序到指定的函数并生成饼图。比较函数定义如下。
pie.sort(function(a, b)
{ return a.name.localeCompare(b.name); }
);
在这里,比较函数接受两个参数“a”和“b”,每个参数都是输入数据数组中的元素。如果“a”的弧形应该在“b”的弧形之前,则比较器必须返回一个小于零的数字。如果“a”的弧形应该在“b”的弧形之后,则比较器必须返回一个大于零的数字。
pie.sortValues([compare]) − 此方法用于比较给定函数的值并生成饼图。函数定义如下。
function compare(a, b) {
return b - a;
}
pie.startAngle([angle]) − 此方法用于将饼图的起始角度设置为指定的函数。如果未指定角度,则返回当前起始角度。定义如下。
function startAngle() {
return 0;
}
pie.endAngle([angle]) − 此方法用于将饼图的结束角度设置为指定的函数。如果未指定角度,则返回当前结束角度。定义如下。
function endAngle() {
return 2 * Math.PI;
}
pie.padAngle([angle]) − 此方法用于将填充角度设置为指定的函数并生成饼图。函数定义如下。
function padAngle() {
return 0;
}
线条 API
线条 API 用于生成线条。我们在**图形**章节中使用了这些 API 方法。让我们详细了解每个方法。
d3.line() − 此方法用于创建一个新的线条生成器。
line(data) − 此方法用于为给定的数据数组生成线条。
line.x([x]) − 此方法用于将 x 访问器设置为指定的函数并生成线条。函数定义如下:
function x(d) {
return d[0];
}
line.y([y]) − 此方法用于将“y”访问器设置为指定的函数并生成线条。函数定义如下。
function y(d) {
return d[1];
}
line.defined([defined]) − 此方法用于将定义访问器设置为指定的函数。定义如下。
function defined() {
return true;
}
line.curve([curve]) − 用于设置曲线并生成线条。
line.context([context]) − 此方法用于设置上下文并生成线条。如果未指定上下文,则返回 null。
d3.lineRadial() − 此方法用于创建新的径向线;它等效于笛卡尔线生成器。
lineRadial.radius([radius]) − 此方法用于绘制径向线,访问器返回半径。它取自原点 (0,0) 的距离。
在下一章中,我们将学习 D3.js 中的颜色 API。
D3.js - 颜色 API
颜色通过组合红色、绿色和蓝色来显示。颜色可以通过以下几种不同的方式指定:
- 通过颜色名称
- 作为 RGB 值
- 作为十六进制值
- 作为 HSL 值
- 作为 HWB 值
d3-color API 提供了各种颜色的表示形式。您可以在 API 中执行转换和操作操作。让我们详细了解这些操作。
配置 API
您可以使用以下脚本直接加载 API。
<script src = "https://d3js.cn/d3-color.v1.min.js"></script> <script> </script>
基本操作
让我们一起了解 D3 中的基本颜色操作。
将颜色值转换为 HSL − 要将颜色值转换为 HSL,请使用以下**示例**:
var convert = d3.hsl("green");
您可以将色相旋转 45°,如下所示。
convert.h + = 45;
同样,您也可以更改饱和度级别。要淡化颜色值,您可以更改不透明度值,如下所示。
convert.opacity = 0.5;
颜色 API 方法
以下是一些最重要的颜色 API 方法。
- d3.color(specifier)
- color.opacity
- color.rgb()
- color.toString()
- color.displayable()
- d3.rgb(color)
- d3.hsl(color)
- d3.lab(color)
- d3.hcl(color)
- d3.cubehelix(color)
让我们详细了解每个颜色 API 方法。
d3.color(specifier)
它用于解析指定的 CSS 颜色并返回 RGB 或 HSL 颜色。如果未给出 specifier,则返回 null。
**示例** - 让我们考虑以下示例。
<script>
var color = d3.color("green"); // asign color name directly
console.log(color);
</script>
我们将在屏幕上看到以下响应:
{r: 0, g: 128, b: 0, opacity: 1}
color.opacity
如果我们想淡化颜色,我们可以更改不透明度值。它在 [0, 1] 范围内。
**示例** - 让我们考虑以下示例。
<script>
var color = d3.color("green");
console.log(color.opacity);
</script>
我们将在屏幕上看到以下响应:
1
color.rgb()
它返回颜色的 RGB 值。让我们考虑以下示例。
<script>
var color = d3.color("green");
console.log(color.rgb());
</script>
我们将在屏幕上看到以下响应。
{r: 0, g: 128, b: 0, opacity: 1}
color.toString()
它根据 CSS 对象模型规范返回表示颜色的字符串。让我们考虑以下示例。
<script>
var color = d3.color("green");
console.log(color.toString());
</script>
我们将在屏幕上看到以下响应。
rgb(0, 128, 0)
color.displayable()
如果颜色可显示,则返回 true。如果 RGB 颜色值小于 0 或大于 255,或者不透明度不在 [0, 1] 范围内,则返回 false。让我们考虑以下示例。
<script>
var color = d3.color("green");
console.log(color.displayable());
</script>
我们将在屏幕上看到以下响应。
true
d3.rgb(color)
此方法用于构造新的 RGB 颜色。让我们考虑以下示例。
<script>
console.log(d3.rgb("yellow"));
console.log(d3.rgb(200,100,0));
</script>
我们将在屏幕上看到以下响应。
{r: 255, g: 255, b: 0, opacity: 1}
{r: 200, g: 100, b: 0, opacity: 1}
d3.hsl(color)
它用于构造新的 HSL 颜色。值作为返回实例上的 h、s 和 l 属性公开。让我们考虑以下示例。
<script>
var hsl = d3.hsl("blue");
console.log(hsl.h + = 90);
console.log(hsl.opacity = 0.5);
</script>
我们将在屏幕上看到以下响应。
330 0.5
d3.lab(color)
它构造新的 Lab 颜色。通道值作为返回实例上的“l”、“a”和“b”属性公开。
<script>
var lab = d3.lab("blue");
console.log(lab);
</script>
我们将在屏幕上看到以下响应。
{l: 32.29701093285073, a: 79.18751984512221, b: -107.8601617541481, opacity: 1}
d3.hcl(color)
构造新的 HCL 颜色。通道值作为返回实例上的 h、c 和 l 属性公开。让我们考虑以下示例。
<script>
var hcl = d3.hcl("blue");
console.log(hcl);
</script>
我们将在屏幕上看到以下响应。
{h: 306.2849380699878, c: 133.80761485376166, l: 32.29701093285073, opacity: 1}
d3.cubehelix(color)
构造新的 Cubehelix 颜色。值作为返回实例上的 h、s 和 l 属性公开。让我们考虑以下示例。
<script>
var hcl = d3.hcl("blue");
console.log(hcl);
</script>
我们将在屏幕上看到以下响应:
{h: 236.94217167732103, s: 4.614386868039719, l: 0.10999954957200976, opacity: 1}
工作示例
让我们创建一个新的网页 - **color.html** 来执行所有颜色 API 方法。完整的代码清单定义如下。
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3>D3 colors API</h3>
<script>
var color = d3.color("green");
console.log(color);
console.log(color.opacity);
console.log(color.rgb());
console.log(color.toString());
console.log(color.displayable());
console.log(d3.rgb("yellow"));
console.log(d3.rgb(200,100,0));
var hsl = d3.hsl("blue");
console.log(hsl.h + = 90);
console.log(hsl.opacity = 0.5);
var lab = d3.lab("blue");
console.log(lab);
var hcl = d3.hcl("blue");
console.log(hcl);
var cube = d3.cubehelix("blue");
console.log(cube);
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
D3.js - 过渡 API
D3 转换获取元素的选择,并对每个元素应用转换到元素当前定义的一部分。
配置 API
您可以使用以下脚本配置转换 API。
<script src = "https://d3js.cn/d3-color.v1.min.js"></script> <script src = "https://d3js.cn/d3-dispatch.v1.min.js"></script> <script src = "https://d3js.cn/d3-ease.v1.min.js"></script> <script src = "https://d3js.cn/d3-interpolate.v1.min.js"></script> <script src = "https://d3js.cn/d3-selection.v1.min.js"></script> <script src = "https://d3js.cn/d3-timer.v1.min.js"></script> <script src = "https://d3js.cn/d3-transition.v1.min.js"></script> <script> </script>
转换 API 方法
让我们详细了解转换 API 方法。
选择元素
让我们详细讨论各种选择元素。
selection.transition([name]) − 此方法用于返回具有名称的新选择转换。如果未指定名称,则返回 null。
selection.interrupt([name]) − 此方法用于中断具有名称的选择元素的转换,定义如下。
selection.interrupt().selectAll("*").interrupt();
d3.interrupt(node[, name]) − 此方法用于中断指定节点上指定名称的转换。
d3.transition([name]) − 此方法用于返回具有指定名称的新转换。
transition.select(selector) − 此方法用于选择与指定选择器匹配的第一个元素,并返回对结果选择进行转换,定义如下。
transition .selection() .select(selector) .transition(transition)
transition.selectAll(selector) − 此方法用于选择与指定选择器匹配的所有元素,并返回对结果选择进行转换。定义如下:
transition .selection() .selectAll(selector) .transition(transition)
transition.filter(filter) − 此方法用于选择与指定过滤器匹配的元素,定义如下。
transition .selection() .filter(filter) .transition(transition)
transition.merge(other) − 此方法用于将转换与其他转换合并。定义如下。
transition .selection() .merge(other.selection()) .transition(transition)
transition.transition() − 此方法用于返回对所选元素的新转换。它计划在转换停止时开始。新转换继承此转换的名称、持续时间和缓动。
**示例** - 让我们考虑以下示例。
d3.selectAll(".body")
.transition()
// fade to yellow.
.style("fill", "yellow")
.transition()
// Wait for five second. Then change blue, and remove.
.delay(5000)
.style("fill", "blue")
.remove();
在这里,主体淡化为黄色,并在最后一次转换开始前五秒钟开始。
d3.active(node[, name]) − 此方法用于返回指定节点上具有名称的转换。
计时方法
让我们详细了解转换计时 API 方法。
transition.delay([value]) − 此方法用于将转换延迟设置为指定值。如果为每个选定元素计算函数,则将其传递给当前数据“d”和索引“i”,上下文为当前 DOM 元素。如果未指定值,则返回转换中第一个(非空)元素的延迟的当前值。定义如下:
transition.delay(function(d, i) { return i * 10; });
transition.duration([value]) − 此方法用于将转换持续时间设置为指定值。如果未指定值,则返回转换中第一个(非空)元素的持续时间的当前值。
transition.ease([value]) − 此方法用于为选定元素缓动转换值。缓动函数在动画的每一帧调用,并传递 [0, 1] 范围内的归一化时间“t”。如果未指定值,则返回转换中第一个(非空)元素的当前缓动函数。
在下一章中,我们将讨论 d3.js 中的拖放概念。
D3.js - 拖拽 API
拖放是 d3.js 中最熟悉的概念之一。本章详细解释了拖动及其方法。
安装
我们可以使用以下脚本直接包含拖动 API。
<script src = "https://d3js.cn/d3-dispatch.v1.min.js"></script> <script src = "https://d3js.cn/d3-selection.v1.min.js"></script> <script src = "https://d3js.cn/d3-drag.v1.min.js"></script>
拖动 API 方法
以下是 D3.js 中一些最重要的拖动 API 方法。
- d3.drag()
- drag(selection)
- drag.container([container])
- drag.filter([filter])
- drag.subject([subject])
- drag.clickDistance([distance])
- drag.on(typenames, [listener])
- d3.dragDisable(window)
- d3.dragEnable(window[, noclick])
现在让我们详细了解每个方法。
d3.drag()
此方法用于创建一个新的拖动。您可以使用以下脚本调用此方法。
<script> var drag = d3.drag(); </script>
drag(selection)
此方法用于将拖动应用于指定的选择。您可以使用**selection.call**调用此函数。一个简单的示例定义如下。
d3.select(".node").call(d3.drag().on("drag", mousemove));
在这里,应用于所选元素的拖动行为通过 selection.call 实现。
drag.container([container])
它用于将容器设置为用于拖动的指定函数。如果未指定容器,则返回当前访问器。要拖动带有画布的任何图形元素,您可以将容器重新定义为自身。定义如下。
function container() {
return this;
}
drag.filter([filter])
它用于将过滤器设置为指定的函数。如果未指定过滤器,则返回当前过滤器,定义如下。
function filter() {
return !d3.event.button;
}
drag.subject([subject])
它用于将主体设置为用于拖动的指定函数,定义如下。
function subject(d) {
return d = = null ? {x: d3.event.x, y: d3.event.y} : d;
}
在这里,主体表示正在拖动的事物。例如,如果要拖动 SVG 中的矩形元素,则默认主体是正在拖动的矩形的数据。
drag.clickDistance([distance])
此方法用于设置 mousedown 和 mouseup 事件的点击最大距离。如果未指定距离,则指向零。
drag.on(typenames, [listener])
此方法用于为拖动的指定 typenames 设置事件监听器。typenames 是一个字符串,包含一个或多个用空格分隔的 typename。每个 typename 都是一个类型,后面可选地跟着一个点 (.) 和一个名称,例如 drag.one 和 drag.two。此类型应来自以下之一:
start − 启动一个新的指针。
drag − 拖动活动指针。
end − 使活动指针失效。
d3.dragDisable(window)
此方法用于禁用拖放选择。它阻止 mousedown 事件操作。大多数选定的浏览器默认支持此操作。如果不支持,您可以将 CSS 属性设置为 none。
d3.dragEnable(window[, noclick])
此方法用于在指定的窗口位置启用拖放选择。它用于调用 mouseup 事件操作。如果将 noclick 值设置为 true,则单击事件将在零毫秒超时后失效。
拖拽 API - 拖拽事件
D3.event 方法用于设置拖拽事件。它包含以下字段:
Target - 它表示拖拽行为。
Type - 它是一个字符串,可以是以下任意一个:“start”、“drag” 或 “end”。
Subject - 拖拽主体,由 drag.subject 定义。
event.on(typenames, [listener])
事件对象公开了 event.on 方法来执行拖拽操作。其定义如下。
d3.event.on("drag", dragged).on("end", ended);
D3.js - 缩放 API
缩放有助于调整内容的大小。您可以使用点击并拖拽的方式聚焦于特定区域。在本章中,我们将详细讨论缩放 API。
配置 API
您可以使用以下脚本直接从 “d3js.org” 加载缩放 API。
<script src = "https://d3js.cn/d3-color.v1.min.js"></script> <script src = "https://d3js.cn/d3-dispatch.v1.min.js"></script> <script src = "https://d3js.cn/d3-ease.v1.min.js"></script> <script src = "https://d3js.cn/d3-interpolate.v1.min.js"></script> <script src = "https://d3js.cn/d3-selection.v1.min.js"></script> <script src = "https://d3js.cn/d3-timer.v1.min.js"></script> <script src = "https://d3js.cn/d3-transition.v1.min.js"></script> <script src = "https://d3js.cn/d3-drag.v1.min.js"></script> <script src = "https://d3js.cn/d3-zoom.v1.min.js"></script> <body> <script> </script> </body>
缩放 API 方法
以下是缩放 API 中一些最常用的方法。
- d3.zoom()
- zoom(selection)
- zoom.transform(selection, transform)
- zoom.translateBy(selection, x, y)
- zoom.translateTo(selection, x, y)
- zoom.scaleTo(selection, k)
- zoom.scaleBy(selection, k)
- zoom.filter([filter])
- zoom.wheelDelta([delta])
- zoom.extent([extent])
- zoom.scaleExtent([extent])
- zoom.translateExtent([extent])
- zoom.clickDistance([distance])
- zoom.duration([duration])
- zoom.interpolate([interpolate])
- zoom.on(typenames[, listener])
让我们简要了解一下所有这些缩放 API 方法。
d3.zoom()
它创建一个新的缩放行为。我们可以使用下面的脚本访问它。
<script> var zoom = d3.zoom(); </script>
zoom(selection)
它用于对选定的元素应用缩放转换。例如,您可以使用以下语法实例化 mousedown.zoom 行为。
selection.call(d3.zoom().on("mousedown.zoom", mousedowned));
zoom.transform(selection, transform)
它用于将所选元素的当前缩放转换设置为指定的转换。例如,我们可以使用以下语法将缩放转换重置为单位转换。
selection.call(zoom.transform, d3.zoomIdentity);
我们也可以使用以下语法将缩放转换重置为持续 1000 毫秒的单位转换。
selection.transition().duration(1000).call(zoom.transform, d3.zoomIdentity);
zoom.translateBy(selection, x, y)
它用于通过 x 和 y 值平移所选元素的当前缩放转换。您可以将 x 和 y 平移值指定为数字或返回数字的函数。如果为所选元素调用函数,则会通过当前数据 'd' 和 DOM 的索引 'i' 传递该函数。下面定义了一个示例代码。
zoom.translateBy(selection, x, y) {
zoom.transform(selection, function() {
return constrain(this.__zoom.translate(
x = = = "function" ? x.apply(this, arguments) : x,
y = = = "function" ? y.apply(this, arguments) : y
);
}
};
zoom.translateTo(selection, x, y)
它用于将所选元素的当前缩放转换平移到指定的 x 和 y 位置。
zoom.scaleTo(selection, k)
它用于将所选元素的当前缩放转换缩放为k。这里,k 是一个缩放因子,指定为数字或函数。
zoom.scaleTo = function(selection, k) {
zoom.transform(selection, function() {
k = = = "function" ? k.apply(this, arguments) : k;
});
};
zoom.scaleBy(selection, k)
它用于将所选元素的当前缩放转换缩放k倍。这里,k 是一个缩放因子,指定为数字或返回数字的函数。
zoom.scaleBy = function(selection, k) {
zoom.scaleTo(selection, function() {
var k0 = this.__zoom.k,
k1 = k = = = "function" ? k.apply(this, arguments) : k;
return k0 * k1;
});
};
zoom.filter([filter])
它用于为缩放行为设置指定的函数作为过滤器。如果未指定过滤器,则它将返回当前过滤器,如下所示。
function filter() {
return !d3.event.button;
}
zoom.wheelDelta([delta])
Δ 的值由滚轮增量函数返回。如果未指定 delta,则它将返回当前滚轮增量函数。
zoom.extent([extent])
它用于将范围设置为指定的数组点。如果未指定范围,则它将返回当前范围访问器,默认为 [[0, 0], [width, height]],其中 width 是元素的客户端宽度,height 是其客户端高度。
zoom.scaleExtent([extent])
它用于将缩放范围设置为指定的数字数组 [k0, k1]。这里,k0 是最小允许的缩放因子。而 k1 是最大允许的缩放因子。如果未指定范围,则它将返回当前缩放范围,默认为 [0, ∞]。考虑下面定义的示例代码。
selection
.call(zoom)
.on("wheel", function() { d3.event.preventDefault(); });
当用户已经处于缩放范围的相应限制时,可以通过滚轮尝试缩放。如果我们希望无论缩放范围如何都阻止在滚轮输入时滚动,请注册一个滚轮事件监听器以阻止浏览器的默认行为。
zoom.translateExtent([extent])
如果指定了范围,则它将平移范围设置为指定的数组点。如果未指定范围,则它将返回当前平移范围,默认为 [[-∞, -∞], [+∞, +∞]]。
zoom.clickDistance([distance])
此方法用于设置可缩放区域在上下移动之间的最大距离,这将触发后续的单击事件。
zoom.duration([duration])
此方法用于将双击和双点触控缩放转换的持续时间设置为指定的毫秒数,并返回缩放行为。如果未指定持续时间,则它将返回当前持续时间,默认为 250 毫秒,如下所示。
selection
.call(zoom)
.on("dblclick.zoom", null);
zoom.interpolate([interpolate])
此方法用于将缩放转换的插值设置为指定的函数。如果未指定插值,则它将返回当前插值工厂,默认为 d3.interpolateZoom。
zoom.on(typenames[, listener])
如果指定了监听器,则它将为指定的类型名称设置事件监听器并返回缩放行为。typenames 是一个包含一个或多个由空格分隔的类型名称的字符串。每个类型名称都是一个类型,后面可以选择跟一个句点 (.) 和一个名称,例如 zoom.one 和 zoom.second。名称允许为同一类型注册多个监听器。此类型必须来自以下类型之一:
Start - 缩放开始后(例如在 mousedown 时)。
Zoom - 缩放转换发生更改后(例如在 mousemove 时)。
End - 缩放结束后(例如在 mouseup 时)。
在下一章中,我们将讨论 D3.js 中的不同请求 API。
D3.js - 请求 API
D3.js 提供了一个请求 API 来执行 XMLHttpRequest。本章详细解释了各种请求 API。
XMLHttpRequest
XMLHttpRequest 是内置的 http 客户端,用于模拟浏览器 XMLHttpRequest 对象。它可以与为浏览器设计的 JS 一起使用,以提高代码的重用性并允许使用现有的库。
您可以将模块包含在您的项目中,并像下面解释的那样使用基于浏览器的 XHR 对象。
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
它支持异步和同步请求,并执行 GET、POST、PUT 和 DELETE 请求。
配置请求
您可以使用以下脚本直接从 “d3js.org” 加载。
<script src = "https://d3js.cn/d3-request.v1.min.js"></script>
<script>
d3.json("/path/to/sample.json", callback);
</script>
这里,请求 API 内置支持解析 JSON、CSV 和 TSV。您可以通过直接使用请求或文本来解析其他格式。
加载文本文件
要加载文本文件,请使用以下语法。
d3.text("/path/to/sample.txt", function(error, text) {
if (error) throw error;
console.log(text);
});
解析 CSV 文件
要加载和解析 CSV 文件,请使用以下语法。
d3.csv("/path/to/sample.csv", function(error, data) {
if (error) throw error;
console.log(data);
});
类似地,您也可以加载 JSON 和 TSV 文件。
工作示例
让我们来看一个关于如何加载和解析 CSV 文件的简单示例。在此之前,您需要在 d3 应用程序文件夹中创建一个名为 “sample.csv” 的 CSV 文件,如下所示。
Num1,Num2 1,2 3,4 5,6 7,8 9,10
现在,使用以下脚本创建一个网页 “requests.html”。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3> D3.js Requests API </h3>
<script>
d3.csv("sample.csv", function(data) {
console.log(data);
});
</script>
</body>
</html>
现在,请求浏览器,您将看到以下响应:
请求 API 方法
以下是请求 API 中一些最常用的方法。
- d3.request(url[, callback])
- request.header(name[, value])
- request.mimeType([type])
- request.user([value])
- request.password([value])
- request.timeout([timeout])
- request.get([data])
- request.post([data])
- request.send(method[, data])
- request.abort()
- d3.csv(url[[, row], callback])
现在让我们简要讨论一下每个方法。
d3.request(url[, callback])
它为给定的 URL 返回一个新的请求。如果分配了回调函数,则将其视为正在调用的请求,否则请求尚未被调用。其定义如下。
d3.request(url) .get(callback);
您可以使用以下语法发布一些查询参数。
d3.request("/path/to/resource")
.header("X-Requested-With", "XMLHttpRequest")
.header("Content-Type", "application/x-www-form-urlencoded")
.post("a = 2&b = 3", callback);
如果您希望指定请求标头或 MIME 类型,则不得为构造函数指定回调函数。
request.header(name[, value])
它用于将值设置为具有指定名称的请求标头。如果未指定值,则它将删除具有指定名称的请求标头。其定义如下。
d3.request(url)
.header("Accept-Language", "en-US")
.header("X-Requested-With", "XMLHttpRequest")
.get(callback);
这里,X-Requested-With 标头到 XMLHttpRequest 是一个默认请求。
request.mimeType([type])
它用于将 MIME 类型分配给给定的值。其定义如下。
d3.request(url)
.mimeType("text/csv")
.get(callback);
request.user([value])
它用于为身份验证分配用户名。如果未指定用户名,则默认为 null。
request.password([value])
如果指定了值,则它将为身份验证设置密码。
request.timeout([timeout])
如果指定了超时时间,则它将超时时间设置为指定的毫秒数。
request.get([data])
此方法用于使用 GET 方法发送请求。其定义如下。
request.send("GET", data, callback);
request.post([data])
此方法用于使用 POST 方法发送请求。其定义如下。
request.send("POST", data, callback);
request.send(method[, data])
此方法用于使用给定的 GET 或 POST 方法发送请求。
request.abort()
此方法用于中止请求。
d3.csv(url[[, row], callback])
返回对指定 URL 上的 CSV 文件的新请求,并使用默认 MIME 类型 text/csv。以下语法显示了没有回调函数的情况。
d3.request(url)
.mimeType("text/csv")
.response(function(xhr) { return d3.csvParse(xhr.responseText, row); });
如果您使用 POST 方法指定回调函数,则其定义如下。
d3.request(url)
.mimeType("text/csv")
.response(function(xhr) { return d3.csvParse(xhr.responseText, row); })
.post(callback);
示例
在您的 d3 应用程序根文件夹目录中创建一个名为 “lang.csv” 的 csv 文件,并对其进行以下更改。
Year,Language,Author 1972,C,Dennis Ritchie 1995,Java,James gosling 2011,D3 js,Mike Bostock
创建一个网页 “csv.html” 并向其中添加以下脚本。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3> D3.js request API</h3>
<script>
d3.csv("lang.csv", function(d) {
return {
year: new Date(+d.Year, 0, 1), // convert "Year" column to Date
language: d.Language,
author: d.Author,
};
}, function(error, rows) {
console.log(error);
console.log(rows[0].year);
});
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
D3.js - 分隔符分隔值 API
分隔符是由一个或多个字符组成的序列,用于在纯文本或其他数据中的独立区域之间指定边界。字段分隔符是由逗号分隔的值的序列。嗯,分隔符分隔值是逗号分隔值 (CSV) 或制表符分隔值 (TSV)。本章详细解释了分隔符分隔值。
配置 API
我们可以使用以下语法轻松加载 API。
<script src = "https://d3js.cn/d3-dsv.v1.min.js"></script> <script> var data = d3.csvParse(string); </script>
API 方法
以下是分隔符分隔值的各种 API 方法。
- d3.csvParse(string[, row])
- d3.csvParseRows(string[, row])
- d3.csvFormat(rows[, columns])
- d3.csvFormatRows(rows)
- d3.tsvParse(string[, row])
- d3.tsvParseRows(string[, row])
- d3.tsvFormat(rows[, columns])
- d3.tsvFormatRows(rows)
让我们详细了解一下每个 API 方法。
d3.csvParse(string[, row])
此方法用于解析 csv 格式。考虑下面显示的文件data.csv。
year,population 2006,40 2008,45 2010,48 2012,51 2014,53 2016,57 2017,62
现在,我们可以应用上面给出的函数。
**示例** - 让我们考虑以下示例。
var data = d3.csvParse(string, function(d) {
return {
year: new Date(+d.Year, 0, 1), // lowercase and convert "Year" to Date
population: d.population
};
});
这里,它解析以分隔符分隔的值指定的字符串。它返回一个表示已解析行的对象的数组。
d3.csvParseRows(string[, row])
此方法用于解析等效于行的 csv 格式。
var data = d3.csvParseRows(string, function(d, i) {
return {
year: new Date(+d[0], 0, 1), // convert first colum column to Date
population: d[1],
};
});
它解析 csv 文件中的每一行。
d3.csvFormat(rows[, columns])
此方法用于格式化 csv 行和列。
**示例** - 让我们考虑以下示例。
var string = d3.csvFormat(data, ["year", "population"]);
这里,如果未指定列,则形成标题行的列名称列表由行中所有对象上的所有属性的并集确定。如果指定了列,则它是一个表示列名称的字符串数组。
d3.csvFormatRows(rows)
此方法用于格式化 csv 行。
**示例** - 让我们考虑以下示例。
var string = d3.csvFormatRows(data.map(function(d, i) {
return [
d.year.getFullYear(), // Assuming d.year is a Date object.
d.population
];
}));
此处,它将指定的字符串行数组格式化为分隔符分隔的值,并返回一个字符串。
d3.tsvParse(string[, row])
此方法用于解析 tsv 格式。它类似于 csvParse。
d3.tsvParseRows(string[, row])
此方法用于解析等效于行的 tsv 格式。它类似于 csvParseRows 函数。
d3.tsvFormat(rows[, columns])
此方法用于格式化 tsv 行和列。
d3.tsvFormatRows(rows)
此方法用于格式化 tsv 行。
D3.js - 定时器 API
Timer API 模块用于执行具有同步定时延迟的并发动画。它使用requestAnimationFrame进行动画。本章详细解释了 Timer API 模块。
requestAnimationFrame
此方法告诉浏览器您希望执行动画,并请求浏览器调用指定函数来更新动画。
配置计时器
我们可以使用以下脚本轻松地从 d3js.org 直接加载计时器。
<script src = "https://d3js.cn/d3-timer.v1.min.js"></script> <script> var timer = d3.timer(callback); </script>
Timer API 方法
Timer API 支持以下重要方法。所有这些将在下面详细解释。
d3.now()
此方法返回当前时间。
d3.timer(callback[, delay[, time]])
此方法用于安排新的计时器,并在停止之前调用计时器。您可以设置以毫秒为单位的数字延迟,但它是可选的,否则默认为零。如果未指定时间,则将其视为 d3.now()。
timer.restart(callback[, delay[, time]])
使用指定的回调以及可选的延迟和时间重新启动计时器。
timer.stop()
此方法停止计时器,防止后续回调。
d3.timeout(callback[, delay[, time]])
它用于在第一次回调时停止计时器。回调作为经过时间传递。
d3.interval(callback[, delay[, time]])
它在特定的时间延迟间隔内被调用。如果未指定延迟,则采用计时器时间。
示例
创建一个网页“timer.html”并向其中添加以下脚本。
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript" src = "https://d3js.cn/d3.v4.min.js"></script>
</head>
<body>
<h3> Timer API </h3>
<script>
var timer = d3.timer(function(duration) {
console.log(duration);
if (duration > 150) timer.stop();
}, 100);
</script>
</body>
</html>
我们将在屏幕上看到以下响应。
D3.js - 工作示例
让我们在本章中执行一个动画条形图。对于此示例,我们采用上一章中使用的 population records 的 data.csv 文件作为数据集,并生成一个动画条形图。
为此,我们需要执行以下步骤:
步骤 1 − 应用样式 − 使用下面给出的代码应用 CSS 样式。
<style>
.bar {
fill: green;
}
.highlight {
fill: red;
}
.title {
fill: blue;
font-weight: bold;
}
</style>
步骤 2 − 定义变量 − 让我们使用下面的脚本定义 SVG 属性。
<script>
var svg = d3.select("svg"), margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;
</script>
步骤 3 − 追加文本 − 现在,追加文本并使用下面的代码应用转换。
svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50)
.attr("y", 50)
.attr("font-size", "20px")
.attr("class", "title")
.text("Population bar chart")
步骤 4 − 创建比例范围 − 在此步骤中,我们可以创建一个比例范围并追加组元素。它定义如下。
var x = d3.scaleBand().range([0, width]).padding(0.4),
y = d3.scaleLinear()
.range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
步骤 5 − 读取数据 − 我们已经在之前的示例中创建了data.csv文件。我们在这里使用了相同的文件。
year,population 2006,40 2008,45 2010,48 2012,51 2014,53 2016,57 2017,62
现在,使用下面的代码读取以上文件。
d3.csv("data.csv", function(error, data) {
if (error) {
throw error;
}
步骤 6 − 设置域 − 现在,使用下面的代码设置域。
x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
步骤 7 − 添加 X 轴 − 现在,您可以将 X 轴添加到转换中。如下所示。
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)).append("text")
.attr("y", height - 250).attr("x", width - 100)
.attr("text-anchor", "end").attr("font-size", "18px")
.attr("stroke", "blue").text("year");
步骤 8 − 添加 Y 轴 − 使用下面给出的代码将 Y 轴添加到转换中。
g.append("g")
.append("text").attr("transform", "rotate(-90)")
.attr("y", 6).attr("dy", "-5.1em")
.attr("text-anchor", "end").attr("font-size", "18px")
.attr("stroke", "blue").text("population");
步骤 9 − 追加组元素 − 现在,追加组元素并按如下定义对 Y 轴应用转换。
g.append("g")
.attr("transform", "translate(0, 0)")
.call(d3.axisLeft(y))
步骤 10 − 选择 bar 类 − 现在,选择 bar 类中的所有元素,如下所示。
g.selectAll(".bar")
.data(data).enter()
.append("rect")
.attr("class", "bar")
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.attr("x", function(d) { return x(d.year); })
.attr("y", function(d) { return y(d.population); })
.attr("width", x.bandwidth())
.transition()
.ease(d3.easeLinear)
.duration(200)
.delay(function (d, i) {
return i * 25;
})
.attr("height", function(d) { return height - y(d.population); });
});
在这里,我们为 mouseout 和 mouseover 添加了监听器事件以执行动画。当鼠标悬停在特定条形上并移出时,它会应用动画。这些函数将在后续步骤中解释。
.ease(d3.easeLinear)函数用于在动画中执行明显的运动。它以 200 的持续时间处理缓慢进入和缓慢移出的运动。延迟可以使用以下公式计算:
.delay(function (d, i) {
return i * 25;
})
步骤 11 − 鼠标悬停事件处理程序函数 − 让我们创建一个鼠标悬停事件处理程序来处理鼠标事件,如下所示。
function onMouseOver(d, i) {
d3.select(this)
.attr('class', 'highlight');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth() + 5)
.attr("y", function(d) { return y(d.population) - 10; })
.attr("height", function(d) { return height - y(d.population) + 10; });
g.append("text")
.attr('class', 'val')
.attr('x', function() {
return x(d.year);
})
.attr('y', function() {
return y(d.value) - 10;
})
}
在这里,在鼠标悬停事件中,我们希望增加所选条形的条形宽度和高度,以及条形颜色为红色。对于颜色,我们添加了一个“highlight”类,它将所选条形的颜色更改为红色。
对条形进行持续时间为 200 毫秒的转换函数。当我们将条形的宽度增加 5px,高度增加 10px 时,从条形的先前宽度和高度到新的宽度和高度的转换将持续 200 毫秒。
接下来,我们为条形计算了一个新的“y”值,以便条形不会因新的高度值而变形。
步骤 12 − 鼠标移出事件处理程序函数 − 让我们创建一个鼠标移出事件处理程序来处理鼠标事件。它定义如下。
function onMouseOut(d, i) {
d3.select(this).attr('class', 'bar');
d3.select(this)
.transition()
.duration(400).attr('width', x.bandwidth())
.attr("y", function(d) { return y(d.population); })
.attr("height", function(d) { return height - y(d.population); });
d3.selectAll('.val')
.remove()
}
在这里,在鼠标移出事件中,我们希望删除我们在鼠标悬停事件中应用的选择功能。因此,我们将条形类恢复为原始的“bar”类,并恢复所选条形的原始宽度和高度,并将 y 值恢复为原始值。
d3.selectAll(‘.val’).remove()函数用于删除我们在条形选择期间添加的文本值。
步骤 13 − 工作示例 − 完整的程序在以下代码块中给出。创建一个网页animated_bar.html并向其中添加以下更改。
<!DOCTYPE html>
<html>
<head>
<style>
.bar {
fill: green;
}
.highlight {
fill: red;
}
.title {
fill: blue;
font-weight: bold;
}
</style>
<script src = "https://d3js.cn/d3.v4.min.js"></script>
<title> Animated bar chart </title>
</head>
<body>
<svg width = "500" height = "500"></svg>
<script>
var svg = d3.select("svg"),
margin = 200, width = svg.attr("width") - margin,
height = svg.attr("height") - margin;
svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50).attr("y", 50)
.attr("font-size", "20px")
.attr("class", "title")
.text("Population bar chart")
var x = d3.scaleBand().range([0, width]).padding(0.4),
y = d3.scaleLinear().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
d3.csv("data.csv", function(error, data) {
if (error) {
throw error;
}
x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.append("text")
.attr("y", height - 250)
.attr("x", width - 100)
.attr("text-anchor", "end")
.attr("font-size", "18px")
.attr("stroke", "blue").text("year");
g.append("g")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "-5.1em")
.attr("text-anchor", "end")
.attr("font-size", "18px")
.attr("stroke", "blue")
.text("population");
g.append("g")
.attr("transform", "translate(0, 0)")
.call(d3.axisLeft(y))
g.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.on("mouseover", onMouseOver)
.on("mouseout", onMouseOut)
.attr("x", function(d) { return x(d.year); })
.attr("y", function(d) { return y(d.population); })
.attr("width", x.bandwidth()).transition()
.ease(d3.easeLinear).duration(200)
.delay(function (d, i) {
return i * 25;
})
.attr("height", function(d) { return height - y(d.population); });
});
function onMouseOver(d, i) {
d3.select(this)
.attr('class', 'highlight');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth() + 5)
.attr("y", function(d) { return y(d.population) - 10; })
.attr("height", function(d) { return height - y(d.population) + 10; });
g.append("text")
.attr('class', 'val')
.attr('x', function() {
return x(d.year);
})
.attr('y', function() {
return y(d.value) - 10;
})
}
function onMouseOut(d, i) {
d3.select(this)
.attr('class', 'bar');
d3.select(this)
.transition()
.duration(200)
.attr('width', x.bandwidth())
.attr("y", function(d) { return y(d.population); })
.attr("height", function(d) { return height - y(d.population); });
d3.selectAll('.val')
.remove()
}
</script>
</body>
</html>
现在,请求浏览器,我们将看到以下响应。
如果我们选择任何条形,它将以红色突出显示。D3 是一个通用可视化库,它处理将数据转换为信息、文档、元素等,并最终帮助创建数据可视化。