mkraska
mkraska

Reputation: 3

JSXGraph: call of class methods in event binding

I want to define an object for use in JSXGraph widgets, which can be activated or deactivated upon mouseclick (for now just switching visiblity and "fixed" property).

I defined methods activate() and deactivate(). These can be called from within the constructor method (to set the initial state depending on parameters). Yet I can't bind the methods to mouse event.

Any idea what might cause the problem or how to solve the task correctly?

     this.graph = board.create('functiongraph' [ 
       JXG.Math.Numerics.hermitePolynomial(this.p1, this.p2, this.pt1, this.pt2, 
         this.t1, this.t2),
       this.p1.X(), this.p2.X() ],
       { strokecolor: 'red', strokewidth: 3 });
    // set activate/deactivate, this works
    this.obj = [ this.p1, this.p2, this.pt1, this.pt2, this.t1, this.t2 ];
    if (this.state == "active") { this.activate() }
    else {this.deactivate() }
    
    //switch by mouseclick, this doesn't work
    this.graph.on('down', function() {
      if (this.state == "active") { 
        console.log("deactivate", this.obj); this.deactivate(); }
      else {  console.log("activate"); this.activate(); }
      } )
  }
  activate() {console.log("activate"); this.state = "active";
        for (var part of this.obj) {
          part.setAttribute({visible:true});
          part.setAttribute({fixed:false});
        } update()}
  deactivate() {console.log("deactivate"); this.state = "inactive";
        for (var part of this.obj) {
          part.setAttribute({visible:false});
          part.setAttribute({fixed:true});
        } update()}

In the example, the red splines to the right should be switchable by mouse click.

Yet clicking them results in an error

Uncaught TypeError: this.activate is not a function

I don't understand this, because the methods can be successfully called directly above in the code.

complete example on jsfiddle

Upvotes: 0

Views: 109

Answers (1)

mkraska
mkraska

Reputation: 3

I found a solution myself. The problem was that "this" in the mouse binding referres to the object, the binding is applied to. In this case, it is a graphics object.

If I want to access the methods of the parent object, I can define a parent property of that object and access the method by "this.parent.method()"

I might have implemented it a bit overcomplicated but it works now.

this.graph = board.create('functiongraph', [hermiteplot(this.P,this.p1, this.p2, this.pt1, this.pt2), this.p1.X(), this.p2.X()], { strokecolor: 'red', strokewidth: 3  });
    // set activate/deactivate
        this.obj = [ this.p1, this.p2, this.pt1, this.pt2 ];
    if (this.state == "active") { this.activate(this) }
    if (this.state == "inactive") { this.deactivate(this) }
    if (this.state == "locked") { this.deactivate(this); this.state = "locked" }
    
    //switch by doubleclick
    this.graph.parent = this;
    this.graph.lastclick = Date.now();    
    this.graph.on('up', function() {
      if (Date.now()-this.lastclick < 500) {console.log(this.parent.state); this.parent.switch()}
      else {this.lastclick = Date.now() }})
  }
  switch() {if (this.state == "active") { this.deactivate(this)}
      else if (this.state == "inactive") { this.activate(this);}
      console.log(this.state)}
  activate(ref) {console.log("this.activate()"); ref.state = "active";
        for (var part of ref.obj) {
          part.setAttribute({visible:true});
          part.setAttribute({fixed:false});
        } update()}
  deactivate(ref) {console.log("this.deactivate()"); ref.state = "inactive";
        for (var part of ref.obj) {
          part.setAttribute({visible:false});
          part.setAttribute({fixed:true});
        } update()}

jsfiddle

Upvotes: 0

Related Questions