plotagents 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -1
- package/README.md +18 -1
- package/bin/plotagents.js +3 -1
- package/dist/plotagents-geo.js +1 -1
- package/dist/plotagents.js +1857 -110
- package/docs/charts.md +86 -1
- package/docs/es/agents.md +102 -0
- package/docs/es/api.md +172 -0
- package/docs/es/charts.md +436 -0
- package/docs/es/colorscales.md +46 -0
- package/docs/es/dashboards.md +79 -0
- package/docs/es/getting-started.md +142 -0
- package/docs/es/rendering.md +47 -0
- package/docs/es/themes.md +116 -0
- package/index.d.ts +92 -8
- package/package.json +3 -2
- package/schema.json +359 -9
- package/skills/plotagents/SKILL.md +105 -0
- package/src/charts/bar.js +13 -5
- package/src/charts/chord.js +3 -1
- package/src/charts/choropleth.js +3 -1
- package/src/charts/corr.js +512 -0
- package/src/charts/dist.js +2 -1
- package/src/charts/donut.js +3 -1
- package/src/charts/kpi.js +2 -2
- package/src/charts/line.js +19 -7
- package/src/charts/network.js +13 -8
- package/src/charts/pointmap.js +9 -6
- package/src/charts/regplot.js +9 -3
- package/src/charts/sankey.js +1 -1
- package/src/charts/scatter.js +4 -2
- package/src/charts/sunburst.js +2 -2
- package/src/charts/table.js +882 -0
- package/src/charts/treemap.js +2 -2
- package/src/charts/wordcloud.js +17 -3
- package/src/colorscales.js +12 -1
- package/src/dashboard.js +21 -8
- package/src/data.js +2 -0
- package/src/facet.js +4 -3
- package/src/format.js +36 -13
- package/src/frame.js +8 -5
- package/src/geo/projection.js +4 -2
- package/src/hierarchy.js +6 -0
- package/src/i18n.js +107 -0
- package/src/index.js +17 -4
- package/src/infer.js +9 -1
- package/src/lint.js +66 -4
- package/src/runtime.js +94 -6
- package/src/scale.js +3 -2
- package/src/schema.js +54 -11
- package/src/stats.js +5 -3
- package/src/svg.js +4 -1
- package/src/text.js +5 -0
package/docs/charts.md
CHANGED
|
@@ -15,7 +15,7 @@ Every chart takes a spec with `data` (rows) plus field names for each role. The
|
|
|
15
15
|
| `highlight` | One name or a list: emphasize these, mute the rest. |
|
|
16
16
|
| `colors` | `{ "name": "#hex" }` to pin an entity's color. |
|
|
17
17
|
| `format`, `xFormat`, `yFormat` | `"number" \| "compact" \| "percent" \| "currency" \| "integer"` or `{ prefix, suffix, decimals, currency }`. |
|
|
18
|
-
| `locale` | `"es"` (default: `1.234,5`)
|
|
18
|
+
| `locale` | `"es"` (default: `1.234,5`), `"en"` (`1,234.5`), `"pt"`, `"fr"` (`1 234,5`), `"de"`, or `"auto"`: recognized from the title, subtitle, column names and categories. Tables use `"auto"` when `locale` is omitted. |
|
|
19
19
|
| `xLabel`, `yLabel` | Axis titles (horizontal, never rotated). |
|
|
20
20
|
| `xScale`, `yScale` | `"log"` where it makes sense. |
|
|
21
21
|
| `xDomain`, `yDomain` | Fixed `[min, max]`. |
|
|
@@ -134,6 +134,40 @@ plot({
|
|
|
134
134
|
| `kind` | `jointplot`: `"scatter"` or `"reg"`. |
|
|
135
135
|
| `marginal` | `jointplot`: `"hist"` or `"kde"`. |
|
|
136
136
|
|
|
137
|
+
### `corr` (`correlation`, `corrplot`) · `clustermap`
|
|
138
|
+
|
|
139
|
+
Correlation matrix of numeric fields, computed for you from the rows (pairwise complete cases, like `df.corr()`). Each pair appears once, below the diagonal, on a diverging scale fixed at −1 to 1, so the same color means the same strength in every chart. Long labels turn 45°. The tooltip gives r, n and the p-value.
|
|
140
|
+
|
|
141
|
+
```js
|
|
142
|
+
plot({ type: 'corr', data, vars: ['income', 'schooling', 'poverty', 'density'], alpha: 0.05,
|
|
143
|
+
title: 'Where schooling is higher, income is higher (r = 0.85) and poverty lower (r = −0.81)' });
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Option | Meaning |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `vars` | Fields to relate, in order. Default: every numeric field. `y: [...]` works too. |
|
|
149
|
+
| `method` | `"pearson"` (default) or `"spearman"` (ranks: monotonic relations, robust to outliers). |
|
|
150
|
+
| `triangle` | `"lower"` (default) or `"full"`. |
|
|
151
|
+
| `cluster` | Reorder by hierarchical clustering (average linkage on 1 − r) and draw the dendrogram on top. `type: "clustermap"` sets it and shows the full matrix; `dendrogram: false` keeps the order without the tree. |
|
|
152
|
+
| `alpha` | Grey out pairs with p ≥ alpha (Fisher's z) and add a legend key. |
|
|
153
|
+
| `order` | Variable order (list). |
|
|
154
|
+
| `highlight` | One variable: its row and column stay, the rest fade. |
|
|
155
|
+
| `labelsFor` | Display names, e.g. `{ areas_verdes: "Green space" }`. |
|
|
156
|
+
| `x`, `y`, `value` | Draw a matrix you already computed, in long form (one row per pair). |
|
|
157
|
+
|
|
158
|
+
### `pairplot` (`pairs`, `splom`, `scattermatrix`)
|
|
159
|
+
|
|
160
|
+
Scatter-plot matrix: each pair as a scatter below the diagonal, each variable's distribution on it (histogram, or density with `hue`), and Pearson r above, tinted by strength and split by `hue` group when there is room. Axes are shared by column and row; tick labels sit only on the outer edges.
|
|
161
|
+
|
|
162
|
+
| Option | Meaning |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `vars` | Fields to plot (3–6 read best). Default: the first 6 numeric fields. |
|
|
165
|
+
| `hue` | Color by group, with a legend. |
|
|
166
|
+
| `diag` | `"hist"` or `"kde"`. |
|
|
167
|
+
| `upper` | `"corr"` (default), `"scatter"` or `false`. `corner: true` keeps only the lower triangle. |
|
|
168
|
+
| `kind` | `"reg"` adds a least-squares line to every scatter panel. |
|
|
169
|
+
| `radius`, `bins`, `panelSize` | Point radius, histogram bins, maximum panel size. |
|
|
170
|
+
|
|
137
171
|
### `radar` (`spider`)
|
|
138
172
|
|
|
139
173
|
Long data (`axis`, `value`, `series`) or wide data (`axes: [fields]`, one row per series with `label`). `normalize` scales each axis to its own maximum (tooltips keep raw values); `grid: "polygon" | "circle"`; `domain`. Best with ≤ 4 series.
|
|
@@ -350,3 +384,54 @@ A cloud is good at "what comes up most" and bad at "by how much". `lint` suggest
|
|
|
350
384
|
### `kpi`
|
|
351
385
|
|
|
352
386
|
`items: [{ label, value, delta, previous, period, good: "up" | "down", trend: [...], target, format }]`. Delta is a fraction (`0.12` → +12%); `good: "down"` for costs. Tiles reflow into balanced rows.
|
|
387
|
+
|
|
388
|
+
## Tables
|
|
389
|
+
|
|
390
|
+
### `table` (`tabla`, `datatable`)
|
|
391
|
+
|
|
392
|
+
For when the reader needs to look up the exact number. Thin rules between rows and nothing else; numbers right-aligned in tabular figures with the same decimals down each column; empty cells as a dash. Each column gets the indicator that explains it.
|
|
393
|
+
|
|
394
|
+
```js
|
|
395
|
+
plot({
|
|
396
|
+
type: 'table',
|
|
397
|
+
title: 'Two of six projects are already over budget',
|
|
398
|
+
data: projects,
|
|
399
|
+
columns: ['project', 'area',
|
|
400
|
+
{ field: 'progress', type: 'progress' },
|
|
401
|
+
{ field: 'spent', label: 'Spent / budget', type: 'progress', target: 'budget', good: 'down' },
|
|
402
|
+
'status'],
|
|
403
|
+
sortBy: 'progress',
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
| Column `type` | Draws | Inferred when |
|
|
408
|
+
|---|---|---|
|
|
409
|
+
| `bar` | Value + data bar on a shared scale (diverging around 0) | The main numeric column (`value`/`y`, or the first number); `bars: false` turns it off |
|
|
410
|
+
| `delta` | ▲ / ▼ + signed change, green or red by `good` (`"down"` for costs) | Field named var, change, delta, growth, yoy, cambio, variación… |
|
|
411
|
+
| `heat` | Cell tinted by a sequential scale (diverging when it crosses 0); `colorScale` per column | — |
|
|
412
|
+
| `sparkline` | Mini line, last point in the accent | The field holds lists of numbers |
|
|
413
|
+
| `progress` | Percent + meter; against `target` (field or number) or as 0–1 / 0–100 | Field named progress, avance, completion…, or meta/target/goal with fractions |
|
|
414
|
+
| `badge` | Status pill | Values are status words (done, at risk, late, in progress… in es/en/pt/fr/de): good, warning, critical, info colors |
|
|
415
|
+
| `check` | ✓ or a dash, with an accessible label | Booleans, or sí/no, yes/no… |
|
|
416
|
+
| `date` | Readable date in the chart's language | ISO dates |
|
|
417
|
+
| `link` | Underlined link; only `http(s)` and `mailto` get an `href` | URLs |
|
|
418
|
+
| `rank` | Position under the current sort | `rank: true` |
|
|
419
|
+
| `text`, `number` | Text (wraps to 2–3 lines) and plain numbers | Everything else |
|
|
420
|
+
|
|
421
|
+
| Option | Meaning |
|
|
422
|
+
|---|---|
|
|
423
|
+
| `columns` | Order and type: field names or `{ field, label, type, format, align, width, good, target, colorScale, total, lines }`. Omit to use every field. `x`/`label` picks the row-name column and `y` a list of value columns. |
|
|
424
|
+
| `sortBy`, `sort` | Column and direction (`"desc"` for numbers, `"asc"` for text by default). `sort: "-sales"` works too. Empty cells always go last. |
|
|
425
|
+
| `pageSize`, `page` | Up to 15 rows are shown whole; beyond that, pages of 10. `pageSize: false` shows everything. The pager is numbers and arrows only (`11–20 / 248`, `‹ 1 2 3 … 25 ›`). |
|
|
426
|
+
| `query` | Keep rows that contain these words, ignoring accents and case. |
|
|
427
|
+
| `total` | Totals row: sums numbers, averages percents and progress, leaves changes blank. `{ sales: "mean" }` per column; `totalLabel` renames it. |
|
|
428
|
+
| `group` | Rows under a tinted band per value, with a count. |
|
|
429
|
+
| `highlight` | Rows whose name matches get a tint and an accent mark; the bars of the other rows are muted. |
|
|
430
|
+
| `top` | Keep the first N rows after sorting. |
|
|
431
|
+
| `cards` | `"auto"` (default) turns each row into a card when the columns do not fit (phones): name and main value on top, the bar under them, the other columns as label–value lines. `true` always, `false` never. |
|
|
432
|
+
| `density`, `striped` | `"compact"` / `"comfortable"` rows; zebra stripes for very wide tables. |
|
|
433
|
+
|
|
434
|
+
In the browser `render()` adds a search box above 20 rows (`search: false` hides it; `true` forces it), click-to-sort headers (natural order, reversed, then the original order), and page buttons; all of them work from the keyboard and announce `aria-sort` and `aria-current`. Resizing re-renders at the new width, so a table becomes cards on a phone and columns again on a desktop.
|
|
435
|
+
|
|
436
|
+
The language of the few words a table writes (Total, Search, No results) and the number format come from `locale`; without it, the table recognizes the language from its own title, headers and categories.
|
|
437
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# plotagents · guía para agentes de IA
|
|
2
|
+
|
|
3
|
+
Una función, un objeto JSON. Sin decisiones de diseño: la biblioteca las toma por ti.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
import { plot, safePlot } from 'plotagents';
|
|
7
|
+
const svg = plot({ type, data, x, y, series, title, subtitle, source });
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Reglas para un buen gráfico
|
|
11
|
+
|
|
12
|
+
1. **`title` es el hallazgo**, una oración completa con la cifra clave: "Biobío concentra el 30% de las ventas", no "Ventas por región".
|
|
13
|
+
2. **`subtitle` dice cómo leerlo**: medida, unidad y período.
|
|
14
|
+
3. **Define siempre `source`.** Si los datos son inventados, usa `source: "illustrative data"`.
|
|
15
|
+
4. `data` es una lista de filas (`[{ region: "Biobío", sales: 1240 }]`). Para una tabla ancha, pasa `y: ["revenue", "costs"]`.
|
|
16
|
+
5. Usa `safePlot(spec)` como tu herramienta: nunca lanza excepciones y devuelve `errors`, `warnings` y `suggestions`, cada uno con un `fix`. Si `ok` es `false`, corrige el spec y vuelve a llamarla.
|
|
17
|
+
6. Define `locale: "en"` para formatos numéricos en inglés (el valor por defecto es español: `1.234,5`); también hay `"pt"`, `"fr"`, `"de"` o `"auto"` para reconocerlo a partir del texto. Las tablas lo reconocen por sí solas.
|
|
18
|
+
|
|
19
|
+
## Qué tipo usar
|
|
20
|
+
|
|
21
|
+
| Para mostrar | `type` | Campos clave |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Comparar categorías | `bar` | `x`, `y`, `series?`, `stack?` (`true` / `"percent"`), `top?` |
|
|
24
|
+
| Contar filas por categoría | `countplot` | `x` |
|
|
25
|
+
| Media por categoría con un IC | `barplot` o `point` | `x`, `y`, `hue?` |
|
|
26
|
+
| Cambio en el tiempo | `line` | `x` fecha (`"2024-03"`) o año, `y`, `series?`; `ci: true` con varias observaciones por x |
|
|
27
|
+
| Un plan de proyecto o un cronograma | `gantt` | `task`, `start`, `end` (o `duration`), `group?`, `progress?`, `dependsOn?`, `today?`, `collapsed?` |
|
|
28
|
+
| Volumen en el tiempo | `area` | como `line`; se apila con `series` |
|
|
29
|
+
| Medidas en escalas distintas | `line` + `index: true`, o `facet` | **no hay doble eje** |
|
|
30
|
+
| Crecimiento exponencial | `line` + `yScale: "log"` | |
|
|
31
|
+
| Relación entre dos medidas | `regplot` (ajuste + IC) / `scatter` / `bubble` | `x`, `y`, `hue?`, `size?`, `label?` |
|
|
32
|
+
| Relación + marginales | `jointplot` | `x`, `y` |
|
|
33
|
+
| Qué medidas se mueven juntas | `corr` (`correlation`) | `vars?` (por defecto: todos los campos numéricos), `method?` (`"spearman"`), `alpha?: 0.05`; `cluster: true` o `type: "clustermap"` las agrupa con un dendrograma |
|
|
34
|
+
| Todos los pares de medidas a la vez | `pairplot` (`splom`) | `vars` (3–6), `hue?`, `corner?`, `kind?: "reg"` |
|
|
35
|
+
| Distribución de una medida | `hist` (`kde: true`), `kde`, `ecdf` | `x`, `hue?` |
|
|
36
|
+
| Distribución por categoría | `box`, `violin`, `strip`, `swarm` | `x` categoría, `y` medida, `hue?` |
|
|
37
|
+
| Perfil multidimensional | `radar` | `axis`, `value`, `series` (≤ 4 series) |
|
|
38
|
+
| Parte de un todo jerárquico | `treemap` o `sunburst` | `path: [level1, level2, …]`, `value` |
|
|
39
|
+
| Parte de un todo, ≤ 6 partes | `donut` / `pie` | `label`, `value`; `half: true` para un semicírculo |
|
|
40
|
+
| Magnitud en una grilla | `heatmap` | `x`, `y`, `value` |
|
|
41
|
+
| Un valor por región, estado o país | `choropleth` (`symbolmap` para totales) | `geo: "chile" \| "usa" \| "world"` o cualquier objeto GeoJSON/TopoJSON, `key`, `value` (texto → un color por categoría) |
|
|
42
|
+
| Puntos en lugares reales sobre un mapa de calles | `pointmap` | `lon`, `lat` (se detectan solos), `size?`, `hue?`, `value?`, `label?`; `tiles: "osm"` (por defecto) / `"esri-gray"` / `"esri-dark"`, o carto-* / mapbox-* con `tilesKey` |
|
|
43
|
+
| Quién se conecta con quién | `network` | aristas `from`, `to`, `value?`; `nodes?` con `group`; `layout?` |
|
|
44
|
+
| Intercambios entre pocos grupos | `chord` | `from`, `to`, `value` |
|
|
45
|
+
| Estructura por edad | `pyramid` | `age`, `sex`, `value` |
|
|
46
|
+
| Un proceso con decisiones | `flowchart` | `nodes` (`type`, `lane`), `edges` (`label`) |
|
|
47
|
+
| Flujos entre etapas | `sankey` | `from`, `to`, `value` |
|
|
48
|
+
| Una o más cifras | `kpi` | `items: [{ label, value, delta, period, trend, target, good }]` |
|
|
49
|
+
| Valores exactos para consultar | `table` | `columns?: [field \| { field, type, label, format, good, target }]`, `sortBy?`, `total?`, `group?`; los tipos `bar`, `delta`, `heat`, `sparkline`, `progress`, `badge` y `check` se infieren cuando se omiten |
|
|
50
|
+
| Lo que más aparece en un texto | `wordcloud` | `text` (campo o texto sin procesar), `value?`, `series?`; para comparar con exactitud, prefiere `bar` + `top` |
|
|
51
|
+
|
|
52
|
+
Los nombres de seaborn funcionan (`histplot`, `kdeplot`, `boxplot`, `violinplot`, `lmplot`, `stripplot`, `swarmplot`, `pointplot`), y `hue` es un alias de `series`. Omite `type` para que se infiera de los datos.
|
|
53
|
+
|
|
54
|
+
## Opciones más útiles
|
|
55
|
+
|
|
56
|
+
- `highlight: "Ñuble"`: destaca una categoría o serie y atenúa el resto. `exclude: ["Maule"]` quita entradas y recalcula el gráfico; los colores no cambian.
|
|
57
|
+
- `legend: "top" | "bottom" | "left" | "right" | false`: dónde va la leyenda (arriba por defecto).
|
|
58
|
+
- `colorScale: "viridis"`: cualquier mapa de colores de matplotlib para mapas de calor, mapas y treemaps por variación (`"RdBu"` diverge en torno a 0; `_r` lo invierte; también sirve una lista de colores). `palette: "tab10"` para categorías.
|
|
59
|
+
- `dashed` para lo que no es una cifra firme (estimaciones, proyecciones, cifras provisionales): un nombre, una lista o un campo de los datos (`dashed: "provisional"`). Las formas mantienen su color, con relleno achurado y contorno discontinuo. En un eje de tiempo, `dashedFrom: 2025` dibuja con trazo discontinuo las líneas, áreas y columnas desde ese año. **Define siempre `dashedLabel`** ("Proyección", "Preliminar") para que los lectores sepan qué significa el achurado.
|
|
60
|
+
- `facet: "region"` (+ `columns`): un panel por valor, con una escala compartida.
|
|
61
|
+
- `time: "year"`: un período a la vez (el más reciente) con la variación % respecto del anterior. Los controles de tiempo están **desactivados por defecto**: agrega `slider: true` solo cuando la persona pida recorrer los períodos (botones para ≤ 8 períodos y un deslizador mínimo en los demás casos; `"buttons"` / `"slider"` fuerzan uno de los dos, `play: false` oculta el botón de reproducir). Los treemaps se pueden colorear por variación con `colorBy: "change"`.
|
|
62
|
+
- `refLines: [{ y: 600, label: "Target" }]` y `annotations: [{ x: "2024-01", label: "New branch" }]`.
|
|
63
|
+
- `format: "percent" | "currency" | "compact" | "integer"` o `{ prefix, suffix, decimals }`.
|
|
64
|
+
- `xScale` / `yScale: "log"`.
|
|
65
|
+
- `table`: dale un título que enuncie el hallazgo, como a cualquier gráfico. Con más de 15 filas se pagina de a diez (`pageSize`), en teléfonos cada fila se muestra como una tarjeta y el navegador agrega orden, búsqueda y paginación. Usa `good: "down"` en los costos para que ▲ se vuelva rojo, `progress` con `target: "budget"` para el gasto frente al presupuesto y `total: true` para una fila de totales. Usa entre 4 y 7 columnas.
|
|
66
|
+
- `theme: "noche"` o un objeto JSON (`{ extends, categorical, type, marks, font }`); `palette: [...]` para tus propios colores.
|
|
67
|
+
- `font: "Poppins"` y `textScale: 1.5` (modo presentación); `configure({ font, textScale })` los define para todos los gráficos.
|
|
68
|
+
- `network` + `focus: "node id"`: centra un nodo y destaca sus vecinos.
|
|
69
|
+
- Tu propio mapa: `geo: <GeoJSON or TopoJSON>`; la propiedad que coincide se busca sola (`featureKey` para forzarla). Agrega `markers: [{ lon, lat, label }]`, `layers: [{ geo, label }]` para ríos o rutas, y `fitTo: ["Biobío"]` o una caja `[lonMin, latMin, lonMax, latMax]` para hacer zoom.
|
|
70
|
+
- `gantt`: las fechas `end` por día son inclusivas; una fila sin `end` es un hito. Define siempre `today` en un plan en curso. `collapsed: ["Phase 2"]` (o `true`) pliega las fases en una barra resumen; en el navegador, un clic en una fase la abre o la cierra.
|
|
71
|
+
- `network` + `layout: "force" | "circular" | "radial" | "concentric" | "clusters" | "tree" | "grid"` elige la disposición; `curveness: 0` endereza las aristas.
|
|
72
|
+
- `pointmap` dibuja sobre teselas de OpenStreetMap por defecto (`tiles: "esri-gray"`, `"mapbox-light"` + `tilesKey`, o tus propias `{ url, attribution }`). Las teselas solo se cargan cuando el SVG va incrustado en la página o en `toHTML`, no dentro de `<img>`.
|
|
73
|
+
- Tu propio estilo para todos los gráficos: `registerTheme("acme", { background, text, grid: { color, dash }, categorical: "tab10", font })` y luego `configure({ theme: "acme" })`.
|
|
74
|
+
- `geo: "usa"`: los estados coinciden por código postal ("TX"), nombre en inglés o en español, o código FIPS ("48"). Alaska y Hawái aparecen en recuadros; Puerto Rico aparece solo cuando tus datos lo incluyen. En el navegador, los mapas hacen zoom con un clic, con Ctrl/⌘ + rueda o pellizcando.
|
|
75
|
+
|
|
76
|
+
## Errores que la biblioteca ya resuelve
|
|
77
|
+
|
|
78
|
+
- Más de 8 series → de la 9.ª en adelante se pintan en gris; `lint` sugiere `highlight` o `facet`.
|
|
79
|
+
- Etiquetas de líneas que chocan → se separan con líneas guía.
|
|
80
|
+
- Dona con más de 6 partes → el resto se agrupa en "Otros".
|
|
81
|
+
- Etiquetas de categoría largas → el gráfico pasa a horizontal.
|
|
82
|
+
- Paleta propia difícil de distinguir → `lint` nombra el par problemático.
|
|
83
|
+
- Números como texto ("1.234,5", "12%", "$ 3.000") → se interpretan automáticamente.
|
|
84
|
+
- Decenas de miles de puntos → se dibujan como trazados agrupados y sigue siendo rápido.
|
|
85
|
+
|
|
86
|
+
## Tableros
|
|
87
|
+
|
|
88
|
+
Cuando alguien pida un dashboard, llama a `safeDashboard({ title, subtitle, source, data, kpis, charts, filters })` (herramienta: `toolDefinition({ kind: 'dashboard' })`). La disposición, los anchos, los colores compartidos y los filtros se deciden por ti:
|
|
89
|
+
|
|
90
|
+
- `title` es la **pregunta** que responde el tablero; cada gráfico igual lleva su hallazgo como título.
|
|
91
|
+
- Como máximo **5 KPI**, calculados a partir de `data` cuando sea posible: `{ label, field, agg: "sum", compare: { field: "year", current: 2025, previous: 2024 }, trendBy: "month" }`.
|
|
92
|
+
- **De 4 a 6 gráficos**. La primera serie de tiempo (o la que tenga `primary: true`) va a todo el ancho; el resto llena filas equilibradas.
|
|
93
|
+
- `filters: ["region", "channel"]` se convierten en botones que filtran todos los gráficos y KPI.
|
|
94
|
+
- No más de una dona; una sola `source` para la página.
|
|
95
|
+
|
|
96
|
+
## Salidas
|
|
97
|
+
|
|
98
|
+
- `plot(spec)` → cadena SVG. Insértala en HTML, Markdown, un archivo `.svg` o un PDF.
|
|
99
|
+
- `toHTML([spec1, spec2])` → página autocontenida con tooltips, deslizadores y drill-down.
|
|
100
|
+
- `describe(spec)` → texto alternativo del gráfico.
|
|
101
|
+
- `schema` / `toolDefinition()` → JSON Schema y definición de herramienta (Anthropic u OpenAI).
|
|
102
|
+
- CLI: `npx plotagents spec.json -o chart.svg`.
|
package/docs/es/api.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Referencia de la API
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
import {
|
|
5
|
+
plot, safePlot, lint, describe, render, toHTML, configure,
|
|
6
|
+
dashboard, safeDashboard, renderDashboard, lintDashboard, planDashboard,
|
|
7
|
+
schema, dashboardSchema, toolDefinition, validatePalette, registerGeo, countWords,
|
|
8
|
+
} from 'plotagents';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Los tipos completos están en [`index.d.ts`](../index.d.ts) y cada opción del spec, en [`schema.json`](../schema.json).
|
|
12
|
+
|
|
13
|
+
## Dibujo
|
|
14
|
+
|
|
15
|
+
### `plot(spec)`
|
|
16
|
+
|
|
17
|
+
Dibuja un gráfico y devuelve una cadena SVG. Funciona en Node, Deno, Bun y el navegador. Lanza un `PlotError` cuando el spec no se puede dibujar; el `hint` del error dice cómo corregirlo.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
const svg = plot({ type: 'bar', data, x: 'region', y: 'sales', title: 'Biobío leads with 30%' });
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `safePlot(spec)`
|
|
24
|
+
|
|
25
|
+
La versión que debes exponer como herramienta de un agente: nunca lanza excepciones.
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
const { ok, svg, type, description, errors, warnings, suggestions } = safePlot(spec);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Campo | Significado |
|
|
32
|
+
|---|---|
|
|
33
|
+
| `ok` | `true` cuando el gráfico se dibujó. |
|
|
34
|
+
| `svg` | La cadena SVG, o `null`. |
|
|
35
|
+
| `type` | El tipo de gráfico resuelto (útil cuando `type` se infirió). |
|
|
36
|
+
| `description` | Texto alternativo del gráfico. |
|
|
37
|
+
| `errors` | Problemas que impiden dibujar el gráfico: `{ code, message, fix }`. |
|
|
38
|
+
| `warnings` | Problemas que vuelven el gráfico engañoso o difícil de leer. |
|
|
39
|
+
| `suggestions` | Mejoras de diseño, como un mejor título o `highlight`. |
|
|
40
|
+
|
|
41
|
+
### `lint(spec)`
|
|
42
|
+
|
|
43
|
+
Revisa un spec sin dibujarlo y devuelve `{ ok, type, errors, warnings, suggestions }`. Los mensajes siguen el `locale` del spec (español por defecto, inglés con `locale: "en"`); cada uno trae un `fix` con el cambio que hay que hacer.
|
|
44
|
+
|
|
45
|
+
### `dashboard(spec)` · `safeDashboard(spec)` · `renderDashboard(el, spec)`
|
|
46
|
+
|
|
47
|
+
Un dashboard HTML autocontenido con una disposición según buenas prácticas, colores compartidos, KPI y filtros. `safeDashboard` nunca lanza excepciones y devuelve `{ ok, html, plan, errors, warnings, suggestions }`; `renderDashboard` dibuja dentro de un elemento en el navegador; `lintDashboard` revisa; `planDashboard` devuelve las decisiones de disposición. Consulta [Tableros](dashboards.md).
|
|
48
|
+
|
|
49
|
+
### `describe(spec)`
|
|
50
|
+
|
|
51
|
+
Devuelve una descripción en texto del gráfico, como "Mayor: Biobío con 1.240 (30%)…". El mismo texto va en el `<desc>` del SVG para los lectores de pantalla.
|
|
52
|
+
|
|
53
|
+
## En el navegador
|
|
54
|
+
|
|
55
|
+
### `render(target, spec, opts?)`
|
|
56
|
+
|
|
57
|
+
Dibuja dentro de un elemento (un selector CSS o un nodo del DOM) con tooltips, ancho adaptable, controles de tiempo cuando el spec los pide (`slider: true`), drill-down en treemaps y sunbursts, clic para enfocar en redes, fases plegables en Gantt y clics en la leyenda (shift + clic excluye una entrada; en treemaps y sunbursts, un clic hace zoom en la categoría).
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
const chart = plotagents.render('#chart', spec);
|
|
61
|
+
chart.update({ ...spec, highlight: 'Ñuble' }); // redraw
|
|
62
|
+
chart.destroy(); // remove listeners and markup
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
| Opción | Significado |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `controls` | `false` oculta los controles de tiempo aunque el spec los pida (`slider: true`). |
|
|
68
|
+
|
|
69
|
+
El controlador expone `svg` (el elemento `<svg>` actual) y `spec`.
|
|
70
|
+
|
|
71
|
+
### `attach(root)`
|
|
72
|
+
|
|
73
|
+
Agrega tooltips a un contenedor que ya tiene un SVG de plotagents, por ejemplo uno generado en el servidor.
|
|
74
|
+
|
|
75
|
+
### `toHTML(specs, opts?)`
|
|
76
|
+
|
|
77
|
+
Una página HTML autocontenida con uno o más gráficos interactivos y la biblioteca incluida.
|
|
78
|
+
|
|
79
|
+
| Opción | Por defecto | Significado |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `title` | `"Gráficos"` | Título de la página. |
|
|
82
|
+
| `lang` | `"es"` | Idioma de la página. |
|
|
83
|
+
| `columns` | `1` | Con dos o más, los gráficos se ordenan en una grilla. |
|
|
84
|
+
|
|
85
|
+
## Configuración
|
|
86
|
+
|
|
87
|
+
### `configure(options)`
|
|
88
|
+
|
|
89
|
+
Define valores por defecto para todos los gráficos siguientes; el spec siempre tiene prioridad.
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
configure({ font: 'Poppins', textScale: 1.5, locale: 'en' });
|
|
93
|
+
configure(); // returns the current defaults
|
|
94
|
+
configure(null); // clears them
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Acepta cualquier opción del spec: `font`, `textScale`, `locale`, `theme`, `palette`, `ramp`, `colorScale`, `legend`, etc. Si un spec trae su propio objeto `theme`, este se combina sobre el global.
|
|
98
|
+
|
|
99
|
+
### `registerTheme(name, theme)`
|
|
100
|
+
|
|
101
|
+
Registra un tema con nombre (combinado sobre `extends`, `papel` por defecto) para que `theme: name` y `configure({ theme: name })` puedan usarlo. Consulta [Temas](themes.md#your-own-theme-everywhere).
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
registerTheme('acme', { background: '#FFF', text: '#111', categorical: 'tab10', grid: { dash: '2 3' } });
|
|
105
|
+
configure({ theme: 'acme' });
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `colorScaleNames()` · `resolveColorScale(name)`
|
|
109
|
+
|
|
110
|
+
Todos los nombres de escalas de color agrupados por tipo (`sequential`, `diverging`, `cyclic`, `qualitative`), y las paradas de una escala: `{ name, stops, kind }`. `interpolateColor(stops, t)` devuelve el color en `t ∈ [0, 1]` (OKLab).
|
|
111
|
+
|
|
112
|
+
### `validatePalette(colors, opts?)`
|
|
113
|
+
|
|
114
|
+
Revisa una paleta propia con las mismas pruebas que pasa la paleta incluida. Consulta [temas](themes.md#validating-a-palette).
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
validatePalette(['#223C6A', '#E69B0A', '#D21428'], { mode: 'light', surface: '#FFFFFF' });
|
|
118
|
+
// → { ok: false, checks: [{ name: 'lightness', status: 'fail', detail: '…' }, …] }
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `registerGeo(name, featureCollection, aliases?)`
|
|
122
|
+
|
|
123
|
+
Registra tu propio GeoJSON para que los specs puedan usar `geo: name`. Chile y el mundo vienen incluidos.
|
|
124
|
+
|
|
125
|
+
## Para agentes
|
|
126
|
+
|
|
127
|
+
### `toolDefinition({ name?, flavor? })`
|
|
128
|
+
|
|
129
|
+
Devuelve una definición de herramienta construida a partir del JSON Schema: `flavor: "anthropic"` (por defecto) entrega `{ name, description, input_schema }` y `flavor: "openai"` entrega `{ type: "function", function: { … } }`.
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
133
|
+
import { safePlot, toolDefinition } from 'plotagents';
|
|
134
|
+
|
|
135
|
+
const client = new Anthropic();
|
|
136
|
+
const res = await client.messages.create({
|
|
137
|
+
model: process.env.ANTHROPIC_MODEL,
|
|
138
|
+
max_tokens: 4096,
|
|
139
|
+
tools: [toolDefinition()],
|
|
140
|
+
messages: [{ role: 'user', content: 'Plot the distribution of service times per clinic: …' }],
|
|
141
|
+
});
|
|
142
|
+
const call = res.content.find((b) => b.type === 'tool_use');
|
|
143
|
+
const { ok, svg, errors } = safePlot(call.input);
|
|
144
|
+
// If !ok, send `errors` back as the tool_result: every error carries a `fix`.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### `schema`
|
|
148
|
+
|
|
149
|
+
El JSON Schema de un spec, publicado también como [`schema.json`](../schema.json) e importable como `plotagents/schema.json`.
|
|
150
|
+
|
|
151
|
+
## Utilidades
|
|
152
|
+
|
|
153
|
+
| Exportación | Significado |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `TYPES` | Todos los nombres de tipos de gráfico. |
|
|
156
|
+
| `themes`, `getTheme(t)`, `themeFor(spec)` | Los temas incluidos y el tema resuelto de un spec. |
|
|
157
|
+
| `palettes`, `ramps` | Paletas categóricas con nombre y rampas secuenciales y divergentes. |
|
|
158
|
+
| `timeValues(spec)` | Valores ordenados del campo `time`. |
|
|
159
|
+
| `makeFormat(fmt, locale, values)` | El formateador de números que usaría un gráfico. |
|
|
160
|
+
| `formatNumber(v, decimals, locale)`, `formatCompact(v, locale)` | Formato de números según el idioma. |
|
|
161
|
+
| `squarify(items, x, y, w, h)` | El algoritmo de disposición del treemap. |
|
|
162
|
+
| `bundleSource()` | Solo en Node: la versión para navegador como cadena, para incrustarla. |
|
|
163
|
+
|
|
164
|
+
## Puntos de entrada del paquete
|
|
165
|
+
|
|
166
|
+
| Importación | Contenido |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `plotagents` | Todo lo anterior (módulo ES). |
|
|
169
|
+
| `plotagents/schema.json` | El JSON Schema. |
|
|
170
|
+
| `plotagents/browser` | `dist/plotagents.js`: un `<script>` que define `window.plotagents`. |
|
|
171
|
+
| `plotagents/browser/geo` | `dist/plotagents-geo.js`: geometrías de Chile y del mundo para la versión de navegador. |
|
|
172
|
+
| `plotagents/geo/chile`, `plotagents/geo/world` | Las geometrías como módulos ES. |
|