Is it possible? I am not sure, since d3 makes heavy use of this
rebindings and this seems to conflict with ES6 spec.
For instance, the following works fine:
// Working fine
var data = [1,2,3]
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'orange');
var gs = svg.selectAll('g').data(data).enter();
gs.append('circle')
.attr('cx', function () { return Math.random()*500; })
.attr('cy', function () { return Math.random()*500; })
.attr('r', function () { return Math.random()*100; })
.each(function () { console.log(this); }); // this is bound to the current element in the enter selection
While the following does not work as expected (this
is not bound to the current element in the enter selection but to Window
object):
var data = [1,2,3]
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'blue');
var gs = svg.selectAll('g').data(data).enter();
gs.append('circle')
.attr('cx', () => Math.random()*500)
.attr('cy', () => Math.random()*500)
.attr('r', () => Math.random()*100)
.each(() => console.log(this)); // this is bound to Window object
Related fiddle here.
An arrow function doesn't have its own this value and the arguments object. Therefore, you should not use it as an event handler, a method of an object literal, a prototype method, or when you have a function that uses the arguments object.
Arrow functions are best for callbacks or methods like map, reduce, or forEach. You can read more about scopes on MDN. On a fundamental level, arrow functions are simply incapable of binding a value of this different from the value of this in their scope.
Arrow functions cannot be used to write object methods because, as you have found, since arrow functions close over the this of the lexically enclosing context, the this within the arrow is the one that was current where you defined the object.
Arrow functions introduce concise body syntax, or implicit return. This allows the omission of the curly brackets and the return keyword. Implicit return is useful for creating succinct one-line operations in map , filter , and other common array methods.
If you are using d3v4, you can access the current DOM node like this:
gs.append('circle')
.attr('cx', () => Math.random()*500)
.attr('cy', () => Math.random()*500)
.attr('r', () => Math.random()*100)
.each((d, i, j) => console.log(j[i]));
// j is current group, i is current index
You can use arrow functions if you don't need access to this
of the current element.
Fallback to the old style functions for cases where you want to access this
of the current element.
Or use explicit binding to allow your function (not arrow function) to access whatever object you want using .bind()
To avoid working with this
you have the option of using d3 name or class selectors to conveniently access any element. e.g.:
var stuffINeed = svg.selectAll('.someClass');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With