目录

D3.js - 快速指南

D3.js - Introduction

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

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

什么是D3.js?

D3.js是一个JavaScript库,用于在浏览器中创建交互式可视化。 D3.js库允许我们在数据集的上下文中操作网页的元素。 这些元素可以是HTML, SVG,Canvas elements ,可以根据数据集的内容进行引入,删除或编辑。 它是一个用于操作DOM对象的库。 D3.js可以成为数据探索的宝贵帮助,它可以让您控制数据的表示,并允许您添加交互性。

我们为什么需要D3.js?

与其他库相比,D3.js是最重要的框架之一。 这是因为它适用于网络,其数据可视化非常出色。 它运作良好的另一个原因是它的灵活性。 由于它可以与现有的Web技术无缝协作,并且可以操作文档对象模型的任何部分,因此它与Client Side Web Technology Stack (HTML,CSS和SVG)一样灵活。 它有很好的社区支持,更容易学习。

D3.js Features

D3.js是最好的数据可视化框架之一,它可以用于生成简单和复杂的可视化以及用户交互和过渡效果。 它的一些显着特征如下 -

  • 非常灵活。
  • 易于使用和快速。
  • 支持大型数据集。
  • 声明性编程。
  • 代码可重用性。
  • 具有多种曲线生成功能。
  • 将数据关联到html页面中的元素或元素组。

D3.js Benefits

D3.js是一个开源项目,没有任何插件。 它需要非常少的代码并提供以下好处 -

  • 出色的数据可视化

  • 它是模块化的。 您可以下载一小段您想要使用的D3.js。 无需每次都加载整个库。

  • 易于构建图表组件。

  • DOM操作。

在下一章中,我们将了解如何在我们的系统上安装D3.js。

D3.js - Installation

在本章中,我们将学习如何设置D3.js开发环境。 在开始之前,我们需要以下组件 -

  • D3.js图书馆
  • Editor
  • 网页浏览器
  • 网络服务器

让我们逐一详细介绍这些步骤。

D3.js Library

我们需要将D3.js库包含在HTML网页中,以便使用D3.js创建数据可视化。 我们可以通过以下两种方式实现 -

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

下载D3.js Library

D3.js是一个开源库,该库的源代码可以在网站https://d3js.org/网站上免费获得。 访问D3.js网站并下载最新版本的D3.js(d3.zip)。 截至目前,最新版本为4.6.0。

下载完成后,解压缩文件并查找d3.min.js 这是D3.js源代码的缩小版本。 复制d3.min.js文件并将其粘贴到项目的根文件夹或任何其他要保留所有库文件的文件夹中。 在HTML页面中包含d3.min.js文件,如下所示。

Example - 让我们考虑以下示例。

<!DOCTYPE html>
<html lang = "en">
   <head>
      <script src = "/path/to/d3.min.js"></script>
   </head>
   <body>
      <script>
         // write your d3 code here.. 
      </script>
   </body>
</html>

D3.js是一个JavaScript代码,所以我们应该在“script”标签内写下我们所有的D3代码。 我们可能需要操作现有的DOM元素,因此建议在“body”标记结束之前编写D3代码。

包括CDN的D3库

我们可以通过将内容交付网络(CDN)直接链接到我们的HTML页面来使用D3.js库。 CDN是托管文件的服务器网络,并根据其地理位置提供给用户。 如果我们使用CDN,我们不需要下载源代码。

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

Example - 让我们考虑以下示例。

<!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 Editor

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

  • Visual Studio代码
  • WebStorm
  • Eclipse
  • 崇高文本

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

网页浏览器

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

网络服务器

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

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

查看您的页面

