add react component and build for that #16

Merged
rozetko merged 3 commits from react-component-attempt-2 into main 1 year ago
  1. 9
      build/webpack.base.conf.js
  2. 121
      react/ChartwerkLinePod.tsx
  3. 6
      tsconfig.json

9
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: [
{

121
react/ChartwerkLinePod.tsx

@ -0,0 +1,121 @@
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<HTMLDivElement, PropsWithChildren<ChartwerkLinePodProps>>((props, ref) => {
const [pod, setPod] = useState<LinePod | null>(null);
const [hack, setHack] = useState<number | null>(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);
newPod.render();
} else {
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 (
<div ref={ref}>
<div id={props.id} className={props.className} ref={chartRef}></div>
{props.children}
</div>
);
});

6
tsconfig.json

@ -17,6 +17,8 @@
"noImplicitUseStrict": false,
"noImplicitAny": false,
"noUnusedLocals": false,
"baseUrl": "./src"
}
"baseUrl": "./src",
},
"include": ["src/**/*"],
"exclude": ["*.tsx"]
}

Loading…
Cancel
Save