查看chart.js的advanced tooltips和legend configuration,我不知道如何为我的图表实现以下标签样式。
如何输出此圆环图的每个部分的数字,并将这些数字连接到图表的每个部分?
如果使用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"/>
答案 0 :(得分:3)
我发现chartjs很难处理(但是它很好用)。您可以尝试D3,它是高度可定制的。它使用svgs而不是canvas创建图表,因此元素更易于访问和使用。
这是代码,但它不会在原地运行,因为它需要带有数据的外部CSV文件,以及防止CORs错误的Web服务器。这是您的数据的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>
我的结果相当接近:
以下是我对基本D3圆环图进行的修改(基于此示例:https://bl.ocks.org/mbostock/3887193):
我确信这一切都可以削减并提高效率。我还建议使分段颜色与标签/标注颜色不同(一个标注在最后一个分段上丢失)。
我没有相同的标签字体,但因为这是使用SVG完成的,所以您可以轻松地使用样式更改字体。 Chartjs的情况并非如此(当我尝试修改Chartjs中的标签样式时遇到了同样的问题)。
D3具有比Chartjs更陡峭的学习曲线,但是一旦掌握了它,你几乎可以做任何与它相关的图形。官方网站在这里https://d3js.org/答案 1 :(得分:1)
Custom positioning of individual point labels is possible with Charts.js Data Labels Plugin.
Source: https://github.com/chartjs/chartjs-plugin-datalabels
The radial positioning is illustrated here: https://chartjs-plugin-datalabels.netlify.com/guide/positioning.html