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 相关文章推荐
Jquery:ajax实现翻页无刷新功能代码
Aug 05 Javascript
Javascript学习笔记之 对象篇(四) : for in 循环
Jun 24 Javascript
jQuery+Ajax实现无刷新操作
Jan 04 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
Jan 26 Javascript
jQuery基于扩展简单实现倒计时功能的方法
May 14 Javascript
Javascript基础_标记文字的实现方法
Jun 14 Javascript
jQuery动态增减行的实例代码解析(推荐)
Dec 05 Javascript
js实现复选框的全选和取消全选效果
Jan 03 Javascript
Angular2入门--架构总览
Mar 29 Javascript
JS实现图片预览的两种方式
Jun 27 Javascript
js截取字符串功能的实现方法
Sep 27 Javascript
微信小游戏中three.js离屏画布的示例代码
Oct 12 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
PHPMailer的主要功能特点和简单使用说明
2014/02/17 PHP
php随机抽奖实例分析
2015/03/04 PHP
PHP判断IP并转跳到相应城市分站的方法
2015/03/25 PHP
CI框架实现框架前后端分离的方法详解
2016/12/30 PHP
浅析js设置控件的readonly与enabled属性问题
2013/12/25 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
举例说明如何为JavaScript的方法参数设置默认值
2015/11/17 Javascript
Vue表单实例代码
2016/09/05 Javascript
jQuery 实现图片的依次加载图片功能
2017/07/06 jQuery
利用Ionic2 + angular4实现一个地区选择组件
2017/07/27 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
2017/08/09 Javascript
详解微信小程序input标签正则初体验
2018/08/18 Javascript
JavaScript实现的前端AES加密解密功能【基于CryptoJS】
2018/08/28 Javascript
Angular请求防抖处理第一次请求失效问题
2019/05/17 Javascript
Vue.js组件实现选项卡以及切换特效
2019/07/24 Javascript
Vue简单封装axios之解决post请求后端接收不到参数问题
2020/02/16 Javascript
在Angular中实现一个级联效果的下拉框的示例代码
2020/05/20 Javascript
微信小程序实现星星评分效果
2020/11/01 Javascript
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
使用PDB简单调试Python程序简明指南
2015/04/25 Python
Python FTP两个文件夹间的同步实例代码
2018/05/25 Python
Python 字符串转换为整形和浮点类型的方法
2018/07/17 Python
在python plt图表中文字大小调节的方法
2019/07/08 Python
scrapy redis配置文件setting参数详解
2020/11/18 Python
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
路德维希•贝克(LUDWIG BECK)中文官网:德国大型美妆百货
2020/09/19 全球购物
当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
2014/09/09 面试题
模具设计与制造专业应届生求职信
2013/10/18 职场文书
教师个人的自我评价分享
2014/01/02 职场文书
村捐赠仪式答谢词
2014/01/21 职场文书
债务纠纷委托书范本
2014/10/14 职场文书
师德师风整改措施
2014/10/24 职场文书
通报表扬范文
2015/01/17 职场文书
行政助理岗位职责范本
2015/04/11 职场文书
商务英语邮件开头问候语
2015/11/10 职场文书
通过feDisplacementMap和feImage实现水波特效
2022/04/24 HTML / CSS