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表格行换色的三种实现方法
Jun 27 Javascript
jQuery提交表单ajax查询实例代码
Oct 07 Javascript
JS+CSS实现的经典圆角下拉菜单效果代码
Oct 21 Javascript
js实时获取窗口大小变化的实例代码
Nov 18 Javascript
浅谈Javascript事件对象
Feb 05 Javascript
vue.js实现数据动态响应 Vue.set的简单应用
Jun 15 Javascript
浅谈jQuery框架Ajax常用选项
Jul 08 jQuery
用Vue-cli搭建的项目中引入css报错的原因分析
Jul 20 Javascript
浅谈webpack-dev-server的配置和使用
May 17 Javascript
Vue.js子组件向父组件通信的方法实例代码详解
Dec 10 Javascript
mpvue开发音频类小程序踩坑和建议详解
Mar 12 Javascript
JS箭头函数和常规函数之间的区别实例分析【 5 个区别】
May 27 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
关于BIG5-HKSCS的解决方法
2007/03/20 PHP
PHP常用的缓存技术汇总
2014/05/05 PHP
PHP语法自动检查的Vim插件
2014/08/11 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
Some tips of wmi scripting in jscript (1)
2007/04/03 Javascript
JS实现self的resend
2010/07/22 Javascript
js中更短的 Array 类型转换
2011/10/30 Javascript
Javascript级联下拉菜单以及AJAX数据验证核心代码
2013/05/10 Javascript
node.js中的fs.fstat方法使用说明
2014/12/15 Javascript
给angular加上动画效遇到的问题总结
2016/02/17 Javascript
javascript实现一个简单的弹出窗
2016/02/22 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
2016/05/16 Javascript
AngularJS中的包含详细介绍及实现示例
2016/07/28 Javascript
vue-star评星组件开发实例
2018/03/01 Javascript
微信小程序开发之自定义tabBar的实现
2018/09/06 Javascript
JS实现深度优先搜索求解两点间最短路径
2019/01/17 Javascript
js观察者模式的弹幕案例
2020/11/23 Javascript
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
Python性能优化的20条建议
2014/10/25 Python
Mac中升级Python2.7到Python3.5步骤详解
2017/04/27 Python
Python爬虫实现(伪)球迷速成
2018/06/10 Python
使用pytorch进行图像的顺序读取方法
2018/07/27 Python
python  创建一个保留重复值的列表的补码
2018/10/15 Python
python存储16bit和32bit图像的实例
2018/12/05 Python
Python中作用域的深入讲解
2018/12/10 Python
python正则表达式匹配[]中间为任意字符的实例
2018/12/25 Python
Python实现点阵字体读取与转换的方法
2019/01/29 Python
详解numpy的argmax的具体使用
2019/05/27 Python
canvas之自定义头像功能实现代码示例
2017/09/29 HTML / CSS
莫斯科绝对前卫最秘密的商店:SVMoscow
2017/10/23 全球购物
华为c/c++笔试题
2016/01/25 面试题
几个Linux面试题笔试题
2012/12/01 面试题
商务英语专业毕业生自荐信
2013/11/05 职场文书
商铺门面租房协议书
2014/10/21 职场文书
浅析MySQL如何实现事务隔离
2021/06/26 MySQL
tomcat默认最大连接数及相关调整方法
2022/05/06 Servers