D3 Note - Basis
D3 (Data-Driven Documents) 是一个 JavaScript Library,用来做 Web 端的数据可视化实现以及各种绘图。
D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS.
学习 D3 需要很多预备知识:
HTML / DOM CSS JavaScript (better with jQuery) SVGHTML / CSS 不必多说,因为 D3 含有大量链式操作函数以及选择器等,因此如果有 jQuery 基础将轻松很多。此外,由于一般采用 SVG 方式进行绘图,所以 SVG 基础知识也需要掌握。
虽然必须的预备知识如此之多,但 D3 的定位其实是 Web 前端绘图的底层工具,所谓底层,即是操作复杂而功能强大者。
关于 SVG 🔗
SVG (Scalable Vector Graphics) 是一种绘图标准,已经被绝大多数的现代浏览器所支持。SVG 采用 XML 语法定义图像,可直接嵌入 HTML 中使用。
SVG 的特点是矢量绘图(与 Canvas 不同),除了预设样式以外同时也支持 CSS 样式。
比如,画一个园圈,坐标为 (100, 50),半径为 40px,拥有 2px 的黑色 border,以及红色填充:
<svg>
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>
</svg>
SVG 有一些预定义的形状元素,可被开发者使用和操作:
矩形 圆形 椭圆 线 折线 多边形 路径其中,path
是功能最强大者,使用 path
可以构成所有图形。
选择器 🔗
选择元素 🔗
D3 使用与 jQuery 类似的选择器来获取 HTML 元素。常用的方法有:
d3.select(selector)
d3.selectAll(selector)
(参数既可以传 selector 也可以直接传 HTML Element )
顾名思义,selectAll
就是选择所有符合条件的元素了,那么 select
选择的是符合条件的第一个元素。如:
d3.select('body') //选择 body 元素
d3.selectAll('p') //选择所有 p 元素
d3.selectAll('.className') //选择所有 class 包含 className 的元素
更多就不说了。
操作选择 🔗
选择器返回的是一组选择(selection),这组选择可以进行一些操作,如:
在此选择的基础上继续选择; 改变属性; 改变样式; 绑定事件; 插入、删除; 绑定数据。大多数操作都与 jQuery 十分类似,同时也支持链式操作,不再赘述。只是这个“绑定数据”操作稍有特别。
数据绑定 🔗
通过 D3 可以把数据“绑定”到 HTML 元素上,绑定的目的主要是为了方便一些需要相应数据才能进行的元素操作(如:更改元素大小、位置等)。
绑定数据有两个方法:
datum
: 将一个数据绑定到选择上;
data
: 将一个数组绑定到选择上,数组的各项分别与选择的各项一一对应。
下面引用一个例子来说明这二者的不同。假设有如下三个节点:
<p>Apple</p>
<p>Pear</p>
<p>Banana</p>
datum 🔗
执行以下代码:
let str = 'datum';
let p = d3.selectAll('p');
p.datum(str);
p.text((d, i) => `Element ${i} bind with ${d}`);
将得到:
Element 0 bind with datum
Element 1 bind with datum
Element 2 bind with datum
在对选择进行操作时,传入的值可以是值,也可以是函数。当传入函数时,D3 会向函数注入两个参数,分别是 d (data) 与 i (index),代表当前元素绑定的数据与其索引。
data 🔗
执行以下代码:
let strArr = ['data0', 'data1', 'data2'];
let p = d3.selectAll('p');
p.data(strArr);
p.text((d, i) => `Element ${i} bind with ${d}`);
将得到:
Element 0 bind with data0
Element 1 bind with data1
Element 2 bind with data2
可以看到,数组中的 3 个项分别与 3 个 p 元素绑定到了一起。因此,可以将 datum
看作是 data
函数的一个特例,实际开发中使用更多的是 data
函数。
实践:简单柱状图 🔗
先定义一个 SVG 画布,并将它插入到 HTML 的 body 中去:
let width = 300,
height = 300;
let svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
在这里,画布的宽高都为 300 像素。
然后,定义一组数据:
let data = [250, 210, 170, 100, 190];
最后使用以上数据画出柱状图,柱子使用 SVG 预定义的 rect
元素:
let rectWidth = 25;
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('y', (d, i) => height - d)
.attr('x', (d, i) => i * rectWidth)
.attr('height', d => d)
.attr('width', rectWidth - 2)
.attr('fill', 'steelblue');
rectWidth
表示柱子的宽度,至于坐标、宽高则分别通过 x / y 以及 height / width 属性来控制,效果如下:
可以发现,这里并没有指定需要插入的 rect
个数,但 D3 却根据数据量自动地把图画出来了,这个工作是通过 enter
语句完成的。关于其工作原理,下回分解。
文章来源:
Author:wxsm's blog
link:https://blog.wxsm.space/p/d3-note-basis