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基础学习资料
Nov 23 Javascript
让人期待的2011年度最佳 jQuery 插件分享
Mar 16 Javascript
sogou地图API用法实例教程
Sep 11 Javascript
javascript先序遍历DOM树的方法
Feb 27 Javascript
基于jQuery实现表格的查看修改删除
Aug 01 Javascript
JQuery遍历元素的后代和同胞实现方法
Sep 18 Javascript
jQuery中Nicescroll滚动条插件的用法
Nov 10 Javascript
Javascript中字符串replace方法的第二个参数探究
Dec 05 Javascript
全面总结Javascript对数组对象的各种操作
Jan 22 Javascript
Vue.js 插件开发详解
Mar 29 Javascript
Vue-cli项目部署到Nginx服务器的方法
Nov 01 Javascript
vue 实现tab切换保持数据状态
Jul 21 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中防止SQL注入实现代码
2011/02/19 PHP
PHP下判断网址是否有效的代码
2011/10/08 PHP
php三维数组去重(示例代码)
2013/11/26 PHP
php创建sprite
2014/02/11 PHP
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
jquery $.each() 使用小探
2013/08/23 Javascript
特殊情况下如何获取span里面的值
2014/05/20 Javascript
CSS3,HTML5和jQuery搜索框集锦
2014/12/02 Javascript
VUE使用vuex解决模块间传值问题的方法
2017/06/01 Javascript
解决vue里碰到 $refs 的问题的方法
2017/07/13 Javascript
JavaScript实现公告栏上下滚动效果
2020/03/13 Javascript
vue中jsonp插件的使用方法示例
2020/09/10 Javascript
vue添加自定义右键菜单的完整实例
2020/12/08 Vue.js
使用Python来编写HTTP服务器的超级指南
2016/02/18 Python
浅谈python字符串方法的简单使用
2016/07/18 Python
Python栈算法的实现与简单应用示例
2017/11/01 Python
python psutil库安装教程
2018/03/19 Python
Windows下PyCharm安装图文教程
2018/08/27 Python
Python的log日志功能及设置方法
2019/07/11 Python
python字符串切割:str.split()与re.split()的对比分析
2019/07/16 Python
TensorFlow保存TensorBoard图像操作
2020/06/23 Python
深入浅析Python代码规范性检测
2020/07/31 Python
html5设计原理(推荐收藏)
2014/05/17 HTML / CSS
将SVG图引入到HTML页面的实现
2019/09/20 HTML / CSS
阿迪达斯芬兰官方网站:adidas芬兰
2017/01/30 全球购物
.NET面试题:什么是反射
2016/09/30 面试题
学生实习自我鉴定
2013/10/11 职场文书
搞笑获奖感言
2014/01/30 职场文书
三月雷锋月活动总结
2014/07/03 职场文书
安全责任书范文
2014/08/25 职场文书
2014乡镇班子个人对照检查材料思想汇报
2014/09/26 职场文书
500字小学生检讨书
2015/02/19 职场文书
英语导游欢迎词
2015/09/30 职场文书
离婚协议书格式范本
2016/03/18 职场文书
退休劳动合同怎么写?
2019/10/25 职场文书
python实现图片九宫格分割的示例
2021/04/25 Python