@danielsimonjr/mathts-plot 0.4.2 → 0.4.4

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.
Files changed (45) hide show
  1. package/README.md +142 -142
  2. package/dist/coerce.d.ts +8 -0
  3. package/dist/coerce.d.ts.map +1 -0
  4. package/dist/contour.d.ts +6 -0
  5. package/dist/contour.d.ts.map +1 -0
  6. package/dist/emit.d.ts +5 -0
  7. package/dist/emit.d.ts.map +1 -0
  8. package/dist/frame.d.ts +4 -0
  9. package/dist/frame.d.ts.map +1 -0
  10. package/dist/heatmap.d.ts +4 -0
  11. package/dist/heatmap.d.ts.map +1 -0
  12. package/dist/histogram.d.ts +6 -0
  13. package/dist/histogram.d.ts.map +1 -0
  14. package/dist/index.d.ts +12 -106
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +111 -20
  17. package/dist/marks2d.d.ts +16 -0
  18. package/dist/marks2d.d.ts.map +1 -0
  19. package/dist/overlay.d.ts +4 -0
  20. package/dist/overlay.d.ts.map +1 -0
  21. package/dist/palette.d.ts +3 -0
  22. package/dist/palette.d.ts.map +1 -0
  23. package/dist/plot.d.ts +12 -0
  24. package/dist/plot.d.ts.map +1 -0
  25. package/dist/render-core.d.ts +21 -0
  26. package/dist/render-core.d.ts.map +1 -0
  27. package/dist/render-file.d.ts +10 -9
  28. package/dist/render-file.d.ts.map +1 -0
  29. package/dist/scale.d.ts +9 -0
  30. package/dist/scale.d.ts.map +1 -0
  31. package/dist/scene.d.ts +52 -0
  32. package/dist/scene.d.ts.map +1 -0
  33. package/dist/svg.d.ts +34 -0
  34. package/dist/svg.d.ts.map +1 -0
  35. package/dist/three/points3d.d.ts +11 -0
  36. package/dist/three/points3d.d.ts.map +1 -0
  37. package/dist/three/project.d.ts +12 -0
  38. package/dist/three/project.d.ts.map +1 -0
  39. package/dist/three/surface.d.ts +28 -0
  40. package/dist/three/surface.d.ts.map +1 -0
  41. package/dist/tikz.d.ts +8 -0
  42. package/dist/tikz.d.ts.map +1 -0
  43. package/dist/types.d.ts +42 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/package.json +13 -12