在大多数情况下,我们只需在Web浏览器中打开您的HTML文件即可查看。 但是,在加载外部数据源时,运行本地Web服务器并从服务器查看页面更为可靠(http://localhost:8080)

D3.js - Concepts

D3.js是一个开源JavaScript库,用于 -

  • 文档对象模型(DOM)的数据驱动操作。
  • 使用数据和形状。
  • 为线性,分层,网络和地理数据布置视觉元素。
  • 在用户界面(UI)状态之间启用平滑过渡。
  • 实现有效的用户交互。

网络标准

在我们开始使用D3.js创建可视化之前,我们需要熟悉Web标准。 以下Web标准在D3.js中大量使用。

  • 超文本标记语言(HTML)
  • 文档对象模型(DOM)
  • 层叠样式表(CSS)
  • 可缩放矢量图形(SVG)
  • JavaScript

让我们逐一详细介绍这些Web标准。

HyperText Markup Language (HTML)

我们知道,HTML用于构建网页的内容。 它存储在扩展名为“.html”的文本文件中。

Example - 典型的简单HTML示例如下所示

<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title></title>
   </head>
   <body>
   </body>
</html>

Document Object Model (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文档的文档对象模型如下,

文档对象模型

Cascading Style Sheets (CSS)

虽然HTML为网页提供了一种结构,但CSS样式使网页更加令人愉悦。 CSS是一种Style Sheet Language用于描述用HTML或XML编写的文档的表示(包括SVG或XHTML等XML方言)。 CSS描述了如何在网页上呈现元素。

Scalable Vector Graphics (SVG)

SVG是一种在网页上呈现图像的方法。 SVG不是直接图像,而只是使用文本创建图像的一种方式。 顾名思义,它是一个Scalable Vector 。 它会根据浏览器的大小进行缩放,因此调整浏览器大小不会使图像失真。 除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”并将值指定为黄色,如下所示 -

<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 Standards ,其中包括基于ECMA-262规范的核心功能以及不基于ECMAScript标准的其他功能。 JavaScript知识是D3.js的先决条件。

D3.js - Selections

选择是D3.js的核心概念之一。 它基于CSS选择器。 它允许我们选择网页中的一个或多个元素。 此外,它允许我们修改,追加或删除与预定义数据集相关的元素。 在本章中,我们将了解如何使用选择来创建数据可视化。

D3.js有助于使用以下两种方法从HTML页面中选择元素 -

  • select() - 通过匹配给定的CSS选择器,仅选择一个DOM元素。 如果给定的CSS选择器有多个元素,则仅选择第一个元素。

  • selectAll() - 通过匹配给定的CSS选择器来选择所有DOM元素。 如果您熟悉使用jQuery选择元素,则D3.js选择器几乎相同。

让我们详细介绍每种方法。

The select() method

select()方法根据CSS选择器选择HTML元素。 在CSS选择器中,您可以通过以下三种方式定义和访问HTML元素 -

  • HTML元素的标记(例如div,h1,p,span等)
  • HTML元素的类名
  • HTML元素的ID

让我们通过例子看看它的实际效果。

按标签选择

您可以使用其TAG选择HTML元素。 以下语法用于选择“div”标记元素,

d3.select(“div”)

Example - 创建页面“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>
         alert(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>
         alert(d3.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>
         alert(d3.select("#hello").text());
      </script>
   </body>
</html>

通过浏览器请求网页,您将在屏幕上看到以下输出。

新页面打开

添加DOM元素

D3.js选择提供append()text()方法,以将新元素附加到现有HTML文档中。 本节将详细介绍如何添加DOM元素。

The append() Method

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>

The text() Method

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巧妙地采用了一种称为chain syntax的技术,您可以从jQuery识别出来。 通过将方法与句点链接在一起,您可以在一行代码中执行多个操作。 它快速而简单。 相同的脚本也可以在没有链语法的情况下访问,如下所示。

var body = d3.select("div.myclass");
var span = body.append("span");
span.text("from D3.js");

修改元素

D3.js提供了各种方法, html(), attr()style()来修改所选元素的内容和样式。 让我们看看本章中如何使用修改方法。

The html() Method

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>

通过浏览器请求网页,您将在屏幕上看到以下输出。

新页面打开

The attr() Method

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>

通过浏览器请求网页,您将在屏幕上看到以下输出。

新页面打开

The style() Method

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>

通过浏览器请求网页,您将在屏幕上看到以下输出。

新页面打开

The classed() Method

classed()方法专门用于设置HTML元素的“class”属性。 因为,单个HTML元素可以有多个类; 在为HTML元素分配类时,我们需要小心。 此方法知道如何处理元素上的一个或多个类,并且它将具有高性能。

  • Add class - 要添加类,必须将分类方法的第二个参数设置为true。 它定义如下 -

d3.select(".myclass").classed("myanotherclass", true);
  • Remove class - 要删除类,必须将分类方法的第二个参数设置为false。 它定义如下 -

d3.select(".myclass").classed("myanotherclass", false);
  • Check class - 要检查是否存在类,只需省略第二个参数并传递要查询的类名。 如果存在则返回true,否则返回false。

d3.select(".myclass").classed("myanotherclass");

如果选择中的任何元素具有类,则返回true。 使用d3.select进行单个元素选择。

  • Toggle class - 将类翻转到相反的状态 - 如果它已经存在则将其删除,如果它尚不存在则添加它 - 您可以执行以下操作之一。

    对于单个元素,代码可能如下所示 -

var element = d3.select(".myclass")
element.classed("myanotherclass", !oneBar.classed("myanotherclass"));

The selectAll() Method

selectAll()方法用于选择HTML文档中的多个元素。 select方法选择第一个元素,但selectAll方法选择与特定选择器字符串匹配的所有元素。 如果选择匹配none,则返回空选择。 我们也可以在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 tag ,两个h2 tag本的颜色都变为红色。

D3.js - Data Join

数据连接是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()和selector的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() method用于处理从数据集中动态删除的数据项,如下所示。

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

让我们详细介绍这些方法。

The datum() Method

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>

上述代码的输出如下。

新页面打开

The data() method

data()方法用于将数据集分配给HTML文档中的元素集合。 使用选择器选择HTML元素后使用它。 在我们的列表示例中,我们使用它来设置li选择器的数据集。

d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15]);

The enter() method

enter()方法输出之前没有图形元素的数据项集。 在我们的列表示例中,我们使用它来创建新的li元素。

d3.select("#list").selectAll("li")
   .data([10, 20, 30, 25, 15])
   .text(function(d) { return "This is pre-existing element and the value is " + d; })
   .enter()
   .append("li")
   .text(function(d) { return "This is dynamically created element and the value is " + d; });

The exit() method

exit()方法输出不再存在数据的图形元素集。 在我们的列表示例中,我们使用它通过删除数据集中的数据项来动态删除其中一个li元素。

function remove() {
   d3.selectAll("li")
      .data([10, 20, 30, 15])
      .exit()
      .remove()
}

数据功能

在DOM操作章节中,我们了解了D3.js中的不同DOM操作方法,例如style(), text()等。这些函数中的每一个通常都以常量值作为参数。 然而,在Data join的上下文中,它将匿名函数作为参数。 此匿名函数获取相应的数据和使用data()方法分配的数据集的索引。 因此,将为绑定到DOM的每个数据值调用此匿名函数。 考虑以下text()函数。

.text(function(d, i) {
   return d;
});

在此函数中,我们可以应用任何逻辑来操作数据。 这些是匿名函数,意味着没有与函数关联的名称。 除了data(d)和index(i)参数之外,我们可以使用this关键字访问当前对象,如下所示 -

.text(function (d, i) {
   console.log(d); // the data element
   console.log(i); // the index element
   console.log(this); // the current DOM object
   return d;
});

请考虑以下示例。

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

D3.js - Introduction to SVG

SVG代表Scalable Vector Graphics 。 SVG是一种基于XML的矢量图形格式。 它提供了绘制不同形状的选项,如直线,矩形,圆形,椭圆等。因此,使用SVG设计可视化为您提供更多功能和灵活性。

SVG的功能

SVG的一些显着特征如下 -

  • SVG是基于矢量的图像格式,它是基于文本的。
  • SVG在结构上与HTML类似。
  • SVG可以表示为Document object model
  • 可以将SVG属性指定为属性。
  • SVG应该具有相对于原点(0,0)的绝对位置。
  • SVG可以包含在HTML文档中。

一个极小的例子

让我们创建一个最小的SVG图像并将其包含在HTML文档中。

Step 1 - 创建SVG图像并将宽度设置为300像素,高度设置为300像素。

<svg width = "300" height = "300">
</svg>

这里, svg标签启动SVG图像,它具有宽度和高度作为属性。 SVG格式的默认单位是pixel

Step 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 - 线的粗细。

Step 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>

上述程序将产生以下结果。

新页面打开

SVG使用D3.js

要使用D3.js创建SVG,请按照下面给出的步骤操作。

Step 1 - 创建一个容器来保存SVG图像,如下所示。

<div id = "svgcontainer"></div>

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

Step 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》标记表示,如下所述。

<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 Transformation

SVG提供了转换单个SVG形状元素或SVG元素组的选项。 SVG变换支持Translate, Scale, RotateSkew 。 让我们在本章学习转型。

SVG转换简介

SVG引入了一个新属性, transform为支持转换。 可能的值是以下一项或多项,

  • Translate - 它有两个选项, tx沿x轴平移, ty沿y轴平移。 例如 - 翻译(30 30)。

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

  • Scale - 它有两个选项, sx沿x轴的比例因子, sy沿y轴的比例因子。 这里, sy是可选的,如果没有指定,则它取sx的值。 例如 - 比例(10)。

  • Skew (SkewX and SkewY) - 只需一个选项; skew-angle指的是SkewX沿x轴的角度和SkewY沿y轴的角度。 例如 - skewx(20)。

带有translate的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图像,请尝试缩放,并使用变换旋转它,让我们按照下面给出的步骤进行操作。

Step 1 - 创建SVG图像并将宽度设置为300像素,将高度设置为300像素。

<svg width = "300" height = "300">
</svg>

Step 2 - 创建一个SVG组。

<svg width = "300" height = "300">
   <g>
   </g>
</svg>

Step 3 - 创建一个长度为60,高度为30的矩形,并用绿色填充。

<svg width = "300" height = "300">
   <g>
      <rect x = "20" 
         y = "20" 
         width = "60" 
         height = "30" 
         fill = "green">
      </rect>
   </g>
</svg>

Step 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>

Step 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>

Step 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,请按照下面给出的步骤操作。

Step 1 - 创建一个容器来保存SVG图像,如下所述。

<div id = "svgcontainer"></div>

Step 2 - 创建SVG图像,如下所述。

var width = 300;
var height = 300;
var svg = d3.select("#svgcontainer")
   .append("svg")
   .attr("width", width)
   .attr("height", height);

Step 3 - 创建SVG组元素并设置转换和旋转属性。

var group = svg.append("g").attr("transform", "translate(60, 60) rotate(30)");

Step 4 - 创建一个SVG矩形并将其附加到组中。

var rect = group
   .append("rect")
   .attr("x", 20)
   .attr("y", 20)
   .attr("width", 60)
   .attr("height", 30)
   .attr("fill", "green")

Step 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 - Transition

过渡是从一个项目的一个状态转换到另一个状态的过程。 D3.js提供了一个transition()方法来在HTML页面中执行转换。 让我们在本章中了解过渡。

The transition() method

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()方法开始转换。 然后,我们已指示将背景颜色从当前颜色转换为light blue

现在,刷新浏览器并在屏幕上,背景颜色从白色变为浅蓝色。 如果我们想将背景颜色从浅蓝色更改为灰色,我们可以使用以下过渡 -

d3.select("body").transition().style("background-color", "gray");

D3.js - Animation

D3.js通过过渡支持动画。 我们可以通过正确使用过渡来做动画。 转换是Key Frame Animation的有限形式,只有两个关键帧 - 开始和结束。 起始关键帧通常是DOM的当前状态,而结束关键帧是您指定的一组属性,样式和其他属性。 转换非常适合转换到新视图,而不需要依赖于起始视图的复杂代码。

Example - 让我们在“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>

这里,文档的背景颜色从白色变为浅灰色,然后变为灰色。

The duration() Method

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负责使用适当的插值方法,在高级情况下,我们可以直接使用插值方法来获得我们想要的结果。 如果需要,我们甚至可以创建一个新的插值方法。

The delay() Method

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>

转型的生命周期

Transition有一个四阶段的生命周期 -

  • 过渡计划。
  • 过渡开始了。
  • 转型运行。
  • 转型结束。

让我们一一详细地讨论这些问题。

过渡计划

创建转换时会计划转换。 当我们调用selection.transition ,我们正在安排转换。 这也是我们调用attr(), style()和其他转换方法来定义结束关键帧的时候。

过渡开始了

转换基于其延迟开始,该延迟是在安排转换时指定的。 如果未指定延迟,则转换将尽快开始,通常在几毫秒之后。

如果转换有延迟,则应仅在转换开始时设置起始值。 我们可以通过听取开始事件来做到这一点 -

d3.select("body")
   .transition()
   .delay(200)
   .each("start", function() { d3.select(this).style("color", "green"); })
   .style("color", "red");

过渡运行

当转换运行时,它会以0到1的转换值重复调用。除了延迟和持续时间之外,转换还可以轻松控制时序。 缓和会扭曲时间,例如慢进和慢进。 某些缓动函数可能暂时给出t大于1或小于0的值。

转型结束

转换结束时间始终精确为1,因此在转换结束时准确设置结束值。 转换基于其延迟和持续时间的总和而结束。 转换结束时,将调度end事件。

D3.js - Drawing Charts

D3.js用于创建静态SVG图表。 它有助于绘制以下图表 -

  • 条形图
  • 圆图
  • 饼形图
  • 甜甜圈图表
  • 折线图
  • 气泡图等

本章介绍D3中的绘图。 让我们详细了解每一个。

条形图

条形图是最常用的图形类型之一,用于显示和比较不同离散类别或组的数量,频率或其他度量(例如平均值)。 该图以这样的方式构造,即不同条的高度或长度与它们所代表的类别的大小成比例。

x轴(水平轴)表示没有比例的不同类别。 y轴(垂直轴)具有刻度,这表示测量单位。 可以垂直或水平绘制条,这取决于类别的数量和类别的长度或复杂性。

绘制条形图

让我们使用D3在SVG中创建条形图。 对于此示例,我们可以使用条形和text elementsrect elements text elements来显示与条形对应的数据值。

要使用D3在SVG中创建条形图,请按照下面给出的步骤操作。

Step 1 - Adding style in the rect element - 让我们将以下样式添加到rect元素。

svg rect {
   fill: gray;
}

Step 2 - Add styles in text element - 添加以下CSS类以将样式应用于文本值。 将此样式添加到SVG文本元素。 它定义如下 -

svg text {
   fill: yellow;
   font: 12px sans-serif;
   text-anchor: end;
}

这里,Fill用于应用颜色。 文本锚用于将文本定位到条的右端。

Step 3 - Define variables - 让我们在脚本中添加变量。 这将在下面解释。

<script>
   var data = [10, 5, 12, 15];
   var width = 300,
      scaleFactor = 20,
      barHeight = 30;
</script>

这里,

  • Width - SVG的宽度。

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

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

Step 4 - Append SVG elements - 让我们使用以下代码在D3中添加SVG元素。

var graph = d3.select("body")
   .append("svg")
   .attr("width", width)
   .attr("height", barHeight * data.length);

在这里,我们将首先选择文档正文,创建一个新的SVG元素然后追加它。 我们将在此SVG元素中构建条形图。 然后,设置SVG的宽度和高度。 高度计算为条形高度*数据值的数量。

我们将条形高度设为30,数据数组长度为4.然后SVG高度计算为barheight * datalength,即120 px。

Step 5 - Apply transformation - 让我们使用以下代码在bar中应用转换。

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

这里,每个栏内部对应一个元素。 因此,我们创建组元素。 我们的每个组元素都需要一个位于另一个之下,以构建一个水平条形图。 让我们采用转换公式索引*条高度。

Step 6 - Append rect elements to the bar - 在上一步中,我们附加了组元素。 现在使用以下代码将rect元素添加到栏中。

bar.append("rect")
   .attr("width", function(d) {
      return d * scaleFactor;
   })
   .attr("height", barHeight - 1);

这里,宽度是(数据值*比例因子),高度是(条形高度 - 边距)。

Step 7 - Display data - 这是最后一步。 让我们使用以下代码在每个条上显示数据。

bar.append("text")
   .attr("x", function(d) { return (d*scaleFactor); })
   .attr("y", barHeight/2)
   .attr("dy", ".35em")
   .text(function(d) { return d; });

这里,宽度定义为(数据值*比例因子)。 文本元素不支持填充或边距。 出于这个原因,我们需要给它一个“dy”偏移量。 这用于垂直对齐文本。

Step 8 - Working example - 完整的代码清单显示在以下代码块中。 创建网页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中创建一个圆形图。 要做到这一点,我们必须遵守以下步骤 -

Step 1 - Define variables - 让我们在脚本中添加变量。 它显示在下面的代码块中。

<script>
   var width = 400;
   var height = 400;
   var data = [10, 20, 30];
   var colors = ['green', 'purple', 'yellow'];
</script>

这里,

  • Width - SVG的宽度。

  • Height - SVG的高度。

  • Data - 数据元素数组。

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

Step 2 - Append SVG elements - 让我们使用以下代码在D3中添加SVG元素。

var svg = d3.select("body")
   .append("svg")
   .attr("width", width)
   .attr("height", height);

Step 3 - Apply transformation - 让我们使用以下代码在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用于相对于原点定位元素。

Step 4 - Append circle elements - 现在,使用以下代码将圆形元素附加到组中。

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

Step 5 - Display data - 这是最后一步。 让我们使用以下代码显示每个圆圈上的数据。

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

Step 6 - Working Example - 完整的代码清单显示在以下代码块中。 创建一个网页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()方法。

让我们详细了解这两种方法。

The d3.arc() Method - d3.arc()方法生成一个弧。 您需要为弧设置内半径和外半径。 如果内半径为0,则结果将为饼图,否则结果将为圆环图,将在下一节中讨论。

The d3.pie()Method - d3.pie()方法用于生成饼图。 它从数据集中获取数据并计算饼图的每个楔形的起始角度和结束角度。

让我们使用以下步骤绘制饼图。

Step 1 - Applying styles - 让我们将以下样式应用于arc元素。

.arc text {
   font: 12px arial;
   text-anchor: middle;
}
.arc path {
   stroke: #fff;
}
.title {
   fill: green;
   font-weight: italic;
}

这里,填充用于应用颜色。 文本锚用于将文本定位到弧的中心。

Step 2 - Define variables - 在脚本中定义变量,如下所示。

<script>
   var svg = d3.select("svg"),
      width = svg.attr("width"),
      height = svg.attr("height"),
      radius = Math.min(width, height)/2;
</script>

这里,

  • Width - SVG的宽度。

  • Height - SVG的高度。

  • Radius - 可以使用Math.min(width,height)/ 2的函数计算;

Step 3 - Apply Transformation - 使用以下代码在SVG中应用以下转换。

var g = svg.append("g")
   .attr("transform", "translate(" + width/2 + "," + height/2 + ")");

现在使用d3.scaleOrdinal函数添加颜色,如下所示。

var color = d3.scaleOrdinal(['gray', 'green', 'brown', 'orange']);

Step 4 - Generate a pie chart - 现在,使用下面给出的函数生成饼图。

var pie = d3.pie()
   .value(function(d) { return d.percent; });

在这里,您可以绘制百分比值。 返回d.percent并将其设置为饼值需要匿名函数。

Step 5 - Define arcs for pie wedges - 生成饼图后,现在使用下面给出的函数为每个饼形楔形定义弧形。

var arc = d3.arc()
   .outerRadius(radius)
   .innerRadius(0);

这里,该弧将被设置为路径元素。 计算出的半径设置为outerradius,而innerradius设置为0。

Step 6 - Add labels in wedges - 通过提供半径在饼形楔中添加标签。 它的定义如下。

var label = d3
   .arc()
   .outerRadius(radius)
   .innerRadius(radius - 80);

Step 7 - Read data - 这是重要的一步。 我们可以使用下面给出的函数读取数据。

d3.csv("populations.csv", function(error, data) {
   if (error) {
      throw error;
   }
});

populations.csv包含数据文件。 d3.csv函数从数据集中读取数据。 如果数据不存在,则会引发错误。 我们可以在D3路径中包含此文件。

Step 8 - Load data - 下一步是使用以下代码加载数据。

var arc = g.selectAll(".arc")
   .data(pie(data))
   .enter()
   .append("g")
   .attr("class", "arc");

在这里,我们可以为数据集中的每个数据值的组元素分配数据。

Step 9 - Append path - 现在,追加路径并将一个类'arc'分配给组,如下所示。

arcs.append("path")
   .attr("d", arc)
   .attr("fill", function(d) { return color(d.data.states); });

这里,fill用于应用数据颜色。 它取自d3.scaleOrdinal函数。

Step 10 - Append text - 使用以下代码在标签中显示文本。

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提供数据。

Step 11 - Append group elements - 添加组元素属性并添加类标题以使文本着色并使其变为斜体,这在步骤1中指定并在下面定义。

svg.append("g")
   .attr("transform", "translate(" + (width/2 - 120) + "," + 20 + ")")
   .append("text")
   .text("Top population states in india")
   .attr("class", "title")

Step 12 - Working Example - 要绘制饼图,我们可以获取印度人口的数据集。 此数据集显示虚拟网站中的人口,其定义如下。

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>
饼形图

甜甜圈图表

甜甜圈或甜甜圈图表只是一个内部有洞的简单饼图。 我们可以将孔半径定义为您需要的任何尺寸,包括百分比或像素。 我们可以创建圆环图而不是饼图。 更改弧的内半径以使用大于零的值。 它的定义如下。

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 - Graphs

图表是表示为矩形的二维平面空间。 图形具有坐标空间,其中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");

图示例

让我们考虑一下线图的一个例子。

Line Graph - 折线图用于显示某些东西的价值。 它比较了两个变量。 每个变量沿轴绘制。 折线图具有垂直轴和水平轴。

在这个示例图中,我们可以将csv文件记录作为2006年至2017年的印度国家人口增长。让我们首先创建一个data.csv来显示人口记录。

在D3文件夹中创建一个新的csv文件 -

year,population
2006,40
2008,45
2010,48
2012,51
2014,53
2016,57
2017,62

现在,保存文件并执行以下步骤在D3中绘制折线图。 让我们详细介绍每一步。

Step 1 - Adding styles - 让我们使用下面给出的代码为lineAdding styles

.line {
   fill: none;
   stroke: green;
   stroke-width: 5px;
}

Step 2 - Define variables - SVG属性定义如下。

var margin = {top: 20, right: 20, bottom: 30, left: 50},
   width = 960 - margin.left - margin.right,
   height = 500 - margin.top - margin.bottom;

这里,第一行定义了四个边距,它们围绕图形所在的块。

Step 3 - Define line - 使用d3.line()函数绘制一条新线,如下所示。

var valueline = d3.line()
   .x(function(d) { return x(d.year); })
   .y(function(d) { return y(d.population); });

这里,Year表示X轴记录中的数据,而总体表示Y轴中的数据。

Step 4 - Append SVG attributes - 使用以下代码附加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 + ")");

在这里,我们附加了组元素并应用了转换。

Step 5 - Read data - 现在,我们可以从数据集data.csv读取数据。

d3.csv("data.csv", function(error, data) {
   if (error) throw error;
}

这里,data.csv不存在,它会抛出错误。

Step 6 - Format data - 现在,使用以下代码格式化数据。

data.forEach(function(d) {
   d.year = d.year;
   d.population = +d.population;
});

上面的代码确保从csv文件中提取的所有值都已正确设置和格式化。 每行包含两个值 - 一个值为'year',另一个值为'population'。 该功能一次拉出一行'年'和'人口'的值。

Step 7 - Set scale range - 格式化数据后,您可以设置X和Y的比例范围。

x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);

Step 8 - Append path - 追加路径和数据,如下所示。

svg.append("path").data([data])
   .attr("class", "line").attr("d", valueline);

Step 9 - Add X-axis - 现在,您可以使用下面的代码添加X轴。

svg.append("g")
   .attr("transform", "translate(0," + height + ")")
   .call(d3.axisBottom(x));

Step 10 - Add Y-axis - 我们可以将Y轴添加到组中,如下所示。

svg.append("g")
   .call(d3.axisLeft(y));

Step 11 - Working Example - 完整代码在以下代码块中给出。 创建一个简单的网页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>
         // set the dimensions and margins of the graph
         var margin = {top: 20, right: 20, bottom: 30, left: 50},
         width = 960 - margin.left - margin.right,
         height = 500 - margin.top - margin.bottom;
         // set the ranges
         var x = d3.scaleTime().range([0, width]);
         var y = d3.scaleLinear().range([height, 0]);
         // define the line
         var valueline = d3.line()
            .x(function(d) { return x(d.year); })
            .y(function(d) { return y(d.population); });
         // append the svg obgect to the body of the page
         // appends a 'group' element to 'svg'
         // moves the 'group' element to the top left margin
         var svg = d3.select("body").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g").attr("transform",
               "translate(" + margin.left + "," + margin.top + ")");
         // Get the data
         d3.csv("data.csv", function(error, data) {
            if (error) throw error;
            // format the data
            data.forEach(function(d) {
               d.year = d.year;
               d.population = +d.population;
            });
            // Scale the range of the data
            x.domain(d3.extent(data, function(d) { return d.year; }));
            y.domain([0, d3.max(data, function(d) { return d.population; })]);
            // Add the valueline path.
            svg.append("path")
               .data([data])
               .attr("class", "line")
               .attr("d", valueline);
            // Add the X Axis
            svg.append("g")
               .attr("transform", "translate(0," + height + ")")
               .call(d3.axisBottom(x));
            // Add the Y Axis
            svg.append("g")
               .call(d3.axisLeft(y));
         });
      </script>
   </body>
