D3.js实现直方图的方法详解


Posted in Javascript onSeptember 25, 2016

一、直方图简介

直方图就是一种照片的分析方式,横向代表亮度,纵向代表像素数量。首先分析出照片中所有像素的亮度,然后计算出具体数值,再把它们映射到横轴上。这样的话,越高,这个亮度上的像素就越多。

直方图的观看规则就是“左黑右白”,左边代表暗部,右边代表亮部,而中间则代表中间调。

纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多。

直方图用于描述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据。

D3.js实现直方图的方法详解

假设有数组 a = [10, 11, 11.5, 12.5, 13, 15, 19, 20 ],现在把10~20的数值范围分为5段,即:

10~12, 12~14, 14~16, 16~18, 18~20

那么数组 a 的各数值都落在这几段区域的哪一部分呢?经过计算,可以知道,这5段分别具有的元素个数为:

3, 2, 1, 0 , 2

将这个用图形展示出来的,就是直方图。

好了,开始制作吧~

二、数据

首先生成随机数据:

var rand = d3.random.normal(0,25); 
var dataset = []; 
for(var i=0;i<100;i++){ 
 dataset.push( rand() ); 
}

d3.random.normal 生成一个函数,这个函数能够按正态(高斯)分布随机生成数值。要传入两个参数,第一个是位置参数,第二个是尺寸参数。关于正态分布的定义,可参见维基百科。将这个函数赋值给 rand 之后,接下来只要用 rand() 即可生成随机数。

三、布局(数据转换)

接下来,要将上述数据进行转换,即确定一个区间和分隔数之后,另数组的数值落在各区域里。先定义一个布局:

var bin_num = 15; 
var histogram = d3.layout.histogram() 
   .range([-50,50]) 
    .bins(bin_num) 
   .frequency(true);

d3.layout.histogram: 直方图的布局

range: 区间的范围

bins: 分隔数

frequency: 若值为 true,则统计的是个数;若值为 false,则统计的是概率

接下来即可转换数据:

var data = histogram(dataset);

来看看转换前后的数据有什么分别吧。转换前:

D3.js实现直方图的方法详解

转换后:

D3.js实现直方图的方法详解

可以看到,转换后的数组,长度即分隔数,每一个区间内有落到此区间的数值(图中的0,1,2,...),数值的个数(length),还

有三个参数:

x: 区间的起始位置

dx: 区间的宽度

y: 落到此区间的数值的数量(如果 frequency 为 true);落到此区间的概率(如果 frequency 为 false)

四、绘制

绘制之前,需要定义一个比例尺,因为通常我们需要让转换后的 y 在希望的范围内伸缩。

var max_height = 400; 
var rect_step = 30; 
var heights = []; 
for(var i=0;i<data.length;i++){ 
 heights.push( data[i].y ); 
} 
var yScale = d3.scale.linear() 
     .domain([d3.min(heights),d3.max(heights)]) 
     .range([0,max_height]);

最后,绘制图形:

//绘制图形 
var graphics = svg.append("g") 
     .attr("transform","translate(30,20)"); 
 
//绘制矩形 
graphics.selectAll("rect") 
  .data(data) 
  .enter() 
  .append("rect") 
  .attr("x",function(d,i){ 
   return i * rect_step; 
  }) 
  .attr("y", function(d,i){ 
   return max_height - yScale(d.y); 
  }) 
  .attr("width", function(d,i){ 
   return rect_step - 2; 
  }) 
  .attr("height", function(d){ 
   return yScale(d.y); 
  }) 
  .attr("fill","steelblue"); 
 
//绘制坐标轴的直线 
graphics.append("line") 
  .attr("stroke","black") 
  .attr("stroke-width","1px") 
  .attr("x1",0) 
  .attr("y1",max_height) 
  .attr("x2",data.length * rect_step) 
  .attr("y2",max_height); 
 
