@ggts-sh/skill 0.43.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/LICENSE +21 -0
- package/README.md +80 -0
- package/SKILL.md +196 -0
- package/package.json +39 -0
- package/references/composition-surfaces.md +199 -0
- package/references/geoms-and-stats.md +276 -0
- package/references/grammar.md +111 -0
- package/references/interactions.md +312 -0
- package/references/react.md +101 -0
- package/references/recipes.md +441 -0
- package/references/registration.md +72 -0
- package/references/scales-and-palettes.md +396 -0
- package/references/svelte.md +79 -0
- package/references/themes.md +96 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
<!-- Recipes adapted from examples/<category>/<name>/ where noted; hand-authored recipes are validated by scripts/skill-content/fences.test.ts (normalize + validate on every json complete fence). -->
|
|
2
|
+
|
|
3
|
+
# Long-tail recipes
|
|
4
|
+
|
|
5
|
+
Each recipe pairs a validated JSON `PortableSpec` with its Svelte-children twin.
|
|
6
|
+
Inline data is cut to a few rows — swap in yours. Plot-level `aes` inherits into
|
|
7
|
+
every layer; a layer `aes` merges over it, and `null` unsets a channel.
|
|
8
|
+
|
|
9
|
+
## Error bars from raw values (stat summary)
|
|
10
|
+
|
|
11
|
+
Raw observations per group; the summary stat computes mean ± se, no preaggregation.
|
|
12
|
+
<!-- adapted from examples/errorbar/mean-se/ -->
|
|
13
|
+
|
|
14
|
+
```json complete
|
|
15
|
+
{
|
|
16
|
+
"data": {
|
|
17
|
+
"values": [
|
|
18
|
+
{ "drug": "A", "sleep": 0.7 },
|
|
19
|
+
{ "drug": "A", "sleep": 1.6 },
|
|
20
|
+
{ "drug": "A", "sleep": 0.2 },
|
|
21
|
+
{ "drug": "B", "sleep": 1.9 },
|
|
22
|
+
{ "drug": "B", "sleep": 3.4 },
|
|
23
|
+
{ "drug": "B", "sleep": 2.5 }
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"aes": { "x": { "field": "drug" }, "y": { "field": "sleep" } },
|
|
27
|
+
"layers": [
|
|
28
|
+
{
|
|
29
|
+
"geom": "point",
|
|
30
|
+
"position": "jitter",
|
|
31
|
+
"positionParams": { "width": 0.1, "height": 0, "seed": 7 },
|
|
32
|
+
"params": { "alpha": 0.5 }
|
|
33
|
+
},
|
|
34
|
+
{ "geom": "errorbar", "stat": "summary", "params": { "width": 0.3 } }
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```svelte fragment
|
|
40
|
+
<GGPlot data={rows} aes={{ x: "drug", y: "sleep" }}>
|
|
41
|
+
<GeomPoint
|
|
42
|
+
position="jitter"
|
|
43
|
+
positionParams={{ width: 0.1, height: 0, seed: 7 }}
|
|
44
|
+
alpha={0.5}
|
|
45
|
+
/>
|
|
46
|
+
<GeomErrorbar stat="summary" width={0.3} />
|
|
47
|
+
</GGPlot>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `stat="summary"` override needs one call at app startup:
|
|
51
|
+
`import { registerSummary } from "@ggts-sh/svelte"; registerSummary();`
|
|
52
|
+
(or `registerAll()`; the JSON spec twin needs `registerAll()` regardless).
|
|
53
|
+
|
|
54
|
+
## Value labels on columns
|
|
55
|
+
|
|
56
|
+
`dy`/`dx` are PIXEL offsets (negative dy = up); `position: "nudge"` + `positionParams` offsets in DATA units instead.
|
|
57
|
+
<!-- adapted from examples/text/labels/ -->
|
|
58
|
+
|
|
59
|
+
```json complete
|
|
60
|
+
{
|
|
61
|
+
"data": {
|
|
62
|
+
"values": [
|
|
63
|
+
{ "cat": "a", "n": 4 },
|
|
64
|
+
{ "cat": "b", "n": 7 },
|
|
65
|
+
{ "cat": "c", "n": 5 }
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"aes": { "x": { "field": "cat" }, "y": { "field": "n" } },
|
|
69
|
+
"layers": [
|
|
70
|
+
{ "geom": "col" },
|
|
71
|
+
{
|
|
72
|
+
"geom": "text",
|
|
73
|
+
"aes": { "label": { "field": "n" } },
|
|
74
|
+
"params": { "dy": -8 }
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```svelte fragment
|
|
81
|
+
<GGPlot data={rows} aes={{ x: "cat", y: "n" }}>
|
|
82
|
+
<GeomCol />
|
|
83
|
+
<GeomText aes={{ label: "n" }} dy={-8} />
|
|
84
|
+
</GGPlot>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Big scatter on canvas
|
|
88
|
+
|
|
89
|
+
`"render": "canvas"` forces the canvas path; layers over `CANVAS_AUTO_THRESHOLD` (2000) marks switch on their own. Plot-level `"a11y": "force-svg"` overrides for assistive tech.
|
|
90
|
+
|
|
91
|
+
```json complete
|
|
92
|
+
{
|
|
93
|
+
"data": {
|
|
94
|
+
"values": [
|
|
95
|
+
{ "x": 1, "y": 2 },
|
|
96
|
+
{ "x": 2, "y": 3 },
|
|
97
|
+
{ "x": 3, "y": 2.5 },
|
|
98
|
+
{ "x": 4, "y": 4 }
|
|
99
|
+
]
|
|
100
|
+
},
|
|
101
|
+
"layers": [
|
|
102
|
+
{
|
|
103
|
+
"geom": "point",
|
|
104
|
+
"render": "canvas",
|
|
105
|
+
"aes": { "x": { "field": "x" }, "y": { "field": "y" } },
|
|
106
|
+
"params": { "size": 1.2, "alpha": 0.4 }
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
"a11y": "force-svg"
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```svelte fragment
|
|
114
|
+
<GGPlot data={rows} aes={{ x: "x", y: "y" }} a11y="force-svg">
|
|
115
|
+
<GeomPoint render="canvas" size={1.2} alpha={0.4} />
|
|
116
|
+
</GGPlot>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Log10 axis scatter
|
|
120
|
+
|
|
121
|
+
Positive data only; the transform runs before stats. Authored `"type": "log"` canonicalizes to this form.
|
|
122
|
+
<!-- adapted from examples/point/log-scale/ -->
|
|
123
|
+
|
|
124
|
+
```json complete
|
|
125
|
+
{
|
|
126
|
+
"data": {
|
|
127
|
+
"values": [
|
|
128
|
+
{ "density": 10, "rate": 3 },
|
|
129
|
+
{ "density": 100, "rate": 9 },
|
|
130
|
+
{ "density": 1000, "rate": 30 },
|
|
131
|
+
{ "density": 5000, "rate": 55 }
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
"layers": [
|
|
135
|
+
{
|
|
136
|
+
"geom": "point",
|
|
137
|
+
"aes": { "x": { "field": "density" }, "y": { "field": "rate" } }
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
"scales": { "x": { "type": "linear", "transform": "log10" } }
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```svelte fragment
|
|
145
|
+
<GGPlot data={rows} aes={{ x: "density", y: "rate" }}>
|
|
146
|
+
<GeomPoint />
|
|
147
|
+
<ScaleXLog10 />
|
|
148
|
+
</GGPlot>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Violin with jittered points
|
|
152
|
+
|
|
153
|
+
Distribution shape per group; needs several y values per group for the density. Seeded jitter is deterministic.
|
|
154
|
+
<!-- adapted from examples/boxplot/violin/ -->
|
|
155
|
+
|
|
156
|
+
```json complete
|
|
157
|
+
{
|
|
158
|
+
"data": {
|
|
159
|
+
"values": [
|
|
160
|
+
{ "run": "a", "v": 1 },
|
|
161
|
+
{ "run": "a", "v": 2 },
|
|
162
|
+
{ "run": "a", "v": 2.4 },
|
|
163
|
+
{ "run": "a", "v": 3.1 },
|
|
164
|
+
{ "run": "a", "v": 1.7 },
|
|
165
|
+
{ "run": "b", "v": 4 },
|
|
166
|
+
{ "run": "b", "v": 5.2 },
|
|
167
|
+
{ "run": "b", "v": 4.4 },
|
|
168
|
+
{ "run": "b", "v": 6 },
|
|
169
|
+
{ "run": "b", "v": 5.1 }
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
"aes": { "x": { "field": "run" }, "y": { "field": "v" } },
|
|
173
|
+
"layers": [
|
|
174
|
+
{ "geom": "violin", "params": { "trim": true, "alpha": 0.7 } },
|
|
175
|
+
{
|
|
176
|
+
"geom": "point",
|
|
177
|
+
"position": "jitter",
|
|
178
|
+
"positionParams": { "width": 0.08, "height": 0, "seed": 3 },
|
|
179
|
+
"params": { "size": 2 }
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
```svelte fragment
|
|
186
|
+
<GGPlot data={rows} aes={{ x: "run", y: "v" }}>
|
|
187
|
+
<GeomViolin trim alpha={0.7} />
|
|
188
|
+
<GeomPoint
|
|
189
|
+
position="jitter"
|
|
190
|
+
positionParams={{ width: 0.08, height: 0, seed: 3 }}
|
|
191
|
+
size={2}
|
|
192
|
+
/>
|
|
193
|
+
</GGPlot>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Tile heatmap (discrete x/y, continuous fill)
|
|
197
|
+
|
|
198
|
+
One tile per (x, y) pair; a sequential fill scale carries the value.
|
|
199
|
+
<!-- adapted from examples/tile/heatmap/ -->
|
|
200
|
+
|
|
201
|
+
```json complete
|
|
202
|
+
{
|
|
203
|
+
"data": {
|
|
204
|
+
"values": [
|
|
205
|
+
{ "day": "Mon", "hour": "am", "n": 3 },
|
|
206
|
+
{ "day": "Mon", "hour": "pm", "n": 8 },
|
|
207
|
+
{ "day": "Tue", "hour": "am", "n": 5 },
|
|
208
|
+
{ "day": "Tue", "hour": "pm", "n": 12 }
|
|
209
|
+
]
|
|
210
|
+
},
|
|
211
|
+
"layers": [
|
|
212
|
+
{
|
|
213
|
+
"geom": "tile",
|
|
214
|
+
"aes": {
|
|
215
|
+
"x": { "field": "day" },
|
|
216
|
+
"y": { "field": "hour" },
|
|
217
|
+
"fill": { "field": "n" }
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"scales": { "fill": { "type": "sequential", "scheme": "viridis" } }
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```svelte fragment
|
|
226
|
+
<GGPlot data={rows} aes={{ x: "day", y: "hour", fill: "n" }}>
|
|
227
|
+
<GeomTile />
|
|
228
|
+
<ScaleFillContinuous scheme="viridis" />
|
|
229
|
+
</GGPlot>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Hex density heatmap
|
|
233
|
+
|
|
234
|
+
Overplotted x/y pairs binned into hexagons; fill defaults to the stat's `count`. `bin_2d` is the rectangular twin.
|
|
235
|
+
<!-- adapted from examples/hex/basic/ -->
|
|
236
|
+
|
|
237
|
+
```json complete
|
|
238
|
+
{
|
|
239
|
+
"data": {
|
|
240
|
+
"values": [
|
|
241
|
+
{ "x": 1, "y": 1 },
|
|
242
|
+
{ "x": 1.1, "y": 1.2 },
|
|
243
|
+
{ "x": 0.9, "y": 0.8 },
|
|
244
|
+
{ "x": 3, "y": 3 },
|
|
245
|
+
{ "x": 3.2, "y": 2.9 },
|
|
246
|
+
{ "x": 2.8, "y": 3.1 }
|
|
247
|
+
]
|
|
248
|
+
},
|
|
249
|
+
"layers": [
|
|
250
|
+
{
|
|
251
|
+
"geom": "hex",
|
|
252
|
+
"aes": { "x": { "field": "x" }, "y": { "field": "y" } },
|
|
253
|
+
"params": { "bins": 6 }
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```svelte fragment
|
|
260
|
+
<GGPlot data={rows} aes={{ x: "x", y: "y" }}>
|
|
261
|
+
<GeomHex bins={6} />
|
|
262
|
+
</GGPlot>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Step chart (ECDF)
|
|
266
|
+
|
|
267
|
+
Stairs through precomputed points; `direction: "hv"` is the ECDF convention. `step` takes stat `identity` only, so compute F̂(x) = i/n yourself.
|
|
268
|
+
<!-- adapted from examples/step/ecdf/ -->
|
|
269
|
+
|
|
270
|
+
```json complete
|
|
271
|
+
{
|
|
272
|
+
"data": {
|
|
273
|
+
"values": [
|
|
274
|
+
{ "x": 1.2, "y": 0.25 },
|
|
275
|
+
{ "x": 2, "y": 0.5 },
|
|
276
|
+
{ "x": 3.1, "y": 0.75 },
|
|
277
|
+
{ "x": 4.5, "y": 1 }
|
|
278
|
+
]
|
|
279
|
+
},
|
|
280
|
+
"layers": [
|
|
281
|
+
{
|
|
282
|
+
"geom": "step",
|
|
283
|
+
"aes": { "x": { "field": "x" }, "y": { "field": "y" } },
|
|
284
|
+
"params": { "direction": "hv" }
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
```svelte fragment
|
|
291
|
+
<GGPlot data={rows} aes={{ x: "x", y: "y" }}>
|
|
292
|
+
<GeomStep direction="hv" />
|
|
293
|
+
</GGPlot>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Ribbon band with a center line
|
|
297
|
+
|
|
298
|
+
Map ymin/ymax at plot level for the band; the line layer adds its own y.
|
|
299
|
+
<!-- adapted from examples/ribbon/bounds/ -->
|
|
300
|
+
|
|
301
|
+
```json complete
|
|
302
|
+
{
|
|
303
|
+
"data": {
|
|
304
|
+
"values": [
|
|
305
|
+
{ "t": 1, "lo": 2, "hi": 5, "mid": 3.4 },
|
|
306
|
+
{ "t": 2, "lo": 3, "hi": 6, "mid": 4.5 },
|
|
307
|
+
{ "t": 3, "lo": 2.5, "hi": 7, "mid": 4.8 },
|
|
308
|
+
{ "t": 4, "lo": 4, "hi": 8, "mid": 6 }
|
|
309
|
+
]
|
|
310
|
+
},
|
|
311
|
+
"aes": {
|
|
312
|
+
"x": { "field": "t" },
|
|
313
|
+
"ymin": { "field": "lo" },
|
|
314
|
+
"ymax": { "field": "hi" }
|
|
315
|
+
},
|
|
316
|
+
"layers": [
|
|
317
|
+
{ "geom": "ribbon", "params": { "alpha": 0.35 } },
|
|
318
|
+
{
|
|
319
|
+
"geom": "line",
|
|
320
|
+
"aes": { "y": { "field": "mid" } },
|
|
321
|
+
"params": { "linewidth": 1.5 }
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
```svelte fragment
|
|
328
|
+
<GGPlot data={rows} aes={{ x: "t", ymin: "lo", ymax: "hi" }}>
|
|
329
|
+
<GeomRibbon alpha={0.35} />
|
|
330
|
+
<GeomLine aes={{ y: "mid" }} linewidth={1.5} />
|
|
331
|
+
</GGPlot>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Horizontal boxplot (coord flip)
|
|
335
|
+
|
|
336
|
+
Map the category to x and the value to y as usual, then flip — long labels get room.
|
|
337
|
+
<!-- hand-authored; validated by skill-content test -->
|
|
338
|
+
|
|
339
|
+
```json complete
|
|
340
|
+
{
|
|
341
|
+
"data": {
|
|
342
|
+
"values": [
|
|
343
|
+
{ "g": "a", "v": 1 },
|
|
344
|
+
{ "g": "a", "v": 2 },
|
|
345
|
+
{ "g": "a", "v": 3 },
|
|
346
|
+
{ "g": "a", "v": 2.2 },
|
|
347
|
+
{ "g": "b", "v": 4 },
|
|
348
|
+
{ "g": "b", "v": 5 },
|
|
349
|
+
{ "g": "b", "v": 6 },
|
|
350
|
+
{ "g": "b", "v": 4.8 }
|
|
351
|
+
]
|
|
352
|
+
},
|
|
353
|
+
"layers": [
|
|
354
|
+
{
|
|
355
|
+
"geom": "boxplot",
|
|
356
|
+
"aes": { "x": { "field": "g" }, "y": { "field": "v" } }
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
"coord": { "type": "flip" }
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
```svelte fragment
|
|
364
|
+
<GGPlot data={rows} aes={{ x: "g", y: "v" }}>
|
|
365
|
+
<GeomBoxplot />
|
|
366
|
+
<CoordFlip />
|
|
367
|
+
</GGPlot>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Smooth trend with per-layer aes override
|
|
371
|
+
|
|
372
|
+
Both layers inherit x/y; only the point layer maps size. A layer channel set to `null` would drop an inherited one instead.
|
|
373
|
+
<!-- adapted from examples/smooth/loess-scatter/ -->
|
|
374
|
+
|
|
375
|
+
```json complete
|
|
376
|
+
{
|
|
377
|
+
"data": {
|
|
378
|
+
"values": [
|
|
379
|
+
{ "year": 1, "angle": 10, "w": 1 },
|
|
380
|
+
{ "year": 2, "angle": 14, "w": 3 },
|
|
381
|
+
{ "year": 3, "angle": 13, "w": 2 },
|
|
382
|
+
{ "year": 4, "angle": 18, "w": 4 },
|
|
383
|
+
{ "year": 5, "angle": 21, "w": 2 },
|
|
384
|
+
{ "year": 6, "angle": 20, "w": 5 }
|
|
385
|
+
]
|
|
386
|
+
},
|
|
387
|
+
"aes": { "x": { "field": "year" }, "y": { "field": "angle" } },
|
|
388
|
+
"layers": [
|
|
389
|
+
{ "geom": "smooth", "params": { "method": "loess", "span": 0.9 } },
|
|
390
|
+
{
|
|
391
|
+
"geom": "point",
|
|
392
|
+
"aes": { "size": { "field": "w" } },
|
|
393
|
+
"params": { "alpha": 0.85 }
|
|
394
|
+
}
|
|
395
|
+
]
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
```svelte fragment
|
|
400
|
+
<GGPlot data={rows} aes={{ x: "year", y: "angle" }}>
|
|
401
|
+
<GeomSmooth method="loess" span={0.9} />
|
|
402
|
+
<GeomPoint aes={{ size: "w" }} alpha={0.85} />
|
|
403
|
+
</GGPlot>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Map polygons (geom sf)
|
|
407
|
+
|
|
408
|
+
Rows carry a `geometry` column of GeoJSON Geometry JSON strings, already projected; map no x/y — fill carries the value.
|
|
409
|
+
<!-- adapted from examples/sf/basic/ -->
|
|
410
|
+
|
|
411
|
+
```json complete
|
|
412
|
+
{
|
|
413
|
+
"data": {
|
|
414
|
+
"values": [
|
|
415
|
+
{
|
|
416
|
+
"region": "A",
|
|
417
|
+
"rate": 12,
|
|
418
|
+
"geometry": "{\"type\":\"Polygon\",\"coordinates\":[[[0,0],[2,0],[1,2],[0,0]]]}"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"region": "B",
|
|
422
|
+
"rate": 28,
|
|
423
|
+
"geometry": "{\"type\":\"Polygon\",\"coordinates\":[[[2.2,0],[4.2,0],[3.2,2],[2.2,0]]]}"
|
|
424
|
+
}
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
"layers": [
|
|
428
|
+
{
|
|
429
|
+
"geom": "sf",
|
|
430
|
+
"aes": { "fill": { "field": "rate" } },
|
|
431
|
+
"params": { "linewidth": 0.8 }
|
|
432
|
+
}
|
|
433
|
+
]
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
```svelte fragment
|
|
438
|
+
<GGPlot data={regions} aes={{ fill: "rate" }}>
|
|
439
|
+
<GeomSf linewidth={0.8} />
|
|
440
|
+
</GGPlot>
|
|
441
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Registration reference
|
|
2
|
+
|
|
3
|
+
## Registration (call these)
|
|
4
|
+
|
|
5
|
+
The `@ggts-sh/core` barrel is side-effect-free. A missing opt-in throws
|
|
6
|
+
`not registered in this build` and names the fix. **Default for agents:**
|
|
7
|
+
call `registerAll()` once at startup for every spec-driven, `layers`,
|
|
8
|
+
`<GGPlot spec>`, `runPipeline`, or `renderToSVGString` path. Do not invent
|
|
9
|
+
a lean register list unless the user asked for a small bundle.
|
|
10
|
+
|
|
11
|
+
`ggts render` already registers the full grammar. Svelte **children**
|
|
12
|
+
self-register only the piece they are.
|
|
13
|
+
|
|
14
|
+
| Surface | What is already registered | What you must still call |
|
|
15
|
+
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
16
|
+
| `<Geom*>` child | that geom + its **default** stat | `register<Family>()` for a `stat="…"` override (from `@ggts-sh/svelte`) — e.g. `<GeomErrorbar stat="summary" />` → `registerSummary()` |
|
|
17
|
+
| `<ScaleXDate>` / `<ScaleYDatetime>` / other Temporal scale children | `installTemporal()` | nothing |
|
|
18
|
+
| `<GGPlot>` construction | `registerBasic()` + `installCandidates()` (identity geoms/stats, every color/style kind, band-axis planner, host hit-testing) | `registerAll()` for specialty geoms/stats; `installTemporal()` for spec/`layers` temporal charts that have no Temporal child |
|
|
19
|
+
| `@ggts-sh/core/render` import | same basic tier as `registerBasic()` | specialty families + Temporal |
|
|
20
|
+
| `@ggts-sh/core/temporal` import | Temporal polyfill + guides | the rest of the grammar |
|
|
21
|
+
| CLI `ggts render` | full grammar | nothing |
|
|
22
|
+
|
|
23
|
+
**Spec-driven Temporal:** ISO strings with no explicit temporal options keep
|
|
24
|
+
the lean UTC path. Charts driven through `spec` or `layers` have no Temporal
|
|
25
|
+
child. Call `installTemporal()` (from `@ggts-sh/svelte` or `@ggts-sh/core`)
|
|
26
|
+
or `registerAll()` when those charts set `type: "time"`, a named parser,
|
|
27
|
+
timezone, date interval, or full Temporal guide planning.
|
|
28
|
+
|
|
29
|
+
**Lean headless** (`@ggts-sh/core/headless` + `@ggts-sh/core/headless/register`)
|
|
30
|
+
is opt-in per family. One forgotten call fails at render:
|
|
31
|
+
|
|
32
|
+
- Basic geoms: `registerBasicPoints()`, `registerBasicLines()`,
|
|
33
|
+
`registerBasicAreas()`, `registerBasicBars()`, `registerBasicRects()`,
|
|
34
|
+
`registerBasicGlyphs()`, `registerBasicSegments()`.
|
|
35
|
+
- Specialty geoms/stats (same names from `@ggts-sh/core` /
|
|
36
|
+
`@ggts-sh/svelte`): `registerAbline()`, `registerAlign()`, `registerBin()`,
|
|
37
|
+
`registerBin2d()`, `registerBoxplot()`, `registerConnect()`,
|
|
38
|
+
`registerContour()`, `registerCrossbar()`, `registerCurve()`,
|
|
39
|
+
`registerDensity()`, `registerDensity2d()`, `registerDensity2dFilled()`,
|
|
40
|
+
`registerDotplot()`, `registerEcdf()`, `registerEllipse()`,
|
|
41
|
+
`registerErrorbar()`, `registerFunction()`, `registerHex()`,
|
|
42
|
+
`registerLinerange()`, `registerManual()`, `registerMap()`,
|
|
43
|
+
`registerPointrange()`, `registerPolygon()`, `registerQq()`,
|
|
44
|
+
`registerQqLine()`, `registerQuantile()`, `registerRaster()`,
|
|
45
|
+
`registerRug()`, `registerSf()`, `registerSfLabel()`, `registerSfText()`,
|
|
46
|
+
`registerSmooth()`, `registerSpoke()`, `registerSummary()`,
|
|
47
|
+
`registerSummaryBin()`, `registerSummaryRolling()`, `registerTile()`,
|
|
48
|
+
`registerUnique()`, `registerViolin()`.
|
|
49
|
+
- Color: `registerDefaultOrdinalColor()` for the built-in palette or an
|
|
50
|
+
explicit `range`. A named **categorical** scheme (`observable10`,
|
|
51
|
+
`colorblind`, `Dark2`, …) needs `registerOrdinalColor()`. A named
|
|
52
|
+
**sequential or diverging** scheme (`viridis`, `magma`, `Blues`, `RdBu`,
|
|
53
|
+
Crameri `batlow`, cyclic `romaO`, …) needs `registerSequentialColor()`
|
|
54
|
+
— a sequential name with no `type` infers sequential, so
|
|
55
|
+
`registerOrdinalColor()` is not enough. Cyclic `*O` names are sequential
|
|
56
|
+
only. Explicit `type: "ordinal"` (including discrete sampling of a
|
|
57
|
+
non-cyclic sequential name) still needs `registerOrdinalColor()`. Other kinds:
|
|
58
|
+
`registerBinnedColor()`, `registerManualColor()`,
|
|
59
|
+
`registerIdentityColor()`.
|
|
60
|
+
- Style: `registerNumericStyle()` (size / linewidth / alpha),
|
|
61
|
+
`registerFiniteStyle()` (shape / linetype).
|
|
62
|
+
- Band axes: `registerBandGuide()` for categorical x/y.
|
|
63
|
+
- Legends: `registerDiscreteLegend()` / `registerContinuousLegend()` (the
|
|
64
|
+
matching color register also pulls these).
|
|
65
|
+
- Named themes: `@ggts-sh/core/headless` resolves only `default` and `void`.
|
|
66
|
+
`dark`, `minimal`, and the rest need `@ggts-sh/core` or
|
|
67
|
+
`@ggts-sh/core/render` — not a `register*()` call.
|
|
68
|
+
|
|
69
|
+
`registerAll()` covers every stat frame, every geom batch, every color kind
|
|
70
|
+
(with catalogs), every style kind, the band-axis planner, Temporal, and
|
|
71
|
+
interaction candidates. `registerBasic()` covers identity charts only; it
|
|
72
|
+
does not install Temporal or specialty geoms/stats.
|