D3.js實(shí)現(xiàn)折線圖的方法詳解
前言
D3.js是一個(gè)幫助開發(fā)者操縱基于數(shù)據(jù)的文檔的JavaScript類庫(kù),在《D3.js實(shí)現(xiàn)柱狀圖的方法詳解》中已經(jīng)給大家介紹過(guò)如何用D3.js來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的柱狀圖了,今天我們來(lái)學(xué)習(xí)用D3.js來(lái)實(shí)現(xiàn)折線圖,感興趣的朋友們下面來(lái)一起看看吧。
折線圖由坐標(biāo)軸、線條和點(diǎn)組成。和實(shí)現(xiàn)柱狀圖一樣,我們還是先把大概的畫圖框架搭起來(lái),代碼如下(別忘了添加D3.js):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>折線圖</title> <style> .container { margin: 30px auto; width: 600px; height: 300px; border: 1px solid #000; } </style> </head> <body> <div class="container"> <svg width="100%" height="100%"></svg> </div> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script> window.onload = function() { var width = 600, height = 300; // SVG畫布邊緣與圖表內(nèi)容的距離 var padding = { top: 50, right: 50, bottom: 50, left: 50 }; // 創(chuàng)建一個(gè)分組用來(lái)組合要畫的圖表元素 var main = d3.select('.container svg').append('g') // 給這個(gè)分組加上main類 .classed('main') // 設(shè)置該分組的transform屬性 .attr('transform', "translate(" + padding.top + ',' + padding.left + ')'); }; </script> </body> </html>
坐標(biāo)軸的實(shí)現(xiàn)
要?jiǎng)?chuàng)建坐標(biāo)軸,需要先創(chuàng)建比例尺。在《D3.js實(shí)現(xiàn)柱狀圖的方法詳解》中提到過(guò)序數(shù)比例尺和線性比例尺,因?yàn)檎劬€的點(diǎn)與點(diǎn)之間是存在連續(xù)的關(guān)系的,所以折線圖的x軸和y軸我們都采用線性比例尺。
// 模擬數(shù)據(jù) var dataset = [ {x: 0, y: 11}, {x: 1, y: 35}, {x: 2, y: 23}, {x: 3, y: 78}, {x: 4, y: 55}, {x: 5, y: 18}, {x: 6, y: 98}, {x: 7, y: 100}, {x: 8, y: 22}, {x: 9, y: 65} ]; // 創(chuàng)建x軸的比例尺(線性比例尺) var xScale = d3.scale.linear() .domain(d3.extent(dataset, function(d) { return d.x; })) .range([0, width - padding.left - padding.right]); // 創(chuàng)建y軸的比例尺(線性比例尺) var yScale = d3.scale.linear() .domain([0, d3.max(dataset,function(d) { return d.y; })]) .range([height - padding.top - padding.bottom, 0]); // 創(chuàng)建x軸 var xAxis = d3.svg.axis() .scale(xScale) .orient('bottom'); // 創(chuàng)建y軸 var yAxis = d3.svg.axis() .scale(yScale) .orient('left'); // 添加SVG元素并與x軸進(jìn)行“綁定” main.append('g') .attr('class', 'axis') .attr('transform', 'translate(0,' + (height - padding.top - padding.bottom) + ')') .call(xAxis); // 添加SVG元素并與y軸進(jìn)行“綁定” main.append('g') .attr('class', 'axis') .call(yAxis);
這次我們模擬了一些點(diǎn)的數(shù)據(jù)來(lái)進(jìn)行折線的繪制。d3.scale.linear()
創(chuàng)建了線性比例尺,linear.domain()
定義定義域,linear.range()
定義值域。這里需要注意一下,因?yàn)镾VG畫布的y軸與傳統(tǒng)認(rèn)知上的y軸的方向是反著來(lái)的,所以在定義y軸的定義域和值域?qū)?yīng)關(guān)系時(shí),也需要反著來(lái)。d3.extent
可以得到參數(shù)數(shù)組中的最大值和最小值,并以數(shù)組的形式返回。然后用d3.svg.axis()
創(chuàng)建了兩個(gè)坐標(biāo)軸,把比例尺應(yīng)用到它們上面,并且用axis.orient()
設(shè)置了坐標(biāo)軸的刻度尺的方向。最后,添加SVG元素,用call()
把定義好的坐標(biāo)軸與SVG元素聯(lián)系起來(lái)。通過(guò)設(shè)置它們的transform屬性來(lái)移動(dòng)元素,使它們看起來(lái)像是一個(gè)坐標(biāo)系。
折線的實(shí)現(xiàn)
在D3.js中,需要先創(chuàng)建一個(gè)線的函數(shù),然后由該函數(shù)得出的值賦給代表折線的path元素的d屬性,才能繪制出折線。需要明確,line是一個(gè)函數(shù),不是一個(gè)對(duì)象。
具體的代碼如下:
// 添加折線 var line = d3.svg.line() .x(function(d) { return xScale(d.x) }) .y(function(d) { return yScale(d.y); }) // 選擇線條的類型 .interpolate('linear'); // 添加path元素,并通過(guò)line()計(jì)算出值來(lái)賦值 main.append('path') .attr('class', 'line') .attr('d', line(dataset));
這樣做了以后,我們得到了如下圖所示的一條線。
點(diǎn)的實(shí)現(xiàn)
點(diǎn)其實(shí)就是一個(gè)個(gè)的圓,所以在這里我們用SVG里的circle元素來(lái)畫點(diǎn)。
// 添加點(diǎn) main.selectAll('circle') .data(dataset) .enter() .append('circle') .attr('cx', function(d) { return xScale(d.x); }) .attr('cy', function(d) { return yScale(d.y); }) .attr('r', 5) .attr('fill', function(d, i) { return getColor(i); });
在main元素中選擇到所有的圓先“占位”(因?yàn)榇藭r(shí)選擇到的是一個(gè)空的集合,只是這個(gè)集合代表main中所有的圓),然后綁定dataset到此集合上,通過(guò)enter()
和append()
搭配使用添加新的circle元素直到集合元素個(gè)數(shù)與dataset子元素個(gè)數(shù)相同為止。用比例尺計(jì)算出各圓的坐標(biāo)并對(duì)其相關(guān)屬性進(jìn)行賦值,就完成了點(diǎn)的添加。
總結(jié)
以上就是利用D3.js實(shí)現(xiàn)折線圖的全部?jī)?nèi)容,希望這篇文章對(duì)大家的學(xué)習(xí)和工作能有所幫助。如果有疑問(wèn)大家可以留言交流,小編還會(huì)陸續(xù)更新關(guān)于D3.js的文章,請(qǐng)大家繼續(xù)關(guān)注腳本之家。
相關(guān)文章
返回頂部按鈕響應(yīng)滾動(dòng)且動(dòng)態(tài)顯示與隱藏
返回頂部功能在很多的網(wǎng)站上都有,判斷滾動(dòng)參數(shù)動(dòng)態(tài)顯示與隱藏,下面的示例很實(shí)用,喜歡的朋友可以收藏下2014-10-10JavaScript 中文轉(zhuǎn)拼音實(shí)現(xiàn)代碼 有些bug
在做項(xiàng)目時(shí)候遇到一個(gè)小小的顯示客戶部門名稱(拼音)的業(yè)務(wù),就是在部門名稱下有相應(yīng)的拼音,而在現(xiàn)有的數(shù)據(jù)庫(kù)中沒(méi)有相應(yīng)字段,并且部門數(shù)量比較多,添加起來(lái)比較費(fèi)時(shí),就想能否在js中實(shí)現(xiàn),在頁(yè)面中處理。2010-03-03編寫一個(gè)javascript元循環(huán)求值器的方法
這篇文章主要介紹了編寫一個(gè)javascript元循環(huán)求值器的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04