D3.js - 快速指南

D3.js - 简介

数据可视化是以图片或图形格式呈现数据。数据可视化的主要目标是通过统计图形、图表和信息图形清晰有效地传达信息。

数据可视化有助于我们快速有效地传达我们的见解。可视化所表示的任何类型的数据都允许用户比较数据、生成分析报告、了解模式,从而帮助他们做出决策。数据可视化可以是交互式的,以便用户分析图表中的特定数据。好吧,可以使用不同的 JavaScript 框架在常规网站甚至移动应用程序中开发和集成数据可视化。

什么是 D3.js?

D3.js 是一个 JavaScript 库,用于在浏览器中创建交互式可视化。D3.js 库允许我们在数据集的上下文中操作网页元素。这些元素可以是 HTML、SVGCanvas 元素,并且可以根据数据集的内容进行引入、删除或编辑。它是一个用于操作 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 库包含到您的 HTML 网页中,以便使用 D3.js 创建数据可视化。我们可以通过以下两种方式实现 −

  • 从项目文件夹中包含 D3.js 库。
  • 从 CDN(内容分发网络)包含 D3.js 库。

下载 D3.js 库

D3.js 是一个开源库,该库的源代码可在 https://d3js.org/ 网站上免费获取。访问 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 代码,因此我们应将所有 D3 代码写在"script"标记内。我们可能需要操作现有的 DOM 元素,因此建议在"body"标记结束之前写 D3 代码。

从 CDN 包含 D3 库

我们可以通过将 D3.js 库从内容分发网络 (CDN) 直接链接到我们的 HTML 页面来使用它。CDN 是一个服务器网络,文件托管于其中,并根据用户的地理位置传递给用户。如果我们使用 CDN,则无需下载源代码。

使用 CDN URL https://d3js.org/d3.v4.min.js 将 D3.js 库包含到我们的页面中,如下所示。

示例 − 让我们考虑以下示例。

<!DOCTYPE html>
<html lang = "en">
   <head>
      <script src = "https://d3js.org/d3.v4.min.js"></script>
   </head>

   <body>
      <script>
         // write your d3 code here.. 
      </script>
   </body>
</html>

D3.js 编辑器

我们需要一个编辑器来开始编写代码。有一些很棒的 IDE(集成开发环境)支持 JavaScript,例如 −

  • Visual Studio Code
  • WebStorm
  • Eclipse
  • Sublime Text

这些 IDE 提供智能代码完成功能,并支持一些现代 JavaScript 框架。如果您没有花哨的 IDE,您可以随时使用记事本、VI 等基本编辑器。

Web 浏览器

D3.js 适用于除 IE8 及更低版本之外的所有浏览器。

Web 服务器

大多数浏览器直接从本地文件系统提供本地 HTML 文件。但是,在加载外部数据文件时存在某些限制。在本教程的后面几章中,我们将从外部文件(如 CSVJSON)加载数据。因此,如果我们从一开始就设置好 Web 服务器,那么对我们来说会更容易。

您可以使用任何您熟悉的 Web 服务器,例如 IIS、Apache 等。

查看您的页面

在大多数情况下,我们只需在 Web 浏览器中打开您的 HTML 文件即可查看。但是,在加载外部数据源时,运行本地 Web 服务器并从服务器 (http://localhost: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 不是直接的图像,而只是一种使用文本创建图像的方法。顾名思义,它是一种可缩放矢量。它会根据浏览器的大小自行缩放,因此调整浏览器大小不会扭曲图像。除 IE 8 及以下版本外,所有浏览器都支持 SVG。数据可视化是视觉表示,使用 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",并将值指定为 yellow,如下所示 −

<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.org/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.org/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.org/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.org/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.org/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.org/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.org/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() 方法用于设置所选元素的 style 属性。创建网页"select_and_style.html"并添加以下代码。

<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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);
  • 删除类 − 要删除类,必须将类方法的第二个参数设置为 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.org/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() 方法适用于 divh2 标签,并且两个标签中的文本颜色均变为红色。

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 code

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()

在这里,我们使用 exit() 和 remove() 方法从数据集及其对应的 li 中删除了第四项。

完整代码如下 −

<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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.org/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 dynamic 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); // 数据元素
    console.log(i); // 索引元素
    console.log(this); // 当前 DOM 对象
    return d;
});

考虑以下示例。

