zoukankan      html  css  js  c++  java
  • 【 D3.js 进阶系列 — 5.0 】 直方图

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

    501

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

    将这个用图形展示出来的,就是直方图。好了,開始制作吧~

    1. 数据

    首先生成随机数据:

    	var rand = d3.random.normal(0,25);
    	var dataset = [];
    	for(var i=0;i<100;i++){
    		dataset.push( rand() );
    	}

    d3.random.normal 生成一个函数,这个函数能够按正态(高斯)分布随机生成数值。要传入两个參数,第一个是位置參数,第二个是尺寸參数。关于正态分布的定义,可參见维基百科。将这个函数赋值给 rand 之后,接下来仅仅要用 rand() 就可以生成随机数。

    2. 布局(数据转换)

    接下来,要将上述数据进行转换,即确定一个区间和分隔数之后,另数组的数值落在各区域里。先定义一个布局:

    	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);

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

    502

    转换后:

    503

    能够看到,转换后的数组,长度即分隔数,每个区间内有落到此区间的数值(图中的0,1,2,...),数值的个数(length),还有三个參数:

    • x: 区间的起始位置
    • dx: 区间的宽度
    • y: 落到此区间的数值的数量(假设 frequency 为 true);落到此区间的概率(假设 frequency 为 false)

    3. 绘制

    绘制之前,须要定义一个比例尺,由于通常我们须要让转换后的 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);
    			});

    4. 结果

    结果图即本文开头的图片。

    完整代码请点击以下的链接后,单击右键后再“查看源码”:

    http://www.ourd3js.com/demo/J-5.0/histogram.html

    文档信息

  • 相关阅读:
    marginleft IE Firefox 浏览器下的不同
    提取HTML代码中文字的C#函数
    分享按钮汇总
    jquery UI集合
    向用户授予对象特权
    oracle中使用聚合函数
    创建对象类型
    jdk1.6.0_01配置系统环境变量
    修改表
    将一个实体映射到多张数据库表
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4466700.html
Copyright © 2011-2022 走看看