ES6中的D3.js饼图补间-未捕获的TypeError

时间:2019-06-03 15:34:59

标签: javascript d3.js es6-class

我尝试在带有动画的D3.js和ES6上创建自己的饼图库。

这是我的代码:

class PieChart{

    constructor(element, options) {
        Object.assign(this, Piedefaults, options);
        this.element = element;
        this.init();
    }

    init(){

        const [ innerWidth, innerHeight, innerRadius, outerRadius ] = this.dimensions();
        const createGradient = select => {

            const gradient = select.select('defs').append('linearGradient').attr('id', 'gradient-pie').attr('x1', '0%').attr('y1', '100%').attr('x2', '0%').attr('y2', '0%');
            gradient.append('stop').attr('offset', '0%').attr('style', 'stop-color:#fa6293;stop-opacity:1');
            gradient.append('stop').attr('offset', '100%').attr('style', 'stop-color:#ffa77f;stop-opacity:1');

        }

        const arc = this.arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius).startAngle(0).cornerRadius(20);
        const chart = this.chart = d3.select(this.element).append('svg').attr('width', this.width).attr('height', this.height).append('g').attr('transform', `translate(${innerWidth/2}, ${innerHeight/2})`);
        chart.append('defs');
        chart.call(createGradient);

        const background = this.background = chart.append('path').datum({endAngle : Math.PI*2}).attr('class', 'background').attr('d', arc);
        const foreground = this.foreground = chart.append('path').datum({endAngle : 0}).attr('class', 'foreground').attr('fill', 'url(#gradient-pie)').attr('d', arc);

    }

    dimensions() {
        return [this.width, this.height, this.radius, this.radius-this.thickness];
    }

    arcTween(transition, value){

        var newAngle = value * Math.PI / 180;
        console.log("calculated angle is: " + newAngle);

        transition.attrTween('d', function(d) {
            var interpolate = d3.interpolate(d.endAngle, newAngle);
            return function(t) {
                d.endAngle = interpolate(t);
                return this.arc(d);
            };
        });
    }

    renderforeground(data, options){
        console.log("data: " + data);
        this.foreground.transition().duration(750).call(this.arcTween, data);
    }

    render(data, options){
        this.renderforeground(data, options)
    }

    update(data, options){
        this.render(data, options);
    }
}

我的问题是,绘制饼图需要一些补间功能来使饼图动画化,而我在arcTween方法上得到了这一点:

  

未捕获的TypeError:无法读取未定义的属性'arc'

并且无法解决问题。任何形式的帮助,我们都感激不尽:)

1 个答案:

答案 0 :(得分:0)

调用时只需将this绑定到arcTween方法即可

this.foreground.transition().duration(750).call(this.arcTween.bind(this), data);

然后将以下行添加到“ arcTween”方法中:

let { arc } = this;

这是输出:

arcTween(transition, value) {

    let { arc } = this;

    var newAngle = value * Math.PI / 180;
    console.log("calculated angle is: " + newAngle);

    transition.attrTween('d', function(d) {
        var interpolate = d3.interpolate(d.endAngle, newAngle);
        return function(t) {
            d.endAngle = interpolate(t);
            return arc(d);
        };
    });
}

renderforeground(data, options){
    console.log("data: " + data);
    this.foreground.transition().duration(750).call(this.arcTween.bind(this), data);
}