4

前言

本来在另一篇里已经写了一点了,不知为啥,我再编辑更新内容一直保存不了,无奈只能再新创建一篇文章了。

SVG简介

什么是SVG: SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用来定义用于网络的基于矢量的图形 ,SVG 使用 XML 格式定义图形 。SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失。

SVG 的历史和优势:
在 2003 年一月,SVG 1.1 被确立为 W3C 标准。

参与定义 SVG 的组织有:Sun公司(已被Oracle公司收购)、Adobe、苹果公司、IBM 以及柯达。

与其他图像格式相比,使用 SVG 的优势在于:

  • SVG 可被非常多的工具读取和修改,比如记事本。
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • SVG 是可伸缩的 SVG 图像可在任何的分辨率下被高质量地打印。
  • SVG 可在图像质量不下降的情况下被放大。
  • SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
  • SVG 是开放的标准
  • SVG 文件是纯粹的 XML
  • Flash 相比,SVG 最大的优势是与其他标准(比如 XSL 和 DOM)相兼容。而 Flash 则是未开源的私有技术

SVG元素

  • rect : x="10" y="10" height="90" width="90" rx="5" ry="5"

x,y就是矩形左上角坐标,rx,ry就是矩形的圆角宽高。

  • circle : cx="50" cy="150" r="40"

cx、cy就是圆心坐标,r是半径

  • ellipse :cx="150" cy="150" rx="50" ry="30"

cx、cy就是圆心坐标,rx、ry就是圆的长宽两个半径

  • line:x1="10" y1="200" x2="10" y2="300"

(x1,y1)是起点坐标,(x2,y2)是终点坐标。

  • polyline:points="80,320 130,320 95,400 80,320"

points就是一系列的坐标点,从第一个点开始直线连接下一个点,直到结束。如果你想要图形封闭,可以把起始点再加在末尾。

  • path: <path d="M50,50 A30,30 0 0,1 35,20 L100,100 M110,11 L100,0" style="stroke:#660000; fill:none;"/>

path元素的所有绘图都在d属性中指定。d属性包含绘制命令。上面的例子中,M发出“移至”命令,A发出“弧”命令,L发出“线段”命令。这些命令都作用在一个“虚拟画笔”。这支笔可以移动,绘制形状等。

这是一个例子

SVG坐标系

在SVG坐标系中,x=0,y=0点在左上角。与正常的图坐标系相比,y轴被反转。随着SVG中y的增加,点、形状等向下移动,而不是向上。

D3简介

D3 的全称是(Data-Driven Documents), 顾名思义可以知道是一个被数据驱动的文档。D3.js是一个基于数据的操作文档的JavaScript库,可以让你绑定任何数据到DOM,支持DIV这种图案生成,也支持SVG这种图案的生成。D3帮助你屏蔽了浏览器差异,做出来图案的效果可以说是炫目得一塌糊涂,可是代码却很简洁。

模块划分

D3可以整个模块安装使用,也可以只安装你需要的模块
下面是我用过的几个模块
Arrays (Statistics, Search, Transformations, Histograms)
数组操作,排序,搜索,总结,统计数据,变换,直方图
Axes
创建坐标轴,以及坐标轴相关的设置,操作等。会创建相关dom元素
Brushes
刷子组件,选择区域用。会创建相关dom元素
Dragging
拖拽组件,用于实现拖拽事件
Scales (Continuous, Sequential, Quantize, Ordinal)
比例尺,会和坐标轴结合使用
Selections (Selecting, Modifying, Data, Events, Control, Local Variables, Namespaces)
选择集
Transitions
过渡组件,用来定义一些过渡效果
Zooming
缩放组件
Shapes (Arcs, Pies, Lines, Areas, Curves, Links, Symbols, Stacks)
数据集到几何数据的转换

API

Arrays (d3-array)

数组操作,排序,搜索,统计数据,变换,直方图
<br/>
Statistics(统计)基本的统计数据方法
下面这些方法的第二个参数都可以指定一个可选的访问器函数,这相当于在计算总和之前调用array.map(访问器)。 这些方法忽略未定义的和NaN值; 这对忽略缺失数据很有用。
<br/>

  • d3.min - d3.max(array),d3.min(array),返回数组的最小值
  • d3.max - d3.max(array),返回数组最大值。

与内建的Math.max不同,此方法忽略未定义的值; 这对忽略缺失数据很有用。 另外,使用自然顺序而不是数字顺序比较元素。 例如,字符串[“20”,“3”]的最大值是“3”,而数字[20,3]的最大值是20。

  • d3.extent - d3.extent(array),把数组的最小最大值放在一个数组里返回
  • d3.sum -d3.sum(array),返回一个数字数组的累计和
  • d3.mean - 回给定数字数组的平均值。
  • d3.median - 返回给定数组的中值。
  • d3.quantile - d3.quantile(array, 0.5),返回给定数组的分位数。
  • d3.variance - 返回给定数组的总体方差。
  • d3.deviation - 返回给定数组的标准偏差。

<br/>
Search
<br/>

  • d3.scan

