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 相关文章推荐
javascript 对象的定义方法
Jan 10 Javascript
use jscript List Installed Software
Jun 11 Javascript
用javascript实现点击链接弹出&quot;图片另存为&quot;而不是直接打开
Aug 15 Javascript
js改变文章字体大小的实例代码
Nov 27 Javascript
JS控制输入框内字符串长度
May 21 Javascript
微信分享的标题、缩略图、连接及描述设置方法
Oct 14 Javascript
AngularJS指令详解及示例代码
Aug 16 Javascript
JavaScript获取URL中参数querystring的方法详解
Oct 11 Javascript
基于jQuery实现的打字机效果
Jan 16 Javascript
JavaScript中数组的各种操作的总结(必看篇)
Feb 13 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
Nov 22 Javascript
vue中使用heatmapjs的示例代码(结合百度地图)
Sep 05 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
无线电广播的开始
2002/01/30 无线电
php 注册时输入信息验证器的实现详解
2013/07/05 PHP
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
在Win7 中为php扩展配置Xcache
2014/10/08 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
2020/04/02 PHP
jquery 延迟执行实例介绍
2013/08/20 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
查看大图功能代码jquery版
2013/11/05 Javascript
探寻Javascript执行效率问题
2014/11/12 Javascript
jQuery中odd选择器的定义和用法
2014/12/23 Javascript
jQuery插件实现无缝滚动特效
2015/11/24 Javascript
实例讲解JavaScript中instanceof运算符的用法
2016/06/08 Javascript
Vue.js绑定HTML class数组语法错误的原因分析
2016/10/19 Javascript
Vue.js的复用组件开发流程完整记录
2018/11/29 Javascript
create-react-app使用antd按需加载的样式无效问题的解决
2019/02/26 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
node脚手架搭建服务器实现token验证的方法
2021/01/20 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python 文件和路径操作函数小结
2009/11/23 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
python调用matplotlib模块绘制柱状图
2019/10/18 Python
linux环境下安装python虚拟环境及注意事项
2020/01/07 Python
python zip()函数的使用示例
2020/09/23 Python
详解HTML5如何使用可选样式表为网站或应用添加黑暗模式
2020/04/07 HTML / CSS
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
Skyscanner新西兰:全球领先的旅游搜索网站
2019/08/26 全球购物
美国在线家具网站:GDFStudio
2021/03/13 全球购物
构造方法和其他方法的区别
2016/04/26 面试题
大专学生推荐信范文
2013/11/19 职场文书
高三毕业生自我鉴定
2013/12/20 职场文书
冰淇淋店的创业计划书
2014/02/07 职场文书
离婚被告答辩状
2015/05/22 职场文书
学校扫黄打非工作总结
2015/10/15 职场文书
高中历史教学反思
2016/02/19 职场文书