D3.js实现折线图的方法详解


Posted in Javascript onSeptember 21, 2016

前言

D3.js是一个帮助开发者操纵基于数据的文档的JavaScript类库,在《D3.js实现柱状图的方法详解》中已经给大家介绍过如何用D3.js来实现一个简单的柱状图了,今天我们来学习用D3.js来实现折线图,感兴趣的朋友们下面来一起看看吧。

折线图由坐标轴、线条和点组成。和实现柱状图一样,我们还是先把大概的画图框架搭起来,代码如下(别忘了添加D3.js):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>折线图</title>
    <style>
      .container {
        margin: 30px auto;
        width: 600px;
        height: 300px;
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <svg width="100%" height="100%"></svg>
    </div>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script>
      window.onload = function() {
        var width = 600, height = 300;
        // SVG画布边缘与图表内容的距离
        var padding = { top: 50, right: 50, bottom: 50, left: 50 };
        // 创建一个分组用来组合要画的图表元素
        var main = d3.select('.container svg').append('g')
          // 给这个分组加上main类
          .classed('main')
          // 设置该分组的transform属性
          .attr('transform', "translate(" + padding.top + ',' + padding.left + ')');
      };
    </script>
  </body>
</html>

坐标轴的实现

要创建坐标轴,需要先创建比例尺。在《D3.js实现柱状图的方法详解》中提到过序数比例尺和线性比例尺,因为折线的点与点之间是存在连续的关系的,所以折线图的x轴和y轴我们都采用线性比例尺。

// 模拟数据
var dataset = [
  {x: 0, y: 11}, {x: 1, y: 35},
  {x: 2, y: 23}, {x: 3, y: 78},
  {x: 4, y: 55}, {x: 5, y: 18},
  {x: 6, y: 98}, {x: 7, y: 100},
  {x: 8, y: 22}, {x: 9, y: 65}
];
// 创建x轴的比例尺(线性比例尺)
var xScale = d3.scale.linear()
    .domain(d3.extent(dataset, function(d) {
      return d.x;
    }))
    .range([0, width - padding.left - padding.right]);
// 创建y轴的比例尺(线性比例尺)
var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset,function(d) {
      return d.y;
    })])
    .range([height - padding.top - padding.bottom, 0]);
// 创建x轴
var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient('bottom');
// 创建y轴
var yAxis = d3.svg.axis()
    .scale(yScale)
    .orient('left');
// 添加SVG元素并与x轴进行“绑定”
main.append('g')
    .attr('class', 'axis')
    .attr('transform', 'translate(0,' + (height - padding.top - padding.bottom) + ')')
    .call(xAxis);
// 添加SVG元素并与y轴进行“绑定”
main.append('g')
    .attr('class', 'axis')
    .call(yAxis);

这次我们模拟了一些点的数据来进行折线的绘制。d3.scale.linear()创建了线性比例尺,linear.domain()定义定义域,linear.range()定义值域。这里需要注意一下,因为SVG画布的y轴与传统认知上的y轴的方向是反着来的,所以在定义y轴的定义域和值域对应关系时,也需要反着来。d3.extent可以得到参数数组中的最大值和最小值,并以数组的形式返回。然后用d3.svg.axis()创建了两个坐标轴,把比例尺应用到它们上面,并且用axis.orient()设置了坐标轴的刻度尺的方向。最后,添加SVG元素,用call()把定义好的坐标轴与SVG元素联系起来。通过设置它们的transform属性来移动元素,使它们看起来像是一个坐标系。

D3.js实现折线图的方法详解

折线的实现

在D3.js中,需要先创建一个线的函数,然后由该函数得出的值赋给代表折线的path元素的d属性,才能绘制出折线。需要明确,line是一个函数,不是一个对象。

具体的代码如下:

// 添加折线
var line = d3.svg.line()
    .x(function(d) {
      return xScale(d.x)
    })
    .y(function(d) {
      return yScale(d.y);
    })
    // 选择线条的类型
    .interpolate('linear');
// 添加path元素,并通过line()计算出值来赋值
main.append('path')
    .attr('class', 'line')
    .attr('d', line(dataset));

这样做了以后,我们得到了如下图所示的一条线。

D3.js实现折线图的方法详解

点的实现

点其实就是一个个的圆,所以在这里我们用SVG里的circle元素来画点。

// 添加点
main.selectAll('circle')
    .data(dataset)
    .enter()
    .append('circle')
    .attr('cx', function(d) {
      return xScale(d.x);
    })
    .attr('cy', function(d) {
      return yScale(d.y);
    })
    .attr('r', 5)
    .attr('fill', function(d, i) {
      return getColor(i);
    });

