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给input和textarea设定ie中的focus
May 29 Javascript
javascript下判断一个元素是否存在的代码
Mar 05 Javascript
UserData用法总结 lanyu出品
Jul 01 Javascript
JavaScript省市联动实现代码
Feb 15 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
JS及PHP代码编写八大排序算法
Jul 12 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
Sep 28 Javascript
Bootstrap源码解读按钮(5)
Dec 23 Javascript
浅谈Vue render函数在ElementUi中的应用
Sep 06 Javascript
VueCli3构建TS项目的方法步骤
Nov 07 Javascript
Nuxt.js实现一个SSR的前端博客的示例代码
Sep 06 Javascript
基于jQuery实现可编辑的表格
Dec 11 jQuery
关于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获取指定日期所在月的开始日期与结束日期
2013/08/01 PHP
关于PHP的curl开启问题探讨
2014/04/08 PHP
9个实用的PHP代码片段分享
2015/01/22 PHP
PHP扩展开发入门教程
2015/02/26 PHP
PHP生成条形码大揭秘
2015/09/24 PHP
PHP实现HTML页面静态化的方法
2015/11/04 PHP
ThinkPHP实现图片上传操作的方法详解
2017/05/08 PHP
Thinkphp 框架扩展之应用模式实现方法分析
2020/04/27 PHP
JavaScript的面向对象(二)
2006/11/09 Javascript
jQuery select操作控制方法小结
2010/05/26 Javascript
javascript一个无懈可击的实例化XMLHttpRequest的方法
2010/10/13 Javascript
js+html+css实现鼠标移动div实例
2013/01/30 Javascript
jQuery不间断滚动效果(模拟百度新闻支持文字/图片/垂直滚动)
2013/02/05 Javascript
Jquery加载时从后台读取数据绑定到dropdownList实例
2013/06/09 Javascript
JavaScript Ajax Json实现上下级下拉框联动效果实例代码
2013/11/23 Javascript
基于jQuery+JSON的省市二三级联动效果
2015/06/05 Javascript
Vue手把手教你撸一个 beforeEnter 钩子函数
2018/04/24 Javascript
python的常见命令注入威胁
2013/02/18 Python
python计算N天之后日期的方法
2015/03/31 Python
Python 爬虫之Beautiful Soup模块使用指南
2018/07/05 Python
python3.5基于TCP实现文件传输
2020/03/20 Python
使用Python快速制作可视化报表的方法
2019/02/03 Python
keras处理欠拟合和过拟合的实例讲解
2020/05/25 Python
python交互模式基础知识点学习
2020/06/18 Python
美国职棒大联盟官方网上商店:MLBShop.com
2017/11/12 全球购物
英国设计的甲板鞋和船鞋:Chatham
2018/12/06 全球购物
采购主管的岗位职责
2013/12/17 职场文书
车间操作工岗位职责
2013/12/19 职场文书
国际商贸专业自荐信
2014/06/09 职场文书
学习焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
党的群众路线教育实践活动心得体会(医院)
2014/11/03 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
2015新年联欢晚会开场白
2014/12/14 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
海底两万里读书笔记
2015/06/26 职场文书
vue中利用mqtt服务端实现即时通讯的步骤记录
2021/07/01 Vue.js