0

I made a module that draws a bar chart including a d3.svg.brush(). Part of my code is

Bar.prototype.init = function ( ) {
     //...
     this.brush = d3.svg.brush()
                     .y( this.y)
                     .on("brushend", this.brushend);
     console.log(this.brushend); // works
} 
Bar.prototype.brushend = function() {
    console.log(this.brush); // undefined. why?
}

To access this.* values, I cannot make brushend function a normal function by using function brushend() or var brushend = function().

How should I call it properly?

altocumulus
  • 21,179
  • 13
  • 61
  • 84
DK2
  • 651
  • 1
  • 7
  • 34

1 Answers1

0

D3 will call the event handler provided for its brushend event much like event handlers for normal DOM events will get called. For standard events this will reference the element the event occured upon. This rule does also apply to D3's brush event handlers where this references the group containing the DOM elements of the brush. Obviously, this group doesn't have a property brush you could reference by using this.brush from with the handler.

A workaround would be to save your reference by using a closure:

Bar.prototype.init = function ( ) {
     //...
     this.brush = d3.svg.brush()
                     .y(this.y)
                     .on("brushend", this.brushend());  // Get handler by calling factory
}

// A factory returning the handler function while saving 'this'. 
Bar.prototype.brushend = function() {
    var self = this;      // Save a reference to the real 'this' when the factory is called.
    return function() {   // Return the handler itself.
         // By referencing 'self' the function has access to the preserved
         // value of 'this' when the handler is called later on.
        console.log(self.brush);
    };
}
Community
  • 1
  • 1
altocumulus
  • 21,179
  • 13
  • 61
  • 84