在main元素中选择到所有的圆先“占位”(因为此时选择到的是一个空的集合,只是这个集合代表main中所有的圆),然后绑定dataset到此集合上,通过enter()append()搭配使用添加新的circle元素直到集合元素个数与dataset子元素个数相同为止。用比例尺计算出各圆的坐标并对其相关属性进行赋值,就完成了点的添加。

D3.js实现折线图的方法详解

总结

以上就是利用D3.js实现折线图的全部内容,希望这篇文章对大家的学习和工作能有所帮助。如果有疑问大家可以留言交流,小编还会陆续更新关于D3.js的文章,请大家继续关注三水点靠木。

Javascript 相关文章推荐
jQuery EasyUI 开源插件套装 完全替代ExtJS
Mar 24 Javascript
js和as的稳定传值问题解决
Jul 14 Javascript
基于原生js淡入淡出函数封装(兼容IE)
Oct 20 Javascript
javascript实现将数字转成千分位的方法小结【5种方式】
Dec 11 Javascript
利用Query+bootstrap和js两种方式实现日期选择器
Jan 10 Javascript
vue仿淘宝订单状态的tab切换效果
Jun 23 Javascript
微信小程序实现顶部下拉菜单栏
Nov 04 Javascript
前后端常见的几种鉴权方式(小结)
Aug 04 Javascript
小程序最新获取用户昵称和头像的方法总结
Sep 23 Javascript
js实现单元格拖拽效果
Feb 10 Javascript
深入解读VUE中的异步渲染的实现
Jun 19 Javascript
JavaScript实现多文件下载方法解析
Aug 07 Javascript
利用BootStrap弹出二级对话框的简单实现方法
Sep 21 #Javascript
angular route中使用resolve在uglify压缩后问题解决
Sep 21 #Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
Sep 21 #Javascript
D3.js实现柱状图的方法详解
Sep 21 #Javascript
AngularJS ng-style中使用filter
Sep 21 #Javascript
BootStrap与validator 使用笔记(JAVA SpringMVC实现)
Sep 21 #Javascript
JS实现简单的tab切换选项卡效果
Sep 21 #Javascript
You might like
随时给自己贴的图片加文字的php水印
2007/03/16 PHP
php绝对路径与相对路径之间关系的的分析
2010/03/03 PHP
PHP 开发环境配置(Zend Studio)
2010/04/28 PHP
php更改目录及子目录下所有的文件后缀的代码
2010/09/24 PHP
php的sso单点登录实现方法
2015/01/08 PHP
php返回相对时间(如:20分钟前,3天前)的方法
2015/04/14 PHP
PHP中类型转换 ,常量,系统常量,魔术常量的详解
2017/10/26 PHP
php中通用的excel导出方法实例
2017/12/30 PHP
Laravel 模型关联基础教程详解
2019/09/17 PHP
一段利用WSH修改和查看IP配置的代码
2008/05/11 Javascript
JQuery动态创建DOM、表单元素的实现代码
2011/08/09 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
jQuery插件MixItUp实现动画过滤和排序
2015/04/12 Javascript
Javascript简写条件语句(推荐)
2016/06/12 Javascript
JavaScript探测CSS动画是否已经完成的方法
2016/08/30 Javascript
VueJs路由跳转——vue-router的使用详解
2017/01/10 Javascript
基于AGS JS开发自定义贴图图层
2017/03/31 Javascript
Angular实现的敏感文字自动过滤与提示功能示例
2017/12/29 Javascript
webpack+vue-cil中proxyTable处理跨域的方法
2018/07/20 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
[09:47]2018DOTA2亚洲邀请赛4.5SOLO赛 No[o]ne vs Sumail
2018/04/06 DOTA
python k-近邻算法实例分享
2014/06/11 Python
python3.5使用tkinter制作记事本
2016/06/20 Python
Python文本处理之按行处理大文件的方法
2018/04/09 Python
PyQt5 QListWidget选择多项并返回的实例
2019/06/17 Python
Django 开发环境与生产环境的区分详解
2019/07/26 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
pycharm软件实现设置自动保存操作
2020/06/08 Python
Hotels.com英国:全球领先的酒店住宿提供商
2019/01/24 全球购物
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
2014年国培研修感言
2014/03/09 职场文书
爱国演讲稿400字
2014/05/07 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
2015年党员个人自我评价
2015/03/03 职场文书
nginx常用命令放入shell脚本详解
2021/03/31 Servers
原生JS中应该禁止出现的写法
2021/05/05 Javascript