使用 forEach 时难以渲染 canvas 饼图
Difficulties rendering canvas pie chart when using forEach
我正在尝试使用 vanilla JavaScript 从数据集中绘制 canvas 饼图 "slices"。思路是用forEach
方法运行通过每个数据值属性得到每个切片的"startAngle"和"endAngle"
当我使用常规 for
循环 运行 通过我的数据时,切片绘制得很好。但是,当我采用相同的代码并对数据使用 forEach 方法时,不会绘制切片。
我的饼图的完整示例和我正在处理的问题可以在这个 JS fiddle: https://jsfiddle.net/JonDWesley/okvbgau6/328/
中找到
这是循环遍历我的数据并绘制饼图的代码 "slice":
let sliceStartAngle = 0;
for (var n = 0; n < this.data.length; n++) {
var property = this.data[n];
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.stroke();
context.closePath();
sliceStartAngle = sliceEndAngle
}
在第二个示例中,我的代码几乎相同,只是我使用的是 forEach 方法而不是 for 循环:
let sliceStartAngle = 0;
data.forEach(function(property) {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
我希望 forEach 方法以与 for
相同的方式遍历我的数据数组。但是,我想知道为什么在 canvas 上绘制的情况下,当我使用 forEach 方法时会得到不同的结果。
我认为它是本机 Js 中 forEach 中的 "this" 作用域
您的快速解决方案是:
let _this = this;
let sliceStartAngle = 0;
data.forEach(function(property) {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(_this.pieLocationX, _this.pieLocationY);
context.arc(_this.pieLocationX, _this.pieLocationY, _this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
或使用 ES6
let sliceStartAngle = 0;
data.forEach((property) => {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, _this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
一些额外的信息,for-next 循环没有变量的作用域,forEach 正在处理回调(什么是函数)然后 "this" 是函数的作用域
我的 2 美分
我正在尝试使用 vanilla JavaScript 从数据集中绘制 canvas 饼图 "slices"。思路是用forEach
方法运行通过每个数据值属性得到每个切片的"startAngle"和"endAngle"
当我使用常规 for
循环 运行 通过我的数据时,切片绘制得很好。但是,当我采用相同的代码并对数据使用 forEach 方法时,不会绘制切片。
我的饼图的完整示例和我正在处理的问题可以在这个 JS fiddle: https://jsfiddle.net/JonDWesley/okvbgau6/328/
中找到这是循环遍历我的数据并绘制饼图的代码 "slice":
let sliceStartAngle = 0;
for (var n = 0; n < this.data.length; n++) {
var property = this.data[n];
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.stroke();
context.closePath();
sliceStartAngle = sliceEndAngle
}
在第二个示例中,我的代码几乎相同,只是我使用的是 forEach 方法而不是 for 循环:
let sliceStartAngle = 0;
data.forEach(function(property) {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
我希望 forEach 方法以与 for
相同的方式遍历我的数据数组。但是,我想知道为什么在 canvas 上绘制的情况下,当我使用 forEach 方法时会得到不同的结果。
我认为它是本机 Js 中 forEach 中的 "this" 作用域 您的快速解决方案是:
let _this = this;
let sliceStartAngle = 0;
data.forEach(function(property) {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(_this.pieLocationX, _this.pieLocationY);
context.arc(_this.pieLocationX, _this.pieLocationY, _this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
或使用 ES6
let sliceStartAngle = 0;
data.forEach((property) => {
let sliceAngle = 2 * Math.PI * property.value / totalValue;
let sliceEndAngle = sliceStartAngle + sliceAngle;
context.beginPath();
context.moveTo(this.pieLocationX, this.pieLocationY);
context.arc(this.pieLocationX, this.pieLocationY, _this.pieRadius,
sliceStartAngle, sliceEndAngle, false);
context.fill();
context.closePath();
sliceStartAngle += sliceEndAngle
});
一些额外的信息,for-next 循环没有变量的作用域,forEach 正在处理回调(什么是函数)然后 "this" 是函数的作用域
我的 2 美分