ca7a5874e4
From: sources/frontend_designs/Ads Analytics Dashboard _standalone_.html New components: - funnel_chart_ts_ui — visualización de funnel de conversión con barras degradadas y tasa entre etapas como Badge semántico. - heatmap_grid_ts_ui — matriz rows × cols con intensidad color-mix sobre el primary color. Genérica (day×hour, cohort, correlation...). Improvements: - alert_ts_ui v1.1.0 — añadidas variantes semánticas success, warning, info (antes: solo default y destructive). - data_table_ts_ui v1.1.0 — prop opcional density: compact | cozy | roomy. No rompe API existente (default 'cozy' = comportamiento previo). Barrel frontend/functions/ui/index.ts actualizado con los dos nuevos exports y el type DataTableDensity. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
127 lines
4.3 KiB
Markdown
127 lines
4.3 KiB
Markdown
---
|
||
name: heatmap_grid
|
||
kind: component
|
||
lang: ts
|
||
domain: ui
|
||
version: "1.0.0"
|
||
purity: impure
|
||
signature: "HeatmapGrid(props: HeatmapGridProps): JSX.Element"
|
||
description: "Matriz rows × columns con intensidad de color proporcional al valor. Genérico — casos típicos: day×hour, cohort retention, matriz de correlación, heatmap geográfico."
|
||
tags: [heatmap, matrix, dashboard, component, ui, chart, retention, cohort]
|
||
uses_functions: []
|
||
uses_types: []
|
||
returns: []
|
||
returns_optional: false
|
||
error_type: ""
|
||
imports: ["@mantine/core", react]
|
||
output: "Componente HeatmapGrid que renderiza una tabla de celdas coloreadas por intensidad con labels formateados."
|
||
tested: false
|
||
tests: []
|
||
test_file_path: ""
|
||
file_path: "frontend/functions/ui/heatmap_grid.tsx"
|
||
props:
|
||
- name: rows
|
||
type: "Record<string, unknown>[]"
|
||
required: true
|
||
description: "Filas de datos. Cada objeto contiene el label de fila (bajo rowKey) y los valores (bajo las keys de columns)."
|
||
- name: rowKey
|
||
type: "string"
|
||
required: true
|
||
description: "Key en cada row donde está el label de la fila (ej. 'day', 'cohort')."
|
||
- name: columns
|
||
type: "HeatmapColumn[]"
|
||
required: true
|
||
description: "Columnas a visualizar, en orden. Cada una: { key, label? }."
|
||
- name: valueFormatter
|
||
type: "(v: number) => string"
|
||
required: false
|
||
description: "Formateador del valor numérico. Default: int o 2 decimales."
|
||
- name: rowLabelFormatter
|
||
type: "(row: Record<string, unknown>) => string"
|
||
required: false
|
||
description: "Formatear el label de fila. Default: String(row[rowKey])."
|
||
- name: tooltip
|
||
type: "(row, column, value) => string"
|
||
required: false
|
||
description: "Generador del tooltip (title HTML nativo)."
|
||
- name: cellLabelThreshold
|
||
type: "number"
|
||
required: false
|
||
description: "Mostrar el valor dentro de la celda solo si |v| ≥ threshold. Default: siempre mostrar."
|
||
- name: cellSize
|
||
type: "number"
|
||
required: false
|
||
description: "Tamaño de cada celda en px. Default 22."
|
||
- name: colLabelEvery
|
||
type: "number"
|
||
required: false
|
||
description: "Mostrar label de columna cada N columnas (grids densos). Default 1."
|
||
- name: intensityRange
|
||
type: "[number, number]"
|
||
required: false
|
||
description: "Min/max % del baseColor aplicado vía color-mix. Default [6, 84]."
|
||
- name: baseColor
|
||
type: "string"
|
||
required: false
|
||
description: "Color base. Default 'var(--mantine-primary-color-filled)'."
|
||
emits: []
|
||
has_state: false
|
||
framework: react
|
||
variant: [default]
|
||
source_repo: "claude.ai/design"
|
||
source_license: ""
|
||
source_file: "sources/frontend_designs/Ads Analytics Dashboard _standalone_.html"
|
||
---
|
||
|
||
## Ejemplo
|
||
|
||
```tsx
|
||
import { HeatmapGrid } from '@fn_library'
|
||
|
||
// CTR por día × hora (caso del export original)
|
||
const hours = Array.from({ length: 24 }, (_, i) => ({ key: 'h' + i, label: String(i).padStart(2, '0') }))
|
||
const rows = [
|
||
{ day: 'Mon', h0: 0.8, h1: 0.7, /* ... */ h23: 1.4 },
|
||
{ day: 'Tue', h0: 0.9, h1: 0.8, /* ... */ h23: 1.3 },
|
||
// ...
|
||
]
|
||
|
||
<HeatmapGrid
|
||
rows={rows}
|
||
rowKey="day"
|
||
columns={hours}
|
||
colLabelEvery={2}
|
||
valueFormatter={(v) => v.toFixed(2)}
|
||
cellLabelThreshold={1.7}
|
||
tooltip={(r, c, v) => `${r.day} ${c.label}:00 — CTR ${v}%`}
|
||
/>
|
||
|
||
// Cohort retention (semana 0-12)
|
||
const cohortCols = Array.from({ length: 13 }, (_, i) => ({ key: 'w' + i, label: 'W' + i }))
|
||
|
||
<HeatmapGrid
|
||
rows={cohorts}
|
||
rowKey="cohort"
|
||
columns={cohortCols}
|
||
valueFormatter={(v) => v.toFixed(0) + '%'}
|
||
intensityRange={[10, 90]}
|
||
/>
|
||
|
||
// Matriz de correlación
|
||
<HeatmapGrid
|
||
rows={correlationMatrix}
|
||
rowKey="variable"
|
||
columns={variables.map(v => ({ key: v, label: v }))}
|
||
valueFormatter={(v) => v.toFixed(2)}
|
||
cellSize={40}
|
||
baseColor="var(--mantine-color-cyan-6)"
|
||
/>
|
||
```
|
||
|
||
## Notas
|
||
|
||
- El color de cada celda es `color-mix(in oklab, baseColor N%, transparent)` donde N interpola linealmente entre `intensityRange[0]` y `intensityRange[1]` según el valor normalizado en `[min, max]`.
|
||
- El color del texto en la celda cambia automáticamente a blanco si `v > mid` (mid-point del rango) para contraste.
|
||
- Para grids densos (ej. 24 horas × 7 días) usar `colLabelEvery={2}` o mayor para que los headers no se solapen.
|
||
- Extraído de un export de Claude Design (Ads Analytics Dashboard). El `Heatmap` original hardcodeaba `h0..h23`; aquí se generaliza aceptando cualquier array de columnas.
|