D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript文件的后缀通常为.js,所以D3被称为D3.js。

d3.js可以定制出各种图形,今天来用d3.js制作一个简易的仪表盘,废话不多说先上demo,接下来分步讲解。

1.绘制svg,并分组(group)

const height = 600; //画布高度
const width = 1200; //画布宽度
const outerRadius = 200; //仪表盘外半径
const innerRadius = 190; //仪表盘内半径
const svg = d3.select('body').append('svg').attr('width', width).attr('height', height).style('background', '#000000'); // 在body中添加宽高并绘制背景色
const group = svg.append('g').attr('class', 'group').attr('transform', `translate(${width * 0.5}, ${height * 0.5})`); //添加分组并将分组中心移至画布中心
const arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius) //编写弧生成器并传入内外半径
const keduListB = [0,1,2,3,4,5,6,7,8,9,10,11,12]; //(大)刻度的数组
const keduListS = [0,1,2,3,4,5,6,7,8,9,10,11]; //(小)刻度的数组
const radiusScaleB = d3.scaleLinear().domain([0, 12]).range([Math.PI * (- 2 / 3), Math.PI * 2 / 3]) //(大)刻度线性比例尺
const radiusScaleS = d3.scaleLinear().domain([0, 11]).range([Math.PI * (- 11 / 18), Math.PI * ( 11 / 18 )]) //(小)刻度线性比例尺
let baseData = 0; //设置基础速度

2.将内容分组

group.append('g').attr('class', 'pan') //绘制仪表盘的圆弧分组
group.append('g').attr('class', 'kedu_b') //绘制大刻度分组
group.append('g').attr('class', 'kedu_s') //绘制小刻度分组
group.append('g').attr('class', 'zhizhen') //绘制指针分组
group.append('g').attr('class', 'shuzi') //绘制刻度数字分组
group.append('g').attr('class', 'show') //绘制速度框和数字分组
group.append('g').attr('class', 'button') //绘制按钮框和数字分组

3.绘制仪表盘的圆弧

group.select('.pan').append('path').attr('d', arc({startAngle: radiusScaleB(0),endAngle: radiusScaleB(12)})).attr('fill', '#6AE3F8').attr('stroke', '#6AE3F8');

4.绘制大刻度

group.select('.kedu_b')
.selectAll('line')
.data(keduListB)
.enter()
.append('line')
.attr('x1', d => 200 * Math.sin(radiusScaleB(d)))
.attr('y1', d => 200 * Math.cos(radiusScaleB(d)) * -1)
.attr('x2', d => 176 * Math.sin(radiusScaleB(d)))
.attr('y2', d => 176 * Math.cos(radiusScaleB(d)) * -1)
.attr('stroke', '#6AE3F8')
.attr('stroke-width', 5)

5.绘制小刻度

group.select('.kedu_s')
.selectAll('line')
.data(keduListS)
.enter()
.append('line')
.attr('x1', d => 200 * Math.sin(radiusScaleS(d)))
.attr('y1', d => 200 * Math.cos(radiusScaleS(d)) * -1)
.attr('x2', d => 180 * Math.sin(radiusScaleS(d)))
.attr('y2', d => 180 * Math.cos(radiusScaleS(d)) * -1)
.attr('stroke', '#6AE3F8')
.attr('stroke-width', 2)

6.绘制刻度数字

group.select('.shuzi')
.selectAll('text')
.data(keduListB)
.enter()
.append('text')
.attr('x', d => 160 * Math.sin(radiusScaleB(d)))
.attr('y', d => 160 * Math.cos(radiusScaleB(d)) * -1)
.attr('text-anchor', 'middle')
.attr('dy', '0.35em')
.attr('fill', '#6AE3F8')
.style('text-shadow', '0px 0px 2px #6AE3F8')
.text(d => d * 20)

7.绘制指针

group.select('.zhizhen')
.append('polygon')
.attr('points', '-2,-20,2,-20,4,0,1,140,-1,140,-4,0')
.attr('fill', '#6AE3F8')
.attr('transform', 'rotate(60)')

