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 相关文章推荐
js监听输入框值的即时变化onpropertychange、oninput
Jul 13 Javascript
EditPlus注册码生成器(js代码实现)
Mar 25 Javascript
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
详细讲解JavaScript中的this绑定
Oct 10 Javascript
微信小程序 request接口的封装实例代码
Apr 26 Javascript
微信小程序url与token设置详解
Sep 26 Javascript
微信小程序tabBar用法实例详解
Dec 04 Javascript
常用的9个JavaScript图表库详解
Dec 19 Javascript
200行代码实现blockchain 区块链实例详解
Mar 14 Javascript
JavaScript创建对象的常用方式总结
Aug 10 Javascript
vue-cli配置flexible过程详解
Jul 04 Javascript
React 高阶组件HOC用法归纳
Jun 13 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中支持多种编码的中文字符串截取函数!
2007/03/20 PHP
彻底杜绝PHP的session cookie错误
2009/08/09 PHP
php中如何防止表单的重复提交
2013/08/02 PHP
一漂亮的PHP图片验证码实例
2014/03/21 PHP
PHP+Ajax检测用户名或邮件注册时是否已经存在实例教程
2014/08/23 PHP
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
PHP入门教程之数学运算技巧总结
2016/09/11 PHP
php读取出一个文件夹及其子文件夹下所有文件的方法示例
2017/06/15 PHP
thinkPHP5框架自定义验证器实现方法分析
2018/06/11 PHP
Jquery 获取checkbox的checked问题
2011/11/16 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
php与js的区别是什么
2013/08/05 Javascript
jQuery判断指定id的对象是否存在的方法
2015/05/22 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
jQuery EasyUI Draggable拖动组件
2017/03/01 Javascript
JavaScript实现两个select下拉框选项左移右移
2017/03/09 Javascript
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
NodeJS实现一个聊天室功能
2019/11/25 NodeJs
Vue实现PC端靠边悬浮球的代码
2020/05/09 Javascript
iview实现图片上传功能
2020/06/29 Javascript
python中virtualenvwrapper安装与使用
2018/05/20 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
对python中的控制条件、循环和跳出详解
2019/06/24 Python
django之静态文件 django 2.0 在网页中显示图片的例子
2019/07/28 Python
python文件和文件夹复制函数
2020/02/07 Python
CSS3 实现的缩略图悬停效果
2020/12/09 HTML / CSS
Europcar西班牙:全球汽车租赁领域的领导者
2018/09/17 全球购物
莫斯科珠宝厂官方网站:Miuz
2020/09/19 全球购物
const和static readonly区别
2013/05/20 面试题
社区维稳工作方案
2014/06/06 职场文书
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
乡镇党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
乡镇党建工作总结2015
2015/05/19 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
把77A收信机改造成收音机
2022/04/05 无线电
vue配置型表格基于el-table拓展之table-plus组件
2022/04/12 Vue.js