'use client' import type { ApexOptions } from 'apexcharts' import React from 'react' import { cn } from '../../utils/cn' import { useChartOptions, createChartTooltip, mergeChartOptions, } from './chart.config' import { useChartTicks } from './useChartTicks' export type AxisChartSeries = Array<{ name: string color?: string type?: 'area' | 'line' | 'bar' data: Array<{ x: string y: number | null }> }> export type NonAxisChartSeries = number[] export type ChartProps = { series: AxisChartSeries | NonAxisChartSeries type?: 'area' | 'line' | 'bar' | 'pie' | 'donut' | 'radialBar' options?: ApexOptions width?: string | number height?: string | number formatX?: (value: string) => string formatY?: (value: number) => string formatTooltipX?: (value: string) => string formatTooltipY?: (value: number) => string xAxisLabel?: string yAxisLabel?: string showLegend?: boolean } export const Chart = ({ series, type, options: customChartOptions = {}, width = '100%', height = '100%', formatX = (value) => `${value}`, formatY = (value) => `${value}`, formatTooltipX = (value) => `${value}`, formatTooltipY = (value) => `${value}`, xAxisLabel, yAxisLabel, showLegend = false, }: ChartProps) => { const [ReactApexChart, setReactApexChart] = React.useState(null) const chartRef = React.useRef(null) const isDatetimeChart = customChartOptions?.xaxis?.type === 'datetime' const tickAmount = useChartTicks(isDatetimeChart ? null : chartRef) React.useEffect(() => { void import('react-apexcharts').then((module) => { setReactApexChart(() => module.default) }) }, []) const defaultOptions = useChartOptions() const mutableOptions: ApexOptions = React.useMemo( () => ({ chart: { type, }, xaxis: { labels: { formatter: (value: string) => formatX(value), }, title: { text: xAxisLabel, }, ...(tickAmount && { tickAmount }), }, yaxis: { labels: { formatter: (value: number) => (value !== 0 ? formatY(value) : ''), }, title: { text: yAxisLabel, }, }, legend: { show: showLegend, }, tooltip: { enabled: true, shared: true, custom: createChartTooltip(formatTooltipX, formatTooltipY), }, }), [ type, formatX, formatY, formatTooltipX, formatTooltipY, xAxisLabel, yAxisLabel, showLegend, tickAmount, ], ) const mergedOptions = React.useMemo( () => mergeChartOptions(defaultOptions, mutableOptions, customChartOptions), [defaultOptions, mutableOptions, customChartOptions], ) if (!ReactApexChart) return null // Avoid SSR issues return (
) }