8.绘制速度框和数字

group.select('.show')
.attr('transform', 'translate(0, 100)')
.append('rect')
.attr('x', -60)
.attr('y', 0)
.attr('width', 120)
.attr('height', 40)
.attr('fill', 'none')
.attr('stroke', '#6AE3F8')
.attr('stroke-width', 3)
group.select('.show')
.append('text')
.attr('text-anchor', 'middle')
.attr('x', 0)
.attr('y', 20)
.attr('dy', '0.35em')
.attr('fill', '#6AE3F8')
.attr('stroke', '#6AE3F8')
.attr('font-size', '20px')
.text(`0 km/h`)

9.绘制按钮框和数字

d3.select('.button')
.append('rect')
.attr('x', -50)
.attr('y', 250)
.attr('width', 100)
.attr('height', 40)
.attr('fill', 'none')
.attr('stroke', '#6AE3F8')
.attr('stroke-width', 2) d3.select('.button')
.append('text')
.attr('x', 0)
.attr('y', 270)
.attr('text-anchor', 'middle')
.attr('dy', '.35em')
.attr('fill', '#6AE3F8')
.attr('font-size', '20px')
.text('加速')

10.速度不断减小,并且点击“加速”持续加速

d3.select('.button')
.attr('cursor', 'pointer')
.on('click', () => {
if (baseData < 220) {
baseData += 20
change()
} else if (baseData < 240) {
baseData = 240;
change()
}
})
setInterval(() => {
if (baseData > 10) {
baseData -= 10;
change();
} else if (baseData > 0) {
baseData = 0;
change()
}
}, 2000)

11.控制加速的方法(指针旋转,速度数字增加)

const change = () => {
group.select('.zhizhen')
.transition()
.duration(2000)
.ease(d3.easeLinear)
.attrTween('transform', function () {
this._before = typeof this.getAttribute('transform') == 'string' ? this.getAttribute('transform').match(/\d+/g)[0] : 0;
this._after = baseData;
console.log('this._before',this._before)
console.log('this._after',this._after)
let interpolate = d3.interpolate(this._before, this._after);
return function(t) {
texts(interpolate(t))
return `rotate(${interpolate(t)})`
};
})
} const texts = text => {
group.select('.show').select('text')
.attr('text-anchor', 'middle')
.attr('x', 0)
.attr('y', 20)
.attr('dy', '0.35em')
.attr('fill', '#6AE3F8')
.attr('stroke', '#6AE3F8')
.attr('font-size', '20px')
.text(`${Math.floor(text)} km/h`)
}

这样点击加速就会调用change()方法,而change()方法在过渡是就会调用texts()方法。
这样子就好了,一个基本的仪表盘就绘制好了

原创博客:转载请注明d3.js 入门指南 - 仪表盘

