D3.js实现简洁实用的动态仪表盘的示例


Posted in Javascript onApril 04, 2018

本文介绍了D3.js实现简洁实用的动态仪表盘的示例,分享给大家,具体如下:

动态效果图:

D3.js实现简洁实用的动态仪表盘的示例

仪表盘效果图

细看上面的动态效果图,可以发现:

  1. 一个值变换到一个新的值时,是一个渐变的过程;
  2. 圆弧末尾有一个竖线,作为仪表盘的指针,在仪表盘数值变化时,有一个弹性的动画效果。

一开始,我是用Echarts来实现仪表盘,但是它无法满足上面的两点需求。所以后来改成用D3.js。

D3.js可以完美地实现图表的定制,从细节上,完美地满足我们的需求。

初始化仪表盘

1、首先定义一个svg元素:

<svg id="myGauge" width="80" height="108" ></svg>

然后,声明一些变量用于初始化:

var width=80, 
  height=108,  //svg的高度和宽度,也可以通过svg的width、height属性获取
  innerRadius = 22,
  outerRadius = 30, //圆弧的内外半径
  arcMin = -Math.PI*2/3,
  arcMax = Math.PI*2/3, //圆弧的起始角度和终止角度

2、创建一个 arc 方法,并设置所有的属性,除了 endAngle。在创建圆弧的时候,传递一个包含 endAngle 属性的对象到这个方法,就可以计算出一个给定角度的 SVG path。

var arc = d3.arc()
  .innerRadius(22)
  .outerRadius(30)
  .startAngle(arcMin)

圆弧角度怎么设置呢?

把一个圆圈对应到一个时钟,那么12点钟对应的角度就是0,顺时针3点钟的角度是Math.PI/2,逆时针6点钟的角度是-Math.PI。因此-Math.PI*2/3到Math.PI*2/3的圆弧形状如上面的效果图所示。更多参考API文档中的arc.startAngle。

3、获取SVG元素,并且转换原点到画布的中心,这样我们在之后创建圆弧时就不需要再单独指定它们的位置了

var svg = d3.select("#myGauge")
var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

4、添加仪表盘中的文字(标题,数值,单位)

//添加仪表盘的标题
g.append("text").attr("class", "gauge-title")
  .style("alignment-baseline", "central") //相对父元素对齐方式
  .style("text-anchor", "middle") //文本锚点,居中
  .attr("y", -45)  //到中心的距离
  .text("CPU占用率");
//添加仪表盘显示的数值,因为之后还要更新,所以声明一个变量
var valueLabel = g.append("text").attr("class", "gauge-value")
  .style("alignment-baseline", "central") //相对父元素对齐方式
  .style("text-anchor", "middle") //文本锚点,居中
  .attr("y", 25)  //到中心的距离
  .text(12.65); 
//添加仪表盘显示数值的单位      
g.append("text").attr("class", "gauge-unity")
  .style("alignment-baseline", "central") //相对父元素对齐方式
  .style("text-anchor", "middle") //文本锚点,居中
  .attr("y", 40)  //到中心的距离
  .text("%");

D3制作的SVG图,与Echarts绘制的Canvas比起来,很重要的一个优点是,可以用CSS定义SVG的样式。比如,此处仪表盘标题的样式如下:

.gauge-title{
  font-size: 10px;
  fill: #A1A6AD;
}

5、添加背景圆弧

//添加背景圆弧
var background = g.append("path")
  .datum({endAngle:arcMax}) //传递endAngle参数到arc方法
  .style("fill", "#444851")
  .attr("d", arc);

6、添加表示百分比的圆弧,其中percentage是要表示的百分比,0到1的小数。

//计算圆弧的结束角度
var currentAngle = percentage*(arcMax-arcMin) + arcMin
//添加另一层圆弧,用于表示百分比
var foreground = g.append("path")
  .datum({endAngle:currentAngle})
  .style("fill", "#444851")
  .attr("d", arc);

7、在圆弧末尾添加一个指针标记

var tick = g.append("line")
  .attr('class', 'gauge-tick')
  .attr("x1", 0)
  .attr("y1", -innerRadius)
  .attr("x2", 0)
  .attr("y2", -(innerRadius + 12)) //定义line位置,默认是在圆弧正中间,12是指针的长度
  .style("stroke", "#A1A6AD")
  .attr('transform', 'rotate('+ angleToDegree(currentAngle) +')')

rotate中的参数是度数,Math.PI对应180,因此需要自定义一个angleToDegree方法把currentAngle转换一下。

至此,一个SVG仪表盘就制作出来了,不过是静止的,那怎么更新这个仪表盘呢?

更新仪表盘

需要更新:表示新的百分比的圆弧;圆弧下方的数值。

修改圆弧下方的数值很简单:

valueLabel.text(newValue)

更新圆弧则稍麻烦一点,具体思路是:修改圆弧的endAngle,以及修改圆弧末尾指针的transform值。

实现的过程中,需要使用的API:

selection.transition:https://github.com/d3/d3-transition/blob/master/README.md#selection_transition
transition.attrTween:https://github.com/d3/d3-transition/blob/master/README.md#transition_attrTween
d3.interpolate:https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate

