带玩具逛街时突然按下按钮的故事,丰满的妺妺3伦理播放,新婚人妻不戴套国产精品,大肉大捧一进一出好爽视频百度

利用HTML5 Canvas創建交互式Bubble Chart

轉載 1 收藏 評論
舉報 2012-04-23

眾所周知資訊圖像一種使數據易于理解和充滿娛樂性的方式。不同的人采用不同的方式使數據易于理解充滿娛樂性,一些人通過充滿創意的平面設計實現這個目標如打印資訊信息,另外也有一些人通過增加動畫和交互性實現目標。軟件工程師、研究者、業余設計師Josh Marinacci強烈推薦讀者看Hans Rosling教授和一群富有想象力的人的TED會談。這個會談揭露了關于發展中國家的共同的神話。會談中Rosling教授成功的關鍵是他采用一種非專業人士不能理解的方式渲染數據。他作品的核心是一個令人驚奇的Bubble Chart,可以隨著時間的推移比較世界上的各個地區的數據信息。


Josh Marinacci也在其博客中詳細地介紹了“如何利用HTML5 Canvas創建可以在移動桌面上運行的交互式圖表以及如何利用真實數據填充圖表。”下面讓我們跟隨作者學習如何創建我們自己的Bubble Chart。

來源:HTML5中國


準備工作:


需要知識:媒介HTML和JavaScript

需求:文本編輯器和現代瀏覽器


關于Bubble Chart


Bubble Chart就和它聽起來一樣是由氣泡組成的圖表,氣泡實際上就是一些圓。但是Bubble Chart卻能可視化五維數據,這也是其強大之處。每個氣泡代表由 X和Y坐標定位的數據點,這和任何其他的線狀圖和散點圖一樣。可是每個氣泡的大小和顏色屬性可以表示另外兩維的數據。如果我們動態顯示圖表,那么我們可以增加時間作為第五維數據。


盡管Bubble Chart的五個屬性都可以代表任何類型的數據,但是實踐中我們通常用X和Y坐標代表數字型數據,而氣泡顏色這個屬性用于區分兩個不同的數據集。例如利用X和Y分表代表兒童的“死亡數”和“受教育比例”,而氣泡顏色代表不同的國家。氣泡大小一般用來代表某種事物的數量如某個國家的人口。當動態顯示圖標時,第五維的坐標用來代表時間如表示從1960年到現在。仔細地創造性地使用這些氣泡屬性是創造出一個與眾不同的資訊圖標的關鍵。


利用模擬數據創建簡單的圖表


數據本身應該代表按照一定標準分組隨著時間變化的數據點。假設數據由5格國家,20個時間點(從1980到2000年)的數據組成。每個數據點由x、y和大小三個屬性組成。初始化這些模擬數據的代碼如下:


var data = [];
for(var t=0; t<20; t++) {
var cdata = [];
data[t] = cdata;
for(var country=0; country<5; country++) {
cdata.push({
x:50+Math.random()*500,
y:50+Math.random()*300 ,
size: 3+Math.random()*20,
country: country});
}
}

接下來在屏幕上用氣泡描繪出這些數據,代碼如下:


var canvas = document.getElementById(‘canvas’);
var ctx = canvas.getContext(’2d’);
var colors = ["red","green","blue","yellow","orange"];
var time = 0;
function draw() {
//bg and border
ctx.fillStyle = ”white”;
ctx.fillRect(0,0, canvas.width,canvas.height);
ctx.strokeStyle = ”black”;
ctx.strokeRect(0,0,canvas.width,canvas.height);
//time indicator
ctx.fillStyle = ”black”;
ctx.fillText(“time “ + time, 10,20);
//draw the data for the current time slice
data[time].forEach(function(d) {
ctx.save();
ctx.fillStyle = colors[d.country%colors.length];
ctx.globalAlpha = 0.5;
ctx.beginPath();
ctx.arc(d.x,d.y,d.size,0,Math.PI*2);
ctx.fill();
ctx.restore();
});

上述代碼用白色填充背景,利用Canvas邊框作為背景的邊界。然后描繪當前時間指示器,最后描繪數據本身。每個數據點都根據當前點的x、y和大小描繪成相應的圓。每個國家的顏色從定義的顏色列表中選取。


基本表如下:


為了增加表的時間屬性,我們只需要用不同的時間變量重復調用描繪函數重復描繪即可。代碼如下:


$(“#play”).click(function() {
var animdraw = function() {
draw();
time++;
if(time < data.length) {
setTimeout(animdraw,100);
} else {
time = 0;
}
}
animdraw();
});

獲取“世界數據銀行”的數據


