数据可视化之_D3.js简介_svg_d3.selection API

前言

什么是数据可视化

将结果数据的每一个数据项,作为单个图元元素展示,大量的数据集构成数据图像,同时将数据的各个属性以多维度的方式展现,从而提高数据的可读性。

数据可视化的优点

  • 图形化展示比文字的描述能力更强。
  • 降低大数据据阅读门槛。
  • 清晰有效地传达与沟通信息。

具体做法:是指将大型数据集中的数据以图形图像形式表示。基于几何的技术、面向像素技术、基于图标的技术、基于层次的技术、基于图像的技术和分布式技术等等。

数据处理流程

  1. 数据收集:将已经存在的数据管理起来( 收集、采集 );
  2. 数据清洗 ETL (extract transform load 数据仓库技术):将脏数据,指那些没有意义、没有用的数据清洗掉;
  3. 数据计算:进行多维度计算,统计分析(分组、极值、多维度展示), 结果预测(spark)、python机器学习(分类/聚类算法);
  4. 数据可视化:通过一些插件库,将数据以图表的形式进行展示,目前常用的插件库有以下:
    • echarts:(百度开源项目,国内应用领域十分广泛,apache孵化器,各大领域,入门比较容易、主要是修改配置)
    • highCharts: (学习可以,商用需要授权,09年发布,使用纯js编写的图表库)
    • d3:D3 的全称是(Data-Driven Documents),一个被数据驱动的文档。听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,主要是用来做数据可视化,将强大的可视化组件应用于需求中。

接下来我们来认识一下D3.js

1. D3.js 简介

D3.js是一个JavaScript库,用于根据数据处理文档。D3可通过使用HTML,SVG和CSS使数据栩栩如生。D3遵循 Web标准,它可以提供了现代浏览器的全部功能,而又不会使自己陷入专有框架,而是结合了强大的可视化组件和数据驱动的DOM操作方法。

使用D3可以将任意数据绑定到文档对象模型(DOM)上,然后将数据驱动的转换应用于文档。例如,可以使用D3从数字数组生成HTML表。或者,使用相同的数据创建具有平滑过渡和交互作用的交互式SVG条形图。

2. 安装

如果使用npm,可以通过npm install d3 来安装,此外还可以下载最新版,最新版支持 AMD、CommonJS 以及基础标签引入形式。 你也可以直接从 d3js.org, CDNJS, 或者 unpkg 加载. 比如:

<script src="https://d3js.org/d3.v5.js"></script>

压缩版:

<script src="https://d3js.org/d3.v5.min.js"></script>

你也可以单独使用 d3 中的某个模块, 比如单独使用 d3-selection

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

D3基于 ES2015 modules 开发。 可以使用 Rollup, webpack 或者其他你偏爱的打包工具进行构建。 在一个符合 ES2015 的应用中导入 d3 或者 d3 的某些模块:

import { scaleLinear } from "d3-scale";

或者导入 d3 的全部功能并且设置命名空间 (这里是 d3):

import * as d3 from "d3";

在 Nodejs 环境中:

var d3 = require("d3");

你也可以导入多个模块然后将这些模块集合到 d3 对象中, 此时使用 Object.assign:

var d3 = Object.assign({}, require("d3-format"), require("d3-geo"), require("d3-geo-projection"));

在 Node 环境中使用 DOM 的时候,必须要提供自己的 DOM 实现。推荐使用 JSDOM,为了避免定义全局 document,建议将 DOM 传递给 d3.select 或者将 NodeList 传递给 d3.selectAll,如下:

var d3 = require("d3"),
    jsdom = require("jsdom");

var document = jsdom.jsdom(),
    svg = d3.select(document.body).append("svg");

3. D3-选择集

在 D3 中,用于选择元素的函数有两个,这两个函数返回的结果称为选择集。

  • d3.select():选择所有指定元素的第一个;
  • d3.selectAll():选择指定的全部元素;

一般情况下,返回当前选择集的选择方法使用四个缩进空间,而返回新选择集的方法仅使用两个缩进空间。通过使上下文脱离链,这有助于揭示上下文的变化:

d3.select("body")
  .append("svg")
    .attr("width", 960)
    .attr("height", 500)
  .append("g")
    .attr("transform", "translate(20,20)")
  .append("rect")
    .attr("width", 920)
    .attr("height", 460);

选择集的常见用法如下:

var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p");      //选择body中的第一个p元素
var p = body.selectAll("p");    //选择body中的所有p元素
var svg = body.select("svg");   //选择body中的svg元素
var rects = svg.selectAll("rect");  //选择svg中所有的rect元素
var id = body.select("#id"); //选择body中id元素
var class = body.select(".class");//选择body中class类元素

链式操作

d3.select("#container").text("这是一段文字").attr("name","cont");

3.1 datum() 与 data()

绑定数据:选择集和绑定数据通常是一起使用的,D3 中是通过以下两个函数来绑定数据的:

  • datum():用来绑定一个数据到选择集上;
  • data():用来绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定;

使用 datum(),可以将一个数据分别绑定到多个DOM元素上。

 <div id="app">
    <p></p>
    <p></p>
    <p></p>
