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 相关文章推荐
php和js对数据库图片进行等比缩放示例
Apr 28 Javascript
深入讲解AngularJS中的自定义指令的使用
Jun 18 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
Sep 14 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
Jun 08 Javascript
纯javaScript、jQuery实现个性化图片轮播【推荐】
Jan 08 Javascript
jQuery表单插件ajaxForm实例详解
Jan 17 Javascript
解决JS内存泄露之js对象和dom对象互相引用问题
Jun 25 Javascript
讲解vue-router之什么是动态路由
May 28 Javascript
微信小程序控制台提示warning:Now you can provide attr &quot;wx:key&quot; for a &quot;wx:for&quot; to improve performance解决方法
Feb 21 Javascript
详解基于vue-cli3快速发布一个fullpage组件
Mar 08 Javascript
vue element upload组件 file-list的动态绑定实现
Oct 11 Javascript
利用javaScript处理常用事件详解
Apr 14 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作的文本留言本的例子(四)
2006/10/09 PHP
收集的PHP中与数组相关的函数
2007/03/22 PHP
PHP 的异常处理、错误的抛出及回调函数等面向对象的错误处理方法
2012/12/07 PHP
今天你说520了吗?不仅有php表白书还有java表白神器
2016/05/20 PHP
一个对于js this关键字的问题
2007/01/09 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
基于jquery的代码显示区域自动拉长效果
2011/12/07 Javascript
jQuery中操控hidden、disable等无值属性的方法
2014/01/06 Javascript
JavaScript实现的双向跨域插件分享
2015/01/31 Javascript
浅谈Node.js中的定时器
2015/06/18 Javascript
javascript实现很浪漫的气泡冒出特效
2020/09/05 Javascript
jquery实现倒计时功能
2015/12/28 Javascript
Bootstrap零基础学习第一课之模板
2016/07/18 Javascript
一次$.getJSON不执行的简单记录
2016/07/19 Javascript
web 前端常用组件之Layer弹出层组件
2016/09/22 Javascript
Node.js开发第三方微信公众平台
2017/06/05 Javascript
vue-cli脚手架引入图片的几种方法总结
2018/03/13 Javascript
jQuery实现的监听导航滚动置顶状态功能示例
2018/07/23 jQuery
react 父子组件之间通讯props
2018/09/08 Javascript
js中位运算的运用实例分析
2018/12/11 Javascript
Vue实现日历小插件
2019/06/26 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
Vue watch响应数据实现方法解析
2020/07/10 Javascript
[02:31]2018年度DOTA2最具人气选手-完美盛典
2018/12/16 DOTA
Python Django给admin添加Action的方法实例详解
2019/04/29 Python
详细介绍Python进度条tqdm的使用
2019/07/31 Python
Theory美国官网:后现代都市风时装品牌
2018/05/09 全球购物
文科教师毕业的自我评价
2014/01/16 职场文书
运动会解说词200字
2014/02/06 职场文书
《路旁的橡树》教学反思
2014/04/07 职场文书
法人授权委托书格式
2014/04/08 职场文书
2014年创先争优活动总结
2014/05/04 职场文书
关于保护环境的标语
2014/06/09 职场文书
超市开店计划书
2014/09/15 职场文书
2014年社区宣传工作总结
2014/12/02 职场文书
小学运动会入场口号
2015/12/24 职场文书