2016-10-02 151 views
3

通過advanced tooltipslegend configuration查看chart.js,我不知道如何實現我的圖表的以下標籤樣式。自定義標籤Chart.js

enter image description here

我該如何輸出我的這個圓環圖和各段數的那些號碼連接到圖表的每一段?

如果Chart.js不可能,那麼任何人都可以指向一個圖表庫,這將允許我這樣做嗎?

new Chart(document.querySelector('#chart'), { 
 
    type: 'doughnut', 
 
    data: { 
 
     labels: [ 
 
      'Red', 
 
      'Blue', 
 
      'Yellow' 
 
     ], 
 
     datasets: [{ 
 
      data: [300, 50, 100], 
 
      backgroundColor: [ 
 
       '#FF6384', 
 
       '#36A2EB', 
 
       '#FFCE56' 
 
      ], 
 
      hoverBackgroundColor: [ 
 
       '#FF6384', 
 
       '#36A2EB', 
 
       '#FFCE56' 
 
      ] 
 
     }] 
 
    }, 
 
    options: { 
 
     legend: { 
 
      display: false 
 
     } 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.bundle.min.js"></script> 
 

 
<canvas id="chart" width="400" height="400"/>

回答

3

我發現chartjs是困難的工作(但它很高興在緊要關頭)。你可以嘗試D3,這是高度可定製的。它使用svgs而不是畫布創建圖表,因此元素更易於訪問和使用。

下面是代碼,但它不會在原位運行,因爲它需要一個包含數據的外部CSV文件和一個防止COR錯誤的網絡服務器。下面是CSV爲您的數據(data.csv):

percentage_label,percentage 
19,19 
10,10 
32,32 
39,39 

var width = 960, 
 
    height = 500, 
 
    radius = Math.min(width, height)/2; 
 

 
var color = d3.scale.ordinal() 
 
    .range(["#fdb92e", "#c02f8e", "#1aaaa9", "#ffffff"]); 
 

 
var arc = d3.svg.arc() 
 
    .outerRadius(radius - 70) 
 
    .innerRadius(radius - 180); 
 

 
var pie = d3.layout.pie() 
 
    .sort(null) 
 
    .value(function(d) { return d.population; }); 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height) 
 
    .append("g") 
 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 
 

 
d3.csv("data.csv", type, function(error, data) { 
 
    if (error) throw error; 
 

 
    var g = svg.selectAll(".arc") 
 
     .data(pie(data)) 
 
    .enter().append("g") 
 
     .attr("class", "arc"); 
 

 
    g.append("path") 
 
     .attr("d", arc) 
 
     .style("fill", function(d) { return color(d.data.percentage_label); }) 
 
     .style("stroke-width","0px"); 
 

 
    g.append("text") 
 
     .attr("transform", function(d) { 
 
    return "translate(" + ((radius + 30) * Math.sin(((d.endAngle - d.startAngle)/2) + d.startAngle)) + ", " + (-1 * (radius - 10) * Math.cos(((d.endAngle - d.startAngle)/2) + d.startAngle)) +")";}) 
 
     .attr("dy", ".5em") 
 
     .style("fill","#ffffff") 
 
     .style("font-size","40px") 
 
     .text(function(d) { return (d.data.percentage_label + "%"); }); 
 
     
 
    g.append("circle") 
 
     .attr("transform", function(d) {return "translate(" + arc.centroid(d) + ")";}) 
 
     .attr("r", 5) 
 
     .style("fill","#ffffff"); 
 
    g.append("circle") 
 
     .attr("transform", function(d) {return "translate(" + ((radius - 20) * Math.sin(((d.endAngle - d.startAngle)/2) + d.startAngle)) + ", " + (-1 * (radius - 50) * Math.cos(((d.endAngle - d.startAngle)/2) + d.startAngle)) +")";}) 
 
     .attr("r", 5) 
 
     .style("fill","#ffffff"); 
 
     
 
     function lineCoordinates(d,x) { 
 
      /* x: coordinate to return */ 
 
      //not the most efficient method 
 
      var pa = []; 
 
      var p1 = arc.centroid(d); 
 
      pa.push(p1[0]); 
 
      pa.push(p1[1]); 
 
      pa.push((radius - 20) * Math.sin(((d.endAngle - d.startAngle)/2) + d.startAngle)); 
 
      pa.push(-1 * (radius - 50) * Math.cos(((d.endAngle - d.startAngle)/2) + d.startAngle)); 
 
      return pa[x]; 
 
     } 
 
    g.append("line") 
 
     .style("stroke","white") 
 
     .style("stroke-width","2px") 
 
     .attr("x1",function(d) { return lineCoordinates(d,0);}) 
 
     .attr("y1", function(d) { return lineCoordinates(d,1);}) 
 
     .attr("x2", function(d) { return lineCoordinates(d,2);}) 
 
     .attr("y2", function(d) { return lineCoordinates(d,3);}); 
 
}); 
 

 

 
function type(d) { 
 
    d.population = +d.percentage_label; 
 
    return d; 
 
}
body { 
 
    background-color: #F68135; 
 
} 
 

 
.arc text { 
 
    font: 10px sans-serif; 
 
    text-anchor: middle; 
 
} 
 

 
.arc path { 
 
    stroke: #fff; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

我的結果是相當接近:

enter image description here

下面是我對所做的修改基本D3甜甜圈圖表(基於此示例:https://bl.ocks.org/mbostock/3887193):

  • 改變內進出半徑(半徑?)
  • 改變顏色(這是scale.ordinal一部分)
  • 添加樣式標籤
  • 移離段的中心的標籤出(因爲有一些涉及電弧數學,這是有幫助的:Label outside arc (Pie chart) d3.js
  • 加入一對圓的用於標註直線的端點
  • 添加的行爲標註
  • 增加了一個小函數(lineCoordinates),使定位數學更容易處理

我確信這可以全部修剪並提高一點效率。我還建議製作不同於標籤/標註顏色的細分顏色(在最後一個細分中,一個標註會丟失)。

我沒有相同的標籤字體,但是因爲這是使用SVG完成的,所以您可以使用樣式輕鬆更改字體。 Chartjs的情況並非如此(當我嘗試修改Chartjs中的標籤樣式時遇到了同樣的問題)。

D3比Chartjs有更陡峭的學習曲線,但一旦你掌握了它,你可以做任何與它有關的圖形。官方網站在這裏https://d3js.org/

+0

這是一個徹底的答案,但它並沒有幫助任何人來這裏尋找添加自定義標籤的方式與chart.js – thanksd

+0

完全同意。解決了我的第一段。 OP問道:「如果Chart.js不可能,那麼任何人都可以指向一個圖表庫,這將允許我這樣做?」 –