Files
fn_registry/frontend/functions/ui/pie_chart.tsx
T
egutierrez 55e6ff87a8 feat: componentes data_table y pie_chart — tabla con sorting/pagination y gráfico circular Recharts
Nuevos componentes React/TS en frontend/functions/ui/:
- data_table: tabla de datos con columnas tipadas, sorting, paginación y formato personalizable
- pie_chart: gráfico circular Recharts con tooltips, leyenda y paleta configurable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:32:28 +02:00

90 lines
2.3 KiB
TypeScript

import {
PieChart as RechartsPieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer,
} from 'recharts'
import { cn } from '../core/cn'
const DEFAULT_COLORS = [
'#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6',
'#ec4899', '#06b6d4', '#f97316',
]
interface PieChartProps {
data: Record<string, unknown>[]
nameKey: string
valueKey: string
colors?: string[]
donut?: boolean
innerRadius?: number
outerRadius?: number
showLegend?: boolean
showLabels?: boolean
height?: number | string
className?: string
valueFormatter?: (value: number) => string
}
function PieChartComponent({
data,
nameKey,
valueKey,
colors = DEFAULT_COLORS,
donut = false,
innerRadius,
outerRadius = 100,
showLegend = true,
showLabels = true,
height = 300,
className,
valueFormatter = (v) => v.toLocaleString(),
}: PieChartProps) {
// Ensure numeric values for Recharts Pie
const pieData = data.map(row => ({
...row,
[valueKey]: Number(row[valueKey]) || 0,
}))
const resolvedInnerRadius = donut ? (innerRadius ?? 50) : (innerRadius ?? 0)
const labelRenderer = showLabels
? ({ name, percent }: Record<string, unknown>) =>
`${name ?? ''} ${(((percent as number) ?? 0) * 100).toFixed(0)}%`
: undefined
return (
<ResponsiveContainer width="100%" height={height} className={cn(className)}>
<RechartsPieChart>
<Pie
data={pieData}
dataKey={valueKey}
nameKey={nameKey}
cx="50%"
cy="50%"
outerRadius={outerRadius}
innerRadius={resolvedInnerRadius}
strokeWidth={0}
fontSize={11}
label={labelRenderer}
labelLine={showLabels}
>
{pieData.map((_, i) => (
<Cell key={i} fill={colors[i % colors.length]} />
))}
</Pie>
<Tooltip
contentStyle={{
backgroundColor: 'var(--card)',
border: '1px solid var(--border)',
borderRadius: 8,
fontSize: 12,
}}
formatter={(value: unknown) => [valueFormatter(value as number)]}
/>
{showLegend && <Legend wrapperStyle={{ fontSize: 11 }} />}
</RechartsPieChart>
</ResponsiveContainer>
)
}
export const PieChart = PieChartComponent
export type { PieChartProps }