@sipemu/ggplot-rs 0.40.0 → 0.42.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/dist/ggplot_rs.d.ts +146 -8
- package/dist/ggplot_rs_bg.wasm +0 -0
- package/package.json +1 -1
- package/skills/ggplot-rs-js/SKILL.md +8 -5
package/dist/ggplot_rs.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type Aesthetic =
|
|
|
10
10
|
| "x" | "y" | "color" | "colour" | "fill" | "size" | "shape" | "alpha" | "group"
|
|
11
11
|
| "linetype" | "linewidth" | "label" | "weight" | "xmin" | "xmax" | "ymin" | "ymax"
|
|
12
12
|
| "xend" | "yend" | "angle" | "radius" | "tooltip" | "from" | "to" | "subgroup"
|
|
13
|
-
| "open" | "high" | "low" | "close" | "lower" | "middle" | "upper" | "fontface" | "class";
|
|
13
|
+
| "open" | "high" | "low" | "close" | "lower" | "middle" | "upper" | "fontface" | "class" | "key";
|
|
14
14
|
/** Aesthetic → column name. */
|
|
15
15
|
export type AesMap = Partial<Record<Aesthetic, string>>;
|
|
16
16
|
|
|
@@ -104,6 +104,40 @@ export type Position =
|
|
|
104
104
|
preserve?: "total" | "single";
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
/** A per-aesthetic guide: `"none"`, a colourbar / bins kind, or its options (#409). */
|
|
108
|
+
export type GuideSpec =
|
|
109
|
+
| "none"
|
|
110
|
+
| "legend"
|
|
111
|
+
| "bins"
|
|
112
|
+
| "colourbar"
|
|
113
|
+
| "colorbar"
|
|
114
|
+
| "coloursteps"
|
|
115
|
+
| "colorsteps"
|
|
116
|
+
| {
|
|
117
|
+
title?: string;
|
|
118
|
+
reverse?: boolean;
|
|
119
|
+
type?: "legend" | "colourbar" | "colorbar" | "coloursteps" | "colorsteps" | "bins";
|
|
120
|
+
/** Bar width / height in px. */
|
|
121
|
+
barwidth?: number;
|
|
122
|
+
barheight?: number;
|
|
123
|
+
nbin?: number;
|
|
124
|
+
display?: "gradient" | "rectangles";
|
|
125
|
+
frame?: boolean;
|
|
126
|
+
ticks?: boolean;
|
|
127
|
+
even_steps?: boolean;
|
|
128
|
+
/** coloursteps / bins: label the outer limits too. */
|
|
129
|
+
show_limits?: boolean;
|
|
130
|
+
/** bins: draw the axis line and ticks (default true). */
|
|
131
|
+
axis?: boolean;
|
|
132
|
+
/** Draw this legend at its own side (the others stay at `legend`). */
|
|
133
|
+
position?: "right" | "left" | "top" | "bottom";
|
|
134
|
+
/** Fixed key appearance (ggplot2's override.aes). */
|
|
135
|
+
override_aes?: {
|
|
136
|
+
color?: string; fill?: string; shape?: string | number; linetype?: string;
|
|
137
|
+
size?: number; alpha?: number; linewidth?: number;
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
|
|
107
141
|
export interface Layer {
|
|
108
142
|
geom: GeomName;
|
|
109
143
|
/** Merged over the plot-level `aes` (layer wins). */
|
|
@@ -130,8 +164,19 @@ export interface PositionScale {
|
|
|
130
164
|
| "probit" | "pseudo_log" | "reciprocal" | "exp";
|
|
131
165
|
limits?: [number, number];
|
|
132
166
|
breaks?: number[];
|
|
167
|
+
/** About this many breaks (ggplot2's n.breaks). */
|
|
168
|
+
n_breaks?: number;
|
|
169
|
+
/** Time-of-day axis: values in seconds, HH:MM:SS labels (scale_x_time). */
|
|
170
|
+
time?: boolean;
|
|
133
171
|
/** Axis title. */
|
|
134
172
|
name?: string;
|
|
173
|
+
/** Secondary axis (x: top, y: right): `true` repeats the primary
|
|
174
|
+
* (`dup_axis()`), or `secondary = primary * scale + offset`. */
|
|
175
|
+
sec_axis?: boolean | { name?: string; scale?: number; offset?: number };
|
|
176
|
+
/** Binned position scale: about this many breaks (scale_x_binned). */
|
|
177
|
+
binned?: number;
|
|
178
|
+
/** Log10 minor ticks (guide_axis_logticks), with trans "log10". */
|
|
179
|
+
logticks?: boolean;
|
|
135
180
|
}
|
|
136
181
|
|
|
137
182
|
export interface ColorScale {
|
|
@@ -144,16 +189,82 @@ export interface ColorScale {
|
|
|
144
189
|
values?: Record<string, string>;
|
|
145
190
|
/** Two-color gradient `["#low", "#high"]` for a numeric column. */
|
|
146
191
|
gradient?: [string, string];
|
|
192
|
+
/** Diverging binned `["#low", "#mid", "#high"]` (`scale_*_steps2`), mid at `midpoint` (default 0). */
|
|
193
|
+
steps2?: [string, string, string];
|
|
194
|
+
midpoint?: number;
|
|
195
|
+
/** Bins for `steps2` / `palette: "viridis_b:A"…"viridis_b:H"` (default 5). */
|
|
196
|
+
bins?: number;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** A size / alpha / linewidth / shape scale: exactly one of these (#408). */
|
|
200
|
+
export interface ValueScale {
|
|
201
|
+
/** The column already holds the values (shape: `pch` codes or names). */
|
|
202
|
+
identity?: boolean;
|
|
203
|
+
/** Manual `{ level: number }` (not for shape). */
|
|
204
|
+
values?: Record<string, number>;
|
|
205
|
+
/** Output range `[lo, hi]` (size: radius, ggplot2's `scale_radius`). */
|
|
206
|
+
range?: [number, number];
|
|
207
|
+
/** Binned (scale_*_binned): about this many breaks; with `range`. */
|
|
208
|
+
binned?: number;
|
|
147
209
|
}
|
|
148
210
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
|
211
|
+
/** A facet strip labeller (#412). */
|
|
212
|
+
export type Labeller =
|
|
213
|
+
| "value" | "both" | "multi_line" | "parsed"
|
|
214
|
+
| { template: string } | { values: Record<string, string> } | { wrap: number }
|
|
215
|
+
| { vars: Record<string, Labeller> };
|
|
216
|
+
|
|
217
|
+
/** Which panels get axes, and whether inner axes are labelled (#412). */
|
|
218
|
+
export interface FacetAxesSpec {
|
|
219
|
+
/** Proportional panels (a wrap needs one row / column). */
|
|
220
|
+
space?: "fixed" | "free_x" | "free_y" | "free";
|
|
221
|
+
axes?: "margins" | "all" | "all_x" | "all_y";
|
|
222
|
+
axis_labels?: "all" | "margins";
|
|
223
|
+
}
|
|
152
224
|
|
|
153
|
-
export type
|
|
225
|
+
export type Facet = FacetAxesSpec & (
|
|
226
|
+
| {
|
|
227
|
+
wrap: string; ncol?: number; scales?: "fixed" | "free" | "free_x" | "free_y";
|
|
228
|
+
/** "h" (row by row, default) or "v" (column by column). */
|
|
229
|
+
dir?: "h" | "v";
|
|
230
|
+
/** First row at the top (default true; ggplot2's as.table). */
|
|
231
|
+
as_table?: boolean;
|
|
232
|
+
/** Wrap strip labels at this many characters (label_wrap_gen). */
|
|
233
|
+
label_wrap?: number;
|
|
234
|
+
labeller?: Labeller;
|
|
235
|
+
/** The side of each panel its strip sits on (default "top"). */
|
|
236
|
+
strip_position?: "top" | "bottom" | "left" | "right";
|
|
237
|
+
/** Fixed panel order; listed levels without data still get a panel. */
|
|
238
|
+
levels?: string[];
|
|
239
|
+
}
|
|
240
|
+
| {
|
|
241
|
+
rows?: string; cols?: string; scales?: "fixed" | "free" | "free_x" | "free_y";
|
|
242
|
+
labeller?: Labeller;
|
|
243
|
+
/** Column strips below ("x"), row strips left ("y"), or both. */
|
|
244
|
+
switch?: "x" | "y" | "both";
|
|
245
|
+
/** Fixed row / column order, empty ones kept (drop = FALSE). */
|
|
246
|
+
row_levels?: string[]; col_levels?: string[];
|
|
247
|
+
/** An extra "(all)" row and column (margins = TRUE). */
|
|
248
|
+
margins?: boolean;
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
export type CoordName =
|
|
252
|
+
| "cartesian" | "flip" | "polar" | "radial" | "fixed" | "equal" | "radar" | "quickmap" | "map" | "sf";
|
|
154
253
|
export type Coord =
|
|
155
254
|
| CoordName
|
|
156
|
-
| {
|
|
255
|
+
| {
|
|
256
|
+
type: CoordName; ratio?: number; xlim?: [number, number]; ylim?: [number, number];
|
|
257
|
+
/** cartesian: mirror the panel; radial: "theta" | "r" | "thetar". */
|
|
258
|
+
reverse?: "x" | "y" | "xy" | "theta" | "r" | "thetar" | "none";
|
|
259
|
+
/** cartesian: keep the scale padding — `false`, or `[top, right, bottom, left]`. */
|
|
260
|
+
expand?: boolean | [boolean, boolean, boolean, boolean];
|
|
261
|
+
/** radial: theta start / end in radians (clockwise from 12 o'clock) and a donut hole (0–1). */
|
|
262
|
+
start?: number; end?: number; inner_radius?: number;
|
|
263
|
+
/** radial: r axis along the start spoke; theta labels follow the circle. */
|
|
264
|
+
r_axis_inside?: boolean; rotate_angle?: boolean;
|
|
265
|
+
/** "on" (default) clips layers to the panel; "off" lets them draw past it. */
|
|
266
|
+
clip?: "on" | "off";
|
|
267
|
+
};
|
|
157
268
|
|
|
158
269
|
export interface Labels {
|
|
159
270
|
title?: string;
|
|
@@ -164,7 +275,7 @@ export interface Labels {
|
|
|
164
275
|
y?: string;
|
|
165
276
|
}
|
|
166
277
|
|
|
167
|
-
export type ThemePreset = "gray" | "grey" | "bw" | "minimal" | "classic" | "dark" | "light" | "void" | "linedraw";
|
|
278
|
+
export type ThemePreset = "gray" | "grey" | "bw" | "minimal" | "classic" | "dark" | "light" | "void" | "linedraw" | "test";
|
|
168
279
|
export interface TextElement {
|
|
169
280
|
family?: string; size?: number; color?: [number, number, number];
|
|
170
281
|
face?: "plain" | "bold" | "italic"; hjust?: number; vjust?: number; angle?: number; visible?: boolean;
|
|
@@ -193,8 +304,31 @@ export interface ThemeConfig {
|
|
|
193
304
|
text?: TextElement; title?: TextElement; subtitle?: TextElement; caption?: TextElement;
|
|
194
305
|
axis_title_x?: TextElement; axis_title_y?: TextElement;
|
|
195
306
|
axis_text_x?: TextElement; axis_text_y?: TextElement;
|
|
307
|
+
/** A top x axis's / right (secondary) y axis's labels (#413). */
|
|
308
|
+
axis_text_x_top?: TextElement; axis_text_y_right?: TextElement;
|
|
309
|
+
/** Horizontal (x) / turned (y) facet strips only (#413). */
|
|
310
|
+
strip_text_x?: TextElement; strip_text_y?: TextElement;
|
|
311
|
+
strip_background_x?: RectElement; strip_background_y?: RectElement;
|
|
312
|
+
/** Strips below / left of a panel outside its axis (#412), and the gap. */
|
|
313
|
+
strip_placement?: "inside" | "outside"; strip_switch_pad?: number;
|
|
314
|
+
caption_position?: "panel" | "plot";
|
|
315
|
+
legend_location?: "panel" | "plot";
|
|
316
|
+
legend_ticks_length?: number;
|
|
317
|
+
/** Gaps between legend keys and between the panel and the legend, px (#413). */
|
|
318
|
+
legend_key_spacing_x?: number; legend_key_spacing_y?: number; legend_box_spacing?: number;
|
|
319
|
+
/** Line several legends up: "left"/"top" (default), "center", "right"/"bottom", or 0–1. */
|
|
320
|
+
/** Markdown / HTML subset (**bold**, *italic*, ^sup^, ~sub~, <span style='color:…'>) in titles, strips, legends. */
|
|
321
|
+
rich_text?: boolean;
|
|
322
|
+
legend_box_just?: "left" | "top" | "center" | "right" | "bottom" | number;
|
|
196
323
|
legend_title?: TextElement; legend_text?: TextElement; strip_text?: TextElement;
|
|
197
324
|
axis_line?: LineElement; axis_ticks?: LineElement;
|
|
325
|
+
/** Per-axis / per-side axis lines and ticks (#413). */
|
|
326
|
+
axis_line_x?: LineElement; axis_line_y?: LineElement;
|
|
327
|
+
axis_ticks_x?: LineElement; axis_ticks_y?: LineElement;
|
|
328
|
+
axis_line_x_top?: LineElement; axis_line_x_bottom?: LineElement;
|
|
329
|
+
axis_line_y_left?: LineElement; axis_line_y_right?: LineElement;
|
|
330
|
+
axis_ticks_x_top?: LineElement; axis_ticks_x_bottom?: LineElement;
|
|
331
|
+
axis_ticks_y_left?: LineElement; axis_ticks_y_right?: LineElement;
|
|
198
332
|
panel_grid_major?: LineElement; panel_grid_minor?: LineElement; panel_border?: LineElement;
|
|
199
333
|
panel_background?: RectElement; plot_background?: RectElement;
|
|
200
334
|
legend_background?: RectElement; strip_background?: RectElement;
|
|
@@ -210,16 +344,20 @@ export interface PlotSpec {
|
|
|
210
344
|
/** Plot-level mapping inherited by every layer. */
|
|
211
345
|
aes?: AesMap;
|
|
212
346
|
layers: Layer[];
|
|
213
|
-
scales?: { x?: PositionScale; y?: PositionScale; color?: ColorScale; colour?: ColorScale; fill?: ColorScale };
|
|
347
|
+
scales?: { x?: PositionScale; y?: PositionScale; color?: ColorScale; colour?: ColorScale; fill?: ColorScale; size?: ValueScale; alpha?: ValueScale; linewidth?: ValueScale; shape?: ValueScale };
|
|
214
348
|
facet?: Facet;
|
|
215
349
|
coord?: Coord;
|
|
216
350
|
labels?: Labels;
|
|
217
351
|
/** A preset name or a theme overlay (default "minimal"). */
|
|
218
352
|
theme?: ThemePreset | ThemeConfig;
|
|
219
353
|
legend?: Legend;
|
|
354
|
+
/** Per-aesthetic guides: `"none"` drops a legend, `{ title }` names it. */
|
|
355
|
+
guides?: Partial<Record<"color" | "colour" | "fill" | "shape" | "size" | "alpha" | "linetype" | "linewidth", GuideSpec>>;
|
|
220
356
|
/** Pixels (default 640 × 400). */
|
|
221
357
|
width?: number;
|
|
222
358
|
height?: number;
|
|
359
|
+
/** Tag axes, grid, legend, strips and titles with semantic CSS classes (gg-axis-text, gg-legend-key, …). */
|
|
360
|
+
svg_classes?: boolean;
|
|
223
361
|
}
|
|
224
362
|
|
|
225
363
|
|
package/dist/ggplot_rs_bg.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sipemu/ggplot-rs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"description": "Grammar-of-graphics charts (ggplot2-style) rendered to SVG — WebAssembly build of the ggplot-rs Rust crate, no runtime dependencies",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/ggplot_rs.js",
|
|
@@ -70,13 +70,16 @@ if (!svg.startsWith("<svg")) throw new Error("render failed");
|
|
|
70
70
|
| `layers[].data` | layer-specific data |
|
|
71
71
|
| `layers[].key_glyph` | legend key picture: `point path rect polygon boxplot crossbar pointrange linerange smooth text label vline vpath abline timeseries dotplot blank` (default per geom; layers on one mapping share a key) |
|
|
72
72
|
| `layers[].show_legend` | `false` hides the layer from legends; `{ color: false }` per aesthetic |
|
|
73
|
-
| `scales.x/y` | `{ trans, limits: [lo, hi], breaks: [...], name }
|
|
74
|
-
| `scales.color/fill` | `{ palette }` (`Set1 Dark2 Paired npg
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
73
|
+
| `scales.x/y` | `{ trans, limits: [lo, hi], breaks: [...], logticks: true (log10 minor ticks), binned: n (bin x before the stat: geom bar → histogram), n_breaks, time: true (seconds → HH:MM:SS), name, sec_axis: true | { name, scale, offset } }` (secondary axis on top / right); trans `log10 log2 ln sqrt reverse logit probit pseudo_log reciprocal exp` |
|
|
74
|
+
| `scales.color/fill` | `{ palette }` (`Set1 Dark2 Paired npg …`, `hue` = ggplot2's default hues, `viridis:A`…`viridis:H` for categorical; `viridis magma plasma inferno` or any Brewer name (a distiller gradient) for numeric), `{ values: { level: "#rrggbb" } }`, `{ gradient: ["#lo", "#hi"] }`, `{ steps2: ["#lo", "#mid", "#hi"], midpoint: 0, bins: 5 }`, `{ palette: "viridis_b:C", bins: 6 }` (binned), `{ levels: [...] }` |
|
|
75
|
+
| `scales.size/alpha/linewidth/shape` | exactly one of `{ identity: true }` (the column holds the values; shape: `pch` codes or names), `{ values: { level: n } }` (not shape), `{ range: [lo, hi] }`, or `{ binned: n, range? }` (binned; its legend is `guide_bins`, see `guides`) |
|
|
76
|
+
| `facet` | `{ wrap, ncol?, scales?, dir?: "h"/"v", as_table?, label_wrap?: width, strip_position?: "top"/"bottom"/"left"/"right", levels?: [...] }` or `{ rows?, cols?, scales?, switch?: "x"/"y"/"both", row_levels?, col_levels?, margins?: true }` (grid: column strips on top, row strips on the right); `labeller: "both" | { template: "n = {value}" } | { values: { a: "Alpha" } } | { vars: { var: <labeller> } }`; both take `axes: "all"/"all_x"/"all_y"` + `axis_labels: "margins"` and `space: "free_x"/"free_y"/"free"`; scales `fixed free free_x free_y` |
|
|
77
|
+
| `coord` | `cartesian flip polar radial fixed radar quickmap map sf`, or `{ type, xlim, ylim, ratio, reverse: "x"/"y"/"xy", expand: false | [top, right, bottom, left], start, end, inner_radius, r_axis_inside, rotate_angle, clip: "off" }` (radial `reverse: "theta"/"r"/"thetar"`) (`quickmap` / `map` = plain lon/lat data; `radial` partial circles / donuts) |
|
|
77
78
|
| `labels` | `title subtitle caption tag x y` (axis titles are not auto-filled from column names) |
|
|
78
|
-
| `theme` | preset `gray bw minimal classic dark light void linedraw` (default `minimal`), or an overlay `{ base, primary: [r,g,b], palette, title: {...}, panel_grid_major: {...}, … }` |
|
|
79
|
+
| `theme` | preset `gray bw minimal classic dark light void linedraw test` (default `minimal`), or an overlay `{ base, primary: [r,g,b], palette, title: {...}, panel_grid_major: {...}, axis_text_x_top: {...}, axis_text_y_right: {...}, strip_text_x/y: {...}, strip_background_x/y: {...}, strip_placement: "outside", rich_text: true (Markdown/HTML subset in titles, strips, legends), … }` |
|
|
79
80
|
| `legend` | `right left top bottom none inside` or `[x, y]` inside the panel |
|
|
81
|
+
| `svg_classes` | `true` tags axes, grid, legend, strips and titles with CSS classes (`gg-axis-text`, `gg-legend-key`, `gg-strip-text`, `gg-title`, …) for restyling; marks always carry `gg-mark gg-<kind>` |
|
|
82
|
+
| `guides` | per aesthetic: `{ fill: "none", color: { title: "Group", reverse: true } }`; continuous colour/fill: `"coloursteps"` or `{ type: "colourbar", barwidth: 20, barheight: 150, nbin: 10, display: "rectangles", frame: false, ticks: false }` (`even_steps`, `show_limits` for steps); binned size/alpha/shape scales: `"bins"` (the default — keys labelled at bin edges) or `{ type: "bins", show_limits: true, axis: false }`, `"legend"` for one key per bin; one legend at its own side: `{ position: "bottom" }`; fixed key looks: `{ override_aes: { size: 4, alpha: 1, shape: "square", color: "#rrggbb" } }` |
|
|
80
83
|
|
|
81
84
|
## Geoms
|
|
82
85
|
|