48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import type { ApexOptions } from 'apexcharts';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface ApexChartProps {
|
|
type: 'line' | 'area' | 'bar' | 'pie' | 'donut' | 'radialBar' | 'scatter' | 'bubble' | 'heatmap' | 'candlestick' | 'boxPlot' | 'radar' | 'polarArea' | 'rangeBar' | 'rangeArea' | 'treemap';
|
|
series: ApexOptions['series'];
|
|
options: ApexOptions;
|
|
height?: number | string;
|
|
width?: string | number;
|
|
className?: string;
|
|
}
|
|
|
|
export function ApexChart({ type, series, options, height = 280, width = '100%', className }: ApexChartProps) {
|
|
const [Chart, setChart] = useState<typeof import('react-apexcharts').default | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
import('react-apexcharts').then((mod) => {
|
|
if (!cancelled) setChart(() => mod.default);
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
if (!Chart) {
|
|
return (
|
|
<div
|
|
className={cn('min-w-0 w-full max-w-full overflow-hidden animate-pulse rounded-[5px] bg-muted', className)}
|
|
style={{ height }}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'min-w-0 w-full max-w-full overflow-hidden [&_.apexcharts-canvas]:!w-full [&_.apexcharts-canvas]:!max-w-full [&_.apexcharts-canvas]:!overflow-hidden [&_.apexcharts-svg]:!max-w-full',
|
|
className
|
|
)}
|
|
>
|
|
<Chart type={type} series={series} options={options} height={height} width={width} />
|
|
</div>
|
|
);
|
|
}
|