953f598b9b
Componentes React reutilizables: card, dialog, tabs, select, alert, badge, button, input, label, skeleton, tooltip, progress_bar, page_header, form_field, settings_page, crud_page, analytics_page, dashboard_layout. Charts: area, bar, line, sparkline, kpi_card, chart_container. Hooks Wails: use_wails_query, use_wails_mutation, use_wails_stream, use_wails_event, use_animated_canvas. Funciones core: cn, format_compact, chart_colors, get_series_color, wails_cache, theme_config_to_colors. Tipos: chart_series, wails_ipc, theme_config, component_variants. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
63 lines
2.7 KiB
TypeScript
63 lines
2.7 KiB
TypeScript
import {
|
|
AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, Legend,
|
|
} from 'recharts'
|
|
import { ChartContainer, ChartTooltipContent, type Series, getSeriesColor } from './chart_container'
|
|
|
|
interface GradientConfig { from: string; to: string }
|
|
|
|
interface AreaChartProps {
|
|
data: Record<string, unknown>[]
|
|
xKey: string
|
|
yKey?: string
|
|
series?: Series[]
|
|
stacked?: boolean
|
|
gradient?: GradientConfig | boolean
|
|
showGrid?: boolean
|
|
showLegend?: boolean
|
|
height?: number | string
|
|
className?: string
|
|
xAxisFormatter?: (value: unknown) => string
|
|
yAxisFormatter?: (value: unknown) => string
|
|
valueFormatter?: (value: number) => string
|
|
}
|
|
|
|
function AreaChartComponent({
|
|
data, xKey, yKey, series, stacked = false, gradient = true, showGrid = true,
|
|
showLegend = false, height = 300, className, xAxisFormatter, yAxisFormatter,
|
|
valueFormatter = (v) => v.toLocaleString(),
|
|
}: AreaChartProps) {
|
|
const areas = series
|
|
? series.map((s, i) => ({ dataKey: s.key, name: s.name, color: getSeriesColor(i, s.color) }))
|
|
: yKey ? [{ dataKey: yKey, name: yKey, color: getSeriesColor(0) }] : []
|
|
|
|
const gradientConfig: GradientConfig | null = gradient
|
|
? typeof gradient === 'object' ? gradient : { from: '', to: 'transparent' }
|
|
: null
|
|
|
|
return (
|
|
<ChartContainer className={className} height={height}>
|
|
<RechartsAreaChart data={data} margin={{ top: 10, right: 10, left: 10, bottom: 10 }}>
|
|
<defs>
|
|
{areas.map((area) => (
|
|
<linearGradient key={area.dataKey} id={`gradient-${area.dataKey}`} x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="5%" stopColor={gradientConfig?.from || area.color} stopOpacity={0.8} />
|
|
<stop offset="95%" stopColor={gradientConfig?.to || area.color} stopOpacity={0.1} />
|
|
</linearGradient>
|
|
))}
|
|
</defs>
|
|
{showGrid && <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />}
|
|
<XAxis dataKey={xKey} tickFormatter={xAxisFormatter} className="text-xs fill-muted-foreground" />
|
|
<YAxis tickFormatter={yAxisFormatter} className="text-xs fill-muted-foreground" />
|
|
<Tooltip content={<ChartTooltipContent valueFormatter={valueFormatter} />} cursor={{ stroke: 'hsl(var(--muted-foreground))', strokeDasharray: '3 3' }} />
|
|
{showLegend && <Legend />}
|
|
{areas.map((area) => (
|
|
<Area key={area.dataKey} type="monotone" dataKey={area.dataKey} name={area.name} stroke={area.color} strokeWidth={2} fill={gradient ? `url(#gradient-${area.dataKey})` : area.color} fillOpacity={gradient ? 1 : 0.3} stackId={stacked ? 'stack' : undefined} />
|
|
))}
|
|
</RechartsAreaChart>
|
|
</ChartContainer>
|
|
)
|
|
}
|
|
|
|
export const AreaChart = AreaChartComponent
|
|
export type { AreaChartProps, GradientConfig }
|