package/README.md CHANGED
@@ -1,142 +1,142 @@
1
- # @danielsimonjr/mathts-plot
2
-
3
- Headless SVG 2D/3D plotting for [MathTS](https://github.com/danielsimonjr/mathts).
4
-
5
- Pure functions returning self-contained SVG strings — no browser, no canvas, no runtime
6
- dependencies beyond the MathTS bedrock (`core`/`functions`/`expression`). Every function
7
- coerces its input and never throws on bad data: empty, `NaN`, or `Infinity` inputs render a
8
- "no data" placeholder SVG instead of crashing. See
9
- `docs/superpowers/specs/2026-07-07-plotting-design.md` for the design.
10
-
11
- ## Install
12
-
13
- ```sh
14
- npm install @danielsimonjr/mathts-plot
15
- ```
16
-
17
- ## Usage
18
-
19
- Every function below returns a self-contained SVG string (`<svg ...>...</svg>`) — render it
20
- directly in an `<img src="data:image/svg+xml,...">`, write it to a `.svg` file, or drop it
21
- into HTML.
22
-
23
- ### `line` — one series, or overlaid with others
24
-
25
- ```ts
26
- import { line } from '@danielsimonjr/mathts-plot';
27
-
28
- const svg = line([0, 1, 2, 3], [0, 1, 4, 9], { title: 'squares', xLabel: 'x', yLabel: 'y' });
29
- // svg === '<svg ...>...</svg>'
30
- ```
31
-
32
- ### `overlay` — combine several layers on shared, auto-scaled axes
33
-
34
- ```ts
35
- import { overlay } from '@danielsimonjr/mathts-plot';
36
-
37
- const svg = overlay(
38
- [
39
- { type: 'line', x: [0, 1, 2], y: [0, 1, 2], label: 'model' },
40
- { type: 'scatter', x: [0, 1, 2], y: [0.1, 1.2, 1.8], label: 'data' },
41
- ],
42
- { legend: true }
43
- );
44
- ```
45
-
46
- ### `surface` — 3D surface via orthographic projection + painter's algorithm
47
-
48
- ```ts
49
- import { surface } from '@danielsimonjr/mathts-plot';
50
-
51
- const z = [
52
- [0, 1, 2],
53
- [1, 2, 3],
54
- [2, 3, 4],
55
- ]; // z[row][col]
56
- const svg = surface(z, { kind: 'filled', azim: 45, elev: 25 });
57
- ```
58
-
59
- ### `plot` — generic, polymorphic entry point (including expression strings)
60
-
61
- ```ts
62
- import { plot } from '@danielsimonjr/mathts-plot';
63
-
64
- // numeric series → line
65
- plot([0, 1, 4, 9]);
66
- plot([0, 1, 2, 3], [0, 1, 4, 9]);
67
-
68
- // expression string, sampled via functions/expression → line
69
- plot('sin(x)', { from: 0, to: Math.PI, samples: 200 });
70
-
71
- // two free variables → contour (default) or 3D surface
72
- plot('x^2 + y^2', { from: -2, to: 2 });
73
- plot('x^2 + y^2', { from: -2, to: 2, kind: 'surface' });
74
-
75
- // array of Layer2D → overlay
76
- plot([
77
- { type: 'line', x: [0, 1, 2], y: [0, 1, 2] },
78
- { type: 'scatter', x: [0, 1, 2], y: [0.1, 1.2, 1.8] },
79
- ]);
80
- ```
81
-
82
- ### TikZ / LaTeX output
83
-
84
- Every function also accepts `{ format: 'tikz' }` (default is `'svg'`), and there's a
85
- generic `toTikZ()` mirroring `plot()`. The geometry matches the SVG output exactly (a
86
- deterministic y-flip maps SVG's top-left origin to TikZ's bottom-left); only
87
- `\usepackage{tikz}` is required to compile the result.
88
-
89
- ```ts
90
- import { toTikZ, line, surface } from '@danielsimonjr/mathts-plot';
91
-
92
- // generic entry point, expression source → line
93
- const tex = toTikZ('sin(x)', { from: 0, to: Math.PI });
94
-
95
- // per-type function via the format option
96
- const tex2 = line([0, 1, 2, 3], [0, 1, 4, 9], { format: 'tikz' });
97
-
98
- // standalone: false → a bare tikzpicture for \input, not a compilable document
99
- const z = [
100
- [0, 1, 2],
101
- [1, 2, 3],
102
- [2, 3, 4],
103
- ];
104
- const fragment = surface(z, { format: 'tikz', tikz: { standalone: false } });
105
- ```
106
-
107
- `toTikZ`/`{ format: 'tikz' }` return a LaTeX string, not SVG. With `standalone`
108
- (default `true`) the string is a complete `\documentclass{...}` document you can
109
- compile as-is; `standalone: false` returns just the `tikzpicture` environment, meant
110
- to be pulled in via `\input{...}` from a larger document.
111
-
112
- ## What it provides
113
-
114
- Per-type mark functions, each `(x, y, opts?) => string` unless noted:
115
-
116
- - **2D**: `line`, `scatter`, `bar`, `area`, `step`, `errorbar(x, y, yerr, opts?)`,
117
- `quiver(x, y, u, v, opts?)`.
118
- - **`histogram(data, opts?)`** — bins via `functions.histogram`, then renders bar heights at
119
- bin centers.
120
- - **`heatmap(z, opts?)`** — viridis-colored grid, `z` as `z[row][col]`.
121
- - **`contour(z, opts?)`** — marching squares over a `z[row][col]` grid.
122
- - **`overlay(layers, opts?)`** — several `Layer2D`s on shared, auto-scaled axes.
123
- - **3D**: `surface(z, opts?)` (wireframe or painter's-algorithm filled),
124
- `scatter3d(x, y, z, opts?)`, `curve3d(x, y, z, opts?)` — all projected with an orthographic
125
- camera (`azim`/`elev`).
126
- - **`plot(...)`** — generic polymorphic dispatch over numeric series, layer arrays, and
127
- expression-source strings (evaluated via `@danielsimonjr/mathts-expression` /
128
- `@danielsimonjr/mathts-functions`).
129
- - **`viridis(t)`** — the perceptually-uniform colormap used by `heatmap`/`contour`/`surface`,
130
- exposed for reuse.
131
-
132
- Notes:
133
-
134
- - Pure ESM, `strict` TypeScript, no runtime dependencies beyond the MathTS bedrock
135
- (`core`/`functions`/`expression`).
136
- - SVG-only in v1 — no PNG/canvas rendering.
137
- - `workbook` renders its charts through this package (its former private `svg.ts` plotter was
138
- removed).
139
-
140
- ## License
141
-
142
- MIT (c) Daniel Simon Jr.
1
+ # @danielsimonjr/mathts-plot
2
+
3
+ Headless SVG 2D/3D plotting for [MathTS](https://github.com/danielsimonjr/mathts).
4
+
5
+ Pure functions returning self-contained SVG strings — no browser, no canvas, no runtime
6
+ dependencies beyond the MathTS bedrock (`core`/`functions`/`expression`). Every function
7
+ coerces its input and never throws on bad data: empty, `NaN`, or `Infinity` inputs render a
8
+ "no data" placeholder SVG instead of crashing. See
9
+ `docs/superpowers/specs/2026-07-07-plotting-design.md` for the design.
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ npm install @danielsimonjr/mathts-plot
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ Every function below returns a self-contained SVG string (`<svg ...>...</svg>`) — render it
20
+ directly in an `<img src="data:image/svg+xml,...">`, write it to a `.svg` file, or drop it
21
+ into HTML.
22
+
23
+ ### `line` — one series, or overlaid with others
24
+
25
+ ```ts
26
+ import { line } from '@danielsimonjr/mathts-plot';
27
+
28
+ const svg = line([0, 1, 2, 3], [0, 1, 4, 9], { title: 'squares', xLabel: 'x', yLabel: 'y' });
29
+ // svg === '<svg ...>...</svg>'
30
+ ```
31
+
32
+ ### `overlay` — combine several layers on shared, auto-scaled axes
33
+
34
+ ```ts
35
+ import { overlay } from '@danielsimonjr/mathts-plot';
36
+
37
+ const svg = overlay(
38
+ [
39
+ { type: 'line', x: [0, 1, 2], y: [0, 1, 2], label: 'model' },
40
+ { type: 'scatter', x: [0, 1, 2], y: [0.1, 1.2, 1.8], label: 'data' },
41
+ ],
42
+ { legend: true }
43
+ );
44
+ ```
45
+
46
+ ### `surface` — 3D surface via orthographic projection + painter's algorithm
47
+
48
+ ```ts
49
+ import { surface } from '@danielsimonjr/mathts-plot';
50
+
51
+ const z = [
52
+ [0, 1, 2],
53
+ [1, 2, 3],
54
+ [2, 3, 4],
55
+ ]; // z[row][col]
56
+ const svg = surface(z, { kind: 'filled', azim: 45, elev: 25 });
57
+ ```
58
+
59
+ ### `plot` — generic, polymorphic entry point (including expression strings)
60
+
61
+ ```ts
62
+ import { plot } from '@danielsimonjr/mathts-plot';
63
+
64
+ // numeric series → line
65
+ plot([0, 1, 4, 9]);
66
+ plot([0, 1, 2, 3], [0, 1, 4, 9]);
67
+
68
+ // expression string, sampled via functions/expression → line
69
+ plot('sin(x)', { from: 0, to: Math.PI, samples: 200 });
70
+
71
+ // two free variables → contour (default) or 3D surface
72
+ plot('x^2 + y^2', { from: -2, to: 2 });
73
+ plot('x^2 + y^2', { from: -2, to: 2, kind: 'surface' });
74
+
75
+ // array of Layer2D → overlay
76
+ plot([
77
+ { type: 'line', x: [0, 1, 2], y: [0, 1, 2] },
78
+ { type: 'scatter', x: [0, 1, 2], y: [0.1, 1.2, 1.8] },
79
+ ]);
80
+ ```
81
+
82
+ ### TikZ / LaTeX output
83
+
84
+ Every function also accepts `{ format: 'tikz' }` (default is `'svg'`), and there's a
85
+ generic `toTikZ()` mirroring `plot()`. The geometry matches the SVG output exactly (a
86
+ deterministic y-flip maps SVG's top-left origin to TikZ's bottom-left); only
87
+ `\usepackage{tikz}` is required to compile the result.
88
+
89
+ ```ts
90
+ import { toTikZ, line, surface } from '@danielsimonjr/mathts-plot';
91
+
92
+ // generic entry point, expression source → line
93
+ const tex = toTikZ('sin(x)', { from: 0, to: Math.PI });
94
+
95
+ // per-type function via the format option
96
+ const tex2 = line([0, 1, 2, 3], [0, 1, 4, 9], { format: 'tikz' });
97
+
98
+ // standalone: false → a bare tikzpicture for \input, not a compilable document
99
+ const z = [
100
+ [0, 1, 2],
101
+ [1, 2, 3],
102
+ [2, 3, 4],
103
+ ];
104
+ const fragment = surface(z, { format: 'tikz', tikz: { standalone: false } });
105
+ ```
106
+
107
+ `toTikZ`/`{ format: 'tikz' }` return a LaTeX string, not SVG. With `standalone`
108
+ (default `true`) the string is a complete `\documentclass{...}` document you can
109
+ compile as-is; `standalone: false` returns just the `tikzpicture` environment, meant
110
+ to be pulled in via `\input{...}` from a larger document.
111
+
112
+ ## What it provides
113
+
114
+ Per-type mark functions, each `(x, y, opts?) => string` unless noted:
115
+
116
+ - **2D**: `line`, `scatter`, `bar`, `area`, `step`, `errorbar(x, y, yerr, opts?)`,
117
+ `quiver(x, y, u, v, opts?)`.
118
+ - **`histogram(data, opts?)`** — bins via `functions.histogram`, then renders bar heights at
119
+ bin centers.
120
+ - **`heatmap(z, opts?)`** — viridis-colored grid, `z` as `z[row][col]`.
121
+ - **`contour(z, opts?)`** — marching squares over a `z[row][col]` grid.
122
+ - **`overlay(layers, opts?)`** — several `Layer2D`s on shared, auto-scaled axes.
123
+ - **3D**: `surface(z, opts?)` (wireframe or painter's-algorithm filled),
124
+ `scatter3d(x, y, z, opts?)`, `curve3d(x, y, z, opts?)` — all projected with an orthographic
125
+ camera (`azim`/`elev`).
126
+ - **`plot(...)`** — generic polymorphic dispatch over numeric series, layer arrays, and
127
+ expression-source strings (evaluated via `@danielsimonjr/mathts-expression` /
128
+ `@danielsimonjr/mathts-functions`).
129
+ - **`viridis(t)`** — the perceptually-uniform colormap used by `heatmap`/`contour`/`surface`,
130
+ exposed for reuse.
131
+
132
+ Notes:
133
+
134
+ - Pure ESM, `strict` TypeScript, no runtime dependencies beyond the MathTS bedrock
135
+ (`core`/`functions`/`expression`).
136
+ - SVG-only in v1 — no PNG/canvas rendering.
137
+ - `workbook` renders its charts through this package (its former private `svg.ts` plotter was
138
+ removed).
139
+
140
+ ## License
141
+
142
+ MIT (c) Daniel Simon Jr.
@@ -0,0 +1,8 @@
1
+ import type { Data } from './types.js';
2
+ /** Flatten + coerce to finite numbers; non-finite entries are dropped. */
3
+ export declare function coerce1d(raw: Data): number[];
4
+ /** Like coerce1d but position-preserving: non-finite stays NaN (no dropping). */
5
+ export declare function coerce1dPositional(raw: Data): number[];
6
+ /** Coerce a 2-D grid; each cell → number (non-finite kept as NaN gaps). */
7
+ export declare function coerce2d(raw: Data): number[][];
8
+ //# sourceMappingURL=coerce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA6BvC,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,CAS5C;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,CAItD;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,EAAE,EAAE,CAU9C"}
@@ -0,0 +1,6 @@
1
+ import type { PlotOptions } from './types.js';
2
+ /** Contour plot via marching squares over grid z[row][col]. */
3
+ export declare function contour(z: unknown, opts?: PlotOptions & {
4
+ levels?: number;
5
+ }): string;
6
+ //# sourceMappingURL=contour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contour.d.ts","sourceRoot":"","sources":["../src/contour.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,+DAA+D;AAC/D,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,GAAE,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAoFxF"}
package/dist/emit.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Scene } from './scene.js';
2
+ import type { PlotOptions } from './types.js';
3
+ /** Serialize a Scene via the backend chosen by opts.format (default 'svg'). */
4
+ export declare function emit(scene: Scene, opts?: Pick<PlotOptions, 'format' | 'tikz'>): string;
5
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+EAA+E;AAC/E,wBAAgB,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,MAAM,CAAM,GAAG,MAAM,CAE1F"}
@@ -0,0 +1,4 @@
1
+ import type { Layer2D, PlotOptions } from './types.js';
2
+ /** Shared 2-D rendering core: builds a Scene (axes+ticks+grid+labels+legend+marks). Never throws. */
3
+ export declare function draw2D(layers: Layer2D[], opts?: PlotOptions): string;
4
+ //# sourceMappingURL=frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAiCvD,qGAAqG;AACrG,wBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CA2JxE"}
@@ -0,0 +1,4 @@
1
+ import type { PlotOptions } from './types.js';
2
+ /** Heatmap of a 2-D grid z[row][col], colored by viridis over the data range. */
3
+ export declare function heatmap(z: unknown, opts?: PlotOptions): string;
4
+ //# sourceMappingURL=heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../src/heatmap.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,iFAAiF;AACjF,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CA+DlE"}
@@ -0,0 +1,6 @@
1
+ import type { PlotOptions } from './types.js';
2
+ /** Histogram: bins via functions.histogram, then renders bar heights at bin centers. */
3
+ export declare function histogram(data: unknown, opts?: PlotOptions & {
4
+ bins?: number;
5
+ }): string;
6
+ //# sourceMappingURL=histogram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"histogram.d.ts","sourceRoot":"","sources":["../src/histogram.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,GAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAY3F"}
package/dist/index.d.ts CHANGED
@@ -1,106 +1,12 @@
1
- /** Anything the plotter accepts as a data series: numbers, typed arrays, or core values. */
2
- type Data = unknown;
3
- /** A 2-D coordinate axis. */
4
- interface AxisSpec {
5
- label?: string;
6
- scale?: 'linear' | 'log';
7
- }
8
- /** Options shared by all plot functions (each uses the subset it needs). */
9
- interface PlotOptions {
10
- title?: string;
11
- xLabel?: string;
12
- yLabel?: string;
13
- x?: AxisSpec;
14
- y?: AxisSpec;
15
- width?: number;
16
- height?: number;
17
- theme?: 'light' | 'dark';
18
- palette?: readonly string[];
19
- legend?: boolean;
20
- from?: number;
21
- to?: number;
22
- samples?: number;
23
- kind?: '2d' | '3d' | 'surface';
24
- scope?: Record<string, unknown>;
25
- format?: 'svg' | 'tikz';
26
- tikz?: {
27
- standalone?: boolean;
28
- scale?: number;
29
- };
30
- }
31
- /** One drawable 2-D layer for the shared draw2D core / overlay. */
32
- interface Layer2D {
33
- type: 'line' | 'scatter' | 'bar' | 'area' | 'step' | 'errorbar' | 'quiver';
34
- x?: Data;
35
- y: Data;
36
- yerr?: Data;
37
- u?: Data;
38
- v?: Data;
39
- label?: string;
40
- color?: string;
41
- }
42
-
43
- /**
44
- * Generic entry point. Data forms:
45
- * plot(y, opts?) → line, x = 0..n-1
46
- * plot(x, y, opts?) → line
47
- * plot(layers[], opts?) → overlay
48
- * plot(source, opts?) → expression sampling (line / contour / surface)
49
- */
50
- declare function plot(a: unknown, b?: unknown, c?: PlotOptions): string;
51
- /** Generic TikZ entry — same polymorphism as plot(), forced to the TikZ backend. */
52
- declare function toTikZ(a: unknown, b?: unknown, c?: PlotOptions): string;
53
-
54
- /** Public: line chart of one or many series. */
55
- declare function line(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
56
- /** Public: scatter plot of one or many series. */
57
- declare function scatter(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
58
- /** Public: bar chart of one or many series. */
59
- declare function bar(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
60
- /** Public: filled area under one or many series. */
61
- declare function area(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
62
- /** Public: step chart (horizontal-then-vertical) of one or many series. */
63
- declare function step(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
64
- /** Public: vertical error bars (whisker + point) for one or many series. */
65
- declare function errorbar(x: Layer2D['x'], y: Layer2D['y'], yerr: Layer2D['yerr'], opts?: PlotOptions): string;
66
- /** Public: 2-D vector field (arrows) of one or many series. */
67
- declare function quiver(x: Layer2D['x'], y: Layer2D['y'], u: Layer2D['u'], v: Layer2D['v'], opts?: PlotOptions): string;
68
-
69
- /** Histogram: bins via functions.histogram, then renders bar heights at bin centers. */
70
- declare function histogram(data: unknown, opts?: PlotOptions & {
71
- bins?: number;
72
- }): string;
73
-
74
- /** Heatmap of a 2-D grid z[row][col], colored by viridis over the data range. */
75
- declare function heatmap(z: unknown, opts?: PlotOptions): string;
76
-
77
- /** Contour plot via marching squares over grid z[row][col]. */
78
- declare function contour(z: unknown, opts?: PlotOptions & {
79
- levels?: number;
80
- }): string;
81
-
82
- /** Draw several 2-D layers (of any mix of types) on shared auto-scaled axes. */
83
- declare function overlay(layers: Layer2D[], opts?: PlotOptions): string;
84
-
85
- /** 3-D surface z[row][col], projected to 2-D SVG. Painter's algorithm for `filled`. */
86
- declare function surface(z: unknown, opts?: Omit<PlotOptions, 'kind'> & {
87
- azim?: number;
88
- elev?: number;
89
- kind?: 'wireframe' | 'filled';
90
- }): string;
91
-
92
- interface P3Opts extends PlotOptions {
93
- azim?: number;
94
- elev?: number;
95
- }
96
- /** 3-D scatter of (x,y,z) point triples, projected to 2-D SVG. */
97
- declare function scatter3d(x: unknown, y: unknown, z: unknown, opts?: P3Opts): string;
98
- /** Parametric 3-D curve through (x,y,z) coordinate arrays. */
99
- declare function curve3d(x: unknown, y: unknown, z: unknown, opts?: P3Opts): string;
100
-
101
- /** viridis colormap: t in [0,1] → "#rrggbb". */
102
- declare function viridis(t: number): string;
103
-
104
- declare const VERSION: string;
105
-
106
- export { type AxisSpec, type Data, type Layer2D, type PlotOptions, VERSION, area, bar, contour, curve3d, errorbar, heatmap, histogram, line, overlay, plot, quiver, scatter, scatter3d, step, surface, toTikZ, viridis };
1
+ export declare const VERSION: string;
2
+ export type { Data, PlotOptions, AxisSpec, Layer2D } from './types.js';
3
+ export { plot, toTikZ } from './plot.js';
4
+ export { line, scatter, bar, area, step, errorbar, quiver } from './marks2d.js';
5
+ export { histogram } from './histogram.js';
6
+ export { heatmap } from './heatmap.js';
7
+ export { contour } from './contour.js';
8
+ export { overlay } from './overlay.js';
9
+ export { surface } from './three/surface.js';
10
+ export { scatter3d, curve3d } from './three/points3d.js';
11
+ export { viridis } from './palette.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,EAAE,MAAwB,CAAC;AAE/C,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -136,30 +136,101 @@ function fmt(n) {
136
136
  return String(Math.round(n * 1e6) / 1e6);
137
137
  }
138
138
  var r2 = (n) => Math.round(n * 100) / 100;
139
+ var ATTR_ENTITIES = {
140
+ "&": "&amp;",
141
+ "<": "&lt;",
142
+ ">": "&gt;",
143
+ '"': "&quot;",
144
+ "'": "&#39;"
145
+ };
146
+ function escAttr(v) {
147
+ return String(v).replace(/[&<>"']/g, (c) => ATTR_ENTITIES[c]);
148
+ }
149
+ function el(tag, attrs, body) {
150
+ let s = `<${tag}`;
151
+ for (const [name, value] of attrs) if (value !== void 0) s += ` ${name}="${escAttr(value)}"`;
152
+ return body === void 0 ? `${s}/>` : `${s}>${body}</${tag}>`;
153
+ }
154
+ var opacityAttr = (opacity) => opacity !== void 0 && opacity < 1 ? Math.round(opacity * 1e3) / 1e3 : void 0;
155
+ var points = (pts) => pts.map(([x, y]) => `${r2(x)},${r2(y)}`).join(" ");
139
156
  function svgDoc(width, height, body, bg) {
140
- return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="100%" role="img"><rect x="0" y="0" width="${width}" height="${height}" fill="${bg}"/>${body}</svg>`;
157
+ return el(
158
+ "svg",
159
+ [
160
+ ["xmlns", "http://www.w3.org/2000/svg"],
161
+ ["viewBox", `0 0 ${width} ${height}`],
162
+ ["width", "100%"],
163
+ ["role", "img"]
164
+ ],
165
+ el("rect", [
166
+ ["x", 0],
167
+ ["y", 0],
168
+ ["width", width],
169
+ ["height", height],
170
+ ["fill", bg]
171
+ ]) + body
172
+ );
141
173
  }
142
174
  function line(x1, y1, x2, y2, stroke, w = 1, opacity) {
143
- const op = opacity !== void 0 && opacity < 1 ? ` stroke-opacity="${Math.round(opacity * 1e3) / 1e3}"` : "";
144
- return `<line x1="${r2(x1)}" y1="${r2(y1)}" x2="${r2(x2)}" y2="${r2(y2)}" stroke="${stroke}" stroke-width="${w}"${op}/>`;
175
+ return el("line", [
176
+ ["x1", r2(x1)],
177
+ ["y1", r2(y1)],
178
+ ["x2", r2(x2)],
179
+ ["y2", r2(y2)],
180
+ ["stroke", stroke],
181
+ ["stroke-width", w],
182
+ ["stroke-opacity", opacityAttr(opacity)]
183
+ ]);
145
184
  }
146
185
  function circle(cx, cy, r, fill, opacity) {
147
- const op = opacity !== void 0 && opacity < 1 ? ` fill-opacity="${Math.round(opacity * 1e3) / 1e3}"` : "";
148
- return `<circle cx="${r2(cx)}" cy="${r2(cy)}" r="${r}" fill="${fill}"${op}/>`;
186
+ return el("circle", [
187
+ ["cx", r2(cx)],
188
+ ["cy", r2(cy)],
189
+ ["r", r],
190
+ ["fill", fill],
191
+ ["fill-opacity", opacityAttr(opacity)]
192
+ ]);
149
193
  }
150
194
  function rect(x, y, w, h, fill) {
151
- return `<rect x="${r2(x)}" y="${r2(y)}" width="${r2(w)}" height="${r2(h)}" fill="${fill}"/>`;
195
+ return el("rect", [
196
+ ["x", r2(x)],
197
+ ["y", r2(y)],
198
+ ["width", r2(w)],
199
+ ["height", r2(h)],
200
+ ["fill", fill]
201
+ ]);
152
202
  }
153
203
  function polyline(pts, stroke, w = 2) {
154
- const p = pts.map(([x, y]) => `${r2(x)},${r2(y)}`).join(" ");
155
- return `<polyline points="${p}" fill="none" stroke="${stroke}" stroke-width="${w}"/>`;
204
+ return el("polyline", [
205
+ ["points", points(pts)],
206
+ ["fill", "none"],
207
+ ["stroke", stroke],
208
+ ["stroke-width", w]
209
+ ]);
156
210
  }
157
211
  function polygon(pts, fill, stroke = "none") {
158
- const p = pts.map(([x, y]) => `${r2(x)},${r2(y)}`).join(" ");
159
- return `<polygon points="${p}" fill="${fill}" stroke="${stroke}"/>`;
212
+ return el("polygon", [
213
+ ["points", points(pts)],
214
+ ["fill", fill],
215
+ ["stroke", stroke]
216
+ ]);
160
217
  }
161
- function text(x, y, s, fill, anchor = "start", size = 12) {
162
- return `<text x="${r2(x)}" y="${r2(y)}" text-anchor="${anchor}" font-family="system-ui,sans-serif" font-size="${size}" fill="${fill}">${esc(s)}</text>`;
218
+ function text(x, y, s, fill, anchor = "start", size = 12, transform) {
219
+ const pos = transform === void 0 ? [
220
+ ["x", r2(x)],
221
+ ["y", r2(y)]
222
+ ] : [["transform", transform]];
223
+ return el(
224
+ "text",
225
+ [
226
+ ...pos,
227
+ ["text-anchor", anchor],
228
+ ["font-family", "system-ui,sans-serif"],
229
+ ["font-size", size],
230
+ ["fill", fill]
231
+ ],
232
+ esc(s)
233
+ );
163
234
  }
164
235
  function primSVG(p) {
165
236
  switch (p.k) {
@@ -174,7 +245,15 @@ function primSVG(p) {
174
245
  case "polygon":
175
246
  return polygon(p.pts, p.fill, p.stroke);
176
247
  case "text":
177
- return p.rotate !== void 0 ? `<text transform="translate(${p.x},${p.y}) rotate(${p.rotate})" text-anchor="${p.anchor}" font-family="system-ui,sans-serif" font-size="${p.size}" fill="${p.fill}">${esc(p.s)}</text>` : text(p.x, p.y, p.s, p.fill, p.anchor, p.size);
248
+ return p.rotate !== void 0 ? text(
249
+ p.x,
250
+ p.y,
251
+ p.s,
252
+ p.fill,
253
+ p.anchor,
254
+ p.size,
255
+ `translate(${p.x},${p.y}) rotate(${p.rotate})`
256
+ ) : text(p.x, p.y, p.s, p.fill, p.anchor, p.size);
178
257
  }
179
258
  }
180
259
  function emitSVG(scene) {
@@ -342,6 +421,7 @@ function texEsc(s) {
342
421
  }
343
422
  });
344
423
  }
424
+ var TIKZ_COLOR_NAME = /^[A-Za-z][A-Za-z0-9!.]*$/;
345
425
  function tikzColor(c) {
346
426
  if (c === "none") return { color: "none", alpha: 1 };
347
427
  if (c.startsWith("#")) {
@@ -352,7 +432,7 @@ function tikzColor(c) {
352
432
  const alpha = h.length >= 8 ? Math.round(parseInt(h.slice(6, 8), 16) / 255 * 100) / 100 : 1;
353
433
  return { color: `{rgb,255:red,${r};green,${g};blue,${b}}`, alpha };
354
434
  }
355
- return { color: c, alpha: 1 };
435
+ return { color: TIKZ_COLOR_NAME.test(c) ? c : "black", alpha: 1 };
356
436
  }
357
437
  var round = (n) => Math.round(n * 100) / 100;
358
438
  var ANCHOR = {
@@ -736,18 +816,24 @@ function contour(z, opts = {}) {
736
816
  // src/three/project.ts
737
817
  function project(p, cam) {
738
818
  const az = cam.azim * Math.PI / 180;
739
- const el = cam.elev * Math.PI / 180;
819
+ const el2 = cam.elev * Math.PI / 180;
740
820
  const [x, y, z] = p;
741
821
  const xa = x * Math.cos(az) - y * Math.sin(az);
742
822
  const ya = x * Math.sin(az) + y * Math.cos(az);
743
823
  const sx = xa;
744
- const sy = z * Math.cos(el) - ya * Math.sin(el);
745
- const depth = z * Math.sin(el) + ya * Math.cos(el);
824
+ const sy = z * Math.cos(el2) - ya * Math.sin(el2);
825
+ const depth = z * Math.sin(el2) + ya * Math.cos(el2);
746
826
  return [sx, sy, depth];
747
827
  }
748
828
 
749
829
  // src/three/surface.ts
750
830
  var MARGIN3 = 40;
831
+ var DEPTH_EPS = 1e-9;
832
+ function compareDepth(a, b) {
833
+ const d = b.depth - a.depth;
834
+ if (Math.abs(d) > DEPTH_EPS) return d;
835
+ return a.index - b.index;
836
+ }
751
837
  function surface(z, opts = {}) {
752
838
  const width = opts.width ?? 520;
753
839
  const height = opts.height ?? 320;
@@ -826,10 +912,15 @@ function surface(z, opts = {}) {
826
912
  const corners = [proj[r][c], proj[r][c + 1], proj[r + 1][c + 1], proj[r + 1][c]];
827
913
  const depth = (corners[0][2] + corners[1][2] + corners[2][2] + corners[3][2]) / 4;
828
914
  const meanZ = (grid[r][c] + grid[r][c + 1] + grid[r + 1][c + 1] + grid[r + 1][c]) / 4;
829
- quads.push({ depth, pts: corners.map(toScreen), shade: (meanZ - zlo) / zspan });
915
+ quads.push({
916
+ depth,
917
+ index: quads.length,
918
+ pts: corners.map(toScreen),
919
+ shade: (meanZ - zlo) / zspan
920
+ });
830
921
  }
831
922
  }
832
- quads.sort((a, b) => b.depth - a.depth);
923
+ quads.sort(compareDepth);
833
924
  for (const q of quads)
834
925
  prims.push({ k: "polygon", pts: q.pts, fill: viridis(q.shade), stroke: theme.grid });
835
926
  }
@@ -1117,7 +1208,7 @@ function curve3d(x, y, z, opts = {}) {
1117
1208
  }
1118
1209
 
1119
1210
  // src/index.ts
1120
- var VERSION = "0.4.2";
1211
+ var VERSION = "0.4.4";
1121
1212
  export {
1122
1213
  VERSION,
1123
1214
  area,
@@ -0,0 +1,16 @@
1
+ import type { Layer2D, PlotOptions } from './types.js';
2
+ /** Public: line chart of one or many series. */
3
+ export declare function line(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
4
+ /** Public: scatter plot of one or many series. */
5
+ export declare function scatter(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
6
+ /** Public: bar chart of one or many series. */
7
+ export declare function bar(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
8
+ /** Public: filled area under one or many series. */
9
+ export declare function area(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
10
+ /** Public: step chart (horizontal-then-vertical) of one or many series. */
11
+ export declare function step(x: Layer2D['x'], y: Layer2D['y'], opts?: PlotOptions): string;
12
+ /** Public: vertical error bars (whisker + point) for one or many series. */
13
+ export declare function errorbar(x: Layer2D['x'], y: Layer2D['y'], yerr: Layer2D['yerr'], opts?: PlotOptions): string;
14
+ /** Public: 2-D vector field (arrows) of one or many series. */
15
+ export declare function quiver(x: Layer2D['x'], y: Layer2D['y'], u: Layer2D['u'], v: Layer2D['v'], opts?: PlotOptions): string;
16
+ //# sourceMappingURL=marks2d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marks2d.d.ts","sourceRoot":"","sources":["../src/marks2d.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvD,gDAAgD;AAChD,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAEjF;AAED,kDAAkD;AAClD,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAEpF;AAED,+CAA+C;AAC/C,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAEhF;AAED,oDAAoD;AACpD,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAEjF;AAED,2EAA2E;AAC3E,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAEjF;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CACtB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,EACrB,IAAI,CAAC,EAAE,WAAW,GACjB,MAAM,CAER;AAED,+DAA+D;AAC/D,wBAAgB,MAAM,CACpB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EACf,IAAI,CAAC,EAAE,WAAW,GACjB,MAAM,CAER"}
@@ -0,0 +1,4 @@
1
+ import type { Layer2D, PlotOptions } from './types.js';
2
+ /** Draw several 2-D layers (of any mix of types) on shared auto-scaled axes. */
3
+ export declare function overlay(layers: Layer2D[], opts?: PlotOptions): string;
4
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../src/overlay.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvD,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAErE"}
@@ -0,0 +1,3 @@
1
+ /** viridis colormap: t in [0,1] → "#rrggbb". */
2
+ export declare function viridis(t: number): string;
3
+ //# sourceMappingURL=palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../src/palette.ts"],"names":[],"mappings":"AAeA,gDAAgD;AAChD,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAWzC"}
package/dist/plot.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { PlotOptions } from './types.js';
2
+ /**
3
+ * Generic entry point. Data forms:
4
+ * plot(y, opts?) → line, x = 0..n-1
5
+ * plot(x, y, opts?) → line
6
+ * plot(layers[], opts?) → overlay
7
+ * plot(source, opts?) → expression sampling (line / contour / surface)
8
+ */
9
+ export declare function plot(a: unknown, b?: unknown, c?: PlotOptions): string;
10
+ /** Generic TikZ entry — same polymorphism as plot(), forced to the TikZ backend. */
11
+ export declare function toTikZ(a: unknown, b?: unknown, c?: PlotOptions): string;
12
+ //# sourceMappingURL=plot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plot.d.ts","sourceRoot":"","sources":["../src/plot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,YAAY,CAAC;AAuEvD;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAMrE;AAED,oFAAoF;AACpF,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAavE"}
@@ -0,0 +1,21 @@
1
+ import type { Theme } from './svg.js';
2
+ import type { Layer2D } from './types.js';
3
+ import type { Prim } from './scene.js';
4
+ /**
5
+ * Shared rendering context, computed once per `draw2D` call and threaded
6
+ * through every layer's renderer. Lives here (not `frame.ts` or `marks2d.ts`)
7
+ * so both of those modules can depend on it without depending on each other.
8
+ */
9
+ export interface Frame {
10
+ px: (x: number) => number;
11
+ py: (y: number) => number;
12
+ xdom: [number, number];
13
+ ydom: [number, number];
14
+ theme: Theme;
15
+ width: number;
16
+ height: number;
17
+ color: (i: number) => string;
18
+ }
19
+ /** Dispatch a layer to its renderer (extended in later tasks). */
20
+ export declare function renderLayer(layer: Layer2D, f: Frame, i: number): Prim[];
21
+ //# sourceMappingURL=render-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-core.d.ts","sourceRoot":"","sources":["../src/render-core.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1B,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC9B;AAuJD,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAmBvE"}
@@ -1,10 +1,11 @@
1
1
  /** Thrown when an external tool is missing or a conversion fails. Deliberate
2
2
  * exception to plot's never-throw rule: I/O and missing tools must surface. */
3
- declare class PlotRenderError extends Error {
3
+ export declare class PlotRenderError extends Error {
4
4
  readonly missingTool?: string | undefined;
5
5
  constructor(message: string, missingTool?: string | undefined);
6
6
  }
7
- interface RenderOptions {
7
+ /** Options for the file render bridge. `tool` selects one allowed external tool. `timeoutMs` limits each tool run (default 30 s for SVG conversion, 60 s for LaTeX). `density` and `background` apply only to PNG output from rsvg-convert. */
8
+ export interface RenderOptions {
8
9
  tool?: string;
9
10
  timeoutMs?: number;
10
11
  density?: number;
@@ -17,22 +18,22 @@ interface RunResult {
17
18
  }
18
19
  /** Spawn a command, feeding optional stdin, collecting stdout/stderr. Rejects
19
20
  * with PlotRenderError(ENOENT) if the binary is not found. */
20
- declare function runTool(cmd: string, args: string[], opts?: {
21
+ export declare function runTool(cmd: string, args: string[], opts?: {
21
22
  timeoutMs?: number;
22
23
  input?: string;
23
24
  }): Promise<RunResult>;
24
25
  /** True if `name` responds to a version probe (i.e. is on PATH). */
25
- declare function hasTool(name: string): Promise<boolean>;
26
+ export declare function hasTool(name: string): Promise<boolean>;
26
27
  /** SVG string → file. Extension of `outPath` selects the target: `.svg` writes
27
28
  * the SVG through; `.png`/`.pdf` convert via rsvg-convert (preferred) or resvg.
28
29
  * Rejects with PlotRenderError naming the tool to install if none is present. */
29
- declare function renderToFile(svg: string, outPath: string, opts?: RenderOptions): Promise<void>;
30
+ export declare function renderToFile(svg: string, outPath: string, opts?: RenderOptions): Promise<void>;
30
31
  /** Build the CLI args for a LaTeX engine. Shell-escape (\write18) is OFF
31
32
  * for security (arbitrary command execution during compile). */
32
- declare function latexArgs(engine: string, workDir: string, texPath: string): string[];
33
+ export declare function latexArgs(engine: string, workDir: string, texPath: string): string[];
33
34
  /** Standalone LaTeX/TikZ source → PDF via pdflatex (preferred) or tectonic.
34
35
  * Compiles in an OS temp dir and copies the resulting PDF to `outPath`.
35
36
  * Rejects with PlotRenderError naming the engine to install if none is found. */
36
- declare function latexToPdf(texSource: string, outPath: string, opts?: RenderOptions): Promise<void>;
37
-
38
- export { PlotRenderError, type RenderOptions, hasTool, latexArgs, latexToPdf, renderToFile, runTool };
37
+ export declare function latexToPdf(texSource: string, outPath: string, opts?: RenderOptions): Promise<void>;
38
+ export {};
39
+ //# sourceMappingURL=render-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-file.d.ts","sourceRoot":"","sources":["../src/render-file.ts"],"names":[],"mappings":"AAWA;gFACgF;AAChF,qBAAa,eAAgB,SAAQ,KAAK;IAGtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM;IAF/B,YACE,OAAO,EAAE,MAAM,EACN,WAAW,CAAC,EAAE,MAAM,YAAA,EAI9B;CACF;AAED,+OAA+O;AAC/O,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;+DAC+D;AAC/D,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC,SAAS,CAAC,CAuBpB;AAED,oEAAoE;AACpE,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO5D;AAED;;kFAEkF;AAClF,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CA2Df;AAED;iEACiE;AACjE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAcpF;AAED;;kFAEkF;AAClF,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,IAAI,CAAC,CAwCf"}
@@ -0,0 +1,9 @@
1
+ /** [min, max] of a numeric array; a degenerate (flat) range is padded by ±1. */
2
+ export declare function extent(xs: readonly number[]): [number, number];
3
+ /** Linear map from data domain to pixel range. */
4
+ export declare function linearScale(dom: [number, number], range: [number, number]): (v: number) => number;
5
+ /** Log10 map; the domain is clamped to strictly-positive. */
6
+ export declare function logScale(dom: [number, number], range: [number, number]): (v: number) => number;
7
+ /** "Nice" round tick values covering [min,max] (Wilkinson-lite: 1/2/5 × 10^k step). */
8
+ export declare function niceTicks(min: number, max: number, count?: number): number[];
9
+ //# sourceMappingURL=scale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../src/scale.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wBAAgB,MAAM,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAU9D;AAED,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAKjG;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAM9F;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAWvE"}
@@ -0,0 +1,52 @@
1
+ /** Backend-agnostic drawing primitives. Marks build these; a backend serializes them. */
2
+ export type Prim = {
3
+ k: 'line';
4
+ x1: number;
5
+ y1: number;
6
+ x2: number;
7
+ y2: number;
8
+ stroke: string;
9
+ w: number;
10
+ opacity?: number;
11
+ } | {
12
+ k: 'circle';
13
+ cx: number;
14
+ cy: number;
15
+ r: number;
16
+ fill: string;
17
+ opacity?: number;
18
+ } | {
19
+ k: 'rect';
20
+ x: number;
21
+ y: number;
22
+ w: number;
23
+ h: number;
24
+ fill: string;
25
+ } | {
26
+ k: 'polyline';
27
+ pts: Array<[number, number]>;
28
+ stroke: string;
29
+ w: number;
30
+ } | {
31
+ k: 'polygon';
32
+ pts: Array<[number, number]>;
33
+ fill: string;
34
+ stroke: string;
35
+ } | {
36
+ k: 'text';
37
+ x: number;
38
+ y: number;
39
+ s: string;
40
+ fill: string;
41
+ anchor: 'start' | 'middle' | 'end';
42
+ size: number;
43
+ rotate?: number;
44
+ };
45
+ /** A complete drawable: canvas size, background, and an ordered list of primitives. */
46
+ export interface Scene {
47
+ width: number;
48
+ height: number;
49
+ bg: string;
50
+ prims: Prim[];
51
+ }
52
+ //# sourceMappingURL=scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,MAAM,IAAI,GACZ;IACE,CAAC,EAAE,MAAM,CAAC;IACV,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClF;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,CAAC,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,CAAC,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5E;IACE,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN,uFAAuF;AACvF,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,IAAI,EAAE,CAAC;CACf"}
package/dist/svg.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import type { Scene } from './scene.js';
2
+ /** Color scheme for SVG chart output: foreground, muted, grid, axis and background colors, and an ordered list of data-series colors. */
3
+ export interface Theme {
4
+ fg: string;
5
+ muted: string;
6
+ grid: string;
7
+ axis: string;
8
+ bg: string;
9
+ series: string[];
10
+ }
11
+ export declare const THEMES: Record<'light' | 'dark', Theme>;
12
+ /** Replace `&`, `<` and `>` in a string with their XML entities. Quote characters stay unchanged, so use the result as element text only. Attribute values go through `escAttr`. */
13
+ export declare function esc(s: string): string;
14
+ /** Format a number as a tick label. A non-finite value gives an empty string. A non-zero value with magnitude below 1e-3 or at or above 1e6 uses exponential notation with two decimals. Other values are rounded to six decimal places. */
15
+ export declare function fmt(n: number): string;
16
+ /** Escape a value for use inside a quoted XML attribute. Replaces `&`, `<`, `>`, `"` and `'` with entities. A number is converted with `String` first, so a value typed `number` but passed as a string at run time cannot end the attribute. */
17
+ export declare function escAttr(v: string | number): string;
18
+ /** Wrap SVG body markup in a complete `<svg>` document of the given size, with a full-size background rectangle and the `img` ARIA role. Every attribute value is escaped with `escAttr`. */
19
+ export declare function svgDoc(width: number, height: number, body: string, bg: string): string;
20
+ /** Make an SVG `<line>` element between two points. Coordinates are rounded to two decimals. The `stroke-opacity` attribute is added only when the opacity is below 1. Every attribute value is escaped with `escAttr`. */
21
+ export declare function line(x1: number, y1: number, x2: number, y2: number, stroke: string, w?: number, opacity?: number): string;
22
+ /** Make an SVG `<circle>` element. The `fill-opacity` attribute is added only when the opacity is below 1. Every attribute value is escaped with `escAttr`. */
23
+ export declare function circle(cx: number, cy: number, r: number, fill: string, opacity?: number): string;
24
+ /** Make a filled SVG `<rect>` element. Position and size are rounded to two decimals. Every attribute value is escaped with `escAttr`. */
25
+ export declare function rect(x: number, y: number, w: number, h: number, fill: string): string;
26
+ /** Make an SVG `<polyline>` element with no fill from a list of [x, y] points. Every attribute value is escaped with `escAttr`. */
27
+ export declare function polyline(pts: Array<[number, number]>, stroke: string, w?: number): string;
28
+ /** Make an SVG `<polygon>` element from a list of [x, y] vertices. The stroke is `none` by default. Every attribute value is escaped with `escAttr`. */
29
+ export declare function polygon(pts: Array<[number, number]>, fill: string, stroke?: string): string;
30
+ /** Make an SVG `<text>` element. The text content is escaped with `esc`, and every attribute value with `escAttr`. When `transform` is given it replaces the `x`/`y` attributes. */
31
+ export declare function text(x: number, y: number, s: string, fill: string, anchor?: string, size?: number, transform?: string): string;
32
+ /** Serialize a Scene to a self-contained SVG string (reuses the exported builders). */
33
+ export declare function emitSVG(scene: Scene): string;
34
+ //# sourceMappingURL=svg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../src/svg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,YAAY,CAAC;AAE9C,yIAAyI;AACzI,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAaD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,KAAK,CAiBlD,CAAC;AAEF,oLAAoL;AACpL,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAErC;AAED,4OAA4O;AAC5O,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAKrC;AAYD,iPAAiP;AACjP,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAElD;AAwBD,6LAA6L;AAC7L,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAiBtF;AAED,2NAA2N;AAC3N,wBAAgB,IAAI,CAClB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,CAAC,SAAI,EACL,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,CAUR;AACD,+JAA+J;AAC/J,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAQhG;AACD,0IAA0I;AAC1I,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQrF;AACD,mIAAmI;AACnI,wBAAgB,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,SAAI,GAAG,MAAM,CAOpF;AACD,wJAAwJ;AACxJ,wBAAgB,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAS,GAAG,MAAM,CAM3F;AACD,oLAAoL;AACpL,wBAAgB,IAAI,CAClB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,EACZ,MAAM,SAAU,EAChB,IAAI,SAAK,EACT,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAmBR;AA+BD,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAE5C"}
@@ -0,0 +1,11 @@
1
+ import type { PlotOptions } from '../types.js';
2
+ interface P3Opts extends PlotOptions {
3
+ azim?: number;
4
+ elev?: number;
5
+ }
6
+ /** 3-D scatter of (x,y,z) point triples, projected to 2-D SVG. */
7
+ export declare function scatter3d(x: unknown, y: unknown, z: unknown, opts?: P3Opts): string;
8
+ /** Parametric 3-D curve through (x,y,z) coordinate arrays. */
9
+ export declare function curve3d(x: unknown, y: unknown, z: unknown, opts?: P3Opts): string;
10
+ export {};
11
+ //# sourceMappingURL=points3d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"points3d.d.ts","sourceRoot":"","sources":["../../src/three/points3d.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,UAAU,MAAO,SAAQ,WAAW;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA8HD,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,GAAE,MAAW,GAAG,MAAM,CAEvF;AACD,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,GAAE,MAAW,GAAG,MAAM,CAErF"}
@@ -0,0 +1,12 @@
1
+ /** View direction for the orthographic projection. Both angles are in degrees. */
2
+ export interface Camera {
3
+ azim: number;
4
+ elev: number;
5
+ }
6
+ /**
7
+ * Orthographic projection of a 3-D point to screen [x, y, depth].
8
+ * Convention (azim=0, elev=0): world +x → screen +x, world +z → screen +y,
9
+ * world +y → into the screen (depth). Depth increases away from the viewer.
10
+ */
11
+ export declare function project(p: [number, number, number], cam: Camera): [number, number, number];
12
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/three/project.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAY1F"}
@@ -0,0 +1,28 @@
1
+ import type { PlotOptions } from '../types.js';
2
+ /**
3
+ * Depth tolerance for the painter's sort. Every vertex is normalised into the cube
4
+ * [-1, 1]^3 before projection, so |depth| <= sqrt(3) whatever the input data scale.
5
+ * Float rounding in the projection and the 4-corner mean moves a depth by a few ulp
6
+ * (~1e-16 at this scale); a real geometric difference between two quads of any grid
7
+ * up to 10^6 cells per side is >= ~1e-6. 1e-9 sits many orders of magnitude from both.
8
+ */
9
+ export declare const DEPTH_EPS = 1e-9;
10
+ /**
11
+ * Painter's-order comparator: far (large depth) first. Depths within {@link DEPTH_EPS}
12
+ * are a tie, and a tie falls back to the face index (lower index first), so the order
13
+ * never depends on the last bit of a float (which differs between runtimes' Math.sin).
14
+ */
15
+ export declare function compareDepth(a: {
16
+ depth: number;
17
+ index: number;
18
+ }, b: {
19
+ depth: number;
20
+ index: number;
21
+ }): number;
22
+ /** 3-D surface z[row][col], projected to 2-D SVG. Painter's algorithm for `filled`. */
23
+ export declare function surface(z: unknown, opts?: Omit<PlotOptions, 'kind'> & {
24
+ azim?: number;
25
+ elev?: number;
26
+ kind?: 'wireframe' | 'filled';
27
+ }): string;
28
+ //# sourceMappingURL=surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/three/surface.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,OAAO,CAAC;AAE9B;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACnC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC,MAAM,CAIR;AAED,uFAAuF;AACvF,wBAAgB,OAAO,CACrB,CAAC,EAAE,OAAO,EACV,IAAI,GAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CAC1B,GACL,MAAM,CAiHR"}
package/dist/tikz.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { Scene } from './scene.js';
2
+ import type { PlotOptions } from './types.js';
3
+ /** Escape the LaTeX specials that break a plain \node body. Single-pass so an
4
+ * escape's own backslash/braces are never re-processed. */
5
+ export declare function texEsc(s: string): string;
6
+ /** Serialize a Scene to TikZ. Coordinates match the SVG (y-flipped for TikZ's y-up), scaled. */
7
+ export declare function emitTikZ(scene: Scene, opts?: PlotOptions): string;
8
+ //# sourceMappingURL=tikz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tikz.d.ts","sourceRoot":"","sources":["../src/tikz.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;2DAC2D;AAC3D,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAaxC;AAsED,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CAYrE"}
@@ -0,0 +1,42 @@
1
+ /** Anything the plotter accepts as a data series: numbers, typed arrays, or core values. */
2
+ export type Data = unknown;
3
+ /** A 2-D coordinate axis. */
4
+ export interface AxisSpec {
5
+ label?: string;
6
+ scale?: 'linear' | 'log';
7
+ }
8
+ /** Options shared by all plot functions (each uses the subset it needs). */
9
+ export interface PlotOptions {
10
+ title?: string;
11
+ xLabel?: string;
12
+ yLabel?: string;
13
+ x?: AxisSpec;
14
+ y?: AxisSpec;
15
+ width?: number;
16
+ height?: number;
17
+ theme?: 'light' | 'dark';
18
+ palette?: readonly string[];
19
+ legend?: boolean;
20
+ from?: number;
21
+ to?: number;
22
+ samples?: number;
23
+ kind?: '2d' | '3d' | 'surface';
24
+ scope?: Record<string, unknown>;
25
+ format?: 'svg' | 'tikz';
26
+ tikz?: {
27
+ standalone?: boolean;
28
+ scale?: number;
29
+ };
30
+ }
31
+ /** One drawable 2-D layer for the shared draw2D core / overlay. */
32
+ export interface Layer2D {
33
+ type: 'line' | 'scatter' | 'bar' | 'area' | 'step' | 'errorbar' | 'quiver';
34
+ x?: Data;
35
+ y: Data;
36
+ yerr?: Data;
37
+ u?: Data;
38
+ v?: Data;
39
+ label?: string;
40
+ color?: string;
41
+ }
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,MAAM,IAAI,GAAG,OAAO,CAAC;AAE3B,6BAA6B;AAC7B,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;CAC1B;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,CAAC,EAAE,QAAQ,CAAC;IACb,CAAC,CAAC,EAAE,QAAQ,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD;AAED,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC3E,CAAC,CAAC,EAAE,IAAI,CAAC;IACT,CAAC,EAAE,IAAI,CAAC;IACR,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,CAAC,CAAC,EAAE,IAAI,CAAC;IACT,CAAC,CAAC,EAAE,IAAI,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielsimonjr/mathts-plot",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Headless SVG 2D/3D plotting for MathTS — dependency-light, expression-aware, built on core/functions/expression",
5
5
  "author": "Daniel Simon Jr.",
6
6
  "license": "MIT",
@@ -23,26 +23,27 @@
23
23
  "README.md"
24
24
  ],
25
25
  "scripts": {
26
- "build": "tsup",
26
+ "build": "tsup && tsc -p tsconfig.dts.json",
27
27
  "dev": "tsup --watch",
28
- "test": "vitest run",
28
+ "test": "bun test --isolate --timeout 30000",
29
29
  "test:watch": "vitest",
30
- "test:coverage": "vitest run --coverage",
30
+ "test:coverage": "bun test --isolate --timeout 30000 --coverage",
31
31
  "typecheck": "tsc --noEmit",
32
- "lint": "eslint src --ext .ts",
33
- "lint:fix": "eslint src --ext .ts --fix",
32
+ "lint": "oxlint src",
33
+ "lint:fix": "oxlint src --fix",
34
34
  "clean": "rm -rf dist"
35
35
  },
36
36
  "dependencies": {
37
- "@danielsimonjr/mathts-core": "^0.14.1",
38
- "@danielsimonjr/mathts-functions": "^0.64.0",
39
- "@danielsimonjr/mathts-expression": "^0.7.1"
37
+ "@danielsimonjr/mathts-core": "^0.15.0",
38
+ "@danielsimonjr/mathts-functions": "^0.64.1",
39
+ "@danielsimonjr/mathts-expression": "^0.8.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@types/node": "^26.2.0",
42
+ "@types/node": "^26.4.0",
43
+ "@xmldom/xmldom": "^0.9.12",
43
44
  "tsup": "^8.0.0",
44
- "typescript": "^5.3.0",
45
- "vitest": "^4.1.10"
45
+ "typescript": "^7.0.2",
46
+ "vitest": "^5.0.0"
46
47
  },
47
48
  "publishConfig": {
48
49
  "access": "public"