</html>

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

图形

D3.js - Geographies

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

  • Paths - 它们产生最终像素。

  • Projections - 它们将球体坐标转换为笛卡尔坐标和

  • Streams - 他们加快了速度。

在了解D3.js中的地理位置之前,我们应该了解以下两个术语 -

  • D3地理路径和
  • Projections

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

D3地理路径

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

d3.geo.path()

这里, d3.geo.path()路径生成器函数允许我们选择我们想要用于从地理坐标到笛卡尔坐标的平移的地图投影。

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

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

预测(Projections)

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

  • Azimuthal - Azimuthal投影将球体直接投射到平面上。

  • Composite - Composite由多个投影组成,这些投影组成一个显示。

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

  • Cylindrical - 圆柱形投影将球体投射到容纳圆柱体上,然后将圆柱体展开到平面上。

要创建新投影,可以使用以下功能。

d3.geoProjection(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() - gnomonic投影是一个方位投影,将大圆投影为直线。

  • d3.geo.equirectangular() - d3.geo.equirectangular()是最简单的地理投影。 身份功能。 它既不是等面积也不是保形,但有时用于栅格数据。

  • d3.geo.mercator() - 球形墨卡托投影通常由平铺映射库使用。

  • d3.geo.transverseMercator() - 横向墨卡托投影。

工作示例 (Working Example)

让我们在这个例子中创建印度地图。 为此,我们应该遵循以下步骤。

Step 1 - Apply styles - 让我们使用下面的代码在地图中添加样式。

<style>
   path {
      stroke: white;
      stroke-width: 0.5px;
      fill: grey;
   }
   .stateTN { fill: red; }
   .stateAP { fill: blue; }
   .stateMP{ fill: green; }
</style>

在这里,我们为状态TN,AP和MP应用了特定的颜色。

Step 2 - Include topojson script - TopoJSON是GeoJSON的扩展,它对拓扑进行编码,如下所述。

<script src = "http://d3js.org/topojson.v0.min.js"></script>

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

Step 3 - Define variables - 使用下面的代码在脚本中添加变量。

var width = 600;
var height = 400;
var projection = d3.geo.mercator()
   .center([78, 22])
   .scale(680)
   .translate([width/2, height/2]);

这里,SVG宽度为600,高度为400.屏幕是一个二维空间,我们试图呈现一个三维物体。 因此,我们可以使用d3.geo.mercator()函数严重扭曲土地大小/形状。

中心被指定为[78,22],这将投影的中心设置为指定位置,作为经度和纬度的双元素数组,并返回投影。

在这里,地图集中在西经78度和北纬22度。

比例指定为680,这将投影的比例因子设置为指定值。 如果未指定比例,则返回当前比例因子,默认为150.重要的是要注意比例因子在投影之间不一致。

Step 4 - Append SVG - 现在,附加SVG属性。

var svg = d3.select("body").append("svg")
   .attr("width", width)
   .attr("height", height);

Step 5 - Create path - 以下代码部分创建了一个新的地理路径生成器。

var path = d3.geo.path()
   .projection(projection);

这里,路径生成器(d3.geo.path())用于指定投影类型(.projection),之前使用变量投影定义为墨卡托投影。

Step 6 - Generate data - indiatopo.json - 此文件包含许多记录,我们可以从以下附件轻松下载。

下载indiatopo.json file

下载文件后,我们可以添加我们的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]]], ......
........................................

