国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

D3.js實(shí)現(xiàn)柱狀圖的方法詳解

2019-11-20 08:55:40
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

D3.js介紹

D3.js 是一個(gè)基于數(shù)據(jù)操作文檔JavaScript庫(kù)。D3幫助你給數(shù)據(jù)帶來(lái)活力通過使用HTML、SVG和CSS。D3重視Web標(biāo)準(zhǔn)為你提供現(xiàn)代瀏覽器的全部功能,而不是給你一個(gè)專有的框架。結(jié)合強(qiáng)大的可視化組件和數(shù)據(jù)驅(qū)動(dòng)方式Dom操作。這里也可以看到它是用SVG來(lái)呈現(xiàn)圖表的,所以使用D3.js是需要一定的SVG基礎(chǔ)的。

如何用D3.js實(shí)現(xiàn)柱狀圖?

柱狀圖里面有坐標(biāo)軸和柱子。然而我們還需要SVG畫布來(lái)畫這些東西。先把大概的畫圖框架搭起來(lái),代碼如下(請(qǐng)注意此時(shí)我在body標(biāo)簽里添加了D3.js的script標(biāo)簽。這樣我們后面才能使用D3的方法):

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

為了把真實(shí)的數(shù)據(jù)與SVG畫布上的坐標(biāo)軸上的坐標(biāo)聯(lián)系起來(lái),我們需要定義比例尺來(lái)描述這樣的對(duì)應(yīng)關(guān)系。D3中常用的比例尺有線性比例尺和序數(shù)比例尺,它們的區(qū)別如圖所示:

從圖上可以看出,線性比例尺的對(duì)應(yīng)關(guān)系是連續(xù)的,而序數(shù)比例尺的對(duì)應(yīng)關(guān)系是離散的。分析柱狀圖的展現(xiàn)意義可以得出x軸應(yīng)該選用序數(shù)比例尺,而y軸選用線性比例尺。

// 模擬數(shù)據(jù)var dataset = { x: ["趙","錢","孫","李","周","吳","鄭","王"], y: [40, 30, 50, 70, 90, 20, 10, 40]};// 定義x軸的比例尺(序數(shù)比例尺)var xScale = d3.scale.ordinal()  .domain(dataset.x)  .rangeRoundBands([0, width - padding.left - padding.right],0,0);// 定義y軸的比例尺(線性比例尺)var yScale = d3.scale.linear()  .domain([0, d3.max(dataset.y)])  .range([height - padding.top - padding.bottom, 0]);// 定義x軸和y軸var xAxis = d3.svg.axis()  .scale(xScale)  .orient('bottom');var yAxis = d3.svg.axis()  .scale(yScale)  .orient('left');// 添加坐標(biāo)軸元素main.append('g')  .attr('class', 'axis')  .attr('transform', 'translate(0,' + (height - padding.bottom - padding.top) + ')')  .call(xAxis);main.append('g')  .attr('class', 'axis')  .call(yAxis); 

我們模擬了一些數(shù)據(jù),每個(gè)姓氏對(duì)應(yīng)了一個(gè)數(shù)值(從這里也可以看出序數(shù)比例尺的定義域上的值不一定是連續(xù)關(guān)系)。d3.scale.ordinal()創(chuàng)建了一個(gè)序數(shù)比例尺,而ordinal.domain()設(shè)置了該比例尺的定義域,ordinal.rangRoundBands()設(shè)置了值域。同理,d3.scale.linear()創(chuàng)建了一個(gè)線性比例尺,linear.domain()定義定義域,linear.range()定義值域。接著,我們用d3.svg.axis()創(chuàng)建了兩個(gè)坐標(biāo)軸,把比例尺應(yīng)用到它們上面,并且用axis.orient()設(shè)置了坐標(biāo)軸的刻度尺的方向。最后,添加SVG元素,用call()把定義好的坐標(biāo)軸與SVG元素聯(lián)系起來(lái)。通過設(shè)置它們的transform屬性來(lái)移動(dòng)元素,使它們看起來(lái)像是一個(gè)坐標(biāo)系。

這里需要注意以下幾點(diǎn):

     1、ordinal.domain的參數(shù)是一個(gè)表示一系列值的數(shù)組,而linear.domain的參數(shù)是一個(gè)表示范圍的數(shù)組。

     2、比例尺的本質(zhì)是一個(gè)函數(shù),它接收定義域上的值來(lái)得出對(duì)應(yīng)的值域上的值。