<!DOCTYPE html>
<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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() 函数为选定元素提供数据,在我们的例子中是数据数组。

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属性使用strokestroke-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.org/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 −同样的,在svg元素里面添加line元素,如下图所示。

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.org/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.org/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.org/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.org/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 来支持转换。可能的值是以下一个或多个,

  • Translate −它需要两个选项,tx 表示沿 x 轴的平移,ty 表示沿 y 轴的平移。例如,translate(30 30)

  • Rotate − 它需要三个选项,angle 表示旋转角度,cxcy 表示 x 和 y 轴的旋转中心。如果未指定 cxcy,则默认为坐标系的当前原点。例如,rotate − rotate(60)。

  • Scale −它有两个选项,sx 表示沿 x 轴的缩放因子,sy 表示沿 y 轴的缩放因子。这里,sy 是可选的,如果未指定,则采用 sx 的值。例如,示例 − scale(10)。

  • Skew (SkewX 和 SkewY) − 它只有一个选项;skew-angle 表示 SkewX 沿 x 轴的角度和 SkewY 沿 y 轴的角度。例如,示例 − skewx(20)。

带有平移的 SVG 矩形示例,描述如下 −

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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.org/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.org/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 − 添加变换属性并添加平移和旋转,如下所示。

<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.org/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.org/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 = "http://d3js.org/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.org/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.org/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.org/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.org/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>

这里,

  • Width − SVG 的宽度。

  • Scalefactor − 缩放到屏幕上可见的像素值。

  • Barheight − 这是水平条的静态高度。

步骤 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 高度计算为条形高度 * 数据长度,即 120 像素。

步骤 5应用转换 − 让我们使用以下代码在条形图中应用转换。

var bar = graph.selectAll("g") 
   .data(data)
   .enter()
   .append("g")
   .attr("transform", function(d, i) {
      return "translate(0," + i * barHeight + ")";
   });

这里,每个条形图都对应一个元素。因此,我们创建组元素。我们的每个组元素都需要一个接一个地放置,以构建水平条形图。我们采用转换公式索引 * 条形图高度。

步骤 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.org/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>

这里,

  • Width − SVG 的宽度。

  • Height − SVG 的高度。

  • Data − 数据元素数组。

  • Colors − 将颜色应用于圆形元素。

步骤 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.org/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;
}

此处,填充用于应用颜色。文本锚点用于将文本定位到弧线的中心。

步骤 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);

在这里,此弧线将设置为路径元素。计算出的半径设置为外半径,而内半径设置为 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附加组元素 −附加组元素属性并添加类标题以对文本进行着色并使其变为斜体,这在步骤 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.org/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>
piechart

甜甜圈图

甜甜圈图或圆环图只是一个简单的饼图,里面有一个洞。我们可以将洞半径定义为您需要的任何大小,以百分比或像素为单位。我们可以创建一个甜甜圈图而不是饼图。将圆弧的内半径更改为大于零的值。其定义如下。

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.org/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",另一个表示"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.org/d3.v4.min.js"></script>
      <style> 
         .line {
            fill: none;
            stroke: green;
            stroke-width: 5px;
         }
      </style>
   </head>

   <body>
      <script>
        // 设置图表的尺寸和边距
        var margin = {top: 20, right: 20, bottom: 30, left: 50},
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;
        
        // 设置范围
        var x = d3.scaleTime().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);
        
        // 定义线
        var valueline = d3.line()
        .x(function(d) { return x(d.year); })
        .y(function(d) { return y(d.population); });
        
        // 将 svg 对象附加到页面主体
        // 将 'group' 元素附加到 'svg'
        // 将 'group' 元素移动到左上角边距
        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 + ")");
        
        // 获取数据
         d3.csv("data.csv", function(error, data) {
            if (error) throw error;
            // 格式化数据
            data.forEach(function(d) {
            d.year = d.year;
            d.population = +d.population;
            });
            
            // 缩放数据范围
            x.domain(d3.extent(data, function(d) { return d.year; }));
            y.domain([0, d3.max(data, function(d) { return d.population; })]);
            
            // 添加值线路径。
            svg.append("path")
            .data([data])
            .attr("class", "line")
            .attr("d", valueline);
            
            // 添加 X 轴
            svg.append("g")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x));
            
            // 添加 Y 轴
            svg.append("g")
            .call(d3.axisLeft(y));
         });
      </script>
   </body>
</html>

现在请求浏览器,我们将看到以下结果。

Graph

D3.js - 地理

