janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Keyboard navigation breaks after updating chart options in heatmap

Good morning,

I'm working with heat maps in react and I have run into a weird issue. I am using Highcharts version 9.2.2 since I was told there was a bug with the most recent version of heat maps related to keyboard navigation. When I don't try to update the chart, my keyboard navigation works as expected. But when I try to update the chart using setChartOptions function, it breaks and keyboard navigation occurs in a weird order. I've included a code sample below.
Any thought on what is going wrong?

Code: Select all

import React, { useEffect, useState } from 'react';
import { render } from 'react-dom';
import HighchartsReact from 'highcharts-react-official';
import Highcharts from 'highcharts';
import highchartsAccessibility from 'highcharts/modules/accessibility';
import highchartsDebugger from 'highcharts/modules/debugger';
import highchartsExporting from 'highcharts/modules/exporting';
import highchartsExportData from 'highcharts/modules/export-data';
import highchartsNoDataToDisplay from 'highcharts/modules/no-data-to-display';
import highchartsPatternFill from 'highcharts/modules/pattern-fill';
import highchartsHeatMap from 'highcharts/modules/heatmap';
import _set from 'lodash-es/set';
import _clone from 'lodash-es/clone';
import _merge from 'lodash-es/merge';

if (typeof Highcharts === 'object') {
  highchartsAccessibility(Highcharts);
  highchartsDebugger(Highcharts);
  highchartsExporting(Highcharts);
  highchartsNoDataToDisplay(Highcharts);
  highchartsExportData(Highcharts);
  highchartsPatternFill(Highcharts);
  highchartsHeatMap(Highcharts);
}

const HeatMapChart = () => {
  const [chartOptions, setChartOptions] = useState({
    chart: {
      type: 'heatmap',
      displayErrors: false,
    },
    colors: Highcharts.getOptions().colors,
    colorAxis: {
      dataClassColor: 'category',
      dataClasses: [
        {
          from: 125,
        },
        {
          from: 100,
          to: 125,
        },
        {
          from: 75,
          to: 100,
        },
        {
          from: 50,
          to: 75,
        },
        {
          from: 25,
          to: 50,
        },
        {
          from: 0,
          to: 25,
        },
      ],
    },
    series: [
      {
        name: 'Logins over time',
        data: [
          [0, 0, 7],
          [0, 1, 30],
          [0, 2, 90],
          [1, 0, 10],
          [1, 1, 80],
          [1, 2, 90],
          [2, 0, 20],
          [2, 1, 55],
          [2, 2, 120],
          [3, 0, 110],
          [3, 1, 8],
          [3, 2, 55],
          [4, 0, 25],
          [4, 1, 110],
          [4, 2, 70],
          [5, 0, 40],
          [5, 1, 10],
          [5, 2, 100],
          [6, 0, 10],
          [6, 1, 8],
          [6, 2, 50],
          [7, 0, 30],
          [7, 1, 40],
          [7, 2, 25],
        ],
      },
    ],
    plotOptions: {
      series: {
        animation: false,
        dataLabels: {
          enabled: true,
        },
      },
    },
  });


  useEffect(() => {
    _set(chartOptions, 'chart.displayErrors', true);
    _set(chartOptions, 'plotOptions.series.animation', true);

    const newOptions = {
      ...chartOptions,
    };
    setChartOptions(newOptions);
  }, []);

  return <HighchartsReact highcharts={Highcharts} options={chartOptions} />;
};

export default HeatMapChart;

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

magdalena
Posts: 517
Joined: Tue Aug 24, 2021 1:32 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi,

Thank you for contacting us with your issue.

The problem is that in your example chart.update is being executed with all chart options. You should insert only new chart options, like in the following example:

Code: Select all

  useEffect(() => {
    setChartOptions({
      chart: {
        displayErrors: true
      },
      plotOptions: {
        series: {
          animation: true
        }
      }
    });
  } []);

Docs:
https://github.com/highcharts/highchart ... -to-update