Step 7 - Draw map - 现在,从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)
});

在这里,我们将使用印度地图(indiatopo.json)的坐标加载TopoJSON文件。 然后我们声明我们将对图形中的所有路径元素进行操作。 它被定义为,g.selectAll(“path”)。 然后,我们将从TopoJSON文件中提取定义国家/地区的数据。

.data(topojson.object(topology, topology.objects.states)
   .geometries)

最后,我们将使用.enter()方法将它添加到我们要显示的数据中,然后使用.append(“path”)方法将该数据作为路径元素追加。

D3.js - Array API

D3包含一组模块。 您可以单独使用每个模块,也可以将模块集合一起使用以执行操作。 本章详细介绍了Array API。

什么是数组?

Array包含相同类型的固定大小的顺序元素集合。 数组用于存储数据集合,但将数组视为相同类型的变量集合通常更有用。

配置API (Configuring 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)

它使用自然顺序返回给定数组中的最小值。

Example - 请考虑以下脚本。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.min(data));
</script>

Result - 上面的脚本返回控制台中数组20中的minmum值。

d3.max(array)

它返回给定数组中的最大值。

Example - 请考虑以下脚本。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.max(data));
</script>

Result - 上面的脚本返回控制台中数组(100)中的最大值。

d3.extent(array)

