diff --git a/packages/react-jsx-highstock/jest.config.js b/packages/react-jsx-highstock/jest.config.js index 5b467f1a..adc928b8 100644 --- a/packages/react-jsx-highstock/jest.config.js +++ b/packages/react-jsx-highstock/jest.config.js @@ -168,7 +168,7 @@ module.exports = { // "/node_modules/" // ], "transformIgnorePatterns": [ - "node_modules/(?!(lodash-es)/)" + "node_modules/(?!(lodash-es|react-jsx-highcharts)/)" ] // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them // unmockedModulePathPatterns: undefined, diff --git a/packages/react-jsx-highstock/src/components/Navigator/Navigator.js b/packages/react-jsx-highstock/src/components/Navigator/Navigator.js index 9613dec0..c528c382 100644 --- a/packages/react-jsx-highstock/src/components/Navigator/Navigator.js +++ b/packages/react-jsx-highstock/src/components/Navigator/Navigator.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useRef, useEffect } from 'react'; import PropTypes from 'prop-types'; import { attempt } from 'lodash-es'; import { @@ -8,39 +8,35 @@ import { } from 'react-jsx-highcharts'; import NavigatorXAxis from './NavigatorXAxis'; -const Navigator = ({ enabled = true, ...restProps }) => { +const Navigator = ({ enabled = true, children, ...restProps }) => { const props = { enabled, ...restProps }; - const [rendered, setRendered] = useState(false); + const renderedRef = useRef(false); const chart = useChart(); const Highcharts = useHighcharts(); + const modifiedProps = useModifiedProps(props); useEffect(() => { - const { children, ...rest } = props; - // Workaround from http://jsfiddle.net/x40me94t/2/ - const chartObj = chart.object; - chartObj.options.navigator.enabled = true; - // Initialise Navigator https://github.com/highcharts/highcharts/blob/dd730ab/js/parts/Navigator.js#L1837-L1844 - Highcharts.fireEvent(chartObj, 'beforeRender'); - - updateNavigator(rest, chart); - - setRendered(true); - return () => { attempt(updateNavigator, { enabled: false }, chart); }; }, []); - const modifiedProps = useModifiedProps(props); + if (!renderedRef.current) { + // Workaround from http://jsfiddle.net/x40me94t/2/ + const chartObj = chart.object; + chartObj.options.navigator.enabled = true; + // Initialise Navigator https://github.com/highcharts/highcharts/blob/dd730ab/js/parts/Navigator.js#L1837-L1844 + Highcharts.fireEvent(chartObj, 'beforeRender'); - useEffect(() => { + updateNavigator(props, chart); + renderedRef.current = true; + } else { if (modifiedProps !== false) { updateNavigator(modifiedProps, chart); } - }); + } - const { children } = props; - if (!children || !rendered) return null; + if (!children) return null; return {children}; }; diff --git a/packages/react-jsx-highstock/src/components/Navigator/NavigatorAxis.js b/packages/react-jsx-highstock/src/components/Navigator/NavigatorAxis.js index 256b5fb7..578d6e48 100644 --- a/packages/react-jsx-highstock/src/components/Navigator/NavigatorAxis.js +++ b/packages/react-jsx-highstock/src/components/Navigator/NavigatorAxis.js @@ -1,57 +1,38 @@ -import React, { - useRef, - useEffect, - Children, - cloneElement, - isValidElement -} from 'react'; +import React, { useRef } from 'react'; import PropTypes from 'prop-types'; -import { - useAxis, - useModifiedProps, - getNonEventHandlerProps -} from 'react-jsx-highcharts'; - -const NavigatorAxis = ({ children, axisId, ...restProps }) => { - const axis = useAxis(axisId); - const renderedRef = useRef(false); - - useEffect(() => { - if (!axis) return; - - updateNavigatorAxis(getNonEventHandlerProps(restProps), axis); - }, [axis]); +import { useChart, useModifiedProps } from 'react-jsx-highcharts'; +import AxisContext from 'react-jsx-highcharts/dist/es/components/AxisContext'; +import createProvidedAxis from 'react-jsx-highcharts/dist/es/components/Axis/createProvidedAxis'; +const NavigatorAxis = ({ children, axisType, axisId, ...restProps }) => { + const chart = useChart(); const modifiedProps = useModifiedProps(restProps); + const providedAxisRef = useRef(null); - useEffect(() => { - if (!renderedRef.current) { - // don't update on first render - renderedRef.current = true; - return; - } - - if (!axis) return; - - if (modifiedProps !== false) { - updateNavigatorAxis(modifiedProps, axis); - } - }); + if (modifiedProps !== false) { + const config = { + navigator: {} + }; + config.navigator[axisType] = modifiedProps; + chart.update(config); + } if (!children) return null; - const axisChildren = Children.map(children, child => { - if (isValidElement(child) === false) return child; - return cloneElement(child, { axisId }); - }); + const axis = chart.get(axisId); + if (!providedAxisRef.current || axis !== providedAxisRef.current.object) { + providedAxisRef.current = createProvidedAxis(axis); + } - return <>{axisChildren}; -}; -const updateNavigatorAxis = (config, axis) => { - axis.update(config); + return ( + + {children} + + ); }; NavigatorAxis.propTypes = { - axisId: PropTypes.string.isRequired + axisId: PropTypes.string.isRequired, + axisType: PropTypes.string.isRequired }; export default NavigatorAxis; diff --git a/packages/react-jsx-highstock/src/components/Navigator/NavigatorXAxis.js b/packages/react-jsx-highstock/src/components/Navigator/NavigatorXAxis.js index 4ebe16ba..c782aa9b 100644 --- a/packages/react-jsx-highstock/src/components/Navigator/NavigatorXAxis.js +++ b/packages/react-jsx-highstock/src/components/Navigator/NavigatorXAxis.js @@ -2,7 +2,7 @@ import React from 'react'; import NavigatorAxis from './NavigatorAxis'; const NavigatorXAxis = props => ( - + ); export default NavigatorXAxis; diff --git a/packages/react-jsx-highstock/src/components/Navigator/NavigatorYAxis.js b/packages/react-jsx-highstock/src/components/Navigator/NavigatorYAxis.js index 63d5df83..88635411 100644 --- a/packages/react-jsx-highstock/src/components/Navigator/NavigatorYAxis.js +++ b/packages/react-jsx-highstock/src/components/Navigator/NavigatorYAxis.js @@ -2,7 +2,7 @@ import React from 'react'; import NavigatorAxis from './NavigatorAxis'; const NavigatorYAxis = props => ( - + ); export default NavigatorYAxis; diff --git a/packages/react-jsx-highstock/test/components/Navigator/Navigator.spec.js b/packages/react-jsx-highstock/test/components/Navigator/Navigator.spec.js index 50ab9118..2f949fce 100644 --- a/packages/react-jsx-highstock/test/components/Navigator/Navigator.spec.js +++ b/packages/react-jsx-highstock/test/components/Navigator/Navigator.spec.js @@ -63,6 +63,7 @@ describe('', () => { describe('update', () => { it('should use the update method when props change', () => { const wrapper = mount(); + testContext.chartStubs.update.mockClear(); wrapper.setProps({ maskInside: false }); expect(testContext.chartStubs.update).toHaveBeenCalledWith( { diff --git a/packages/react-jsx-highstock/test/components/Navigator/NavigatorXAxis.integration.spec.js b/packages/react-jsx-highstock/test/components/Navigator/NavigatorXAxis.integration.spec.js new file mode 100644 index 00000000..e320e488 --- /dev/null +++ b/packages/react-jsx-highstock/test/components/Navigator/NavigatorXAxis.integration.spec.js @@ -0,0 +1,101 @@ +import React from 'react'; +import Highstock from 'highcharts/highstock'; +import { + Chart, + Debug, + XAxis, + YAxis, + LineSeries, + withHighcharts +} from 'react-jsx-highcharts'; +import { HighchartsStockChart, Navigator } from '../../../src'; + +describe(' integration', () => { + describe('when mounted', () => { + it('passes additional props to navigators xAxis', () => { + const data = [1, 2, 3, 4, 5]; + const labels = { x: 0, y: 12 }; + const Component = props => { + return ( + + + + + + + + + + + + ); + }; + const WithComponent = withHighcharts(Component, Highstock); + mount(); + const chart = window.chart; + expect(chart.options.navigator.xAxis.labels).toEqual( + expect.objectContaining(labels) + ); + }); + }); + + describe('when updated', () => { + it('changes the navigator labels', () => { + const data = [1, 2, 3, 4, 5]; + const labels = { x: 0, y: 12 }; + const Component = props => { + return ( + + + + + + + + + + + + ); + }; + + const WithComponent = withHighcharts(Component, Highstock); + const wrapper = mount(); + wrapper.setProps({ labels }); + const chart = window.chart; + expect(chart.options.navigator.xAxis.labels).toEqual( + expect.objectContaining(labels) + ); + }); + }); + + describe('when parent navigator updated', () => { + it('keeps the axis labels', () => { + const data = [1, 2, 3, 4, 5]; + const labels = { x: 0, y: 12 }; + const Component = props => { + return ( + + + + + + + + + + + + ); + }; + + const WithComponent = withHighcharts(Component, Highstock); + const wrapper = mount(); + wrapper.setProps({ height: 100 }); + const chart = window.chart; + expect(chart.options.navigator.xAxis.labels).toEqual( + expect.objectContaining(labels) + ); + }); + }); +});