Let me know if you have any further questions,
Regards!
Magdalena Gut
Developer and Highcharts Support Engineer
janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hey magdalena,
Thanks for your answer. That was really helpful. I had one additional question related to this. I'm currently trying to use multiple useEffects, each calling setChartOptions, to update different aspects of the chart options like below. In a real life example, these useEffects may be called conditionally like checking if the chart is in loading state or if the data updated so that the chart options are only updated when necessary. But in this example below, I've found that only the options passed into the last setChartOptions called is the one that is set. The first one called is suppose to hide the context menu button but this does not happen unless I comment out the second one that is updating displayErrors and series animation. Is there a way to call setChartOptions multiple times before a render or to set different chart options conditionally in multiple useEffects?

Thanks!

Code: Select all

import React, { useEffect, useState } from 'react';
import { render } from 'react-dom';
import HighchartsReact from 'highcharts-react-official';
import Highcharts from 'highcharts';
import highchartsAccessibility from 'highcharts/modules/accessibility';
import highchartsDebugger from 'highcharts/modules/debugger';
import highchartsExporting from 'highcharts/modules/exporting';
import highchartsExportData from 'highcharts/modules/export-data';
import highchartsNoDataToDisplay from 'highcharts/modules/no-data-to-display';
import highchartsPatternFill from 'highcharts/modules/pattern-fill';
import highchartsHeatMap from 'highcharts/modules/heatmap';
import _set from 'lodash-es/set';
import _clone from 'lodash-es/clone';
import _merge from 'lodash-es/merge';

if (typeof Highcharts === 'object') {
  highchartsAccessibility(Highcharts);
  highchartsDebugger(Highcharts);
  highchartsExporting(Highcharts);
  highchartsNoDataToDisplay(Highcharts);
  highchartsExportData(Highcharts);
  highchartsPatternFill(Highcharts);
  highchartsHeatMap(Highcharts);
}

const HeatMapChart = () => {

  const [chartOptions, setChartOptions] = useState({
    chart: {
      type: 'heatmap',
      displayErrors: false,
    },
    colors: Highcharts.getOptions().colors,
    colorAxis: {
      dataClassColor: 'category',
      dataClasses: [
        {
          from: 125,
        },
        {
          from: 100,
          to: 125,
        },
        {
          from: 75,
          to: 100,
        },
        {
          from: 50,
          to: 75,
        },
        {
          from: 25,
          to: 50,
        },
        {
          from: 0,
          to: 25,
        },
      ],
    },
    series: [
      {
        name: 'Logins over time',
        data: [
          [0, 0, 7],
          [0, 1, 30],
          [0, 2, 90],
          [1, 0, 10],
          [1, 1, 80],
          [1, 2, 90],
          [2, 0, 20],
          [2, 1, 55],
          [2, 2, 120],
          [3, 0, 110],
          [3, 1, 8],
          [3, 2, 55],
          [4, 0, 25],
          [4, 1, 110],
          [4, 2, 70],
          [5, 0, 40],
          [5, 1, 10],
          [5, 2, 100],
          [6, 0, 10],
          [6, 1, 8],
          [6, 2, 50],
          [7, 0, 30],
          [7, 1, 40],
          [7, 2, 25],
        ],
      },
    ],
    plotOptions: {
      series: {
        animation: false,
        dataLabels: {
          enabled: true,
        },
      },
    },
    navigation: {
      buttonOptions: {
        enabled: true,
      },
    },
  });

  // for hiding context menu
  useEffect(() => {
    setChartOptions({
      navigation: {
        buttonOptions: {
          enabled: false,
        },
      },
    });
  }, []);
  // for setting display errors or adding/removing chart animations
  useEffect(() => {
    setChartOptions({
      chart: {
        displayErrors: true,
      },
      plotOptions: {
        series: {
          animation: true,
        },
      },
    });
  }, []);

  return <HighchartsReact highcharts={Highcharts} options={chartOptions} />;
};

export default HeatMapChart;

render(<HeatMapChart />, document.getElementById('root'));
magdalena
Posts: 517
Joined: Tue Aug 24, 2021 1:32 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi,