它返回给定数组中的最小值和最大值。

Example - 请考虑以下脚本。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.max(data));
</script>

Result - 上面的脚本返回一个范围值[20,100]。

d3.sum(array)

它返回给定数组的总和。 如果数组为空,则返回0。

Example - 请考虑以下内容。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.sum(data));
</script>

Result - 上面的脚本返回的总和值为300。

d3.mean(array)

它返回给定数组的平均值。

Example - 请考虑以下内容。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.mean(data));
</script>

Result - 上面的脚本将平均值返回为60.同样,您可以检查中值。

d3.quantile(array)

它返回给定排序数字数组的p分位数,其中p是范围[0,1]中的数字。 例如,中值可以使用p = 0.5计算,第一个四分位数在p = 0.25,第三个四分位数在p = 0.75。 此实现使用R-7方法,默认R编程语言和Excel。

Example - 请考虑以下示例。

var data = [20, 40, 60, 80, 100];
d3.quantile(data, 0); // output is 20
d3.quantile(data, 0.5); // output is 60
d3.quantile(data, 1); // output is 100

同样,您可以检查其他值。

d3.variance(array)

它返回给定数组数组的方差。

Example - 请考虑以下脚本。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.variance(data));
</script>

Result - 上面的脚本将方差值返回为1000。

d3.deviation(array)

它返回给定数组的标准偏差。 如果数组的值少于两个,则返回undefined。

Example - 请考虑以下内容。

<script>
   var data = [20,40,60,80,100];
   console.log(d3.deviation(data));
</script>

Result - 上述脚本将偏差值返回为31.622776601683793。

Example - 让我们使用以下脚本执行上面讨论的所有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>

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

排列

数组搜索API方法

以下是一些重要的Array搜索API方法。

  • d3.scan(array)
  • d3.ascending(a, b)

让我们详细了解这两个方面。

d3.scan(array)

此方法用于执行指定数组的线性扫描。 它将最小元素的索引返回给指定的比较器。 下面定义一个简单的例子。

Example -

var array = [{one: 1}, {one: 10}];
console.log(d3.scan(array, function(a, b) { return a.one - b.one; })); // output is 0
console.log(d3.scan(array, function(a, b) { return b.one - a.one; })); // output is 1

d3.ascending(a, b)

该方法用于执行比较器功能。 它可以实现为 -

function ascending(a, b) {
   return a < b ? -1 : a > b ? 1 : a > =  b ? 0 : NaN;
}

如果没有为内置排序方法指定比较器功能,则默认顺序是按字母顺序排列的。 如果a小于b,则上述函数返回-1;如果a大于b或0,则返回1。

同样,您可以执行降序(a,b)方法。 如果a大于b,则返回-1;如果a小于b,则返回1,或返回0.此函数执行反向自然顺序。

Example -

创建一个网页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"]); // output is [[10, "a"], [10, "b"], [20, "a"], [20, "b"]]

d3.merge(arrays)

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

d3.merge([[10], [20]]); // output is [10, 20]

d3.pairs(array[, reducer])

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

d3.pairs([10, 20, 30, 40]); // output is [[10, 20], [20, 30], [30, 40]]

d3.permute(array, indexes)

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

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

d3.zip(arrays)

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

d3.zip([10, 20], [30, 40]); // output is [[10, 30], [20, 40]]

Example - 创建网页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>

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

数组变换

D3.js - Collections API

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

配置API (Configuring API)

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

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

集合API方法

Collections API包含对象,地图,集合和嵌套。 以下是最常用的集合API方法。

  • 对象API
  • Maps API
  • 设置API
  • 嵌套API

让我们详细介绍这些API。

对象API

Object API是重要的数据类型之一。 它支持以下方法 -

  • d3.keys(object) - 此方法包含对象属性键,并返回属性名称的数组。

  • d3.values(object) - 此方法包含对象值并返回属性值数组。

  • d3.entries(object) - 此方法用于返回包含指定对象的键和值的数组。 每个条目都是一个具有键和值的对象。

Example - 让我们考虑以下代码。

d3.entries({one: 1})

这里,键是1,值是1。

Example - 创建网页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>

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

集合API

Maps API

地图包含基于键和值对的值。 每个键和值对称为条目。 地图仅包含唯一键。 根据密钥搜索,更新或删除元素非常有用。 我们将详细介绍各种Maps API方法。

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

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

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

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

  • map.remove(key) - 用于删除映射条目。 如果未指定密钥,则返回false。

  • map.clear() - 删除此地图中的所有条目。

  • map.keys() - 返回此映射中每个条目的字符串键数组。

  • map.values() - 返回此映射中每个条目的值数组。

  • map.entries() - 返回此映射中每个条目的键值对象数组。

  • (x) map.each(function) - 此方法用于为地图中的每个条目调用指定的函数。

  • (xi) map.empty() - 当且仅当此映射具有零条目时返回true。

  • (xii) map.size() - 返回此映射中的条目数。

Example - 创建网页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

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