扫描数组,按照比较器比较,返回最小值,类似于min方法。

var array = [{foo: 42}, {foo: 91}];
d3.scan(array, function(a, b) { return a.foo - b.foo; }); // 0
d3.scan(array, function(a, b) { return b.foo - a.foo; }); // 1
  • d3.ascending(a, b)
  • d3.descending(a, b)

这两个都是排序的方法,结合array.sort()使用。
<br/>
Transformations
用于转换数组,生成新数组的方法

  • d3.cross

返回两个数组a和b的笛卡尔乘积

d3.cross([1, 2], ["x", "y"]); // returns [[1, "x"], [1, "y"], [2, "x"], [2, "y"]]
d3.cross([1, 2], ["x", "y"], (a, b) => a + b); // returns ["1x", "1y", "2x", "2y"]
  • d3.merge

将指定的数组合并到一个数组中, 这种方法类似于内置的数组concat方法; 唯一的区别是当你有一个数组数组时,它更方便。

d3.merge([[1], [2, 3]]); // returns [1, 2, 3]
  • d3.pairs(array[, reducer])

对于指定数组中的每个相邻元素对,按顺序调用指定的传递元素i和元素i-1的reducer函数。

d3.pairs([1, 2, 3, 4]); // returns [[1, 2], [2, 3], [3, 4]]
d3.pairs([1, 2, 3, 4], (a, b) => b - a); // returns [1, 1, 1];

Selections (d3-selection)

Selecting Elements
d3选择器对象,有两个属性:_groups:Array(),_parents:Array()。_groups里存的就是选中元素的dom对象

  • d3.selection

d3.selection() 返回选择根元素(html)的d3选择器对象

clipboard.png

  • d3.select

d3.select('.block')返回选择的元素的D3选择器对象

  • d3.selectAll

d3.selectAll('.block') 返回匹配的所有的元素的数组
以上3个方法是d3的静态方法,下面这3个对应着相同的原型方法。

  • selection.select

为每个选定的元素选择一个匹配的后代元素。

  • selection.selectAll

为每个选定元素选择所有匹配的后代。

  • selection.filter 过滤选定的元素,对每个选定元素执行filter方法
var even = d3.selectAll("tr").filter(":nth-child(even)");
var even = d3.selectAll("tr:nth-child(even)");
var even = d3.selectAll("tr").select(function(d, i) { return i & 1 ? this : null; });
  • selection.merge

把已选定的组和另外指定的选择合并成一个选择器。但使用起来要注意,他不能把任意的两个选择合并。

  • d3.matcher

测试一个元素是否匹配给定的选择器,一般用来和filter结合使用
var div = selection.filter(d3.matcher("div"));

后面还有几个方法,就不一一说了,感觉很鸡肋,基本不用,就不说了。。。
Modifying Elements

  • selection.attr - get or set an attribute.注意不能使用对象的形式一起传参数设置。
  • selection.classed - get, add or remove CSS classes.
  • selection.style - get or set a style property.
d3.select('.block svg')
.attr('width',500)
.attr('height',500)
.classed('chart first', true)
.classed('chart', false)
.style('background','#f0f')
.style('border','5px solid #0ff')
  • selection.property

某些HTML元素具有特殊属性,这些属性不能通过属性或样式进行寻址,例如表单字段的文本值和复选框的选中布尔值。 使用此方法获取或设置这些属性。

  • selection.text - get or set the text content.
  • selection.html - get or set the inner HTML.
  • selection.append

在所选元素的后面添加一个子元素,并返回该元素的选择器对象

  • selection.insert
d3.select('svg').insert('line','circle')

在svg里面的第一个匹配到'circle'的元素前面插入一个line元素。

  • selection.remove - remove elements from the document.
  • selection.clone - insert clones of selected elements.
  • selection.sort - sort elements in the document based on data.
  • selection.order - reorders elements in the document to match the selection.
  • selection.raise

按顺序重新插入每个选定元素,使这个选定元素作为其父项的最后一个子项。

  • selection.lower

按顺序重新插入每个选定元素,使这个选定元素作为其父项的第一个子项。

  • d3.create - create and select a detached element.
  • d3.creator - create an element by name.

<br/>
这是一个例子

Joining Data
绑定数据

  • selection.data

绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

  • selection.enter

返回缺失元素的选择集

  • selection.exit

返回缺失数据的元素选择集

  • selection.datum

绑定一个数据到选择集上
<br/>
数据绑定的例子

Scales (d3-scale)

一种计算关系,能够:将某一区域的值映射到另一区域,其大小关系不变。
这就是比例尺(Scale)
有哪些比例尺
比例尺,很像数学中的函数。例如,对于一个一元二次函数,有 x 和 y 两个未知数,当 x 的值确定时,y 的值也就确定了。
在数学中,x 的范围被称为定义域,y 的范围被称为值域。
D3 中的比例尺,也有定义域和值域,分别被称为 domain 和 range。开发者需要指定 domain 和 range 的范围,如此即可得到一个计算关系。