地理空间坐标通常用于天气或人口数据。D3.js 为我们提供了三种用于地理数据的工具 −

  • 路径 − 它们产生最终像素。

  • 投影 − 它们将球体坐标转换为笛卡尔坐标和

  • −它们可以加快速度。

在了解 D3.js 中的地理是什么之前,我们应该了解以下两个术语 −

  • D3 地理路径和
  • 投影

让我们详细讨论这两个术语。

D3 地理路径

它是一个地理路径生成器。GeoJSON 生成 SVG 路径数据字符串或将路径渲染到 Canvas。建议使用 Canvas 进行动态或交互式投影以提高性能。要生成 D3 Geo 路径数据生成器,您可以调用以下函数。

d3.geo.path()

此处,d3.geo.path() 路径生成器函数允许我们选择要使用哪个地图投影来从地理坐标转换为笛卡尔坐标。

例如,如果我们想要显示印度的地图详细信息,我们可以定义一条路径,如下所示。

var path = d3.geo.path()
svg.append("path")
.attr("d", path(states))

投影

投影将球面多边形几何体转换为平面多边形几何体。 D3 提供以下投影实现。

  • 方位角 − 方位角投影将球体直接投影到平面上。

  • 复合投影 − 复合投影由多个投影组成,这些投影组合成一个显示画面。

  • 圆锥投影 − 将球体投影到圆锥体上,然后将圆锥体展开到平面上。

  • 圆柱投影 −圆柱投影将球体投影到包含圆柱体上,然后将圆柱体展开到平面上。

要创建新投影,您可以使用以下函数。

d3.geoProjection(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应用样式 − 让我们使用以下代码在地图中添加样式。

<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 = "http://d3js.org/topojson.v0.min.js"></script>

我们可以在编码中包含此脚本。

步骤 3定义变量 − 使用以下代码在脚本中添加变量。

var width = 600;
var height = 400;
var project = 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),该投影类型先前使用变量投影定义为墨卡托投影。

步骤 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.org/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); // 输出为 20
d3.quantile(data, 0.5); // 输出为 60
d3.quantile(data, 1); // 输出为 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。

示例 −让我们使用以下脚本执行上面讨论的所有 Array API 方法。创建一个网页"array.html"并向其中添加以下更改。

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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>

现在,请求浏览器,我们将看到以下响应。

Array

数组搜索 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; })); // 输出为 0
console.log(d3.scan(array, function(a, b) { return b.one - a.one; })); // 输出为 1

d3.ascending(a, b)

该方法用于执行比较函数,可以实现为 −

