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 相关文章推荐
jquery attr方法获取input的checked属性问题
May 26 Javascript
判断iframe里的页面是否加载完成
Jun 06 Javascript
使用JS画图之点、线、面
Jan 12 Javascript
JS实现从连接中获取youtube的key实例
Jul 02 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
Aug 17 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
Feb 17 Javascript
在Docker快速部署Node.js应用的详细步骤
Sep 02 Javascript
BootStrap Tooltip插件源码解析
Dec 27 Javascript
微信小程序 tabs选项卡效果的实现
Jan 05 Javascript
Javascript中的prototype与继承
Feb 06 Javascript
js中split()方法得到的数组长度问题
Jul 19 Javascript
VSCode插件安装完成后的配置(常用配置)
Aug 24 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设计模式 Interpreter(解释器模式)
2011/06/26 PHP
基于flush()不能按顺序输出时的解决办法
2013/06/29 PHP
php+mysql数据库实现无限分类的方法
2014/12/12 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
thinkPHP+PHPExcel实现读取文件日期的方法(含时分秒)
2016/07/07 PHP
修改Laravel5.3中的路由文件与路径
2016/08/10 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
Laravel中的Auth模块详解
2017/08/17 PHP
php中上传文件的的解决方案
2018/09/25 PHP
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
2012/01/15 Javascript
Javascript开发之三数组对象实例介绍
2012/11/12 Javascript
jquery弹出框的用法示例(2)
2013/08/26 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
JavaScript和jQuery制作光棒效果
2017/02/24 Javascript
在vue-cli项目中使用bootstrap的方法示例
2018/04/21 Javascript
原生JS封装_new函数实现new关键字的功能
2018/08/12 Javascript
Vue中控制v-for循环次数的实现方法
2018/09/26 Javascript
详解从react转职到vue开发的项目准备
2019/01/14 Javascript
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
Python中max函数用法实例分析
2015/07/17 Python
Python实现树莓派WiFi断线自动重连的实例代码
2017/03/16 Python
对python 中class与变量的使用方法详解
2019/06/26 Python
Python Pandas实现数据分组求平均值并填充nan的示例
2019/07/04 Python
pandas的resample重采样的使用
2020/04/24 Python
前端H5 Video常见使用场景简介
2020/08/21 HTML / CSS
粉红色的鲸鱼:Vineyard Vines
2018/02/17 全球购物
UNIONBAY官网:美国青少年服装品牌
2019/03/26 全球购物
学生档案自我鉴定
2013/10/07 职场文书
毕业生实习鉴定
2013/12/11 职场文书
社会调查研究计划书
2014/05/01 职场文书
2014年四风问题自我剖析材料
2014/09/15 职场文书
公安局班子个人对照检查材料思想汇报
2014/10/09 职场文书
python之json文件转xml文件案例讲解
2021/08/07 Python
golang操作rocketmq的示例代码
2022/04/06 Golang
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android