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 相关文章推荐
火狐浏览器(firefox)下获得Event对象以及keyCode
Nov 13 Javascript
javascript Array.remove() 数组删除
Aug 06 Javascript
JavaScript的继承的封装介绍
Oct 15 Javascript
javascript中interval与setTimeOut的区别示例介绍
Mar 14 Javascript
node.js中的emitter.emit方法使用说明
Dec 10 Javascript
详谈LABJS按需动态加载js文件
May 07 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
Sep 08 Javascript
JS实现六边形3D拖拽翻转效果的方法
Sep 11 Javascript
使用Javascript监控前端相关数据的代码
Oct 27 Javascript
JS闭包的几种常见形式实例详解
Sep 16 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
Oct 10 jQuery
vue 项目打包时样式及背景图片路径找不到的解决方式
Nov 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
ThinkPHP3.2.2的插件控制器功能简述
2014/07/09 PHP
Codeigniter中mkdir创建目录遇到权限问题和解决方法
2014/07/25 PHP
PHP错误Warning:mysql_query()解决方法
2015/10/24 PHP
js 获取浏览器高度和宽度值(多浏览器)
2009/09/02 Javascript
javascript数字数组去重复项的实现代码
2010/12/30 Javascript
js匿名函数的调用示例(形式多种多样)
2014/08/20 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
JavaScript对表格或元素按文本,数字或日期排序的方法
2015/05/26 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
简单谈谈ES6的六个小特性
2016/11/18 Javascript
jQuery基于ajax操作json数据简单示例
2017/01/05 Javascript
js中的触发事件对象event.srcElement与event.target详解
2017/03/15 Javascript
原生JS+Canvas实现五子棋游戏实例
2017/06/19 Javascript
JavaScript中的高级函数
2018/01/04 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
json前后端数据交互相关代码
2018/09/19 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
2019/01/09 Javascript
vue-property-decorator用法详解
2019/12/12 Javascript
JavaScript实现移动端带transition动画的轮播效果
2020/03/24 Javascript
[44:10]2018DOTA2亚洲邀请赛 4.5 淘汰赛 EG vs VP 第一场
2018/04/06 DOTA
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
python中的函数用法入门教程
2014/09/02 Python
详解python脚本自动生成需要文件实例代码
2017/02/04 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
利用Pycharm断点调试Python程序的方法
2018/11/29 Python
Python判断一个文件夹内哪些文件是图片的实例
2018/12/07 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
2020/04/18 Python
CSS3网格的三个新特性详解
2014/04/04 HTML / CSS
最新的小工具和卓越的产品设计:Oh That Tech!
2019/08/07 全球购物
追悼会答谢词
2015/01/05 职场文书
倡议书作文
2015/01/19 职场文书
员工辞职信怎么写
2015/02/27 职场文书
学校远程教育工作总结
2015/08/11 职场文书
《藏戏》教学反思
2016/02/23 职场文书
Python使用protobuf序列化和反序列化的实现
2021/05/19 Python