Search code examples
reactjshighchartsreact-day-picker

How to implement date selector to HighChart StockChart in reactjs (without jQuery)


I've been using highcharts in a react application, and relatively new to both. The last missing piece of my goal is to get a calendar popup hooked into the date selection range in a stock chart. Without jQuery. There are a couple of examples that come close to what I would like.

Post that links to use of jQuery: HighChart Support - jQuery example

Post that links to use of react-day-picker outside the chart: Post found on the HighChart support forum

What I do have working fully is the use of the react-day-picker calendar outside the chart, including the plumbing - updating the selection range after selecting a date, etc. I've even tried an approach of moving this element into the chart svg, but wasn't able to get that to work. So my goal is to implement a lightweight date picker that can be bound to the built-in data selector input elements inside the chart area (again without jQuery).

Any help would be much appreciated.


Solution

  • You can display DayPicker component after click on default input element and use xAxis.setExtremes method to apply the selected date.

    class HighchartsChart extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          minInput: false,
          maxInput: false
        };
      }
    
      selectDay(time, isMin){
        const timestamp = time.getTime();
        const xAxis = this.internalChart.xAxis[0];
    
        xAxis.setExtremes(
          isMin ? timestamp : xAxis.min,
          isMin ? xAxis.max : timestamp
        );
        this.setState(isMin ? {minInput: false} : {maxInput: false});
      }
    
      render() {
        return (
          <div>
            <HighchartsReact
              constructorType={'stockChart'}
              highcharts={Highcharts}
              options={{
                chart: {
                  events: {
                    load: (function(component){
                      return function(){
                        const inputGroup = this.rangeSelector.inputGroup.element.children;
                        inputGroup[1].addEventListener('click', function(){
                          component.setState({minInput: true});
                        });
    
                        inputGroup[3].addEventListener('click', function(){
                          component.setState({maxInput: true});
                        });
    
                        component.internalChart = this;
                      } 
                    })(this),
                  }
                },
                ...options
              }}
            />
            {
              this.state.minInput && 
              <DayPicker onDayClick={(time) => {
                this.selectDay(time, true);
              }} />
            }
            {
              this.state.maxInput && 
              <DayPicker onDayClick={(time) => {
                this.selectDay(time);
              }} />
            }
          </div>
        );
      }
    }
    

    Live demo: https://codesandbox.io/s/highcharts-react-demo-mqqhu

    API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes