first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import React, { useEffect, useRef, useMemo } from "react";
|
||||
import { Chart } from "chart.js/auto";
|
||||
// import { useThemeStore } from "../../../../../store/useThemeStore";
|
||||
|
||||
// Define Props Interface
|
||||
interface ChartComponentProps {
|
||||
type: any; // Type of chart (e.g., "bar", "line", etc.)
|
||||
title: string; // Title of the chart
|
||||
fontFamily?: string; // Optional font family for the chart title
|
||||
fontSize?: string; // Optional font size for the chart title
|
||||
fontWeight?: "Light" | "Regular" | "Bold"; // Optional font weight for the chart title
|
||||
data: {
|
||||
labels: string[]; // Labels for the x-axis
|
||||
datasets: {
|
||||
data: number[]; // Data points for the chart
|
||||
backgroundColor: string; // Background color for the chart
|
||||
borderColor: string; // Border color for the chart
|
||||
borderWidth: number; // Border width for the chart
|
||||
}[];
|
||||
}; // Data for the chart
|
||||
}
|
||||
|
||||
const ChartComponent = ({
|
||||
type,
|
||||
title,
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight = "Regular", // Default to "Regular"
|
||||
data: propsData,
|
||||
}: ChartComponentProps) => {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
// const { themeColor } = useThemeStore();
|
||||
|
||||
// Memoize Theme Colors to Prevent Unnecessary Recalculations
|
||||
// const buttonActionColor = useMemo(
|
||||
// () => themeColor[0] || "#5c87df",
|
||||
// [themeColor]
|
||||
// );
|
||||
// const buttonAbortColor = useMemo(
|
||||
// () => themeColor[1] || "#ffffff",
|
||||
// [themeColor]
|
||||
// );
|
||||
|
||||
// Memoize Font Weight Mapping
|
||||
const chartFontWeightMap = useMemo(
|
||||
() => ({
|
||||
Light: "lighter" as const,
|
||||
Regular: "normal" as const,
|
||||
Bold: "bold" as const,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// Parse and Memoize Font Size
|
||||
const fontSizeValue = useMemo(
|
||||
() => (fontSize ? parseInt(fontSize) : 12),
|
||||
[fontSize]
|
||||
);
|
||||
|
||||
// Determine and Memoize Font Weight
|
||||
const fontWeightValue = useMemo(
|
||||
() => chartFontWeightMap[fontWeight],
|
||||
[fontWeight, chartFontWeightMap]
|
||||
);
|
||||
|
||||
// Memoize Chart Font Style
|
||||
const chartFontStyle = useMemo(
|
||||
() => ({
|
||||
family: fontFamily || "Arial",
|
||||
size: fontSizeValue,
|
||||
weight: fontWeightValue,
|
||||
color: "#2B3344",
|
||||
}),
|
||||
[fontFamily, fontSizeValue, fontWeightValue]
|
||||
);
|
||||
|
||||
// Memoize Chart Data
|
||||
const data = useMemo(() => propsData, [propsData]);
|
||||
|
||||
// Memoize Chart Options
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
font: chartFontStyle,
|
||||
align: "start", // Left align the title
|
||||
padding: {
|
||||
top: 10, // Add padding above the title
|
||||
bottom: 20, // Add padding between the title and the chart
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
);
|
||||
|
||||
// Initialize Chart on Component Mount
|
||||
useEffect(() => {
|
||||
if (!canvasRef.current) return;
|
||||
|
||||
const ctx = canvasRef.current.getContext("2d");
|
||||
if (!ctx) return;
|
||||
|
||||
const chart = new Chart(ctx, { type, data, options });
|
||||
|
||||
// Cleanup: Destroy the chart instance when the component unmounts
|
||||
return () => chart.destroy();
|
||||
}, [type, data, options]); // Only recreate the chart when these dependencies change
|
||||
|
||||
return <canvas ref={canvasRef} style={{ width: "100%", height: "100%" }} />;
|
||||
};
|
||||
|
||||
export default React.memo(ChartComponent, (prevProps, nextProps) => {
|
||||
// Custom comparison function to prevent unnecessary re-renders
|
||||
return (
|
||||
prevProps.type === nextProps.type &&
|
||||
prevProps.title === nextProps.title &&
|
||||
prevProps.fontFamily === nextProps.fontFamily &&
|
||||
prevProps.fontSize === nextProps.fontSize &&
|
||||
prevProps.fontWeight === nextProps.fontWeight &&
|
||||
JSON.stringify(prevProps.data) === JSON.stringify(nextProps.data)
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user