</div>
<script>
	var data = '这是一段文字';
	var container = d3.select("#app");
	container.selectAll('p')
	  .datum(data)
	  .text(function (d, i) {
	    return "第 " + i + " 个元素绑定的数据是: " + d;
	  })
</script>

页面效果如下:
数据可视化之_D3.js
使用data(),分别将数组的各元素绑定到多个DOM元素上。

 <div id="app">
   <p></p>
   <p></p>
   <p></p>
</div>
<script>
    var datalist = [10, 20, 30];
    var container = d3.select("#app");
    container.selectAll('p')
        .data(datalist)
        .text(function (d, i) {
            return d;
        })
</script>

页面效果如下:
数据可视化之_D3.js

回调函数中,

  • 第一个参数表示 data,即 datum() 或者 data() 中的各项数据;
  • 第二个参数表示 index,表示索引;

动态属性,在回调函数中,可以通过对data判断,给元素动态设置属性:

var datalist = [10, 20, 30]
d3.selectAll('p').data(datalist).text((d, i) => {
  return d;
}).style('color', (d, i) => {
  if (d > 10) {
    return 'red'
  } else {
    return 'blue'
  }
}).style('font-size',(d,i)=>{
  return d+'px';
})

页面效果如下:
数据可视化之_D3.js

3.2 update()、enter()、exit()

数据绑定的时候可能出现 DOM 元素与数据元素个数不匹配的问题,那么 enter 和 exit 就是用来处理这个问题的。enter 操作用来添加新的 DOM 元素exit 操作用来移除多余的 DOM 元素

Update、Enter、Exit 是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况。

  • update(), 当对应的元素正好满足时 ( 绑定数据数量 = 对应元素 ),实际上并不存在这样一个函数,只是为了要与之后的 enter 和 exit 一起说明才想象有这样一个函数。但对应元素正好满足时,直接操作即可,后面直接跟 text ,style 等操作即可。
  • enter(), 当对应的元素不足时 ( 绑定数据数量 > 对应元素 ),当对应的元素不足时,通常要添加元素,使之与绑定数据的数量相等。后面通常先跟 append 操作。
  • exit(), 当对应的元素过多时 ( 绑定数据数量 < 对应元素 ),当对应的元素过多时,通常要删除元素,使之与绑定数据的数量相等。后面通常要跟 remove 操作。

如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与数据对应的部分称为 Update。如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit。示意图如下所示。
在这里插入图片描述
update() 、enter()、exit():

var dataset = [3, 6, 9, 12, 15]
var p = d3.select('body').selectAll('p');	//选择body中的P元素
var update = p.data(dataset);	//获取update部分

update.text(function (d) {	//获取update部分,更新属性值
	return "update " + d;
})

var enter = update.enter()	//获取enter部分
enter.append('p').text(function (d) {
	return "enter " + d;
})

var exit = update.exit()	//获取exit部分
// exit.text(function (d) {
//   return "exit"
// })
exit.remove();

3.3 transition()

过渡动画。

  • duration() 动画的持续时间
  • delay() 动画的延迟时间
var width = 600;
var height = 400;

var svg = d3.select('body')	//添加svg元素
  .append('svg')
	.attr('width',width)
	.attr('height',height);

svg.append('rect')	//在svg中添加宽100高30,填充色为绿色,左上角位置在30,40的rect
	.attr("fill","green")
	.attr("x",30)
	.attr("y",40)
	.attr("width",100)
	.attr("height",30)
	.transition()	//添加动画效果	
	.duration(2000)	//动画持续时间2000ms	
	.delay(3000)	//延时3000ms后 开始执行动画	
	.attr("width",300)	//过渡成宽300高300,移动到200,100的位置
	.attr("height",300)
	.attr("x",200)
	.attr("y",100)

页面的效果如下:
数据可视化之_D3.js

3.4 svg的简单使用

D3.js 主要是通过绘制 svg 来展示数据,这里简单介绍svg的使用方式,详细教程可以查看:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element

SVG 意为可缩放矢量图形(Scalable Vector Graphics)。SVG 使用 XML 格式定义图像。

使用svg绘制矩形椭圆正圆

<svg width="500" height="200" style="background: #efefef;">
	<!-- 矩形 -->
    <rect x="50" y="100" width="100" height="50" class="rect" stroke="blue" stroke-width="5" ></rect>
	<!-- 椭圆 -->
    <ellipse cx="230" cy="100" rx="100" ry="50" style="fill: orange; stroke: orangered; stroke-width: 5px;"></ellipse>
	<!-- 正圆 -->
    <circle cx="380" cy="100" r="90" style="fill: orange; stroke: orangered; stroke-width: 5px;"></circle>
</svg>

页面效果如下,可以看到最先绘制的矩形在最底层,最后绘制的正圆在最上面。
数据可视化之_D3.js
使用svg绘制直线多边形折线路径文本

