内容简介:D3.js是一个基于HTML/SVG/CSS的数据可视化库,是领域内非常强大的存在了。今后会在工作使用,也因此开始了自学之旅。学习过程中,我主要通过Curran Kelleher老师的系列教程进行学习,这个笔记用于学习、整理和分享,陆续学习、更新和记录中....完成效果图:
D3.js是一个基于HTML/SVG/CSS的数据可视化库,是领域内非常强大的存在了。
今后会在工作使用,也因此开始了自学之旅。学习过程中,我主要通过Curran Kelleher老师的系列教程进行学习,这个笔记用于学习、整理和分享,陆续学习、更新和记录中....
原文链接
学习目的:
- 熟悉和认识D3.js
- 练习使用SVG画图,熟悉操作
- 练习D3.js的基本函数和操作
完成效果图: 在线demo
D3初印象
选择集
D3是实现数据可视化,仍然离不开传统DOM的选择和操作,也因此,D3提供了类似Jquery的DOM操作指令:
d3.select d3.selectAll
const svg = d3.select('svg') //选择svg
const p = svg.selectAll('p') //选择svg下所有的p标签
复制代码
当然,可以使用 #id 以及 .class 对id和类进行选择
查看状态
d3.select 和 d3.selectAll 返回的都是选择集,添加、删除以及修改都需要用到选择集,查看状态有三个函数可以使用:
selection.empty() selection.node() selection.size()
设定和获取属性
使用 select 或 selectAll 选择后,可以通过 attr 获取和设定属性,可以使用 append 方法添加元素
const svg = select('svg');
svg.append('circle')
.attr('r','30')
复制代码
使用D3和SVG画图
html文件
<html lang="en">
<head>
<title>Smile face with d3</title>
</head>
<body>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="index.js"></script>
</body>
</html>
复制代码
主要内容通过index.js实现:
第一步:通过d3选择SVG,使用 circle 构建轮廓
const svg = d3.select('svg');
const height = +svg.attr('height');
const width = +svg.attr('width');
svg.append('circle')
.attr('r',height / 2)
.attr('cx', width / 2)
.attr('cy', height / 2)
.attr('fill', 'yellow')
.attr('stroke','black')
const leftEye = svg.append('circle')
.attr('r', 30)
.attr('cx', width / 2 - 100)
.attr('cy', height / 2 - 80)
.attr('fill', 'black')
const rightEye = svg.append('circle')
.attr('r', 30)
.attr('cx', width / 2 + 100)
.attr('cy', height / 2 - 80)
.attr('fill', 'black')
复制代码
要点:
- 通过
attr获取的属性是string类型的,通过parseFloat或者+转换为number类型 - 对圆形
circle的属性cxcy等,使用变量作为其大小设置的值,而不用一个数字,方便日后的维护 - leftEye和RightEye用类似的方法,创造出来,并将眼睛放置在合适的位置。
代码优化
1)可以发现,对三个圆圆心的操作 cx 和 cy 出现了多次,而作用也仅仅是为了将圆放在中心。因此,可以通过SVG中的 <g> 来分组来实现一次性操作。
const g = svg.append('g')
.attr('transform',`translate(${ width / 2}, ${ height / 2})`)
//这样,在画圆的时候,就可以去掉对其圆心的操作,因为默认的位置就在中心了
const circle = g.append('circle')
.attr('r',height / 2)
.attr('fill', 'yellow')
.attr('stroke','black')
复制代码
2)同样的,对于眼睛的操作,也有点繁琐,可以通过变量和分组,提高代码的可维护性能。
const eyeSpacing = 100;
const eyeYoffset = -80
const eyeRadius = 30;
const eyesG = g.append('g')
.attr('transform', `translate(0, ${eyeYoffset})`);
const leftEye = eyesG.append('circle')
.attr('r', eyeRadius)
.attr('cx', - eyeSpacing)
const rightEye = eyesG.append('circle')
.attr('r', eyeRadius)
.attr('cx', + eyeSpacing)
复制代码
第二步 嘴巴
嘴巴实际上是一个弧线,使用SVG中的 path 进行绘制。熟悉 path 的,当然可以直接给参数进行绘制,但是d3对圆弧有更好的支持,可以使用 d3.arc 函数,方便的绘制圆弧。
arc函数
根据官方的API手册,函数的使用方法如下:
var arc = d3.arc();
arc({
innerRadius: 0,
outerRadius: 100,
startAngle: 0,
endAngle: Math.PI / 2
}); // "M0,-100A100,100,0,0,1,100,0L0,0Z"
复制代码
其中,innerRadius是内圆半径,outerRadius是外圆半径,startAngle和endAngle分别是开始和结束的弧度(完整的圆是0~2PI)
笑脸的实现
根据以上内容,代码如下:
const mouth = g.append('path')
.attr('d',d3.arc()({
innerRadius: 150,
outerRadius: 170,
startAngle: Math.PI /2,
endAngle: Math.PI * 3 / 2
}))
复制代码
眉毛
眉毛用简单的长方形来代替,也就是svg中的 <rect> ,使用前文的编程风格,将眉毛归为一个group,并将位置设定。
const eyebrowWidth = 50;
const eyebrowHeight = 10;
const eyebrowYoffset = -150;
const BrowG = g.append('g')
.attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`);
const leftEyebrow = BrowG.append('rect')
.attr('width',eyebrowWidth)
.attr('height',eyebrowHeight)
.attr('x',-eyeSpacing)
const rightEyebrow = BrowG.append('rect')
.attr('width', eyebrowWidth)
.attr('height', eyebrowHeight)
.attr('x', eyeSpacing)
复制代码
加入动画
使用 transition 函数设置眉毛的动画,让笑脸动起来
const BrowG = g.append('g')
.attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`);
BrowG.transition().duration(2000)
.attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset - 50})`)
.transition().duration(2000)
.attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset})`).duration(2000)
复制代码
注意点:
-
transition函数要对号入座,即如果加在了<g>上,对应的增加的属性动画应该在transform上; 如果动画在<rect>上,动画应该在y属性上。 - 添加动画不能在
append函数之后连接,比如BrowG.append('g').attr(...).transition()是不行的。因为过度动画无法绑定在append的元素上,需要分别操作。
完整代码
const svg = d3.select('svg');
const height = +svg.attr('height');
const width = +svg.attr('width');
const g = svg.append('g')
.attr('transform',`translate(${ width / 2}, ${ height / 2})`)
const circle = g.append('circle')
.attr('r',height / 2)
.attr('fill', 'yellow')
.attr('stroke','black')
const eyeSpacing = 100;
const eyeYoffset = -80
const eyeRadius = 30;
const eyebrowWidth = 50;
const eyebrowHeight = 10;
const eyebrowYoffset = -150;
const eyesG = g.append('g')
.attr('transform', `translate(0, ${eyeYoffset})`);
const leftEye = eyesG.append('circle')
.attr('r', eyeRadius)
.attr('cx', - eyeSpacing)
const rightEye = eyesG.append('circle')
.attr('r', eyeRadius)
.attr('cx', + eyeSpacing)
const mouth = g.append('path')
.attr('d',d3.arc()({
innerRadius: 150,
outerRadius: 170,
startAngle: Math.PI /2,
endAngle: Math.PI * 3 / 2
}))
const BrowG = g.append('g')
.attr('transform',`translate(${-eyebrowWidth / 2},${eyebrowYoffset})`);
BrowG.transition().duration(2000)
.attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset - 50})`)
.transition().duration(2000)
.attr('transform', `translate(${-eyebrowWidth / 2},${eyebrowYoffset})`).duration(2000)
const leftEyebrow = BrowG.append('rect')
.attr('width',eyebrowWidth)
.attr('height',eyebrowHeight)
.attr('x',-eyeSpacing)
const rightEyebrow = BrowG.append('rect')
.attr('width', eyebrowWidth)
.attr('height', eyebrowHeight)
.attr('x', eyeSpacing)
复制代码
以上所述就是小编给大家介绍的《D3可视化:(1)初次见面,SVG与D3的魅力》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ordering Disorder
Khoi Vinh / New Riders Press / 2010-12-03 / USD 29.99
The grid has long been an invaluable tool for creating order out of chaos for designers of all kinds—from city planners to architects to typesetters and graphic artists. In recent years, web designers......一起来看看 《Ordering Disorder》 这本书的介绍吧!