Reputation: 370
Fisrt of all I'm using D3js inside a React component so I use some variable of my class to save datas e.g.: this.graphicalId = 'test';
I have two items in my d3 element, svgViewport
which is a g element and streams
which are path elements. I have .on('mousemove'
event handle for each.
In the streams
event I would like save the name of the current stream using d3.select(this)
(note I'm in a function() and not an arrow function so this is local) in a global variable in order to use it in the svgViewport
event.
My problem is that like I'm in a function() this
is local and not link to my class instance so I can't save the value in a member variable this.currentStreamName
.
A bit of code :
svgViewport.on('mousemove', function (d, i) {
if (mouseIsOverStream) {
let mousex = d3.mouse(this);
mousex = mousex[0];
// here I want this of the class instance context
this.nearestTickPosition, this.currentStreamName = findNearestTickPosition(mousex);
}
});
Do you have some advices to deal with it ?
Thanks.
Upvotes: 2
Views: 164
Reputation: 21578
You can use arrow functions to get access to the instance's this
context and still acquire the current DOM element. For the DOM element you resort to the little-known and often overlooked third parameter of the event listener. As the docs have it (emphasis mine):
the specified listener will be evaluated for the element, being passed the current datum (d), the current index (i), and the current group (nodes)
Since the current index i
is the pointer into the current group nodes
you can refer to the current DOM element as nodes[i]
.
Your code thus becomes:
svgViewport.on('mousemove', (d, i, nodes) => {
if (mouseIsOverStream) {
let mousex = d3.mouse(nodes[i]); // get the current element as nodes[i]
mousex = mousex[0];
// this now refers to your instance
this.nearestTickPosition, this.currentStreamName = findNearestTickPosition(mousex);
}
});
Upvotes: 1
Reputation: 202
Store the class context in a variable out of the event binding. Then, make an IIFE and bind it's context to the stored one.
componentDidMount() {
const ctx = this;
svgViewport.on('mousemove', function (d, i) {
if (mouseIsOverStream) {
let mousex = d3.mouse(this);
mousex = mousex[0];
!function () {
// here I want this of the class instance context
this.nearestTickPosition, this.currentStreamName = findNearestTickPosition(mousex);
}.bind(ctx)();
}
});
}
Also, this should work too:
componentDidMount() {
svgViewport = ...;
svgViewport.on('mousemove', (d, i) => {
if (mouseIsOverStream) {
let mousex = d3.mouse(svgViewport); // here
mousex = mousex[0];
this.nearestTickPosition, this.currentStreamName = findNearestTickPosition(mousex);
}
});
}
Upvotes: 1