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

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

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

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

前言

小編在之前已經(jīng)跟大家分享過(guò)關(guān)于怎樣用柱狀圖折線(xiàn)圖這兩種基本圖表。這兩種圖表都是有坐標(biāo)軸的,現(xiàn)在來(lái)說(shuō)一種沒(méi)有坐標(biāo)軸的圖表――餅圖。

餅狀圖實(shí)現(xiàn)

還是和之前一樣,我們先把簡(jiǎn)單的畫(huà)圖框架搭起來(lái),添加SVG畫(huà)布。但是這里需要注意的是,為了方便后面畫(huà)餅圖上的弧形,我們把組合這些元素的g元素移動(dòng)到畫(huà)布的中心:

<!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;  // 創(chuàng)建一個(gè)分組用來(lái)組合要畫(huà)的圖表元素  var main = d3.select('.container svg').append('g')   .classed('main', true)   // 注意這里和前面幾種圖表的差別   .attr('transform', "translate(" + width/2 + ',' + height/2 + ')');  }; </script> </body></html> 

模擬數(shù)據(jù)并轉(zhuǎn)化

為了畫(huà)餅圖,我們模擬了一些這樣的數(shù)據(jù)。

// 模擬數(shù)據(jù)var dataset = [ {name: '購(gòu)物', value: 983}, {name: '日常飲食', value: 300}, {name: '醫(yī)藥', value: 1400}, {name: '交通', value: 402}, {name: '雜費(fèi)', value: 134}];

在柱狀圖等有坐標(biāo)軸的圖表中,我們通過(guò)創(chuàng)建合適的比例尺來(lái)將模擬好的數(shù)據(jù)轉(zhuǎn)化成適合畫(huà)圖的數(shù)據(jù),那在餅圖里,又用什么來(lái)轉(zhuǎn)化呢?看這里~

// 轉(zhuǎn)換原始數(shù)據(jù)為能用于繪圖的數(shù)據(jù)var pie = d3.layout.pie()  .sort(null)  .value(function(d) {   return d.value;  });// pie是一個(gè)函數(shù) var pieData = pie(dataset);

layout叫做布局,在D3.js中它提供了一些轉(zhuǎn)化成特定圖表數(shù)據(jù)的函數(shù),如其中就包括餅圖。它提供一個(gè)基礎(chǔ)的轉(zhuǎn)化函數(shù),在此基礎(chǔ)上我們根據(jù)自己的需要再對(duì)該函數(shù)進(jìn)行進(jìn)一步的設(shè)置,就得到了如上述代碼中pie變量保存的函數(shù)一樣的轉(zhuǎn)化工具,通過(guò)把原始的數(shù)據(jù)dataset傳入pie中就能得到繪圖數(shù)據(jù)pieData。

具體的變化我們可以看下圖。

左邊是轉(zhuǎn)化前的原始的數(shù)據(jù)結(jié)構(gòu),右邊是轉(zhuǎn)化后的適合繪圖的數(shù)據(jù)結(jié)構(gòu)。可以看到,在保留原本的數(shù)據(jù)的基礎(chǔ)上,轉(zhuǎn)化后的數(shù)據(jù)新增了該項(xiàng)在整個(gè)餅圖中的起始角度(startAngle和endAngle),以及弧形之間的間隙角度(padAngle)。

計(jì)算弧形路徑

在餅圖中,我們用SVG中的path元素來(lái)表示每一塊弧形,而從pieData到path元素的d屬性還是有一定的距離,所以我還需要再通過(guò)一步操作來(lái)用pieData計(jì)算出d屬性可用的值。

// 創(chuàng)建計(jì)算弧形路徑的函數(shù)var radius = 100;var arc = d3.svg.arc() .innerRadius(0) .outerRadius(radius); 

添加弧形

上面的代碼用svg.arc()創(chuàng)建了一個(gè)計(jì)算弧形路徑的函數(shù),通過(guò)這個(gè)函數(shù)就可以計(jì)算出path的d屬性的值,就像下面這樣。

// 添加弧形main.selectAll('g') .data(pieData) .enter() .append('path') .attr('fill', function(d, i) {  return getColor(i); }) .attr('d', function(d){  return arc(d); });

好了,餅圖就這樣畫(huà)好了。

