ResidentMario / py_d3

D3 block magic for Jupyter notebook.
MIT License
451 stars 40 forks source link

`this` not bound correctly within anonymous event functions in magic cells #9

Closed Kautenja closed 7 years ago

Kautenja commented 7 years ago

TLDR;

Description

this is not bound to the expected element when used inside anonymous event handler functions.

Expected Behavior

this inside anonymous event handler functions to be bound to the element generating the event.

Actual Behavior

this remains bound to the global window.

Verbose

As the title suggests, I'm seeing an issue with the usage of this from within the anonymous function for event listeners for SVG elements when using %%d3 magic cells.

bars.on('mouseover', (data, index) => {
    console.log(this);
    d3.select(this).attr('fill', 'orange');
});

Say I have a d3 selection of elements called bars that represents the rects in a bar graph of an svg. When executing .on(action, anon) I would expect the this within the anonymous function to be bound to the element that triggered the event; however, through some basic console logging I see that this from within the function is bound to the window.

screen shot 2017-06-16 at 4 34 52 pm

The image above shows this being console logged first by the main body of the script, then by the anonymous function.

Kautenja commented 7 years ago

hmm appears to be either an issue with d3 itself or perhaps my understanding of ECMAScript6 arrow functions? Either way, this works if you use the old notation. I've confirmed this is not py_d3 dependent by testing both methods in a plain HTML page. The arrow functions just seem to not properly bind this.

This works though:

bars.on('mouseover', function(data, index) {
    console.log(this);
    d3.select(this).attr('fill', 'orange');
});

Closing

ResidentMario commented 7 years ago

I believe arrow functions do not bind this by design. To attach state you need to use bind.