D3.js實(shí)現(xiàn)直方圖的方法詳解
一、直方圖簡(jiǎn)介
直方圖就是一種照片的分析方式,橫向代表亮度,縱向代表像素?cái)?shù)量。首先分析出照片中所有像素的亮度,然后計(jì)算出具體數(shù)值,再把它們映射到橫軸上。這樣的話,越高,這個(gè)亮度上的像素就越多。
直方圖的觀看規(guī)則就是“左黑右白”,左邊代表暗部,右邊代表亮部,而中間則代表中間調(diào)。
縱向上的高度代表像素密集程度,越高,代表的就是分布在這個(gè)亮度上的像素很多。
直方圖用于描述概率分布,D3 提供了直方圖的布局 Histogram 用于轉(zhuǎn)換數(shù)據(jù)。

假設(shè)有數(shù)組 a = [10, 11, 11.5, 12.5, 13, 15, 19, 20 ],現(xiàn)在把10~20的數(shù)值范圍分為5段,即:
10~12, 12~14, 14~16, 16~18, 18~20
那么數(shù)組 a 的各數(shù)值都落在這幾段區(qū)域的哪一部分呢?經(jīng)過(guò)計(jì)算,可以知道,這5段分別具有的元素個(gè)數(shù)為:
3, 2, 1, 0 , 2
將這個(gè)用圖形展示出來(lái)的,就是直方圖。
好了,開(kāi)始制作吧~
二、數(shù)據(jù)
首先生成隨機(jī)數(shù)據(jù):
var rand = d3.random.normal(0,25);
var dataset = [];
for(var i=0;i<100;i++){
dataset.push( rand() );
}
d3.random.normal 生成一個(gè)函數(shù),這個(gè)函數(shù)能夠按正態(tài)(高斯)分布隨機(jī)生成數(shù)值。要傳入兩個(gè)參數(shù),第一個(gè)是位置參數(shù),第二個(gè)是尺寸參數(shù)。關(guān)于正態(tài)分布的定義,可參見(jiàn)維基百科。將這個(gè)函數(shù)賦值給 rand 之后,接下來(lái)只要用 rand() 即可生成隨機(jī)數(shù)。
三、布局(數(shù)據(jù)轉(zhuǎn)換)
接下來(lái),要將上述數(shù)據(jù)進(jìn)行轉(zhuǎn)換,即確定一個(gè)區(qū)間和分隔數(shù)之后,另數(shù)組的數(shù)值落在各區(qū)域里。先定義一個(gè)布局:
var bin_num = 15;
var histogram = d3.layout.histogram()
.range([-50,50])
.bins(bin_num)
.frequency(true);
d3.layout.histogram: 直方圖的布局
range: 區(qū)間的范圍
bins: 分隔數(shù)
frequency: 若值為 true,則統(tǒng)計(jì)的是個(gè)數(shù);若值為 false,則統(tǒng)計(jì)的是概率
接下來(lái)即可轉(zhuǎn)換數(shù)據(jù):
var data = histogram(dataset);
來(lái)看看轉(zhuǎn)換前后的數(shù)據(jù)有什么分別吧。轉(zhuǎn)換前:

轉(zhuǎn)換后:

可以看到,轉(zhuǎn)換后的數(shù)組,長(zhǎng)度即分隔數(shù),每一個(gè)區(qū)間內(nèi)有落到此區(qū)間的數(shù)值(圖中的0,1,2,...),數(shù)值的個(gè)數(shù)(length),還
有三個(gè)參數(shù):
x: 區(qū)間的起始位置
dx: 區(qū)間的寬度
y: 落到此區(qū)間的數(shù)值的數(shù)量(如果 frequency 為 true);落到此區(qū)間的概率(如果 frequency 為 false)
四、繪制
繪制之前,需要定義一個(gè)比例尺,因?yàn)橥ǔN覀冃枰屴D(zhuǎn)換后的 y 在希望的范圍內(nèi)伸縮。
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");
//繪制坐標(biāo)軸的直線
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);
//繪制坐標(biāo)軸的分隔符直線
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);
});
五、總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望能對(duì)大家的學(xué)習(xí)或者工作帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
JavaScript語(yǔ)言精粹經(jīng)典實(shí)例(整理篇)
本文是小編日常讀書筆記整理有關(guān)javascript知識(shí),都是js精粹非常不錯(cuò),具有參考借鑒價(jià)值,特此分享到腳本之家平臺(tái)供大家參考2016-06-06
JavaScript快速排序(quickSort)算法的實(shí)現(xiàn)方法總結(jié)
快速排序的思想式 分治法,選一個(gè)基準(zhǔn)點(diǎn),然后根據(jù)大小進(jìn)行分配,分配然完畢之后,對(duì)已經(jīng)分配的進(jìn)行遞歸操作,最終形成快速排序,所以遞歸也是快速排序思想的一個(gè)重要組成部分,本文主要給大家介紹了JavaScript實(shí)現(xiàn)快速排序的寫法,需要的朋友可以參考下2023-11-11
JS實(shí)現(xiàn)自動(dòng)變化的導(dǎo)航菜單效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)自動(dòng)變化的導(dǎo)航菜單效果代碼,涉及JavaScript基于定時(shí)函數(shù)觸發(fā)頁(yè)面元素屬性動(dòng)態(tài)變換的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
JavaScript 筆記二 Array和Date對(duì)象方法
本篇主要講解本地對(duì)象Array和Date的各種方法。2010-05-05
微信小程序中使用自定義字體的實(shí)現(xiàn)與體驗(yàn)優(yōu)化
由于微信支持的字體非常有限,不能滿足個(gè)性化的需求,因此在開(kāi)發(fā)的過(guò)程中可能會(huì)需要使用自定義字體,下面這篇文章主要給大家介紹了關(guān)于微信小程序中使用自定義字體的實(shí)現(xiàn)與體驗(yàn)優(yōu)化的相關(guān)資料,需要的朋友可以參考下2022-02-02

