Search code examples
javascriptclassd3.jsthisonmouseover

Pass a JavaSscript constructor property into mouseover function & still use d3.select(this)


I am trying to use d3.select(this) and this.data_ in this.HandleMouseOver. I have tried various ways to fix the issue such as converting .on('mouseover', this.handleMouseOver); to .on('mouseover', function(){ this.handleMouseOver(d3.select(this), this.data_); }); // >> error: this.handleMouseOver is not a function - but no luck so far (yes, I added the inputs on handleMouseOver(selection,data).

Any suggestions on how I can access d3.select(this) and this.data_ in handleMouseOver()?

class Chart {
    constructor(opts){
        this.data_ = opts.data_;
        this.width_ = opts.width_;
        this.height_ = opts.height_;
        this.draw(); //create the chart
    }

    draw(){
        this.container = svgContainer.append('g')
            .attr('id', 'country-wrapper')
            .attr('width', this.width_)
            .attr('height', this.height_)
            .attr('transform', 'translate(0,0)')
            .on('mouseover', this.handleMouseOver);
            //.on('mouseout', this.handleMouseOut);

    }

    handleMouseOver(){
        var this_ = d3.select(this);
        console.log(this_, this.data_); // this.data_ >> it says it is undefined
}

Solution

  • You can try to select the global event d3.event.target and bind your scope to your event function

    class Chart {
        constructor(opts){
            this.data_ = opts.data_;
            this.width_ = opts.width_;
            this.height_ = opts.height_;
            this.draw(); //create the chart
        }
    
        draw(){
            this.container = svgContainer.append('g')
                .attr('id', 'country-wrapper')
                .attr('width', this.width_)
                .attr('height', this.height_)
                .attr('transform', 'translate(0,0)')
                .on('mouseover', this.handleMouseOver.bind(this));
                //.on('mouseout', this.handleMouseOut);
    
        }
    
        handleMouseOver() {
            var this_ = d3.select(d3.event.target);
            console.log(this_, this.data_); // this.data_ >> it says it is undefined
       }
    }
    

    or if you use the modern arrow functions, it does bind your context automatic

    class Chart {
            constructor(opts){
                this.data_ = opts.data_;
                this.width_ = opts.width_;
                this.height_ = opts.height_;
                this.draw(); //create the chart
            }
    
            draw(){
                this.container = svgContainer.append('g')
                    .attr('id', 'country-wrapper')
                    .attr('width', this.width_)
                    .attr('height', this.height_)
                    .attr('transform', 'translate(0,0)')
                    .on('mouseover', this.handleMouseOver);
                    //.on('mouseout', this.handleMouseOut);
    
            }
    
            handleMouseOver = () => {
                var this_ = d3.select(d3.event.target);
                console.log(this_, this.data_); // this.data_ >> it says it is undefined
           }
        }