From e98997995f7998c8d817378327b2c8c08db124b7 Mon Sep 17 00:00:00 2001 From: glitch4347 Date: Mon, 4 Dec 2023 14:38:48 +0100 Subject: [PATCH] add react component and build for that --- build/webpack.base.conf.js | 9 ++- react/ChartwerkLinePod.tsx | 127 +++++++++++++++++++++++++++++++++++++ tsconfig.json | 6 +- 3 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 react/ChartwerkLinePod.tsx diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index 97b8a60..305a3d5 100755 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -1,4 +1,5 @@ const path = require('path'); +const CopyPlugin = require("copy-webpack-plugin"); function resolve(dir) { @@ -8,7 +9,13 @@ function resolve(dir) { module.exports = { context: resolve('src'), entry: './index.ts', - plugins: [], + plugins: [ + new CopyPlugin({ + patterns: [ + { from: "../react", to: "react" }, + ], + }) + ], module: { rules: [ { diff --git a/react/ChartwerkLinePod.tsx b/react/ChartwerkLinePod.tsx new file mode 100644 index 0000000..7c45717 --- /dev/null +++ b/react/ChartwerkLinePod.tsx @@ -0,0 +1,127 @@ +import type { LineTimeSerie, LineOptions } from '@chartwerk/line-pod'; +import { LinePod } from '@chartwerk/line-pod'; + +// import { AxisRange } from '@chartwerk/core/dist/types'; + +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} +
+ ); +}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 2c5e342..5ab8bf9 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,8 @@ "noImplicitUseStrict": false, "noImplicitAny": false, "noUnusedLocals": false, - "baseUrl": "./src" - } + "baseUrl": "./src", + }, + "include": ["src/**/*"], + "exclude": ["*.tsx"] }