You can use multiple useEffect, but remember to merge initial options. Here is an example demo of how to achieve this:

Demo:
https://codesandbox.io/s/highcharts-rea ... rked-vlc90

Generally, you should use only one useEffect and then check the options conditionally inside of it.

Feel free to ask any further questions,
Regards!
Magdalena Gut
Developer and Highcharts Support Engineer
janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi magdalena,

I just checked out your demo above and this is very similar to what I was originally doing however just like in mine, this demo has broken keyboard navigation. Typically with keyboard navigation in the heatmap, the user traverses all y-values in the first x point and then moves to the y-values in the next one. In your example, it is traversing all x-vales in the first y-point and then traversing the normally pointing with [1,0, value]. This is the weird order that I mentioned in my initial post. Is this a bug in Highcharts?

Thanks!
magdalena
Posts: 517
Joined: Tue Aug 24, 2021 1:32 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi,

My mistake, chartOptions should be removed from the first useEffect.

Demo
https://codesandbox.io/s/highcharts-rea ... rked-npp15

Regards!
Magdalena Gut
Developer and Highcharts Support Engineer
janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi magdalena,

Thanks for your help with this! Your demo helped me figure out what was wrong. I am now able to update every chart option I need without breaking keyboard navigation except for the series. I tried updating just the series in your demo and the keyboard navigation wasn't working again. Here is the update that I made:

Demo: https://codesandbox.io/s/highcharts-rea ... =/demo.jsx

In case the link above doesn't work, from your previous demo, I commented out the other useEffects and added the one below. I've tried it both with and without passing in chartOptions.

Code: Select all

useEffect(() => {
    setChartOptions(() => ({
      series: [
        {
          name: "Logins over time",
          data: [
            [0, 0, 7],
            [0, 1, 30],
            [0, 2, 90],
            [1, 0, 10],
            [1, 1, 80],
            [1, 2, 90],
            [2, 0, 20],
            [2, 1, 55],
            [2, 2, 120],
            [3, 0, 110],
            [3, 1, 8],
            [3, 2, 55],
            [4, 0, 25],
            [4, 1, 110],
            [4, 2, 70]
          ]
        }
      ]
    }));
  }, []);
  
Any suggestions?
janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi magdalena,

As per above, I actually found a way to update the chart data without breaking the keyboard navigation by using setData function and setting updatePoints to false:

Code: Select all

const chartComponent = useRef(null);
  const mergedRef = ref ? useMergedRefs(chartComponent, ref) : chartComponent;
  ...
  
useEffect(() => {
    mergedRef.current.chart.series[0].setData(dataSeries[0].data, true, true, false);
  }, []);
  
  ...
  
  <HighchartsReact
        highcharts={Highcharts}
        options={chartOptions}
        ref={mergedRef}
      />
I tried something like below but it did not work either.

Code: Select all

useEffect(() => {
    setChartOptions(() => ({
      series: [{
        data: dataSeries[0].data
      }]
      
    }));
  }, []);
Is there a way to achieve the results of using setData (updatePoints is false, data updates correctly, and keyboard navigation still works) using react?
magdalena
Posts: 517
Joined: Tue Aug 24, 2021 1:32 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hello,

I have good news and bad news.

The good news is, key navigation in heatmaps was fixed so you can use the latest version of Highcharts.

Unfortunately, we noticed this behaviour of keyboard navigation after the series update is a bug, which you can track here: https://github.com/highcharts/highcharts/issues/16751

Your solution seems to be the best temporary workaround.

Let me know if you have any further questions,
Regards!
Magdalena Gut
Developer and Highcharts Support Engineer
janina
Posts: 31
Joined: Thu Jul 01, 2021 7:19 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

Hi magdalena,

Thanks for all of your help with this issue!
magdalena
Posts: 517
Joined: Tue Aug 24, 2021 1:32 pm

Re: Keyboard navigation breaks after updating chart options in heatmap

You're welcome! In case of any further questions, feel free to contact us again.
Magdalena Gut
Developer and Highcharts Support Engineer

Return to “Highcharts Usage”