Search code examples
reactjshighchartsreact-highcharts

How to disable click on a particular series in Highchart React?


In Highchart React, there are 3 series. Requirements : 1)'Series in Rs' bar should be always visible. It shouldn't be hide on clicking on it's legend. 2) Only one of the other two series should be visible. (Complete. Working fine)

I am not able to achieve the first requirement. Tried a lot of thing but none of them seems to work.

Current highcharts version - 11.4.8

import React, { useEffect, useState } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import drilldown from "highcharts/modules/drilldown";

drilldown(Highcharts);

const BarGraph = ({ graphData, dates }) => {
  const [chartData, setChartData] = useState([]);
  const [showPaisa, setShowPaisa] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (
      Array.isArray(graphData) &&
      graphData.length > 0
    ) {
      const processedData = graphData.map((item, index) => ({
        name: item.name,
        data: item.data || [],
        yAxis: item.yAxis,
        visible: true,
      }));

      setChartData(processedData);
      setLoading(false);
    }
  }, [graphData]);

  const options = {
    chart: {
      type: "column",
    },
    title: {
      text: "",
    },
    xAxis: {
      categories: dates || [],
    },
    yAxis: [
      {
        title: {
          text: "Series in Rs",
        },
        opposite: false,
        labels: {
          formatter: function () {
            return this.value;
          },
        },
      },
      {
        title: {
          text: `Series in   ${showPaisa ? " (p)" : " (%)"}`,
        },
        opposite: true,
        labels: {
          formatter: function () {
            return `${this.value} ${showPaisa ? "p" : "%"}`;
          },
        },
      },
    ],

    series: [
      {
        name: "Series in Rs",
        data: chartData[0]?.data || [],
        yAxis: 0,
        visible: true,
        events: {
          legendItemClick: function (event) {
            event.preventDefault();
            return false;
          },
        },
      },

      {
        name: "Series in p",
        data: chartData[1]?.data || [],
        yAxis: 1,
        events: {
          legendItemClick: function (e) {
            setShowPaisa(!showPaisa);
          },
        },
        visible: !showPaisa,
      },
      {
        name: "Series in %",
        data: chartData[2]?.data || [],
        yAxis: 1,
        events: {
          legendItemClick: function () {
            setShowPaisa(!showPaisa);
          },
        },
        visible: showPaisa,
      },
    ],
  };

  if (loading) {
    return <div>Loading...</div>;
  }

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

export default BarGraph;

Solution

  • The best way is to handle the both requirements is to use the itemClick function.

    Please note that legendItemClick is deprecated since Highcharts v11.4.4.

      legend: {
        events: {
          itemClick: function (e) {
            const series = e.legendItem
            const allSeries = series.chart.series
            // disable click on the last series
            if (series.index === 2) {
              return false
            }
            // only one of the two first series should be visible
            if (series.index === 0) {
              allSeries[1].setVisible(series.visible)
            } else {
              allSeries[0].setVisible(series.visible)
            }
          },
        },
      }
    

    Live demo: https://jsfiddle.net/BlackLabel/gz3kt2h6/

    API Reference:

    https://api.highcharts.com/highcharts/series.line.events.legendItemClick

    https://api.highcharts.com/highcharts/legend.events.itemClick