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中的this指针
Mar 18 Javascript
input标签内容改变的触发事件介绍
Jun 18 Javascript
JavaScript实现简单图片翻转的方法
Apr 17 Javascript
javascript中字体浮动效果的简单实例演示
Nov 18 Javascript
jQuery实现简易的输入框字数计数功能示例
Jan 16 Javascript
vue axios 表单提交上传图片的实例
Mar 16 Javascript
vue页面切换过渡transition效果
Oct 08 Javascript
vue实现点击追加选中样式效果
Nov 01 Javascript
JavaScript如何借用构造函数继承
Nov 06 Javascript
js实现简单贪吃蛇游戏
May 15 Javascript
简单了解three.js 着色器材质
Aug 03 Javascript
彻底搞懂并解决vue-cli4中图片显示的问题实现
Aug 31 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
《雄兵连》《烈阳天道》真的来了
2020/07/13 国漫
PHP4实际应用经验篇(7)
2006/10/09 PHP
探讨PHP中OO之静态关键字以及类常量的详解
2013/06/07 PHP
解析ajax事件的调用顺序
2013/06/17 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
php函数连续调用实例分析
2015/07/30 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
使用jQuery避免鼠标双击的解决方案
2013/08/21 Javascript
jQuery中关于ScrollableGridPlugin.js(固定表头)插件的使用逐步解析
2014/07/17 Javascript
javascript实现table选中的行以指定颜色高亮显示的方法
2015/05/13 Javascript
jquery自定义插件开发之window的实现过程
2016/05/06 Javascript
Jquery删除css属性的简单方法
2016/12/04 Javascript
Vue.js事件处理器与表单控件绑定详解
2017/03/20 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
2017/09/07 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
Javascript的console['']常用输入方法汇总
2018/04/26 Javascript
js字符串倒序的实例代码
2018/11/30 Javascript
详解基于vue-cli3快速发布一个fullpage组件
2019/03/08 Javascript
vue.js购物车添加商品组件的方法
2019/09/17 Javascript
Vue学习之常用指令实例详解
2020/01/06 Javascript
JS实现打砖块游戏
2020/02/14 Javascript
uni-app使用微信小程序云函数的步骤示例
2020/05/22 Javascript
JavaScript实现答题评分功能页面
2020/06/24 Javascript
pandas实现选取特定索引的行
2018/04/20 Python
python Cartopy的基础使用详解
2020/11/01 Python
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
接口的多继承会带来哪些问题
2015/08/17 面试题
英文版餐饮运营管理求职信
2013/11/06 职场文书
数控专业应届生求职信
2013/11/27 职场文书
给校长的一封检讨书
2014/09/20 职场文书
2014大学班主任工作总结
2014/11/08 职场文书
物业客服专员岗位职责
2015/04/07 职场文书
Nginx如何获取自定义请求header头和URL参数详解
2022/07/23 Servers
前端传参数进行Mybatis调用mysql存储过程执行返回值详解
2022/08/14 MySQL