function rising(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.org/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"]); // 输出为 [[10, "a"], [10, "b"], [20, "a"], [20, "b"]]

d3.merge(arrays)

此方法用于合并数组,定义如下。

d3.merge([[10], [20]]); // 输出为 [10, 20]

d3.pairs(array[, Reducer])

此方法用于配对数组元素,定义如下。

d3.pairs([10, 20, 30, 40]); // 输出为 [[10, 20], [20, 30], [30, 40]]

d3.permute(array, indexes)

此方法用于从指定的数组和索引执行排列。您还可以将对象中的值放入数组中。下面解释一下。

var object = {fruit:"mango", color: "yellow"},
fields = ["fruit", "color"];
d3.permute(object, fields); // 输出为 "mango" "yellow"

d3.zip(arrays)

此方法用于返回一个数组数组。如果数组只包含一个数组,则返回的数组包含一个元素数组。如果没有指定参数,则返回的数组为空。它的定义如下。

d3.zip([10, 20], [30, 40]); // 输出为 [[10, 30], [20, 40]]

示例 −创建一个网页array_transform并添加以下更改。

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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>

现在,请求浏览器,我们将看到以下响应。

Array Transform

D3.js - 集合 API

集合只是一个将多个元素分组为一个单元的对象。它也被称为容器。本章详细介绍了集合 API。

配置 API

您可以使用以下脚本配置 API。

<script src = "https://d3js.org/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})

此处,键为 1,值为 1。

示例 − 创建一个网页 objects.html 并向其中添加以下更改。

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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>

现在,请求浏览器,您将看到以下响应。

Collections API

Maps API

地图包含基于键和值对的值。每个键和值对称为一个条目。地图仅包含唯一键。根据键搜索、更新或删除元素很有用。让我们详细了解各种 Maps API 方法。

  • d3.map([object[, key]]) − 此方法用于创建新地图。对象用于复制所有可枚举属性。

  • map.has(key) −此方法用于检查 map 是否有指定键字符串的条目。

  • map.get(key) − 此方法用于返回指定键字符串的值。

  • map.set(key, value) − 此方法用于设置指定键字符串的值。如果 map 之前有相同键字符串的条目,则旧条目将替换为新值。

  • map.remove(key) − 它用于删除 map 条目。如果未指定键,则返回 false。

  • map.clear() − 从此 map 中删除所有条目。

  • 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.org/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>

现在,请求浏览器,我们将看到以下响应。

Map API

同样,您也可以执行其他操作。

Sets API

Set 是一个不能包含重复元素的集合。它模拟了数学集合抽象。让我们详细了解各种 Sets API 方法。

  • d3.set([array[, accessor]]) − 此方法用于创建新集合。数组用于添加字符串值。访问器是可选的。

  • set.has(value) − 此方法用于检查集合是否具有指定值字符串的条目。

  • set.add(value) −它用于将指定的值字符串添加到集合中。

  • set.remove(value) − 它用于删除包含指定值字符串的集合。

  • set.clear() − 从此集合中删除所有值。

  • set.values() − 此方法用于向集合返回一个值数组。

  • set.empty() − 当且仅当此集合具有零个值时,返回 true。

  • set.size() − 返回此集合中的值数量。

示例 −创建一个网页sets.html并添加以下更改。

<html>
   <head>
      <script type = "text/javascript" src = "https://d3js.org/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>

现在,请求浏览器,我们将在屏幕上看到以下响应。

Sets API

同样,我们也可以执行其他操作。

Nests API

Nesting API 包含数组中的元素,并以分层树结构执行。让我们详细了解各种 Nests API 方法。

  • d3.nest() − 此方法用于创建新的 nest。

  • nest.key(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.org/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.org/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)

此方法用于选择与指定选择器字符串匹配的第一个元素。

示例 − 让我们考虑以下示例。

var body = d3.select("body");

如果选择器不是字符串,则它会选择指定的节点,该节点定义如下。

d3.select("p").style("color", "red");

d3.selectAll(selector)

此方法选择与指定选择器字符串匹配的所有元素。

示例 − 让我们考虑以下示例。

var body = d3.selectAll("body");

如果选择器不是字符串,则它会选择指定的节点数组,该节点定义如下。

d3.selectAll("body").style("color", "red");

selection.selectAll(selector)

此方法用于选择元素。它选择与指定选择器字符串匹配的后代元素。返回的选择中的元素按其在此选择中的对应父节点分组。如果没有元素与当前元素的指定选择器匹配,或者选择器为空,则当前索引处的组将为空。

示例 − 让我们考虑以下示例。

var b = d3.selectAll("p").selectAll("b");

selection.filter(filter)

此方法用于过滤选择,返回仅包含指定过滤器为真的元素的新选择。

示例 − 让我们考虑以下示例。

var even = d3.selectAll("tr").filter(":nth-child(odd)");

此处,过滤表格行的选择仅返回奇数。

selection.merge(other)

此方法用于返回与指定的其他选择合并的新选择。

示例 − 让我们考虑以下示例。

var rect = svg.selectAll("rect").data(data);
rect.enter().append("rect").merge(rect);

d3.matcher(selector)

此方法用于分配指定的选择器。它返回一个函数,该函数返回 true。

示例 − 让我们考虑以下示例。

var p = choice.filter(d3.matcher("p"));

d3.creator(name)

此方法用于分配指定的元素名称 它返回一个函数,该函数创建给定名称的元素,假设这是父元素。

示例 −让我们考虑以下示例。

selection.append(d3.creator("p"));

selection.each(function)

此方法用于为每个选定元素调用指定的函数,按照当前数据(d)、当前索引(i)和当前组(节点)传递的顺序,将其作为当前 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 不同,每个本地的值也由 DOM 限定范围。

local.set(node, value)

此方法将指定节点上此本地的值设置为值。

示例 −让我们考虑以下示例。

selection.each(function(d)
    { data.set(this, d.value); });
local.get(node)

此方法返回指定节点上此本地的值。如果节点未定义此本地,则它返回定义它的最近祖先的值。

local.remove(node)

此方法从指定节点删除此本地的值。如果节点已定义,则返回 true,否则返回 false。

D3.js - 路径 API

路径用于绘制矩形、圆形、椭圆形、折线、多边形、直线和曲线。 SVG 路径表示形状的轮廓,可以对其进行描边、填充、用作剪切路径,或三者的任意组合。本章详细介绍了路径 API。

配置路径

您可以使用以下脚本配置路径 API。

<script src = "https://d3js.org/d3-path.v1.min.js"></script>
<script>

</script>

Paths API 方法

下面简要介绍一些最常用的 Paths 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[, anticlock]) −此方法用于绘制到指定中心 (x, y)、半径、startAngle 和 endAngle 的圆弧。如果逆时针值为 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.org/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.org/d3-array.v1.min.js"></script>
<script src = "https://d3js.org/d3-collection.v1.min.js"></script>
<script src = "https://d3js.org/d3-color.v1.min.js"></script>
<script src = "https://d3js.org/d3-format.v1.min.js"></script>
<script src = "https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src = "https://d3js.org/d3-time.v1.min.js"></script>
<script src = "https://d3js.org/d3-time-format.v2.min.js"></script>
<script src = "https://d3js.org/d3-scale.v1.min.js"></script>
<script>