设置API

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

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

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

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

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

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

  • set.values() - 此方法用于将值数组返回到集合。

  • set.empty() - 当且仅当此set具有零值时返回true。

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

Example - 创建网页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>

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

设置API

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

嵌套API

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

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

  • nest.key(key) - 此方法用于初始化新的键功能。 此函数用于调用输入数组中的每个元素并返回组中的元素。

  • nest.sortKeys(comparator) - 此方法用于对指定比较器中的键进行排序。 函数定义为d3.ascending或d3.descending。

  • nest.sortValues(comparator) - 此方法用于对指定比较器中的值进行排序。 比较器函数对叶元素进行排序。

  • nest.map(array) - 此方法用于应用指定的数组并返回嵌套的映射。 返回的映射中的每个条目对应于第一个键函数返回的不同键值。 输入值取决于已注册的键功能的数量。

  • nest.object(array) - 此方法用于将嵌套操作符应用于指定的数组并返回嵌套对象。

  • nest.entries(array) - 此方法用于将nest运算符应用于指定的数组并返回键值条目数组。

考虑一个简单的网页nest.html来执行上面讨论的嵌套方法。

Example - 让我们考虑以下示例。

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

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

Example - 让我们考虑以下示例。

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

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

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

d3.selectAll(selector)

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

Example - 让我们考虑以下示例。

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

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

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

selection.selectAll(selector)

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

Example - 让我们考虑以下示例。

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

selection.filter(filter)

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

Example - 让我们考虑以下示例。

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

这里,过滤选择的表行只返回奇数。

selection.merge(other)

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

Example - 让我们考虑以下示例。

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

d3.matcher(selector)

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

Example - 让我们考虑以下示例。

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

d3.creator(name)

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

Example - 让我们考虑以下示例。

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

selection.each(function)

此方法用于为当前数据(d),当前索引(i)和当前组(节点)传递的顺序调用每个选定元素的指定函数,并将其作为当前DOM元素(节点[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允许您定义独立于数据的本地状态。

Example - 让我们考虑以下示例。

var data = d3.local();

与var不同,每个局部的值也由DOM限定。

local.set(node, value)

此方法将指定节点上此local的值设置为该值。

Example - 让我们考虑以下示例。

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

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

local.remove(node)

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

D3.js - Paths API

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

配置路径

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

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

路径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[, anticlockwise]) - 此方法用于将圆弧绘制到指定的中心(x,y),radius,startAngle和endAngle。 如果逆时针值为真,则沿逆时针方向绘制圆弧,否则沿顺时针方向绘制圆弧。

  • 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的路径数据规范返回此路径的字符串表示形式。

例子 (Example)

让我们使用路径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 - Scales API

D3.js提供缩放功能来执行数据转换。 这些函数将输入域映射到输出范围。

配置API (Configuring 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>

缩放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() - 构造一个序数比例,其中输入数据包含字母并映射到离散数字输出范围。

在做一个工作示例之前,让我们先了解以下两个术语 -

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

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

工作示例 (Working Example)

让我们在这个例子中执行d3.scaleLinear函数。 为此,您需要遵循以下步骤 -

Step 1 - Define variables - 使用下面的编码定义SVG变量和数据。

var data = [100, 200, 300, 400, 800, 0]
   var width = 500, 
      barHeight = 20, 
      margin = 1;

Step 2 - Create linear scale - 使用以下代码创建线性比例。

var scale = d3.scaleLinear()
   .domain([d3.min(data), d3.max(data)])
   .range([100, 400]);

这里,对于手动域的最小值和最大值,我们可以使用内置的d3.min()d3.max()函数,它们将分别从我们的数据数组返回最小值和最大值。

Step 3 - Append SVG attributes - 使用下面给出的代码附加SVG元素。

var svg = d3.select("body")
   .append("svg")
   .attr("width", width)
   .attr("height", barHeight * data.length);

Step 4 - Apply transformation - 使用以下代码应用转换。

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

Step 5 - Append rect elements - Append rect elements追加到缩放,如下所示。

g.append("rect")
   .attr("width", function (d) {
      return scale(d);
   })
   .attr("height", barHeight - margin)

Step 6 - Display data - 现在使用下面给出的编码显示数据。

g.append("text")
   .attr("x", function (d) { return (scale(d)); })
   .attr("y", barHeight/2)
   .attr("dy", ".35em")
   .text(function (d) { return d; });

Step 7 - Working Example - 现在,让我们使用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 - Axis API

D3提供绘制轴的功能。 轴由线,刻度线和标签组成。 轴使用“缩放”,因此需要为每个轴指定一个缩放比例。

配置Axis API

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

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

Axis API方法

D3提供以下绘制轴的重要功能。 它们简要描述如下。

  • d3.axisTop() - 此方法用于创建顶部水平轴。

  • d3.axisRight() - 此方法用于创建垂直的右向轴。

  • d3.axisBottom() - 此方法用于创建底部水平轴。

  • d3.axisLeft() - 它创建左垂直轴。

工作示例 (Working Example)

让我们学习如何将x和y轴添加到图形中。 为此,我们需要遵循以下步骤。

Step 1 - Define variables - 使用以下代码定义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);

Step 2 - Create a scale linear function - 为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]);

在这里,我们创建了一个线性比例并指定了域和范围。

Step 3 - Add scales to x-axis - 现在,我们可以使用以下代码将比例添加到x轴。

var x_axis = d3.axisBottom()
   .scale(xscale);

在这里,我们使用d3.axisBottom创建我们的x轴并为其提供之前定义的比例。

Step 4 - Add scales to the y-axis - 使用以下代码将比例添加到y轴。

var y_axis = d3.axisLeft()
   .scale(yscale);

在这里,我们使用d3.axisLeft创建我们的y轴并为其提供我们在上面定义的比例。

Step 5 - Apply transformation - 您可以追加组元素并插入x,y轴,这将在下面定义。

svg.append("g")
   .attr("transform", "translate(50, 10)")
   .call(y_axis);

Step 6 - Append group elements - 使用以下代码应用转换和组元素。

var xAxisTranslate = height/2 + 10;
svg.append("g")
   .attr("transform", "translate(50, " + xAxisTranslate  +")")
   .call(x_axis)

Step 7 - Working Example - 完整的代码清单在以下代码块中给出。 创建一个网页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 (Configuring 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支持不同的形状。 让我们详细介绍一下突出的形状。

Arcs API

电弧发生器产生圆形或环形。 我们在前面的饼图章节中使用了这些API方法。 让我们详细了解各种Arcs API方法。

  • d3.arc() - 此方法用于创建新的弧生成器。

  • arc(args) - 用于生成具有指定给定参数的弧。 具有对象半径和角度的默认设置定义如下。

<script>
   var arc = d3.arc();
   arc({
      innerRadius: 0,
      outerRadius: 100,
      startAngle: 0,
      endAngle: Math.PI/2
   });
</script>
  • arc.centroid(args) - 此方法用于计算具有指定参数的弧的中心线的中点[x,y]。

  • arc.innerRadius([radius]) - 此方法用于设置给定半径的内半径并返回一个弧生成器。 它定义如下 -

function innerRadius(d) {
   return d.innerRadius;
}
  • arc.outerRadius([radius]) - 此方法用于设置给定半径的外半径并返回一个弧生成器。 它的定义如下。

function outerRadius(d) {
   return d.outerRadius;
}
  • arc.cornerRadius([radius]) - 此方法用于设置给定半径的圆角半径并返回圆弧生成器。 它的定义如下。

function cornerRadius() {
   return 0;
}

如果拐角半径大于零,则使用给定半径的圆将圆弧的拐角倒圆。 角半径可能不大于(outerRadius - innerRadius)/ 2。

  • arc.startAngle([angle]) - 此方法用于从给定角度设置函数的起始角度。 它的定义如下 -

function startAngle(d) {
   return d.startAngle;
}
  • arc.endAngle([angle]) - 此方法用于从给定角度设置函数的结束角度。 它的定义如下。

function endAngle(d) {
   return d.endAngle;
}
  • arc.padAngle([angle]) - 此方法用于从给定角度设置垫片角度到函数。 它的定义如下。

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

  • (xi) arc.context([context]) - 该方法用于设置上下文并返回一个弧生成器。

馅饼API

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

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

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

    • data - 输入数据; 输入数据数组中的相应元素。

    • value - 弧的数值。

    • index - 弧的索引。

    • startAngle - 弧的起始角度。

    • endAngle - 弧的结束角度。

    • padAngle - 弧的垫角。

  • pie.value([value]) - 此方法用于将值设置为指定的函数并生成饼图。 它的定义如下 -

function value(d) {
   return d;
}
  • pie.sort([compare]) - 此方法用于将数据排序到指定的函数并生成饼图。 比较器功能定义如下。

pie.sort(function(a, b) 
   { return a.name.localeCompare(b.name); }
);

这里,compare函数接受两个参数'a'和'b',每个元素来自输入数据数组。 如果'a'的弧应该在'b'的弧之前,那么比较器必须返回一个小于零的数字。 如果'a'的弧应该在'b'的弧之后,那么比较器必须返回一个大于零的数字。

  • pie.sortValues([compare]) - 此方法用于比较给定函数的值并生成饼图。 该功能定义如下。

function compare(a, b) {
   return b - a;
}
  • pie.startAngle([angle]) - 此方法用于将饼图的起始角度设置为指定的函数。 如果未指定角度,则返回当前的起始角度。 它的定义如下。

function startAngle() {
   return 0;
}
  • pie.endAngle([angle]) - 此方法用于将饼图的结束角度设置为指定的函数。 如果未指定角度,则返回当前结束角度。 它的定义如下。

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

function padAngle() {
   return 0;
}

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]) - 此方法用于将已定义的访问者设置为指定的函数。 它的定义如下。