//绘制坐标轴的分隔符直线 
graphics.selectAll(".linetick") 
  .data(data) 
  .enter() 
  .append("line") 
  .attr("stroke","black") 
  .attr("stroke-width","1px") 
  .attr("x1",function(d,i){ 
   return i * rect_step + rect_step/2; 
  }) 
  .attr("y1",max_height) 
  .attr("x2",function(d,i){ 
   return i * rect_step + rect_step/2; 
  }) 
  .attr("y2",max_height + 5); 
 
//绘制文字 
graphics.selectAll("text") 
  .data(data) 
  .enter() 
  .append("text") 
  .attr("font-size","10px") 
  .attr("x",function(d,i){ 
   return i * rect_step; 
  }) 
  .attr("y", function(d,i){ 
   return max_height; 
  }) 
  .attr("dx",rect_step/2 - 8) 
  .attr("dy","15px") 
  .text(function(d){ 
   return Math.floor(d.x); 
  });

五、总结

以上就是这篇文章的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
两种WEB下的模态对话框 (asp.net或js的分别实现)
Dec 02 Javascript
js的逻辑运算符 ||
May 31 Javascript
jQuery中ajax的post()方法用法实例
Dec 26 Javascript
javascript实现全局匹配并替换的方法
Apr 27 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
Jul 12 Javascript
Highcharts学习之数据列
Aug 03 Javascript
微信小程序 canvas API详解及实例代码
Oct 08 Javascript
JS解决移动web开发手机输入框弹出的问题
Mar 31 Javascript
js实现关闭网页出现是否离开提示
Dec 07 Javascript
JavaScript函数重载操作实例浅析
May 02 Javascript
微信小程序之高德地图多点路线规划过程示例详解
Jan 18 Javascript
关于antd tree 和父子组件之间的传值问题(react 总结)
Jun 02 Javascript
关于JS中二维数组的声明方法
Sep 24 #Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
Sep 24 #Javascript
浅谈JS中的!=、== 、!==、===的用法和区别
Sep 24 #Javascript
让DIV的滚动条自动滚动到最底部的3种方法(推荐)
Sep 24 #Javascript
浅谈js常用内置方法和对象
Sep 24 #Javascript
js原生跨域_用script标签的简单实现
Sep 24 #Javascript
js内置对象处理_打印学生成绩单的简单实现
Sep 24 #Javascript
You might like
PHP的SQL注入过程分析
2012/01/06 PHP
将php数组输出html表格的方法
2014/02/24 PHP
php之curl设置超时实例
2014/11/03 PHP
汇总PHPmailer群发Gmail的常见问题
2016/02/24 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
前端开发部分总结[兼容性、DOM操作、跨域等](持续更新)
2010/03/04 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
浅析node.js中close事件
2014/11/26 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
基于Bootstrap的Metronic框架实现条码和二维码的生成及打印处理操作
2016/08/29 Javascript
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
浅谈React中组件间抽象
2018/01/27 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
2018/02/01 Javascript
nodejs 使用http进行post或get请求的实例(携带cookie)
2019/01/03 NodeJs
深入浅出了解Node.js Streams
2019/05/27 Javascript
微信域名检测接口调用演示步骤(含PHP、Python)
2019/12/08 Javascript
解决vue-router 切换tab标签关闭时缓存问题
2020/07/22 Javascript
Python创建系统目录的方法
2015/03/11 Python
python制作企业邮箱的爆破脚本
2016/10/05 Python
神经网络python源码分享
2017/12/15 Python
django中静态文件配置static的方法
2018/05/20 Python
详解Python下Flask-ApScheduler快速指南
2018/11/04 Python
python实现Dijkstra算法的最短路径问题
2019/06/21 Python
python自动结束mysql慢查询会话的实例代码
2019/10/27 Python
Python 使用threading+Queue实现线程池示例
2019/12/21 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
2020/02/22 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
美国在线眼镜商城:Eyeglasses.com
2017/06/26 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
英语生日邀请函
2014/01/23 职场文书
马丁路德金演讲稿
2014/05/19 职场文书
组工干部演讲稿
2014/09/02 职场文书
党的群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
2016公务员年度考核评语
2015/12/01 职场文书
党校培训学习心得体会
2016/01/06 职场文书
PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库
2021/04/16 PHP