Robert
Robert

Reputation: 1646

How can I pass values from Highcharts event callbacks (click, mouseOver, mouseOut) back to React component member function?

I can create a chart and pass a function for the mouseOver event that simply logs the x and y values of the marker that I hover over:

// Works

import React from 'react';
import { render } from 'react-dom';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';

class App extends React.Component {

  render = () => {
    const options = {
      chart: {
        type: 'spline'
      },
      title: {
        text: 'My chart'
      },
      series: [
        {
          data: [1, 2, 1, 4, 3, 6]
        }
      ],
      plotOptions: {
        series: {
          point: {
            events: {
              mouseOver: function () {
                const point = { x: this.x, y: this.y };
                console.log(point);
              }
            }
          }
        }
      }
    };

    return (
      <div>
        <HighchartsReact highcharts={Highcharts} options={options} />
      </div>
    )
  }
}

render(<App />, document.getElementById('root'));

Ultimately I want to be able to pass that point back to my component and use it elsewhere in my app.

The simple idea of calling a function in my component from within the event does not work -- the this that I pass in the plotOptions no longer refers to my component but to the point in the chart:

// Does not work
// Uncaught TypeError: this.handleMouseOver is not a function

import React from 'react';
import { render } from 'react-dom';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';

class App extends React.Component {

  handleMouseOver = point => {
    console.log(`handleMouseOver gets ${point}`);
  }

  render = () => {
    const options = {
      chart: {
        type: 'spline'
      },
      title: {
        text: 'My chart'
      },
      series: [
        {
          data: [1, 2, 1, 4, 3, 6]
        }
      ],
      plotOptions: {
        series: {
          point: {
            events: {
              mouseOver: function () {
                const point = { x: this.x, y: this.y };
                this.handleMouseOver(point);                 <--- not the `this` of my component
              }
            }
          }
        }
      }
    };

    return (
      <div>
        <HighchartsReact highcharts={Highcharts} options={options} />
      </div>
    )
  }
}

render(<App />, document.getElementById('root'));

No surprise, the error that I get in the browser when I hover over a point is

Uncaught TypeError: this.handleMouseOver is not a function

Any suggestions?

Thanks.

Upvotes: 2

Views: 2680

Answers (1)

Wojciech Chmiel
Wojciech Chmiel

Reputation: 7372

You can achieve it using one of these solutions:

1) save the component reference in the chart object like that:

componentDidMount() {
  this.chart = this.refs.chart.chart;
  this.chart.component = this;
}

And use it inside mouseOver callback:

plotOptions: {
  series: {
    point: {
      events: {
        mouseOver: function() {
          const self = this.series.chart.component;
          const point = {
            x: this.x,
            y: this.y
          };

          self.handleMouseOver(point);
        }
      }
    }
  }
}

Demo:



2) use IIFE to save the reference to the component object and then use it inside mouseOver callback function:

plotOptions: {
  series: {
    point: {
      events: {
        mouseOver: (function(self) {
          return function() {
            const point = {
              x: this.x,
              y: this.y
            };
            self.handleMouseOver(point);
          };
        })(this)
      }
    }
  }
}

Demo:

Upvotes: 1

Related Questions