UNPKG

highcharts-react-official

Version:

Official minimal [Highcharts](https://www.highcharts.com/) integration for React.

114 lines (102 loc) 3.27 kB
import React, { forwardRef, memo, useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react'; // React currently throws a warning when using `useLayoutEffect` on the server. // To get around it, we can conditionally `useEffect` on the server (no-op) and // `useLayoutEffect` in the browser. We need `useLayoutEffect` to ensure the // `Highcharts` ref is available in the layout phase. This makes it available // in a parent component's `componentDidMount`. const useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? useLayoutEffect : useEffect; export const HighchartsReact = memo(forwardRef( function HighchartsReact(props, ref) { const containerRef = useRef(); const chartRef = useRef(); const constructorType = useRef(props.constructorType); const highcharts = useRef(props.highcharts); useIsomorphicLayoutEffect(() => { function createChart() { const H = props.highcharts || ( typeof window === 'object' && window.Highcharts ); const constructorType = props.constructorType || 'chart'; if (!H) { console.warn('The "highcharts" property was not passed.'); } else if (!H[constructorType]) { console.warn( 'The "constructorType" property is incorrect or some ' + 'required module is not imported.' ); } else if (!props.options) { console.warn('The "options" property was not passed.'); } else { // Create a chart chartRef.current = H[constructorType]( containerRef.current, props.options, props.callback ); } } if (!chartRef.current) { createChart(); } else { if (props.allowChartUpdate !== false) { // Reacreate chart on Highcharts or constructor type change if ( props.constructorType !== constructorType.current || props.highcharts !== highcharts.current ) { constructorType.current = props.constructorType; highcharts.current = props.highcharts; createChart(); // Use `chart.update` to apply changes } else if (!props.immutable && chartRef.current) { chartRef.current.update( props.options, ...(props.updateArgs || [true, true]) ); } else { createChart(); } } } }, [ props.options, props.allowChartUpdate, props.updateArgs, props.containerProps, props.highcharts, props.constructorType ]); // Destroy the chart on unmount useIsomorphicLayoutEffect(() => { return () => { if (chartRef.current) { chartRef.current.destroy(); chartRef.current = null; } }; }, []); useImperativeHandle( ref, () => ({ get chart() { return chartRef.current; }, container: containerRef }), [] ); // Create container for the chart return <div { ...props.containerProps } ref={ containerRef } />; } )); export default HighchartsReact;