function defined() {
  return true;
}
  • line.curve([curve]) - 用于设置曲线并生成线。

  • line.context([context]) - 此方法用于设置上下文并生成一行。 如果未指定上下文,则返回null。

  • d3.lineRadial() - 此方法用于创建新的径向线; 它相当于笛卡尔线生成器。

  • lineRadial.radius([radius]) - 此方法用于绘制径向线,访问器返回半径。 它需要距离原点(0,0)的距离。

在下一章中,我们将了解D3.js中的Colors API。

D3.js - Colors API

颜色以RED,GREEN和BLUE组合显示。 颜色可以通过以下不同方式指定 -

  • 按颜色名称
  • 作为RGB值
  • 作为十六进制值
  • 作为HSL值
  • 作为HWB值

d3-color API提供各种颜色的表示。 您可以在API中执行转换和操作操作。 让我们详细了解这些操作。

配置API (Configuring API)

您可以使用以下脚本直接加载API。

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

基本操作 (Basic Operations)

让我们来看看D3中的基本颜色操作。

Convert color value to HSL - 要将颜色值转换为HSL,请使用以下Example -

var convert = d3.hsl("green");

您可以将色调旋转45°,如下所示。

convert.h + =  45;

同样,您也可以更改饱和度。 要淡化颜色值,可以更改不透明度值,如下所示。

convert.opacity = 0.5;

颜色API方法

以下是一些最重要的Color 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颜色。 如果未给出说明符,则返回null。

Example - 让我们考虑以下示例。

<script>
   var color = d3.color("green");  // asign color name directly
   console.log(color);
</script>

我们将在屏幕上看到以下回复 -

{r: 0, g: 128, b: 0, opacity: 1}

color.opacity

如果我们想淡化颜色,我们可以改变不透明度值。 它在[0,1]的范围内。

Example - 让我们考虑以下示例。

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

工作示例 (Working Example)

让我们创建一个新的网页 - 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 (Configuring 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>

过渡API方法

让我们详细介绍Transition API方法。

选择元素

让我们详细讨论各种选择元素。

  • selection.transition([name]) - 此方法用于返回具有名称的新选择转换。 如果未指定名称,则返回null。

  • selection.interrupt([name]) - 此方法用于使用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() - 此方法用于返回所选元素的新转换。 它计划在转换停止时开始。 新转换继承了此转换的名称,持续时间和缓动。

Example - 让我们考虑以下示例。

d3.selectAll(".body")
   .transition() 
   // fade to yellow.
   .style("fill", "yellow")
   .transition() 
   // Wait for five second. Then change blue, and remove.
   .delay(5000)
   .style("fill", "blue")
   .remove();

在这里,身体渐渐变黄并在最后一次过渡前五秒开始。

  • d3.active(node[, name]) - 此方法用于返回指定节点上具有名称的转换。

时间方法

让我们详细介绍一下转换时序API方法。

  • transition.delay([value]) - 此方法用于将转换延迟设置为指定值。 如果为每个选定元素计算函数,则将其传递给当前数据“d”并索引“i”,并将上下文作为当前DOM元素。 如果未指定值,则返回转换中第一个(非null)元素的延迟的当前值。 它定义如下,

transition.delay(function(d, i) { return i * 10; });
  • transition.duration([value]) - 此方法用于将转换持续时间设置为指定值。 如果未指定值,则返回转换中第一个(非null)元素的持续时间的当前值。

  • transition.ease([value]) - 此方法用于简化所选元素的转换值。 为动画的每个帧调用缓动函数,并在[0,1]范围内传递标准化时间't'。 如果未指定值,则返回转换中第一个(非null)元素的当前缓动函数。

在下一章中,我们将讨论d3.js中的拖放概念。

D3.js - Dragging API

拖放是d3.js中最熟悉的概念之一。 本章详细介绍了拖动及其方法。

安装 (Installation)

我们可以使用以下脚本直接包含拖动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事件的最大距离。 如果未指定距离,则指向零。

drag.on(typenames, [listener])

此方法用于为指定的类型名称设置事件侦听器以进行拖动。 类型名是一个包含一个或多个由空格分隔的类型名的字符串。 每个typename都是一个类型,可选地后跟句点(。)和名称,例如drag.one和drag.two。 此类型应来自以下之一 -

  • start - 启动一个新指针。

  • drag - 拖动活动指针。

  • end - 非活动指针。

d3.dragDisable(window)

此方法用于禁用拖放选择。 它可以防止mousedown事件操作。 默认情况下,大多数选定的浏览器都支持此操作。 如果不支持,则可以将CSS属性设置为none。

d3.dragEnable(window[, noclick])

此方法用于在指定的窗口位置上启用拖放选择。 它用于调用mouseup事件操作。 如果指定noclick值为true,则click事件将超过零毫秒超时。

拖动API - 拖动事件

D3.event方法用于设置拖动事件。 它包括以下字段 -

  • Target - 它表示拖动行为。

  • Type - 它是一个字符串,可以是以下任何一个 - “开始”,“拖动”或“结束”。

  • Subject - 拖动主题,由drag.subject定义。

event.on(typenames, [listener])

事件对象公开event.on方法以执行拖动。 它的定义如下。

d3.event.on("drag", dragged).on("end", ended);

D3.js - Zooming API

缩放有助于扩展您的内容。 您可以使用单击并拖动方法专注于特定区域。 在本章中,我们将详细讨论Zooming API。

配置API (Configuring API)

您可以使用以下脚本直接从“d3js.org”加载Zooming 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方法

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

让我们简要介绍所有这些Zooming 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转换值指定为数字或返回数字的函数。 如果为所选元素调用了一个函数,那么它将通过DOM的当前数据“d”和索引“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缩放所选元素的当前zoon变换。 这里, k是比例因子,指定为数字或返回数字的函数。

zoom.scaleBy = function(selection, k) {
   zoom.scaleTo(selection, function() {
      var k0 = this.__zoom.k,
      k1 = k = = = "function" ? k.apply(this, arguments) : k;
      return k0 * k1;
   });
};

zoom.filter([filter])

它用于将过滤器设置为指定的缩放行为功能。 如果未指定过滤器,则返回当前过滤器,如下所示。

function filter() {
   return !d3.event.button;
}

zoom.wheelDelta([delta])

Δ值由轮三角函数返回。 如果未指定delta,则返回当前车轮增量功能。

zoom.extent([extent])

它用于将范围设置为指定的数组点。 如果未指定范围,则返回当前范围访问器,默认为[[0,0],[width,height]],其中width是元素的客户端宽度,height是其客户端高度。

zoom.scaleExtent([extent])

它用于将比例范围设置为指定的数字数组[k0,k1]。 这里, k0是允许的最小比例因子。 而k1是允许的最大比例因子。 如果未指定extent,则返回当前缩放范围,默认为[0,∞]。 考虑下面定义的示例代码。

selection
   .call(zoom)
   .on("wheel", function() { d3.event.preventDefault(); });

当已经处于比例范围的相应极限时,用户可以尝试通过转动进行缩放。 如果我们想要阻止滚轮输入而不管刻度范围,请注册滚轮事件侦听器以防止浏览器默认行为。

zoom.translateExtent([extent])

如果指定了范围,则将translate范围设置为指定的点数组。 如果未指定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])

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

  • Start - 缩放开始后(例如在mousedown上)。

  • Zoom - 更改缩放变换后(例如在mousemove上)。

  • End - 缩放结束后(例如鼠标上)。