1、更新圆弧,其中angle为新圆弧的结束角度。

//更新圆弧,并且设置渐变动效
foreground.transition()
  .duration(750)
  .ease(d3.easeElastic)  //设置来回弹动的效果
  .attrTween("d", arcTween(angle));

arcTween方法定义如下。它返回一个d属性的补间(渐变)动画方法,使一个圆弧从当前的角度渐变到另一个新的角度。

arcTween(newAngle) {
  let self=this
  return function(d) {
    var interpolate = d3.interpolate(d.endAngle, newAngle); //在两个值间找一个插值
    return function(t) {
      d.endAngle = interpolate(t);  //根据 transition 的时间 t 计算插值并赋值给endAngle
      return arc(d); //返回新的“d”属性值
    }; 
  };
}

这个方法更详细的说明可以参考Arc Tween中的注释。

2、更新圆弧末尾的指针的原理同上,其中oldAngle是旧圆弧的结束角度。

//更新圆弧末端的指针标记,并且设置渐变动效      
tick.transition()
  .duration(750)
  .ease(d3.easeElastic)  //设置来回弹动的效果
  .attrTween('transform', function(){ //设置“transform”属性的渐变,原理同上面的arcTween方法
    var i = d3.interpolate(angleToDegree(oldAngle), angleToDegree(newAngle));  //取插值
    return function(t) {
      return 'rotate('+ i(t) +')'
    };
  })

至此,我们就成功制作了一个动态刷新的简介美观的SVG仪表盘。

结束

每次使用D3.js都会忍不住觉得它真是太强大、太有意思了~它就像是一个百宝箱,让我们最大限度地满足需求。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
Jun 02 Javascript
JavaScript模板引擎用法实例
Jul 10 Javascript
详细分析JavaScript函数定义
Jul 16 Javascript
JavaScript编写页面半透明遮罩效果的简单示例
May 09 Javascript
js微信分享API
Oct 11 Javascript
js实现九宫格拼图小游戏
Feb 13 Javascript
JavaScript实现百度搜索框效果
Mar 26 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
Sep 05 Javascript
详解滑动穿透(锁body)终极探索
Apr 16 Javascript
Angular.JS读取数据库数据调用完整实例
Jul 02 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
Mar 23 Javascript
layui实现显示数据表格、搜索和修改功能示例
Jun 03 Javascript
vue.js实现点击后动态添加class及删除同级class的实现代码
Apr 04 #Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 #Javascript
详解vue 单页应用(spa)前端路由实现原理
Apr 04 #Javascript
vue cli升级webapck4总结
Apr 04 #Javascript
JavaScript实现短暂提示框功能
Apr 04 #Javascript
Vue filter介绍及详细使用
Apr 04 #Javascript
在Vue项目中引入腾讯验证码服务的教程
Apr 03 #Javascript
You might like
PHP 设计模式之观察者模式介绍
2012/02/22 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
PHP模板引擎Smarty中的保留变量用法分析
2016/04/11 PHP
PHP编程实现微信企业向用户付款的方法示例
2017/07/26 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
基于jquery实现的服务器验证控件的启用和禁用代码
2010/04/27 Javascript
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
js中call与apply的用法小结
2013/12/28 Javascript
js拆分字符串并将分割的数据放到数组中的方法
2015/05/06 Javascript
JQuery查找DOM节点的方法
2015/06/11 Javascript
javascript常用正则表达式汇总
2015/07/31 Javascript
javascript鼠标右键菜单自定义效果
2020/12/08 Javascript
Vuejs第六篇之Vuejs与form元素实例解析
2016/09/05 Javascript
js实现常见的工具条效果
2017/03/02 Javascript
vue2.0结合DataTable插件实现表格动态刷新的方法详解
2017/03/17 Javascript
vue.js自定义组件directives的实例代码
2018/11/09 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
layui 实现自动选择radio单选框(checked)的方法
2019/09/03 Javascript
es6数组的flat(),flatMap()函数用法实例分析
2020/04/18 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
[01:33]真香警告!DOTA2勇士令状不朽珍藏Ⅱ饰品欣赏
2018/06/26 DOTA
python实现的简单FTP上传下载文件实例
2015/06/30 Python
Python 使用SMTP发送邮件的代码小结
2016/09/21 Python
基于Python实现定时自动给微信好友发送天气预报
2018/10/25 Python
python+ffmpeg批量去视频开头的方法
2019/01/09 Python
django-filter和普通查询的例子
2019/08/12 Python
python3文件复制、延迟文件复制任务的实现方法
2019/09/02 Python
Python hashlib模块实例使用详解
2019/12/24 Python
pytorch方法测试——激活函数(ReLU)详解
2020/01/15 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
2020/04/23 Python
python文件操作seek()偏移量,读取指正到指定位置操作
2020/07/05 Python
创先争优活动方案
2014/02/12 职场文书
机械制造专业毕业生求职信
2014/03/02 职场文书
乡镇群众路线教育实践活动整改措施
2014/10/04 职场文书
个人租房协议书(范本)
2014/10/14 职场文书
2016年春季运动会通讯稿
2015/11/25 职场文书