Skip to content

Instantly share code, notes, and snippets.

@huksley
Last active October 28, 2021 06:58
Show Gist options
  • Save huksley/62a4f0e8a955f59fbef2f15a3e9b5cf6 to your computer and use it in GitHub Desktop.
Save huksley/62a4f0e8a955f59fbef2f15a3e9b5cf6 to your computer and use it in GitHub Desktop.
Single component frappe-chart wrapper for react
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useImperativeHandle, forwardRef } from "react";
import { Chart } from "frappe-charts/dist/frappe-charts.esm";
type ChartType = "line" | "bar" | "axis-mixed" | "pie" | "percentage" | "heatmap";
type AxisMode = "span" | "tick";
type ChartData = {
labels?: Array<string>;
datasets?: Array<{
name?: string;
chartType?: ChartType;
values: Array<number>;
}>;
dataPoints?: { [x: string]: number };
start?: Date;
end?: Date;
};
type SelectEvent = {
label: string;
values: number[];
index: number;
};
type TooltipOptions = {
formatTooltipX?: (value: number) => any;
formatTooltipY?: (value: number) => any;
};
type Props = {
animate?: 0 | 1;
title?: string;
type?: ChartType;
data: ChartData;
height?: number;
colors?: Array<string>;
axisOptions?: {
xAxisMode?: AxisMode;
yAxisMode?: AxisMode;
xIsSeries?: 0 | 1;
};
barOptions?: {
spaceRatio?: number;
stacked?: 0 | 1;
height?: number;
depth?: number;
};
lineOptions?: {
dotSize?: number;
hideLine?: 0 | 1;
hideDots?: 0 | 1;
heatline?: 0 | 1;
regionFill?: number;
areaFill?: number;
spline?: 0 | 1;
};
isNavigable?: boolean;
maxSlices?: number;
truncateLegends?: 0 | 1;
tooltipOptions?: TooltipOptions;
onDataSelect?: (event: SelectEvent) => void;
valuesOverPoints?: 0 | 1;
};
export const Chart = forwardRef((props: Props, parentRef) => {
const ref = React.useRef<HTMLDivElement>(null);
const chart = React.useRef<any>(null);
const initialRender = React.useRef<boolean>(true);
const { onDataSelect } = props;
useImperativeHandle(parentRef, () => ({
export: () => {
if (chart && chart.current) {
chart.current.export();
}
}
}));
React.useEffect(() => {
chart.current = new Chart(ref.current, {
isNavigable: onDataSelect !== undefined,
...props
});
if (onDataSelect) {
chart.current.parent.addEventListener(
"data-select",
(e: SelectEvent & React.SyntheticEvent) => {
e.preventDefault();
onDataSelect(e);
}
);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
React.useEffect(() => {
if (initialRender.current) {
initialRender.current = false;
return;
}
chart.current.update(props.data);
}, [props.data]);
return <div ref={ref} />;
});
@huksley
Copy link
Author

huksley commented Oct 28, 2021

@huksley
Copy link
Author

huksley commented Oct 28, 2021

<Chart
    type="bar"
    animate={0}
    title="dasdsads"
    isNavigable
    onDataSelect={event => {
      logger.info(event);
    }}
    tooltipOptions={{
      formatTooltipX: function (value) {
        return value;
      },
      formatTooltipY: function (value) {
        return value;
      }
    }}
    colors={[globalVars.colorAlt]}
    axisOptions={{ xAxisMode: "tick", yAxisMode: "tick", xIsSeries: 1 }}
    height={250}
    data={{
      labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      datasets: [{ values: [18, 40, 30, 35, 8, 52, 17, 4] }]
    }}
  />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment