D3.js实现直方图的方法详解

一、直方图简介

直方图就是一种照片的分析方式,横向代表亮度,纵向代表像素数量。首先分析出照片中所有像素的亮度,然后计算出具体数值,再把它们映射到横轴上。这样的话,越高,这个亮度上的像素就越多。

直方图的观看规则就是“左黑右白”,左边代表暗部,右边代表亮部,而中间则代表中间调。

纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多。

直方图用于描述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据。

假设有数组 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); 

来看看转换前后的数据有什么分别吧。转换前:

转换后:

可以看到,转换后的数组,长度即分隔数,每一个区间内有落到此区间的数值(图中的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);
  }); 

五、总结

以上就是这篇文章的全部内容了,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • D3.js实现雷达图的方法详解

    前言 再简单介绍下D3.js,D3.js 是一个基于数据操作文档JavaScript库.D3帮助你给数据带来活力通过使用HTML.SVG和CSS.D3重视Web标准为你提供现代浏览器的全部功能,而不是给你一个专有的框架.结合强大的可视化组件和数据驱动方式Dom操作.这里也可以看到它是用SVG来呈现图表的,所以使用D3.js是需要一定的SVG基础的. 本文依然是先把简单的画图框架搭起来,添加SVG画布.这里和饼图有点类似,为了方便后面的绘制,我们把组合这些元素的g元素移动到画布的中心: <!DOC

  • 基于d3.js实现实时刷新的折线图

    先来看看效果图 下面直接上源代码,html文件 <html> <head> <meta charset="utf-8"> <title>实时刷新折线图</title> <style> .axis path, .axis line{ fill: none; stroke: black; shape-rendering: crispEdges; } .axis text { font-family: sans-seri

  • D3.js实现折线图的方法详解

    前言 D3.js是一个帮助开发者操纵基于数据的文档的JavaScript类库,在<D3.js实现柱状图的方法详解>中已经给大家介绍过如何用D3.js来实现一个简单的柱状图了,今天我们来学习用D3.js来实现折线图,感兴趣的朋友们下面来一起看看吧. 折线图由坐标轴.线条和点组成.和实现柱状图一样,我们还是先把大概的画图框架搭起来,代码如下(别忘了添加D3.js): <!DOCTYPE html> <html lang="en"> <head>

  • JavaScript可视化图表库D3.js API中文参考

    D3库所提供的所有 API 都在 d3 命名空间下.d3 库使用语义版本命名法(semantic versioning). 你可以用 d3.version 查看当前的版本信息. d3 (核心部分) 选择集 d3.select - 从当前文档中选择一系列元素. d3.selectAll - 从当前文档中选择多项元素. selection.attr - 设置或获取指定属性. selection.classed - 添加或删除选定元素的 CSS 类(CSS class). selection.styl

  • D3.js实现饼状图的方法详解

    前言 小编在之前已经跟大家分享过关于怎样用柱状图和折线图这两种基本图表.这两种图表都是有坐标轴的,现在来说一种没有坐标轴的图表--饼图. 饼状图实现 还是和之前一样,我们先把简单的画图框架搭起来,添加SVG画布.但是这里需要注意的是,为了方便后面画饼图上的弧形,我们把组合这些元素的g元素移动到画布的中心: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"

  • D3.js实现柱状图的方法详解

    D3.js介绍 D3.js 是一个基于数据操作文档JavaScript库.D3帮助你给数据带来活力通过使用HTML.SVG和CSS.D3重视Web标准为你提供现代浏览器的全部功能,而不是给你一个专有的框架.结合强大的可视化组件和数据驱动方式Dom操作.这里也可以看到它是用SVG来呈现图表的,所以使用D3.js是需要一定的SVG基础的. 如何用D3.js实现柱状图? 柱状图里面有坐标轴和柱子.然而我们还需要SVG画布来画这些东西.先把大概的画图框架搭起来,代码如下(请注意此时我在body标签里添加

  • 使用D3.js制作图表详解

    D3是用于数据可视化的Javascript库.使用SVG,Canvas和HTML.结合强大的可视化技术和数据驱动的DOM操作方法. D3与JQuery的区别 D3是数据驱动的,JQuery不是:我们使用JQuery直接操纵元素:但是使用D3 时我们需要通过D3专有的data(),enter()和exit()方法提供数据和回调,然后D3操作元素. D3通常用于数据可视化:JQuery用于创建Web应用.D3有很多数据可视化扩展:JQuery有很多Web应用插件.两者都是Javascript DOM

  • d3.js实现简单的网络拓扑图实例代码

    前言 了解了D3.js的基本开发和组件以后,我们开始应用它激动人心之处:绚丽的预定义图形,应用D3.js,我们在它的示例文件的基础上稍加变动即可应用于我们的数据可视化工作中,D3.js将后台的运算已经预定义好,我们只需少量代码和规范的数据,就能做出很花哨(请原谅我的用词不当)的效果. 力学图(也称为导向图,也有叫网络拓补图的,反正就是通过排斥得到关系远近的结构)在社交网络研究.信息传播途径等群体关系研究中应用非常广泛,它可以直观地反映群体与群体之间联系的渠道.交集多少,群体内部成员的联系强度等.

  • D3.js实现散点图和气泡图的方法详解

    前言 小编之前已经跟大家分享过了<D3.js实现柱状图的方法详解>和<D3.js实现折线图的方法详解>这两篇文章,已经介绍过柱状图和折线图了.下面就来说说和这两种非常相似的图表--散点图和气泡图.有需要的朋友们可以参考学习. 散点图和气泡图的实现 还是和之前一样,我们先把简单的画图框架搭起来,添加SVG画布: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q

  • D3.js实现直方图的方法详解

    一.直方图简介 直方图就是一种照片的分析方式,横向代表亮度,纵向代表像素数量.首先分析出照片中所有像素的亮度,然后计算出具体数值,再把它们映射到横轴上.这样的话,越高,这个亮度上的像素就越多. 直方图的观看规则就是"左黑右白",左边代表暗部,右边代表亮部,而中间则代表中间调. 纵向上的高度代表像素密集程度,越高,代表的就是分布在这个亮度上的像素很多. 直方图用于描述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据. 假设有数组 a = [10, 11, 11.5,

  • js控制台输出的方法(详解)

    console.log(object[, object, ...]) 在控制台输出一条消息.如果有多个参数,输出时会用空格隔开这些参数. 第一个参数可以是一个包含格式化占位符输出的字符串,例如: console.log("The %s jumped over %d tall buildings", animal, count); 上面的例子可以用下面的无格式化占位符输出的代码替换: console.log("The", animal, "jumped ov

  • JS截取字符串的方法详解

    substr() 方法 substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符. stringObject.substr(start,length) start:必需.要抽取的子串的起始下标.必须是数值.如果是负数,那么该参数声明从字符串的尾部开始算起的位置. 也就是说,-1 指字符串中最后一个字符,-2 指倒数第二个字符,以此类推. length:可选.子串中的字符数.必须是数值.如果省略了该参数,那么返回从 stringObject 的开始位置到结尾的字串. 记住: 

  • node.js连接mongoose数据库方法详解

    目录 创建项目命令 连接mongoose数据库 配置跨域 运行 创建项目命令 express --view ejs 项目名 进入项目,我们需要npm i 下载配置文件 有时候会出先端口已经被占用的情况,我们可以在bin目录下www文件中修改端口 连接mongoose数据库 我们创建一个新的文件夹,然后在文件夹下创建一个连接mongoose数据库的文件,代码如下 var mongoose=require('mongoose') mongoose.connect('mongodb://127.0.0

  • D3.js实现文本的换行详解

    一.文字换行是什么问题? 现有一字符串: var str = "云中谁寄锦书来,雁字回时,月满西楼"; 李清照的一剪梅,读过吗? 在 body 里添加一个 svg 元素,大小如下: var width = 300; var height = 300; var svg = d3.select("body") .append("svg") .attr("width",width) .attr("height",

  • d3.js入门教程之数据绑定详解

    前言 d3.js 是一款上手容易的js类库,专门用于绘制svg图形图表,其关键理念为data-join 意即数据绑定.搞清这个概念非常重要,它将以简洁优雅的形式体现数据驱动编程. 以下是Thinking with Joins的拙译 ,原作者Mike Bostock 假设你要用D3画一副散点图,因此需要生成一些 SVG circle 元素来直观地展现数据. 你会惊讶地发现D3没有提供原生的产生多个DOM元素的接口, 是的,只有一个 append 方法,用于产生单个DOM元素: svg.append

  • node.js发送邮件email的方法详解

    本文实例讲述了node.js发送邮件email的方法.分享给大家供大家参考,具体如下: 通常我们做node项目时,可能我们会碰到做一个简单的邮件反馈,那么我们今天就来讨论一下,其中遇到的各种坑. 总的来说做这个东西,我们可能需要node第三方依赖模块,来实现我们要达到的效果. 这里我推荐两个模块:https://github.com/pingfanren/Nodemailer npm install nodemailer //这个模块不错,github上星也比较多,还经常有维护,但是坑也比较多

  • JS访问DOM节点方法详解

    本文实例讲述了JS访问DOM节点方法.分享给大家供大家参考,具体如下: 查找并访问节点 你可通过若干种方法来查找您希望操作的元素: 通过使用 getElementById() 和 getElementsByTagName() 方法 通过使用一个元素节点的 parentNode.firstChild 以及 lastChild 属性 getElementById() 和 getElementsByTagName() getElementById() 和 getElementsByTagName()

  • JS碰撞运动实现方法详解

    本文实例分析了JS碰撞运动实现方法.分享给大家供大家参考,具体如下: 描述:撞到目标点弹回来(速度反转) 一.无重力的漂浮div var div1=document.getElementById("div1"); var iSpeedX=6; var iSpeedY=8; setInterval(function(){ var l=div1.offsetLeft+iSpeedX; var t=div1.offsetTop+iSpeedY; if(t>=document.docum

随机推荐