I want a shared legend for 2 areaspline
highcharts. Using react, I am unable to create that shared legend between the 2.
My code:
component.js
:
import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import AreaSplineChart from "./areaspline";
import "./App.css";
const Component = ({ data, filteredData }) => {
const chartData = filteredData.length !== 0 ? filteredData : data;
seriesOne = {"dts":["Feb 25, 2024","Feb 26, 2024","Feb 27, 2024","Feb 28, 2024","Feb 29, 2024","Mar 01, 2024","Mar 02, 2024","Mar 03, 2024","Mar 04, 2024","Mar 05, 2024","Mar 06, 2024","Mar 07, 2024"],"field":"One","legend":false,"series":[{"name":"page_views","data":[444774,484174,557434,492637,466673,409858,350902,445857,560202,554498,519825,507158],"color":"#DA70D6"},{"name":"article_views","data":[326770,340229,411025,346702,330603,297353,256416,328951,396708,392765,371077,365406],"color":"#FFD700"},{"name":"visits","data":[340812,362617,423843,371288,352045,318796,276761,347808,427239,423992,396206,391983],"color":"#6B8E23"},{"name":"return_visits","data":[156492,183181,209536,199166,186924,152693,130780,165849,217871,226510,207835,200054],"color":"#FF7F50"},{"name":"audio_play","data":[3292,3865,4913,4885,4547,4134,3762,2929,3681,4254,4444,4094],"color":"#20B2AA"},{"name":"video_play_e5","data":[687,644,457,476,776,428,572,462,1257,830,884,651],"color":"#FF8C00"}]}
seriesTwo = {"dts":["Feb 25, 2024","Feb 26, 2024","Feb 27, 2024","Feb 28, 2024","Feb 29, 2024","Mar 01, 2024","Mar 02, 2024","Mar 03, 2024","Mar 04, 2024","Mar 05, 2024","Mar 06, 2024","Mar 07, 2024"],"field":"Two","legend":true,"series":[{"name":"page_views","data":[946159,1140360,1213841,1177459,1185913,1078396,1077760,1088569,1386531,1389498,1303569,1217209],"color":"#DA70D6"},{"name":"article_views","data":[608024,733135,788907,764644,772883,713887,740001,719234,914251,906715,851080,783937],"color":"#FFD700"},{"name":"visits","data":[678800,818550,875175,856391,865832,793614,794805,794055,1001979,995969,936937,882231],"color":"#6B8E23"},{"name":"return_visits","data":[470732,558457,580674,569857,584406,520338,491274,534849,671634,666763,629567,596229],"color":"#FF7F50"},{"name":"audio_play","data":[16255,18510,22248,24258,25180,21633,18850,15823,19976,22023,22546,22746],"color":"#20B2AA"},{"name":"video_play_e5","data":[38688,74568,84344,96184,92342,75586,39355,35294,113613,124318,104916,650926],"color":"#FF8C00"}]}
return (
<div className="trends clearfix w-100 column">
<h3 className="mt-1 ms-1" style={{ color: "#81b0d2" }}>
<u>Trends</u>
</h3>
<div className="clearfix w-100 column">
<div className="clearfix w-100 column">
<div className="w-100 oneArea">
<AreaSplineChart
dates={seriesOne.dts}
nm={seriesOne.field}
lgnd={seriesOne.legend}
trendData={seriesOne.series}
/>
</div>
<div className="w-100 twoArea">
<AreaSplineChart
dates={seriesTwo.dts}
nm={seriesTwo.field}
lgnd={seriesTwo.legend}
trendData={seriesTwo.series}
/>
</div>
</div>
</div>
</div>
);
};
export default Component;
areaspline.js
import React, { useMemo } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import highchartsAccessibility from "highcharts/modules/accessibility";
import highchartsExporting from "highcharts/modules/exporting";
import highchartsExportData from "highcharts/modules/export-data";
import dayjs from "dayjs";
import "dayjs/locale/es";
highchartsAccessibility(Highcharts);
highchartsExporting(Highcharts);
highchartsExportData(Highcharts);
const sharedLegendOptions = () => {
const container = document.querySelector(".oneArea");
var XYZ = container && container.highcharts;
var seriesId = this.options.id;
if (XYZ) {
var series = XYZ.get(seriesId);
console.log(seriesId);
if (series) {
series.visible ? series.hide() : series.show();
}
}
};
const AreaSplineChart = ({ dates, nm, lgnd, trendData }) => {
dayjs.locale("en");
const addCommas = (x) =>
x.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",");
const options = useMemo(
() => ({
chart: {
type: "areaspline",
backgroundColor: "#283347",
zoomType: "x",
height: "25%",
// marginRight: 120,
// marginLeft: -10,
},
exporting: {
enabled: true,
},
navigation: {
buttonOptions: {
verticalAlign: "top",
y: -10,
x: -5,
},
},
title: {
text: nm,
style: {
color: "#fff",
},
},
xAxis: {
categories: dates,
lineColor: "#fff",
lineWidth: 3,
labels: {
style: {
color: "#fff",
},
},
},
yAxis: {
gridLineColor: "#283347",
lineColor: "#fff",
lineWidth: 3,
labels: {
style: {
color: "#fff",
},
},
title: {
text: "",
},
opposite: false,
},
legend: {
enabled: lgnd,
itemStyle: {
color: "#fff",
},
},
accessibility: {
enabled: false,
},
credits: {
enabled: false,
},
tooltip: {
backgroundColor: "#283347",
style: { color: "#fff" },
formatter: function () {
const yFormat = addCommas(this.y);
let tooltip = `
<span><b><u>${dayjs(this.key).format(
"MMM DD, YYYY"
)}</u></b>: ${yFormat}</span>`;
return tooltip;
},
useHTML: true,
},
plotOptions: {
series: {
stacking: "normal",
marker: {
enabled: false,
states: {
hover: {
enabled: true,
},
},
},
events: { legendItemClick: lgnd ? sharedLegendOptions() : undefined },
},
},
series: trendData,
}),
[nm, dates, lgnd, trendData]
);
return (
<HighchartsReact
highcharts={Highcharts}
containerProps={{ className: `${nm}-area` }}
options={options}
/>
);
};
export default AreaSplineChart;
I keep getting the error:
Uncaught TypeError: Cannot read properties of undefined (reading 'options')
at sharedLegendOptions
How to create the shared legend between the 2 Highcharts.
The simplest way is to get a chart reference, find the correct series and call the setVisible
method on it.
const chartComponent1 = useRef(null);
const chartComponent2 = useRef(null);
const legendItemClick = function () {
const seriesName = this.name;
const chart1 = chartComponent1.current.chart;
const chart2 = chartComponent2.current.chart;
const series1 = chart1.series.find((s) => s.name === seriesName);
const series2 = chart2.series.find((s) => s.name === seriesName);
series1.setVisible();
series2.setVisible();
return false;
};
Live demo: https://stackblitz.com/edit/react-yw9ctn
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#setVisible