</script>

Scales 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() − 构建一个序数尺度,其中输入数据包括字母并映射到离散数字输出范围。

在执行工作示例之前,让我们首先了解以下两个术语 −

  • − 域表示输入数据的最小值和最大值。

  • 范围 − Range 是输出范围,我们希望输入值映射到该范围...

工作示例

让我们在此示例中执行 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.org/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.org/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.org/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 - Shapes API

本章讨论 D3.js 中的不同形状生成器。

配置 API

您可以使用以下脚本配置 Shapes API。

<script src = "https://d3js.org/d3-path.v1.min.js"></script>
<script src = "https://d3js.org/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]) − 此方法用于从给定角度设置函数的 pad 角度。其定义如下。

function padAngle() {
    return d && d.padAngle;
}
  • (x) arc.padRadius([radius]) − 此方法用于将 pad 半径设置为给定半径的指定函数。 pad 半径确定相邻圆弧之间的固定线性距离,定义为 padRadius *padAngle。

  • (xi) arc.context([context]) − 此方法用于设置上下文并返回圆弧生成器。

Pies API

此 API 用于创建 Pie 生成器。 我们在上一章中执行了这些 API 方法。 我们将详细讨论所有这些方法。

  • d3.pie() −使用默认设置构造一个新的饼图生成器。

  • pie(data[,arguments]) − 此方法用于为给定的数组值生成饼图。它返回一个对象数组。对象是基准的弧度。每个对象都有以下属性 −

    • data − 输入基准;输入数据数组中的相应元素。

    • value − 弧的数值。

    • index − 弧的索引。

    • startAngle − 弧的起始角度。

    • endAngle −圆弧的结束角度。

    • padAngle − 圆弧的 pad 角度。

  • 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]) − 此方法用于将饼图的终止角度设置为指定的函数。如果没有指定angle,则返回当前结束角度,其定义如下。

function endAngle() {
    return 2 * Math.PI;
}
  • pie.padAngle([angle]) − 该方法用于将pad角度设置为指定函数,并生成饼图,函数定义如下。

function padAngle() {
   return 0;
}

Lines API

Lines API 用于生成一条线。我们在 Graphs 一章中使用了这些 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]) − 该方法用于将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.org/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)

让我们详细了解这些 Color API 方法。

d3.color(specifier)

它用于解析指定的 CSS 颜色并返回 RGB 或 HSL 颜色。如果没有给出 specifier,则返回 null。

示例 − 让我们考虑以下示例。

<script>
    var color = d3.color("green"); // 直接分配颜色名称
    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.org/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>

现在,请求浏览器,我们将看到以下响应。

Colors API

D3.js - Transitions API

D3 Transitions 选择元素,并针对每个元素将转换应用于元素当前定义的一部分。

配置 API

您可以使用以下脚本配置转换 API。

<script src = "https://d3js.org/d3-color.v1.min.js"></script>
<script src = "https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src = "https://d3js.org/d3-ease.v1.min.js"></script>
<script src = "https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src = "https://d3js.org/d3-selection.v1.min.js"></script>
<script src = "https://d3js.org/d3-timer.v1.min.js"></script>
<script src = "https://d3js.org/d3-transition.v1.min.js"></script>
<script>

</script>

Transition API 方法

让我们详细了解 Transition 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()
    
    // 淡入黄色。
    .style("fill", "yellow")
    .transition()
    
    // 等待五秒钟。然后变为蓝色,然后移除。
    .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.org/d3-dispatch.v1.min.js"></script>
<script src = "https://d3js.org/d3-selection.v1.min.js"></script>
<script src = "https://d3js.org/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])

