【问题标题】:Difficulties rendering canvas pie chart when using forEach使用 forEach 时渲染画布饼图的困难
【发布时间】:2019-07-21 11:29:58
【问题描述】:

我正在尝试使用 vanilla JavaScript 从数据集中绘制画布饼图“切片”。思路是使用forEach方法遍历每个数据值属性,得到每个切片的“startAngle”和“endAngle”。

当我使用常规 for 循环遍历我的数据时,切片绘制得很好。但是,当我采用相同的代码并对数据使用 forEach 方法时,不会绘制切片。

我的饼图的完整示例和我正在处理的问题可以在这个 JS fiddle 中找到:https://jsfiddle.net/JonDWesley/okvbgau6/328/

这是循环遍历我的数据并绘制饼图“切片”的代码:

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 相同的方式遍历我的数据数组。但是,我想知道为什么在画布上绘图的情况下,当我使用 forEach 方法时会得到不同的结果。

【问题讨论】:

    标签: for-loop foreach html5-canvas draw


    【解决方案1】:

    我认为它是原生 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 美分

    【讨论】:

    • 感谢霍尔格的帮助。您使用箭头函数的解决方案有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 2014-05-19
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    相关资源
    最近更新 更多