<svg width="500" height="200" style="background: #efefef;">
	<!-- 直线 -->
	<line x1="50" y1="50" x2="450" y2="150" stroke="red" stroke-width="3"></line>
    <!-- 多边形 -->
    <polygon points="50,20 150,60 120,180 100,180 "  fill="none" stroke="blue" stroke-width="5"></polygon> 
	<!-- 折线 -->
    <polyline points="150,20 250,60 220,180 200,180" fill="none"  stroke="blue" stroke-width="5"></polyline>
	<!-- 路径 -->
    <path d="M330,30 L330,150  L470,170 " fill="none" stroke-width="4" stroke="green"></path>
	<!-- 文本 -->
    <text x="180" y="180" style="font-size: 50;fill:none; stroke-width: 1; stroke:red;"> hello world </text>
</svg>

使用 polygon 绘制多边形,或者使用 polyline 绘制折线时,语法为第一点的x坐标,y坐标 第二个点的x坐 y坐标 ...,两者的不同之处在于,绘制多边形时会自动连接起始点和结束点,形成闭合图形;而绘制折线时,不会自动闭合图形。

path 绘制路径时,语法为M第一个点的x坐标,y坐标 L第二个点的x坐标,y坐标....,可以理解为moveTo...lineTo....

页面效果如下:
数据可视化之_D3.js
元素g是用来组合对象的容器。添加到g元素上的变换会应用到其所有的子元素上。添加到g元素的属性会被其所有的子元素继承。此外,g元素也可以用来定义复杂的对象,之后可以通过<use>元素来引用它们。

把所有需要多次使用的引用元素定义在defs元素里面。这样做可以增加SVG内容的易读性和可访问性。 在defs元素中定义的图形元素不会直接呈现。 你可以在你的视口的任意地方利用 <use>元素呈现这些元素。

<svg width="500" height="200" style="background: #efefef;">
	<defs>
		<g id="mycircle" stroke="green" fill="none" stroke-width="5">
			<circle cx="25" cy="30" r="15" />
			<circle cx="55" cy="80" r="15" />
			<circle cx="85" cy="50" r="15" />
		</g>
	</defs>
	<use xlink:href="#mycircle" x="30" y="30" />
	<use xlink:href="#mycircle" x="260" y="80" />
</svg>

页面效果如下:
数据可视化之_D3.js
svg 中的动画,使用 animate 元素,它需要放在形状元素内部,用来定义一个元素的某个属性如何踩着时点改变。在指定持续时间里,属性从开始值变成结束值。

  • attributeName 要改变的属性名称;
  • from to 开始状态跟结束状态;
  • dur 动画的持续时间;
  • repeatCount 动画的重复次数;
<svg width="500" height="200" style="background: #efefef;">
	<circle cx="85" cy="50" r="15">
		<animate attributeName="cx" from="85" to="180" dur="5s" repeatCount="5" />
		<animate attributeName="cy" from="50" to="100" dur="5s" repeatCount="5" />
	</circle>
</svg>

页面效果如下:
数据可视化之_D3.js

4. d3-selection API

d3中的常用的选择集有:

  • d3.select - 从当前文档中选择一系列元素。
  • d3.selectAll - 从当前文档中选择多项元素。
  • selection.attr - 设置或获取指定属性。
  • selection.classed - 添加或删除选定元素的 CSS 类(CSS class)。
  • selection.style - 设置或删除 CSS 属性。style优先级高于attr。
  • selection.text - 设置或获取选定元素的标签体文本内容。
  • selection.html - 设置或获取选定元素的 HTML 内容(类似 innerHTML )。
  • selection.datum - 设置或获取单独元素的数据,不进行关联。
  • selection.data - 设置或获取一组元素的绑定数据。
  • selection.append - 创建并添加新元素到选定元素后。
  • selection.insert - 创建并添加新元素到选定元素前。
  • selection.remove - 从当前文档对象中删除选定的元素。
  • selection.enter - 返回缺失元素的占位对象(placeholder),指向绑定的数据中比选定元素集多出的一部分元素。
  • selection.exit - 返回多余元素的元素集,即选择元素中比绑定数据多出的一部分。(关于data, enter, exit原理的示例1, 示例2, 示例3)
  • selection.filter - 根据绑定的数据过滤选择集。
  • selection.sort - 根据绑定的数据对选择的元素进行排序。
  • selection.order - 对文档中的元素重排序以匹配选择集。
  • selection.on - 添加或删除事件监听器。
  • selection.transition - 启动一个过渡效果(返回 Transition 对象),可以理解为动画。
  • selection.each - 为每个选择的元素集调用指定的函数。
  • selection.call - 为当前选择的元素集调用指定的函数。
  • selection.empty - 测试选择集是否为空。
  • selection.node - 返回选择集中的第一个元素。
  • selection.size - 返回选择集中的元素个数。
  • selection.select - 选择所选的元素中的第一个子元素组成新的选择集。
  • selection.selectAll - 选择所选的元素中的多个子元素组成新的选择集。
  • d3.selection - 选择集对象原型(可通过 d3.selection.prototype 为选择集增强功能)。
  • d3.event - 获取当前交互的用户事件。
  • d3.mouse - 获取鼠标的相对某元素的坐标。
  • d3.touches - 获取相对某元素的触控点坐标。

猜你喜欢

转载自blog.csdn.net/Charissa2017/article/details/106369774