用于将容器设置为指定的拖动函数。如果未指定容器,则返回当前访问器。要使用Canvas拖动任何图形元素,您可以将容器重新定义为其自身。其定义如下。

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 事件的最大距离。如果未指定 distance,则指向零。

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 方法用于设置拖动事件。它由以下字段组成 −

  • 目标 − 它表示拖动行为。

  • 类型 − 它是一个字符串,可以是以下任一项 - "start"、"drag"或"end"。

  • 主题 − 拖动主题,由 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.org/d3-color.v1.min.js"></script>
<script src = "https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src = "https://d3js.org/d3-ease.v1.min.js"></script>
<script src = "https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src = "https://d3js.org/d3-selection.v1.min.js"></script>
<script src = "https://d3js.org/d3-timer.v1.min.js"></script>
<script src = "https://d3js.org/d3-transition.v1.min.js"></script>
<script src = "https://d3js.org/d3-drag.v1.min.js"></script>
<script src = "https://d3js.org/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])

Δ 的值由 wheel delta 函数返回。如果未指定 delta,则返回当前 wheel 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])

此方法用于将缩放过渡插入到指定的函数。如果未指定 interpolate,则返回当前插值工厂,默认为 d3.interpolateZoom。

zoom.on(typenames[, listener])

如果指定了侦听器,则为指定的 typenames 设置事件侦听器并返回缩放行为。typenames 是一个字符串,包含一个或多个由空格分隔的 typename。每个 typename 都是一个类型,后面可以跟一个句点 (.) 和一个名称,例如 zoom.one 和 zoom.second。该名称允许为同一类型注册多个侦听器。此类型必须来自以下 − 之一

  • 开始 − 缩放开始后(例如鼠标按下时)。

  • Zoom 在缩放变换发生改变(例如鼠标移动)后 −。

  • End 在缩放结束(例如鼠标抬起)后 −。

在下一章中,我们将讨论 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.org/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.org/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>

现在,请求浏览器,您将看到以下响应,

Requests API

Requests API 方法

以下是一些最常用的 Requests 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);

此处,XMLHttpRequest 的 X-Requested-With 标头是默认请求。

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.org/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>

现在,请求浏览器,我们将看到以下响应。

CSV

D3.js - 分隔符分隔值 API

分隔符是一个或多个字符的序列,用于指定纯文本或其他数据中独立区域之间的边界。字段分隔符是逗号分隔值的序列。分隔符分隔值是逗号分隔值(CSV)或制表符分隔值(TSV)。本章详细介绍了分隔符分隔值。

配置 API

我们可以使用以下语法轻松加载 API。

<script src = "https://d3js.org/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), // 小写并将"Year"转换为 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), // 将第一列转换为日期
      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(), // 假设 d.year 是 Date 对象。
        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 - Timer API

Timer API 模块用于执行具有同步时间延迟的并发动画。它使用 requestAnimationFrame 进行动画。本章详细介绍了 Timer API 模块。

requestAnimationFrame

此方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数来更新动画。

配置计时器

我们可以使用以下脚本直接从 d3js.org 轻松加载计时器。

<script src = "https://d3js.org/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.org/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>

我们将在屏幕上看到以下响应。

Timer API

D3.js - 工作示例

让我们在本章中制作一个动画条形图。对于此示例,我们将上一章人口记录中使用的 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;
})

步骤 11Mouseover 事件处理函数 − 让我们创建一个 mouseover 事件处理程序来处理鼠标事件,如下所示。

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;
   })
}

在这里,在 mouseover 事件中,我们想要增加条形的宽度和高度,并将所选条形的条形颜色更改为红色。对于颜色,我们添加了一个类"highlight",它将所选条形的颜色更改为红色。

条形的过渡函数,持续时间为 200 毫秒。当我们将条形的宽度增加 5px,将高度增加 10px 时,从条形的先前宽度和高度到新宽度和高度的过渡将持续 200 毫秒。

接下来,我们为条形计算了一个新的"y"值,以便条形不会因新的高度值而扭曲。

步骤 12Mouseout 事件处理函数 − 让我们创建一个 mouseout 事件处理函数来处理鼠标事件。它定义如下。

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()
}

在这里,在 mouseout 事件中,我们想要删除在 mouseover 事件中应用的选择功能。因此,我们将 bar 类恢复为原始的"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.org/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 是一个通用可视化库,用于将数据转换为信息、文档、元素等,并最终帮助创建数据可视化。