d3.js 入门指南 - 仪表盘的更多相关文章

  1. d3.js 入门指南

    说到数据可视化,我们会行到很多优秀的框架,像echarts.highcharts,这些框架很优雅,健壮,能满足我们对可视化的大部分需求,但是缺点也很明显,就是这些框架几乎是不可定制化的,当遇到特殊的需 ...

  2. D3.js 入门教程

    最近需要用到d3, 记录下d3的教程 网上搜了几个关于d3的教程 D3.js 入门教程      http://wiki.jikexueyuan.com/project/d3wiki/author.h ...

  3. 《Three.js 入门指南》3.1.2 - 一份整齐的代码结构以及使用ORBIT CONTROLS插件(轨道控制)实现模型控制

    3.1.2 正式代码结构 & ORBIT CONTROLS插件(轨道控制) 说明 本节内容属于插入节,<Three.js入门指南>这本书中,只是简单的介绍了一些概念,是一本基础的入 ...

  4. 《Three.js 入门指南》3.0 - 代码构建的最基本结构。

    3.0 代码构建的最基本结构 说明: 我们必需首先知道,Three.js 的一些入门级概念: 我们需要知道,OpenGL 是一套三维实现的标准,为什么说是标准,因为它是跨平台,跨语言的.甚至CAD以及 ...

  5. 《Three.js 入门指南》0 - 说明

    本笔记,摘自:<Three.js 入门指南>一书 地址链接为:https://www.ituring.com.cn/book/miniarticle/58552 本书的前言摘录: 本书结构 ...

  6. Vue.js 入门指南之“前传”(含sublime text 3 配置)

    题记:关注Vue.js 很久了,但就是没有动手写过一行代码,今天准备入手,却发现自己比菜鸟还菜,于是四方寻找大牛指点,才终于找到了入门的“入门”,就算是“入门指南”的“前传”吧.此文献给跟我一样“白痴 ...

  7. 【 D3.js 入门系列 — 1 】 第一个程序 HelloWorld

    记得以前刚上大一学 C 语言的时候,写的第一个程序就是在控制台上输出 HelloWorld .当时很纳闷,为什么要输出这个.老师解释说所有学编程入门的第一个程序都是在屏幕上输出 HelloWorld, ...

  8. 【 D3.js 入门系列 — 11 】 入门总结

    D3 新专题首页 一转眼,这个入门系列已经积累了二十二篇文章之多,我想作为 D3.js 这款数据可视化工具的入门来说已经足够了.相信仅仅要看完本系列.以后全然能够在辅以查询的情况下完毕大部分可视化工作 ...

  9. 【 D3.js 入门系列 --- 3 】 做一个简单的图表!

    前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为 ...

随机推荐

  1. 转。http,状态码详解

    转自konglingbinHTTP状态码详解:https://www.cnblogs.com/klb561/p/9205867.html HTTP状态码(HTTP Status Code)是用以表示网 ...

  2. postgresql修改最大连接数配置

    1.查看配置文件位置等信息,用来确定配置对应的配置文件. select setting,boot_val,reset_val,sourcefile,*from pg_settings  where n ...

  3. http_web_cache

    HTTP Web Cache 程序资源的访问具有局部性 时间局部性:一个被访问过的资源很有可能在近期被再次访问. 空间局部性:一个被访问过的资源,它的周边资源很有可能被访问到. 如何衡量缓存的有效性? ...

  4. 题解 P1047 【校门外的树】

    可以直接模拟,用珂朵莉树是不有点小题大做. 你怎么做珂朵莉都会骂你:"这么简单的模拟都要用***" 附赠珂朵莉照片一张 另外讲几点: 可以用int,你要不怕MLE #include ...

  5. Process用法与进程详解

    僵尸与孤儿进程 僵尸进程:父进程的子进程结束的时候父进程没有wait()情况下子进程会变成僵尸进程 孤儿进程(无害) 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿 ...

  6. LNMP架构介绍、MySQL和PHP安装、Nginx介绍

     6月6日任务  12.1 LNMP架构介绍12.2 MySQL安装12.3/12.4 PHP安装12.5 Nginx介绍 扩展Nginx为什么比Apache Httpd高效:原理篇 http://w ...

  7. 【JZOJ】3490. 旅游题解报告

    题目 思路 这道题看上去就像一个动态规划!但是还是要把矩阵压成一行. 然后按 \(A\)数组 将结构体从小到大排个序. 随后我们开始了动规标准步骤: 确定状态 很显然, \(f_i\) 表示游览完第\ ...

  8. IDEA的控制台拖拽出来之后,如何恢复?

    大家搜到这个的时候,肯定遇到了如下图展示的尴尬情况,我们的控制台在不小心之间被拖拽出来,然后不知如何再拖回去?放心,我来告诉你怎么办. 点击左下角的  恢复按钮 就可以了.

  9. 外键(foreign key)的使用及其优缺点

    如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键.由此可见,外键表示了两个关系之间的相关联系.以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表. ...

  10. tensorflow学习笔记——AlexNet

    1,AlexNet网络的创新点 AlexNet将LeNet的思想发扬光大,把CNN的基本原理应用到了很深很宽的网络中.AlexNet主要使用到的新技术点如下: (1)成功使用ReLU作为CNN的激活函 ...