canvas 饼图 - 算法 - 错误结果
pie chart with canvas - algorithm - wrong result
我写了这个算法,它基于数组中的数据,使用 canvas 元素制作饼图:
function pieChart() {
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return num / summ * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let start = 3 * Math.PI / 2;
for (let index = 0; index < data.length; index++) {
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, start, rad(deg(data[index])), false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
start = rad(deg(data[index]));
}
}
<body onload="pieChart();">
<canvas id="pie-chart"></canvas>
</body>
这是我得到的结果:
我做错了什么?
有两个值得注意的问题。
start = rad(deg(data[index]));
您正在将起始角度移动到恰好是前一个楔形的大小,而实际上,您想要添加前一个楔形的大小。这应该是:
start += rad(deg(data[index]));
context.arc(150, 150, 150, start, rad(deg(data[index])), false);
您在此处指定的结束角度是楔角的大小。它需要从起始角度偏移(即您必须向其添加起始角度)。这应该是:
context.arc(150, 150, 150, start, start + rad(deg(data[index])), false);
function pieChart() {
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return num / summ * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let start = 3 * Math.PI / 2;
for (let index = 0; index < data.length; index++) {
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, start, start + rad(deg(data[index])), false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
start += rad(deg(data[index]));
}
}
<body onload="pieChart();">
<canvas id="pie-chart"></canvas>
</body>
您绘制的每条弧线都是从上一条弧线的角度到新弧线的角度,但都从 0 开始。您需要将新弧线的角度添加到之前的结果。
还要注意 arc
函数的最后一个参数。如果为假,则圆弧顺时针绘制,如果为真,则圆弧逆时针绘制。
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc
document.addEventListener("DOMContentLoaded", function(){
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return (num / summ) * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let lastAngle = 2 * Math.PI; //Starting angle
let thisAngle = lastAngle;
for (let index = 0; index < data.length; index++) {
thisAngle += rad(deg(data[index]));
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, lastAngle, thisAngle, false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
lastAngle = thisAngle;
}
} );
<html>
<body>
<canvas id="pie-chart">
</canvas>
</body>
</html>
我写了这个算法,它基于数组中的数据,使用 canvas 元素制作饼图:
function pieChart() {
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return num / summ * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let start = 3 * Math.PI / 2;
for (let index = 0; index < data.length; index++) {
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, start, rad(deg(data[index])), false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
start = rad(deg(data[index]));
}
}
<body onload="pieChart();">
<canvas id="pie-chart"></canvas>
</body>
这是我得到的结果:
我做错了什么?
有两个值得注意的问题。
start = rad(deg(data[index]));
您正在将起始角度移动到恰好是前一个楔形的大小,而实际上,您想要添加前一个楔形的大小。这应该是:
start += rad(deg(data[index]));
context.arc(150, 150, 150, start, rad(deg(data[index])), false);
您在此处指定的结束角度是楔角的大小。它需要从起始角度偏移(即您必须向其添加起始角度)。这应该是:
context.arc(150, 150, 150, start, start + rad(deg(data[index])), false);
function pieChart() {
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return num / summ * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let start = 3 * Math.PI / 2;
for (let index = 0; index < data.length; index++) {
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, start, start + rad(deg(data[index])), false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
start += rad(deg(data[index]));
}
}
<body onload="pieChart();">
<canvas id="pie-chart"></canvas>
</body>
您绘制的每条弧线都是从上一条弧线的角度到新弧线的角度,但都从 0 开始。您需要将新弧线的角度添加到之前的结果。
还要注意 arc
函数的最后一个参数。如果为假,则圆弧顺时针绘制,如果为真,则圆弧逆时针绘制。
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc
document.addEventListener("DOMContentLoaded", function(){
canvas = document.getElementById('pie-chart');
canvas.width = 300;
canvas.height = 300;
context = canvas.getContext('2d');
const data = [1, 5, 4, 3];
const colors = ['brown', 'yellow', 'purple', 'pink'];
let summ = 0;
for (let index = 0; index < data.length; index++) {
summ += data[index];
}
function deg(num) {
return (num / summ) * 360;
}
function rad(deg) {
return deg * (Math.PI / 180);
}
let lastAngle = 2 * Math.PI; //Starting angle
let thisAngle = lastAngle;
for (let index = 0; index < data.length; index++) {
thisAngle += rad(deg(data[index]));
context.beginPath();
context.moveTo(150, 150);
context.arc(150, 150, 150, lastAngle, thisAngle, false);
context.lineTo(150, 150);
context.fillStyle = colors[index];
context.fill();
lastAngle = thisAngle;
}
} );
<html>
<body>
<canvas id="pie-chart">
</canvas>
</body>
</html>