應(yīng)用序數(shù)比例尺的坐標(biāo)軸與線性比例尺的有很大不同,這里大概說(shuō)明一下。

  rangeRoundBands(interval, padding, outerPadding)中的padding和outerPadding都是可選的,默認(rèn)為0。如上圖所示的比例尺的代碼是這樣的。

var o = d3.scale.ordinal() .domain([0, 1, 2]) .rangeRoundBands([0, 100], 0.4, 0.1);

  domain的參數(shù)數(shù)組有多少個(gè)元素,就會(huì)有多少個(gè)rangeBand,rangeBand之間的間隔為padding*step(padding取值范圍為0到1),它與rangeBand的關(guān)系是均分一個(gè)step,比如padding為0.4,則rangeBand的長(zhǎng)度為0.6*step。根據(jù)上述代碼可得最終坐標(biāo)軸的長(zhǎng)度等于(0.1 + 2 + 0.6 + 0.1) * step,由此算出step的長(zhǎng)度,再推出外間距、rangeBand、內(nèi)間距的長(zhǎng)度。而定義域上的取值刻度定位在每個(gè)rangeBand的中間。于是得到了示意圖中的坐標(biāo)軸(紅色標(biāo)注)。

我們接著來(lái)畫柱狀圖,給坐標(biāo)軸設(shè)置一下樣式:

.axis path,.axis line { stroke: #000; fill: none;}

最終得到的柱狀圖的坐標(biāo)軸如下圖所示:

柱子的實(shí)現(xiàn)

柱子無(wú)非就是一個(gè)個(gè)矩形,在SVG中可以使用rect元素來(lái)畫。先選擇到main下所有bar類的元素(此時(shí)選擇到的是一個(gè)空的集合),把dataset.y綁定到這個(gè)集合上,用enter()對(duì)比綁定的數(shù)組元素個(gè)數(shù)與集合中的SVG元素個(gè)數(shù),與append()搭配使用,會(huì)自動(dòng)補(bǔ)齊至兩邊個(gè)數(shù)相等。每一次的append都對(duì)應(yīng)dataset.y中的一個(gè)數(shù)組元素。利用前面創(chuàng)建的比例尺函數(shù)計(jì)算出值并賦給舉行元素的x、y屬性。具體的代碼如下:

// 矩形之間的間距var rectMargin = 10;// 添加矩形main.selectAll('.bar')  .data(dataset.y)  .enter()  .append('rect')  .attr('class', 'bar')  .attr('x', function(d, i) {   return xScale(dataset.x[i]) + rectMargin;  })  .attr('y', function(d, i) {   return yScale(d);  })  .attr('width', xScale.rangeBand() - 2*rectMargin)  .attr('height', function(d, i) {   return height - padding.top - padding.bottom - yScale(d);  })  .attr('fill', function(d, i) {   return getColor(i);  });

至此,得到了如下圖所示的柱狀圖。

總結(jié)

以上就是利用D3.js實(shí)現(xiàn)柱狀圖的全部?jī)?nèi)容,感興趣的朋友們可以自己動(dòng)手實(shí)踐下,這樣更利于大家的理解和學(xué)習(xí),希望這篇文章對(duì)大家的學(xué)習(xí)和工作能有所幫助。如果有疑問大家可以留言交流,謝謝大家對(duì)武林網(wǎng)的支持,小編還會(huì)陸續(xù)更新關(guān)于D3.js的文章,請(qǐng)繼續(xù)關(guān)注武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平塘县| 赞皇县| 夹江县| 武邑县| 宜州市| 永丰县| 凤台县| 瓮安县| 旅游| 梧州市| 平远县| 观塘区| 县级市| 怀化市| 霸州市| 绍兴县| 宿州市| 始兴县| 呼图壁县| 双流县| 阳泉市| 泰宁县| 渝北区| 富裕县| 开封市| 温泉县| 察隅县| 宁陵县| 古丈县| 毕节市| 滕州市| 泸水县| 天气| 米林县| 乐业县| 达拉特旗| 阳西县| 嘉禾县| 松阳县| 扶绥县| 青州市|