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 事件队列调整方法
Sep 18 Javascript
jquery.boxy弹出框(后隔N秒后自动隐藏/自动跳转)
Jan 15 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
javascript实现简单的全选和反选功能
Jan 05 Javascript
使用JS实现图片展示瀑布流效果(简单实例)
Sep 06 Javascript
JavaScript对象创建模式实例汇总
Oct 03 Javascript
easyUI下拉列表点击事件使用方法
May 18 Javascript
基于JavaScript实现飘落星星特效
Aug 10 Javascript
Angular 4.0学习教程之架构详解
Sep 12 Javascript
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
angular 未登录状态拦截路由跳转的方法
Oct 09 Javascript
JS定时器如何实现提交成功提示功能
Jun 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
一周让你学会PHP 不错的学习资料
2009/02/06 PHP
PHP时间和日期函数详解
2015/05/08 PHP
php获取汉字拼音首字母的方法
2015/10/21 PHP
php删除一个路径下的所有文件夹和文件的方法
2018/02/07 PHP
JS和jquery获取各种屏幕的宽度和高度的代码
2013/08/02 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
js去除输入框中所有的空格和禁止输入空格的方法
2014/06/09 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
2014/08/30 Javascript
PHP守护进程实例
2015/03/06 Javascript
浅谈js中的闭包
2015/03/16 Javascript
实例讲解javascript注册事件处理函数
2016/01/09 Javascript
js简单实现图片延迟加载的方法
2016/07/19 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
Html5 js实现手风琴效果
2020/04/17 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
微信小程序实现选择地址省市区三级联动
2020/06/21 Javascript
Python中的map()函数和reduce()函数的用法
2015/04/27 Python
设计模式中的原型模式在Python程序中的应用示例
2016/03/02 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
Python绘制3D图形
2018/05/03 Python
python 实现读取一个excel多个sheet表并合并的方法
2019/02/12 Python
Python通过2种方法输出带颜色字体
2020/03/02 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
2020/07/28 Python
Python实现自动整理文件的脚本
2020/12/17 Python
CSS教程:CSS3圆角属性
2009/04/02 HTML / CSS
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
2014年计生标语
2014/06/23 职场文书
大学第二课堂活动总结
2014/07/08 职场文书
重阳节演讲稿:尊敬帮助老人 弘扬传统美德
2014/09/25 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
后勤工作个人总结
2015/02/28 职场文书
美丽的大脚观后感
2015/06/03 职场文书
2016年元旦寄语
2015/08/17 职场文书
2016党校培训心得体会
2016/01/07 职场文书
Nginx配置根据url参数重定向
2022/04/11 Servers