0

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.

Reuven Trabin
  • 451
  • 7
  • 18

1 Answers1

3

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

ppotaczek
  • 36,341
  • 2
  • 14
  • 24
  • Thanks for providing your response. I don't see a connection between the demo and my question about the date picker which uses highstock chart. The pasted code looks closer, but I ran into an npm install issue/question - when I install highcharts-react-official I lose the highstock component: ./node_modules/highcharts-react-official/dist/highcharts-react.min.js Module not found: Can't resolve 'highcharts' in '\node_modules\highcharts-react-official\dist'. Can you clarify the npm steps to use the official package with highstock? – Reuven Trabin Jan 13 '20 at 17:11
  • Hi @Reuven Trabin, Sorry! Wrong link - fixed. Please check the files structure in the example. If you have any questions just ask. – ppotaczek Jan 13 '20 at 17:21
  • Thanks, the new demo link makes much more sense. But it doesn't transfer directly to my code (which does work with react-day-picker, just with that component's input element, and above the graph). My code also doesn't use highcharts-react-official. So what would help me, since I'm new to react, can you go back a step to show how to build this from a new react app, including the required npm installs? – Reuven Trabin Jan 13 '20 at 22:21
  • @Reuven Trabin, I recomend you to use `highcharts-react-official`. It is a light weight, officially supported wrapper that care of connection between a chart and a component life cycle. You can find out how to create a project with React and Highcharts from here: https://www.highcharts.com/blog/post/highcharts-wrapper-for-react-101/ – ppotaczek Jan 14 '20 at 12:51
  • Thanks ppotaczek, I have your demo working now locally. In both the sandbox and for me locally the calendar ui is positioned outside the graph. Is it possible to show the ui next to (under) the date selection input elements? – Reuven Trabin Jan 15 '20 at 20:17
  • Hi @Reuven Trabin, You can position the calendars by CSS: https://codesandbox.io/s/highcharts-react-demo-9ieen – ppotaczek Jan 16 '20 at 10:28
  • Marking this as answered - the solution that ppotaczek provided was enough information for me to integrate the date picker. A few minor issues remain, but this is the core of my problem - thanks again – Reuven Trabin Jan 18 '20 at 18:19
  • How to convert this to typescript? I run into issues about the type of "this" at this.internalChart and this.rangeSelector. – LWang Jul 29 '21 at 03:09
  • Hi @LWang, `this.internalChart` has `Highcharts.Chart` type: https://api.highcharts.com/class-reference/Highcharts.Chart the same as this for range selector. – ppotaczek Jul 29 '21 at 09:31
  • @ppotaczek Thanks for your quick response. The bug I got for "this.internalChart" is "property internalChart does not exist on Type (my component name)". How do we declare the type of this? My sandbox: https://codesandbox.io/s/type-error-select-date-typescript-react-highcharts-8h30b?file=/src/App.tsx – LWang Jul 29 '21 at 14:55
  • You don't need to use IIFE function in functional components. Please check this example: https://codesandbox.io/s/type-error-select-date-typescript-react-highcharts-fork-xfj1i?file=/src/App.tsx – ppotaczek Jul 30 '21 at 08:14