至此已經創建了一個基本表。下面讓我們利用一些真實的數據填充這個表讓它更有意思。我們從“世界數據銀行”選擇需要的數據,它是一個龐大的組織,具有從UN和其他公開的數據源采集到的龐大的數據集。除了數據承載基地,它還有一個定制的報表生成器,它可以讓你創建數據切片以支持多種格式的數據下載。


本文選擇了“世界發展指標和全球發展金融”數據庫。選擇“東亞及太平洋地區”,“歐洲和中亞”,“拉丁美洲和加勒比地區”一些國家或地區作為集合,利用氣泡的顏色屬性表示不同的集合。選擇“死亡率”、“人口密度”、“總人口”作為研究點,分別用x、y坐標以及氣泡的大小屬性表示。最后選擇了時間變量。簡單的點擊“全選”按鈕即可選擇從1960年到現在以年為單位的數據變量。



現在我們已經選定了一份報告。點擊“導出”按鈕下載CSV文件格式的數據。我們可以利用Excel打開CSV文件查看從“世界數據銀行”所得到的這份報告的內容。如果你利用Excel打開下載的CSV文件,將看到每個國家或者地區都有三行組成,我們選擇的每個變量都有一行。另外你可能看到早年的一些數據值并不存在,這意味著那幾年并沒有收集這些國家的數據。


解析CSV數據


如果你用Excel打開報告,它看起來只是一堆行。我們需要把數據解析成我們能用的形式。為了解析數據文件,我們需要CSV解析程序。Josh Marinacci從Ben Nadel下載了一個解析程序,很好用。為了下載CSV文件并解析它Josh Marinacci使用AJAX調用jQuery。


$(“#load”).click(function() {
$.ajax({
url: ”data.csv”,
context: document.body,
success: function(c) {
var csvdata = CSVToArray(c);
console.log(“got to here “ + csvdata[1]);
}
});
}

CSV文件被解析成由許多行組成的文件,這些行可以繼續進行子劃分被劃分成列。我們可以通過先列循環再行循環的方式處理CSV文件。


data = [];
//start at 9 to skip non-year columns and first few years
for(var t=9; t
var cdata = [];
//loop through rows by threes
for(var i=1; i
var row_mort = csvdata[i];
var row_dens = csvdata[i+1];
var row_total = csvdata[i+2];
var country = (i-1)/3;
cdata.push({
x:row_dens[t] ,
y:row_mort[t],
size: row_total[t],
country: country,
});
}
data[t-9] = cdata;
}

注意上述代碼是從第9列開始處理數據的,不僅跳過了數據不完整的的前幾年的數據點也跳過了一些元數據(如國家名字等等)。處理行的時候每次循環是處理三行數據目的是通過一次循環可以處理一個國家或地區的數據。


如果僅僅按照這種方式處理數據,我們將什么都看不到。整個Canvas都被單一的顏色填充,這不是我們想要的結果。這是因為數據并沒有按比例進行適當的擴展。例如在1960年東亞和太平洋地區的人口是10億。為了描繪圖表需要按比例縮小這個值。為了適用于這些未修改的數據在繪制圖表的時Josh Marinacci使用了可擴展的功能。只需要采用如下方式改變弧度即可:


ctx.arc(
d.x*6,
canvas.height-d.y*2.5,
d.size/(1000*1000*11),
0,Math.PI*2

);


上述代碼修改了x、y和氣泡大小的值適應Canvas。氣泡大小必須除以1100萬才能得到合理的氣泡半徑。Y值由Canvas高度減去y乘以2.5得到。Canvas的標準坐標系要從左上方開始以便被Canvas高度減去之后可以翻轉y坐標。


修改數據變量的值是可以任意選取的,選擇某個特定的值是為了讓表格看起來比較美觀。具體選擇什么值依賴于正在描繪的數據。可以寫一個程序分析數據尋找合理的參數值,比如通過計算每一個變量的最大值或者最小值。


表格看起來如下:

增加交互性


賦予表格時間這一點很好,增加表格的交互性實際上就是讓圖表閱讀者通過點擊不同的氣泡獲取更多的信息。由于Canvas完全使用像素而不是我們需要的圖形,這種圖形使得通過程序我們可以計算哪一個圖形被點擊了。幸運地是Canvas中的氣泡都是完美的圓,這將使事情容易很多。我們只需要計算被點擊點與氣泡圓心的距離即可,如果距離小于半徑就認為該氣泡被點擊。代碼如下:


