我正在尝试创建一个简单的饼图,如下图所示:
该图表将显示测验的结果,其中用户可以选择a、b或c。共有10个问题,每个问题用户只能选择一个选项。
我想要做的是通过传入a、b或c的值来显示饼图,其中每个部分都是100%的百分比。
到目前为止,我有以下几点:
var greenOne = "#95B524";
var greenTwo = "#AFCC4C";
var greenThree = "#C1DD54";
function CreatePieChart() {
var chart = document.getElementById('piechart');
var canvas = chart.getContext('2d');
canvas.clearRect(0, 0, chart.width, chart.height);
var total = 100;
var a = 3;
var b = 4;
var c = 3;
for (var i = 0; i < 3; i++) {
canvas.fillStyle = "#95B524";
canvas.beginPath();
canvas.strokeStyle = "#fff";
canvas.lineWidth = 3;
canvas.arc(100, 100, 100, 0, Math.PI * 2, true);
canvas.closePath();
canvas.stroke();
canvas.fill();
}
}
CreatePieChart();
<canvas id="piechart" width="200" height="200"></canvas>
颜色特定于分段的大小,因此绿色一条用于最大段,绿色三条用于最小段。
谢谢
发布于 2017-01-14 09:08:02
我喜欢前面的答案,但我觉得它缺乏代码清晰度,也没有真正涵盖如何利用标签。
为了便于声明,我将这些值移动到一个数据对象数组中。其他值,比如percentage,我显式声明为数据对象上的属性,或单独的变量。我认为,这会让它更容易阅读。
重构还使得将值绑定到输入框变得更容易,如果您感兴趣的话。
要理解我的意思并使用这些值,请查看这个CodePen:http://codepen.io/zfrisch/pen/pRbZeb
var data = [{
label: "one",
value: 100,
color: 'white'
}, {
label: "two",
value: 100,
color: 'skyBlue'
}, {
label: "three",
value: 100,
color: 'yellow'
}];
var total = 0;
for (obj of data) {
total += obj.value;
}
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var previousRadian;
var middle = {
x: canvas.width / 2,
y: canvas.height / 2,
radius: canvas.height / 2,
};
//background
ctx.beginPath();
ctx.arc(middle.x, middle.y, middle.radius, 0, 2 * Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = "black";
ctx.fill();
//end of background
for (obj of data) {
previousRadian = previousRadian || 0;
obj.percentage = parseInt((obj.value / total) * 100)
ctx.beginPath();
ctx.fillStyle = obj.color;
obj.radian = (Math.PI * 2) * (obj.value / total);
ctx.moveTo(middle.x, middle.y);
//middle.radius - 2 is to add border between the background and the pie chart
ctx.arc(middle.x, middle.y, middle.radius - 2, previousRadian, previousRadian + obj.radian, false);
ctx.closePath();
ctx.fill();
ctx.save();
ctx.translate(middle.x, middle.y);
ctx.fillStyle = "black";
ctx.font = middle.radius / 10 + "px Arial";
ctx.rotate(previousRadian + obj.radian);
var labelText = "'" + obj.label + "' " + obj.percentage + "%";
ctx.fillText(labelText, ctx.measureText(labelText).width / 2, 0);
ctx.restore();
previousRadian += obj.radian;
}
<canvas id="myCanvas" width="500" height="500" ></canvas>
发布于 2017-04-06 14:00:45
我以前也遇到过同样的问题,但后来我解决了这个问题。
我遗漏的是,我在上下文中绘制了一个拱门,并试图填充它,由于颜色在整个圆圈中扩散,因为现在上下文仅在从拱门的中心到起点的半径线和拱门之间绑定。
但是没有其他的边界,从拱顶的末端到中心的线,只要我用下面的方法画出这条线:
ctx.lineTo(center coordinates of circle);
我有一个完整的饼的边界,所以现在如果我在上下文中填充颜色,它将不会在整个圆圈内扩散,而是仅限于该饼。
发布于 2020-08-28 22:36:48
这是一个不使用外部库,使用html5画布的饼图:
但最好是使用库来绘制图表。在apex-charts
中,有一个名为sparkline
的选项,它可以帮助您删除多余的东西,并绘制一个最小且干净的图表。
这是一个使用apex-charts
库的干净的甜甜圈图表。(使用sparkline
选项删除多余的内容):
var options = {
series: [620, 40],
labels: ['Finished', 'Unfinished'],
chart: {
type: 'donut',
sparkline: {
enabled: true,
}
},
plotOptions: {
pie: {
donut: {
labels: {
show: true,
total: {
showAlways: false,
show: true,
label: 'Total'
}
}
}
}
},
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
https://stackoverflow.com/questions/6995797
复制相似问题