下面給大家分享個(gè)實(shí)例代碼,實(shí)現(xiàn)餅圖中加上下圖這樣的文字標(biāo)簽。

效果圖

實(shí)例代碼

<!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;  }  polyline {  fill: none;  stroke: #000000;  stroke-width: 2px;  stroke-dasharray: 5px;  } </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;  // 創(chuàng)建一個(gè)分組用來(lái)組合要畫(huà)的圖表元素  var main = d3.select('.container svg').append('g')   .classed('main', true)   .attr('transform', "translate(" + width/2 + ',' + height/2 + ')');  // 模擬數(shù)據(jù)  var dataset = [   {name: '購(gòu)物', value: 983},   {name: '日常飲食', value: 300},   {name: '醫(yī)藥', value: 1400},   {name: '交通', value: 402},   {name: '雜費(fèi)', value: 134}  ];  // 轉(zhuǎn)換原始數(shù)據(jù)為能用于繪圖的數(shù)據(jù)  var pie = d3.layout.pie()   .sort(null)   .value(function(d) {    return d.value;   });  // pie是一個(gè)函數(shù)  var pieData = pie(dataset);  // 創(chuàng)建計(jì)算弧形路徑的函數(shù)  var radius = 100;  var arc = d3.svg.arc()   .innerRadius(0)   .outerRadius(radius);  var outerArc = d3.svg.arc()   .innerRadius(1.2 * radius)   .outerRadius(1.2 * radius);  var oArc = d3.svg.arc()   .innerRadius(1.1 * radius)   .outerRadius(1.1 * radius);  var slices = main.append('g').attr('class', 'slices');  var lines = main.append('g').attr('class', 'lines');  var labels = main.append('g').attr('class', 'labels');  // 添加弧形元素(g中的path)  var arcs = slices.selectAll('g')   .data(pieData)   .enter()   .append('path')   .attr('fill', function(d, i) {    return getColor(i);   })   .attr('d', function(d){    return arc(d);   });  // 添加文字標(biāo)簽  var texts = labels.selectAll('text')   .data(pieData)   .enter()   .append('text')   .attr('dy', '0.35em')   .attr('fill', function(d, i) {    return getColor(i);   })   .text(function(d, i) {    return d.data.name;   })   .style('text-anchor', function(d, i) {    return midAngel(d)<Math.PI ? 'start' : 'end';   })   .attr('transform', function(d, i) {    // 找出外弧形的中心點(diǎn)    var pos = outerArc.centroid(d);    // 改變文字標(biāo)識(shí)的x坐標(biāo)    pos[0] = radius * (midAngel(d)<Math.PI ? 1.5 : -1.5);    return 'translate(' + pos + ')';   })   .style('opacity', 1);  var polylines = lines.selectAll('polyline')   .data(pieData)   .enter()   .append('polyline')   .attr('points', function(d) {    return [arc.centroid(d), arc.centroid(d), arc.centroid(d)];   })   .attr('points', function(d) {    var pos = outerArc.centroid(d);    pos[0] = radius * (midAngel(d)<Math.PI ? 1.5 : -1.5);    return [oArc.centroid(d), outerArc.centroid(d), pos];   })   .style('opacity', 0.5);  };  function midAngel(d) {  return d.startAngle + (d.endAngle - d.startAngle)/2;  }  function getColor(idx) {  var palette = [   '#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80',   '#8d98b3', '#e5cf0d', '#97b552', '#95706d', '#dc69aa',   '#07a2a4', '#9a7fd1', '#588dd5', '#f5994e', '#c05050',   '#59678c', '#c9ab00', '#7eb00a', '#6f5553', '#c14089'  ]  return palette[idx % palette.length];  } </script> </body></html>

總結(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)注武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 商水县| 丰台区| 阿拉尔市| 太谷县| 河东区| 红安县| 明光市| 六枝特区| 沙河市| 彭阳县| 涟水县| 新乐市| 永仁县| 高碑店市| 呼图壁县| 荔波县| 招远市| 丹凤县| 张家口市| 噶尔县| 安平县| 九江市| 沙雅县| 二手房| 西盟| 鄯善县| 巧家县| 江达县| 宜城市| 滨海县| 江孜县| 扎鲁特旗| 朔州市| 县级市| 襄汾县| 黄冈市| 平山县| 三原县| 土默特左旗| 卓尼县| 保亭|