import type { LineTimeSerie, LineOptions } from '@chartwerk/line-pod'; import { LinePod } from '@chartwerk/line-pod'; import { useEffect, useRef, useState, PropsWithChildren, forwardRef } from 'react'; import * as _ from 'lodash'; export type AxisRange = [number, number] | undefined; export type ChartwerkLinePodProps = { id: string; series: LineTimeSerie[]; options: LineOptions; className?: string; // TODO: callback types should be exported from chartwerk onZoomIn?: (ranges: AxisRange[]) => void; onZoomOut?: (centers: { x: number, y: number }) => void; onMouseMove?: (event: any) => void; onMouseOut?: () => void; onLegendClick?: (idx: number) => void, onPanning?: (event: { ranges: AxisRange[], d3Event: any }) => void; onPanningEnd?: (ranges: AxisRange[]) => void; onContextMenu?: (evt: any) => void; onSharedCrosshairMove?: (evt: any) => void; onRenderStart?: () => void, onRenderEnd?: () => void, } export const ChartwerkLinePod = forwardRef>((props, ref) => { const [pod, setPod] = useState(null); const [hack, setHack] = useState(null); const chartRef = useRef(null); const chart = chartRef.current; useEffect(() => { // this function will be called on component unmount return () => { if (pod === null) { return; } console.log('remove chart'); // @ts-ignore pod.removeEventListeners(); } }, []); useEffect(() => { if (chart === null) { return; } let eventsCallbacks = _.cloneDeep(props.options.eventsCallbacks || {}); if (props.onZoomIn) { eventsCallbacks.zoomIn = props.onZoomIn; } if (props.onZoomOut) { eventsCallbacks.zoomOut = props.onZoomOut; } if (props.onMouseMove) { eventsCallbacks.mouseMove = props.onMouseMove; } if (props.onMouseOut) { eventsCallbacks.mouseOut = props.onMouseOut; } if (props.onLegendClick) { eventsCallbacks.onLegendClick = props.onLegendClick; } if (props.onPanning) { eventsCallbacks.panning = props.onPanning; } if (props.onPanningEnd) { eventsCallbacks.panningEnd = props.onPanningEnd; } if (props.onContextMenu) { eventsCallbacks.contextMenu = props.onContextMenu; } if (props.onSharedCrosshairMove) { eventsCallbacks.sharedCrosshairMove = props.onSharedCrosshairMove; } if (props.onRenderStart) { eventsCallbacks.renderStart = props.onRenderStart; } if (pod === null) { console.log('create chart'); const newPod = new LinePod( // @ts-ignore chart, props.series, { ...props.options, eventsCallbacks, } ); setPod( newPod ); console.log('initial chart render'); newPod.render(); } else { console.log('update chart'); pod.updateData(props.series, { ...props.options, eventsCallbacks, }); } }, [chart, pod, props.id, props.series, props.options]); // TODO: it's a hack to render the LinePod right after the div appears in DOM setTimeout(() => { if (hack === null) { setHack(1); } }, 1); return (
{props.children}
); });