下面介绍两种最常用的比例尺:

Continuous (Linear, Power, Log, Identity, Time)
连续型比例尺包括线性比例尺,指数比例尺,对数比例尺,恒等比例尺,时间比例尺

  • continuous

计算一个给定的定义域值对应的值域的值,或者说给个x返回y。

  • continuous.invert

正好和上面的相反,给定一个y,返回x

  • continuous.domain

设置定义域

  • continuous.range

设置值域

  • continuous.rangeRound

和range同样,只是比range多一个功能,即启用舍入。

  • continuous.clamp
    x.clamp(true)
    这个方法通俗点说就是:设置为true,当你输入的是domain范围外的值时,返回始终是range范围内的值,通常是range的边界值。对invert也同样;设置为false,输入的是domain范围外的值,返回可能是range的范围外的值。
  • continuous.interpolate

设置输出插值器。
这个方法,主要是知道是插值器,留着以后说吧。

  • continuous.ticks

x.ticks(5)设置比例尺的刻度的个数,默认是10个,当然count只是一个提示,具体个数还是取决于domain。返回的tick值是均匀间隔的,具有人类可读的值(例如10的幂的倍数)

  • continuous.tickFormat

用来设置刻度值的格式的,具体如何用还需要了解locale.format相关的,另外它需要和ticks结合使用。

  • continuous.nice

设置扩展domain成一个友好的整数。

  • continuous.copy

创建一个scale的副本。

Ordinal (Band, Point)
scaleBand

  • d3.scaleBand 创建一个序数型的频带比例尺
  • band 输入一个定义域的值,返回对应的频带起点
  • band.domain 设置定义域
  • band.range 设置值域
  • band.rangeRound 设置值域和启用舍入
  • band.round 单独设置是否启用舍入
  • band.paddingInner 设置频带内间距
  • band.paddingOuter 设置起始和结束之外的间距
  • band.padding 把paddingInner和paddingOuter设置为一个值,一起设置。
  • band.align 设置频段对齐,如果有额外的空间。
  • band.bandwidth 获取每个频带的宽度。
  • band.step 获取相邻频段起点之间的距离。
  • band.copy 创建此比例的副本。

clipboard.png

一个柱状图

<br/>

Axes (d3-axis)

创建坐标轴,以及坐标轴相关的设置,操作等。会创建相关dom元素

  • d3.axisTop - create a new top-oriented axis generator.
  • d3.axisRight - create a new right-oriented axis generator.
  • d3.axisBottom - create a new bottom-oriented axis generator.
  • d3.axisLeft - create a new left-oriented axis generator.
  • axis - generate an axis for the given selection.
  • axis.scale - set the scale.
  • axis.ticks - customize how ticks are generated and formatted.
  • axis.tickArguments - customize how ticks are generated and formatted.
  • axis.tickValues - set the tick values explicitly.
  • axis.tickFormat - set the tick format explicitly.
  • axis.tickSize - set the size of the ticks.
  • axis.tickSizeInner - set the size of inner ticks.
  • axis.tickSizeOuter - set the size of outer (extent) ticks.
  • axis.tickPadding - set the padding between ticks and labels.

Shapes

pie
计算必要的角度以将表格数据集表示为饼图或圆环图。

  • d3.pie 创建一个新的饼图生成器。
  • pie 计算给定数据集的弧角。
  • pie.value 设置值访问器。如果你的数据集是一个对象数组,你要告诉它,哪个数据是生成角度的数据
  • pie.sort 设置排序顺序比较器,你可以任意使用对象里的数据进行排序比较,顺序不同,该条数据所在的角度不同
  • pie.sortValues 设置排序顺序比较器。专门用来对value来进行排序设置的,如果设置了sortValues,那sort的排序就无效了。
  • pie.startAngle 设置整体起始角度。默认0
  • pie.endAngle 设置整个结束角度。默认2 * Math.PI;
  • pie.padAngle 设置相邻圆弧之间的衬垫角度。默认0

<br/>

arcs

  • d3.arc - 创建一个新的弧发生器,即下面的arc。
  • arc - 为给定数据生成一个弧。
  • arc.centroid - 计算弧的中点。
  • arc.innerRadius - 设置内半径。
  • arc.outerRadius - 设置外半径。
  • arc.cornerRadius - 设置圆角的圆角半径。
  • arc.startAngle - 设置开始角度。
  • arc.endAngle - 设置结束角度。
  • arc.padAngle - 为填充的弧设置相邻弧之间的角度。
  • arc.padRadius - 设置线性化填充的半径。

一个环图
炫酷的环图

后记

d3还有很多api,我只写了一些,以后还会更新的,我的心得体会是:有很多api其实是冗余的,基本不会用的,了解了解就好;有些api功能很厉害的样子,但很不容易让人懂,而且还没有很好的文档和例子,我实在没办法的时候就点进相应的源码里,看他的代码实现,然后研究研究就懂了。


陈凤娟
171 声望17 粉丝

一个追求专业与卓越的前端开发工程师


« 上一篇
D3入门