$(“#canvas”).mousedown(function(e) {
displayInfo = false;
data[time].forEach(function(d) {
var x = d.x*6;
var y = canvas.height-d.y*2.5;
var radius = d.size/(1000*1000*11);
var dis = dist(e.offsetX,e.offsetY,x,y);
if(dis < radius) {
displayInfo = true;
displayCountry = d.country;
}
});
draw();

});


如果讀者已經點擊了某個圖形,顯示信息的布爾值將變為“true”,保存當前的國家并觸發重繪操作,同時在右上方通過代碼嵌入一個小的信息板。


注意在重繪代碼中填充的數據是來自于當前時間片而不是用戶點擊表格時的時間。這就意味著當表格被賦予時間屬性之后顯示的內容將更新以便用戶可以看到隨著時間變化的數據。


if(displayInfo) {
ctx.save();
ctx.translate(canvas.width-305,5);
ctx.fillStyle = ”rgba(200,200,200,0.7)”;
ctx.fillRect(0,0,300,100);
ctx.strokeStyle = ”black”;
ctx.lineWidth = 2;
ctx.strokeRect(0,0,300,100);
ctx.fillStyle = ”black”;
var displayPoint = data[time][displayCountry];
ctx.fillText(“Region: “ + regions[displayPoint.country],5,20);
ctx.fillText(“Population Density: “ + displayPoint.x,5,20+20*1);
ctx.fillText(“Mortality rate: “ + displayPoint.y,5,20+20*2);
ctx.fillText(“Population: “ + displayPoint.size,5,20+20*3);
ctx.restore();

}


改變圖表的視覺效果


一般而言圖報表不應該有這么多的可視元素否則將減損數據的潛在表現性,但是選擇一個完美的顏色和模式將產生巨大的差別。為了讓這個表看起來更好,Josh Marinacci給每個氣泡增加了一層白色覆蓋物使圓更加完美。同時也給每個圓增加一個黑色的邊框并為每個集合選擇不同的顏色。相對于計算每個氣泡顏色的漸變度Josh Marinacci采用先選擇一個基本的顏色然后改變它的透明度的方式為每個不同的氣泡選擇顏色。


var radgrad = ctx.createRadialGradient(
x-radius/10,y-radius/10,0,
x-radius/10,y-radius/10,radius+30);
radgrad.addColorStop(0,   ’white’);
radgrad.addColorStop(0.5, ’white’);
radgrad.addColorStop(1,   ’rgba(255,255,255,0.3)’);
ctx.globalAlpha = 0.6;
ctx.fillStyle = radgrad;

ctx.fill();


為了使圖表更加美觀上述代碼改變了字體增加了邊框,使用了一個來自于Subtle Patterns網站充滿娛樂性的背景。最終圖表如下:


總結


上面就是創建Bubble Chart的基本過程。利用上面的基本圖表你可以創建自己的Bubble Chart。你可以增加數據自動調整功能,讓圖表閱讀者自己選擇數據集合擴大或者縮小,你也可以在每個時間間隔中插入時間使時間劃分更細,動態過程更流暢。


你可以從這獲取工程源碼,也可以從作者的個人網站JoshOnDesign.com獲取。


本文系作者授權數英發表,內容為作者獨立觀點,不代表數英立場。
轉載請在文章開頭和結尾顯眼處標注:作者、出處和鏈接。不按規范轉載侵權必究。
本文系作者授權數英發表,內容為作者獨立觀點,不代表數英立場。
未經授權嚴禁轉載,授權事宜請聯系作者本人,侵權必究。
本內容為作者獨立觀點,不代表數英立場。
本文禁止轉載,侵權必究。
本文系數英原創,未經允許不得轉載。
授權事宜請至數英微信公眾號(ID: digitaling) 后臺授權,侵權必究。

    評論

    文明發言,無意義評論將很快被刪除,異常行為可能被禁言
    DIGITALING
    登錄后參與評論

    評論

    文明發言,無意義評論將很快被刪除,異常行為可能被禁言
    800

    推薦評論

    暫無評論哦,快來評論一下吧!

    全部評論(0條)

    主站蜘蛛池模板: 盖州市| 邯郸县| 诏安县| 甘德县| 大邑县| 桦川县| 昆明市| 邢台县| 大新县| 阿坝| 丰城市| 浮梁县| 萨嘎县| 改则县| 平泉县| 鄂托克旗| 烟台市| 象山县| 壶关县| 和硕县| 双牌县| 桐庐县| 太谷县| 花垣县| 霍林郭勒市| 太仓市| 泽库县| 枞阳县| 米泉市| 莱芜市| 桂阳县| 吐鲁番市| 乐昌市| 开平市| 桐梓县| 罗定市| 柘城县| 天镇县| 瑞丽市| 都匀市| 石阡县|