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 核心参考教程 内置对象
Oct 13 Javascript
深入理解JavaScript系列(3) 全面解析Module模式
Jan 15 Javascript
Javascript 遮罩层和加载效果代码
Aug 01 Javascript
原生javascript实现无间缝滚动示例
Jan 28 Javascript
javascript中expression的用法整理
May 13 Javascript
使用jQuery实现验证上传图片的格式与大小
Dec 03 Javascript
分享几种比较简单实用的JavaScript tabel切换
Dec 31 Javascript
jquery实现下拉框多选方法介绍
Jan 03 Javascript
Angular4项目中添加i18n国际化插件ngx-translate的步骤详解
Jul 02 Javascript
jQuery实现点击下拉框中的值累加到文本框中的方法示例
Oct 28 jQuery
Vue 配合eiement动态路由,权限验证的方法
Sep 26 Javascript
Vue监听滚动实现锚点定位(双向)示例
Nov 13 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 变量定义方法
2009/06/14 PHP
PHP操作XML作为数据库的类
2010/12/19 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
跟随鼠标旋转的文字
2006/11/30 Javascript
jquery 如何动态添加、删除class样式方法介绍
2012/11/07 Javascript
jquery实现每个数字上都带进度条的幻灯片
2013/02/20 Javascript
jQuery制作简洁的多级联动Select下拉框
2014/12/23 Javascript
jquery判断至少有一个checkbox被选中的方法
2015/06/05 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
实例讲解避免javascript冲突的方法
2016/01/03 Javascript
AngularJS自定义插件实现网站用户引导功能示例
2016/11/07 Javascript
VUE页面中加载外部HTML的示例代码
2017/09/20 Javascript
Angular 容器部署的方法
2018/04/17 Javascript
解决JavaScript layui 下拉框不显示的问题
2018/08/14 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
vue实现直播间点赞飘心效果的示例代码
2019/09/20 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
vue之debounce属性被移除及处理详解
2019/11/13 Javascript
vue如何在项目中调用腾讯云的滑动验证码
2020/07/15 Javascript
[50:58]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 Mineski vs EG
2018/04/03 DOTA
python脚本实现统计日志文件中的ip访问次数代码分享
2014/08/06 Python
浅谈Python对内存的使用(深浅拷贝)
2018/01/17 Python
Django读取Mysql数据并显示在前端的实例
2018/05/27 Python
Django实现学员管理系统
2019/02/26 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
python中数组和矩阵乘法及使用总结(推荐)
2019/05/18 Python
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
华为俄罗斯官方网上商城:购买Huawei手机和平板
2017/04/21 全球购物
Liu Jo西班牙官网:意大利服装品牌
2019/09/11 全球购物
什么是就业协议书
2014/04/17 职场文书
四风问题个人剖析材料
2014/10/07 职场文书
领导干部作风建设工作总结
2014/10/23 职场文书
店长岗位职责
2015/02/11 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers
JS + HTML 罗盘式时钟的实现
2021/05/21 Javascript
ECharts transform数据转换和dataZoom在项目中使用
2022/12/24 Javascript