在下一章中,我们将讨论D3.js中的不同请求API。

D3.js - Requests 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文件。

工作示例 (Working Example)

让我们通过一个简单的示例来了解如何加载和解析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>

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

请求API

请求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);

这里,X-Requested-With标头到XMLHttpRequest是一个默认请求。

request.mimeType([type])

它用于将mime类型分配给给定值。 它定义如下。

d3.request(url)
   .mimeType("text/csv")
   .get(callback);

request.user([value])

它用于分配用于身份验证的用户名。 如果未指定用户名,则默认为null。

request.password([value])

如果指定了值,则会设置身份验证的密码。

request.timeout([timeout])

如果指定超时,则将超时设置为指定的毫秒数。

request.get([data])

此方法用于使用GET方法发送请求。 它定义如下。

request.send("GET", data, callback);

request.post([data])

此方法用于使用POST方法发送请求。 它定义如下。

request.send("POST", data, callback);

request.send(method[, data])

此方法用于使用给定的GET或POST方法发送请求。

request.abort()

此方法用于中止请求。

d3.csv(url[[, row], callback])

使用默认的Mime类型text/csv返回指定URL处的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);

例子 (Example)

在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 - Delimiter-Separated Values API

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

配置API (Configuring 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

现在,我们可以应用上面给出的功能。

Example - 让我们考虑以下示例。

var data = d3.csvParse(string, function(d) {
   return {
      year: new Date(+d.Year, 0, 1), // lowercase and convert "Year" to Date
      population: d.population
   };
});

在这里,它在分隔符分隔值中解析指定的字符串。 它返回一个表示已解析行的对象数组。

d3.csvParseRows(string[, row])

此方法用于解析与行等效的csv格式。

var data = d3.csvParseRows(string, function(d, i) {
   return {
      year: new Date(+d[0], 0, 1), // convert first colum column to Date
      population: d[1],
   };
});

它解析csv文件中的每一行。

d3.csvFormat(rows[, columns])

此方法用于格式化csv行和列。

Example - 让我们考虑以下示例。

var string = d3.csvFormat(data, ["year", "population"]);

这里,如果未指定列,则构成标题行的列名列表由行中所有对象的所有属性的并集确定。 如果指定了列,则它是表示列名称的字符串数组。

d3.csvFormatRows(rows)

此方法用于格式化csv行。

Example - 让我们考虑以下示例。

var string = d3.csvFormatRows(data.map(function(d, i) {
   return [
      d.year.getFullYear(), // Assuming d.year is a Date object.
      d.population
   ];
}));

在这里,它将指定的字符串行数组格式化为分隔符分隔值,返回一个字符串。

d3.tsvParse(string[, row])

此方法用于解析tsv格式。 它类似于csvParse。

d3.tsvParseRows(string[, row])

此方法用于解析等效于行的tsv格式。 它类似于csvParseRows函数。

d3.tsvFormat(rows[, columns])

此方法用于格式化tsv行和列。

d3.tsvFormatRows(rows)

此方法用于格式化tsv行。

D3.js - 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>

计时器API方法

Timer API支持以下重要方法。 所有这些都详细解释如下。

d3.now()

此方法返回当前时间。

d3.timer(callback[, delay[, time]])

此方法用于计划新计时器并调用计时器直到停止。 您可以在MS中设置数字延迟,但它是可选的,否则默认为零。 如果未指定时间,则将其视为d3.now()。

timer.restart(callback[, delay[, time]])

使用指定的回调和可选的延迟和时间重新启动计时器。

timer.stop()

此方法会停止计时器,从而阻止后续回调。

d3.timeout(callback[, delay[, time]])

它用于在第一次回调时停止计时器。 回调作为经过的时间传递。

d3.interval(callback[, delay[, time]])

它在特定的时间延迟间隔上调用。 如果未指定延迟,则需要计时器时间。

例子 (Example)

创建一个网页“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>

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

定时器API

D3.js - Working Example

让我们在本章中执行动画条形图。 对于此示例,我们将人口记录的前一章中使用的data.csv文件作为数据集并生成动画条形图。

为此,我们需要执行以下步骤 -

Step 1 - Apply styles - 使用下面给出的编码应用CSS样式。

<style>
   .bar {
      fill: green;
   }
   .highlight {
      fill: red;
   }
   .title {
      fill: blue;
      font-weight: bold;
   }
</style>

Step 2 - Define variables - 让我们使用下面的脚本定义SVG属性。

<script>
   var svg = d3.select("svg"), margin = 200,
   width = svg.attr("width") - margin,
   height = svg.attr("height") - margin;
</script>

Step 3 - Append text - 现在,附加文本并使用下面的编码应用转换。

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

Step 4 - Create scale range - 在此步骤中,我们可以创建比例范围并附加组元素。 它定义如下。

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 + ")");

Step 5 - Read data - 我们已在前面的示例中创建了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;
   }

Step 6 - Set domain - 现在,使用下面的编码设置域。

x.domain(data.map(function(d) { return d.year; }));
y.domain([0, d3.max(data, function(d) { return d.population; })]);

Step 7 - Add X-axis - 现在,您可以将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");

Step 8 - Add Y-axis - 使用下面给出的代码Add Y-axis添加到变换中。

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

Step 9 - Append group elements - 现在,追加组元素并将变换应用于Y轴,如下所述。

g.append("g")
   .attr("transform", "translate(0, 0)")
   .call(d3.axisLeft(y))

Step 10 - Select the bar class - 现在,选择Select the bar class所有元素,如下所述。

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添加了listener事件以执行动画。 当鼠标悬停在特定条上并离开时,它会应用动画。 这些功能将在以下步骤中说明。

.ease(d3.easeLinear)函数用于在动画中执行明显的运动。 它以200的持续时间处理慢进和慢进运动。可以使用以下方法计算延迟:

.delay(function (d, i) {
   return i * 25;
})

Step 11 - Mouseover event handler function - 让我们创建一个鼠标悬停事件处理程序来处理鼠标事件,如下所示。

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事件中,我们希望将条形宽度和高度以及所选条形的条形颜色增加为红色。 对于颜色,我们添加了一个“突出显示”类,它将所选条形的颜色更改为红色。

到条的转换函数持续200毫秒。 当我们将条的宽度增加5px,高度增加10px时,从条的前一个宽度和高度到新的宽度和高度的过渡将持续200毫秒。

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

Step 12 - Mouseout event handler function - 让我们创建一个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()函数用于删除在条形选择期间添加的文本值。

Step 13 - Working Example - 完整程序在以下代码块中给出。 创建一个网页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是一个通用的可视化库,用于处理数据到信息,文档,元素等的转换,最终有助于创建数据可视化。

↑回到顶部↑
WIKI教程 @2018