@compstats/core 0.2.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/LICENSE +21 -0
  3. package/README.md +310 -0
  4. package/dist/3d.d.ts +33 -0
  5. package/dist/3d.d.ts.map +1 -0
  6. package/dist/3d.js +1984 -0
  7. package/dist/3d.js.map +22 -0
  8. package/dist/core/arith.d.ts +133 -0
  9. package/dist/core/arith.d.ts.map +1 -0
  10. package/dist/core/frame.d.ts +98 -0
  11. package/dist/core/frame.d.ts.map +1 -0
  12. package/dist/core/histogram.d.ts +68 -0
  13. package/dist/core/histogram.d.ts.map +1 -0
  14. package/dist/core/kde.d.ts +106 -0
  15. package/dist/core/kde.d.ts.map +1 -0
  16. package/dist/core/logit.d.ts +109 -0
  17. package/dist/core/logit.d.ts.map +1 -0
  18. package/dist/core/matrix.d.ts +135 -0
  19. package/dist/core/matrix.d.ts.map +1 -0
  20. package/dist/core/moderation.d.ts +127 -0
  21. package/dist/core/moderation.d.ts.map +1 -0
  22. package/dist/core/ols.d.ts +76 -0
  23. package/dist/core/ols.d.ts.map +1 -0
  24. package/dist/core/pca.d.ts +99 -0
  25. package/dist/core/pca.d.ts.map +1 -0
  26. package/dist/core/precision.d.ts +10 -0
  27. package/dist/core/precision.d.ts.map +1 -0
  28. package/dist/core/pretty.d.ts +51 -0
  29. package/dist/core/pretty.d.ts.map +1 -0
  30. package/dist/core/regression.d.ts +68 -0
  31. package/dist/core/regression.d.ts.map +1 -0
  32. package/dist/core/rng.d.ts +206 -0
  33. package/dist/core/rng.d.ts.map +1 -0
  34. package/dist/core/sampling.d.ts +157 -0
  35. package/dist/core/sampling.d.ts.map +1 -0
  36. package/dist/core/special.d.ts +92 -0
  37. package/dist/core/special.d.ts.map +1 -0
  38. package/dist/core/tdist.d.ts +53 -0
  39. package/dist/core/tdist.d.ts.map +1 -0
  40. package/dist/core/ttest.d.ts +146 -0
  41. package/dist/core/ttest.d.ts.map +1 -0
  42. package/dist/data/moderationData.d.ts +40 -0
  43. package/dist/data/moderationData.d.ts.map +1 -0
  44. package/dist/data/pcaDegenerate.d.ts +18 -0
  45. package/dist/data/pcaDegenerate.d.ts.map +1 -0
  46. package/dist/index.d.ts +66 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +4195 -0
  49. package/dist/index.js.map +47 -0
  50. package/dist/interactive/controls.d.ts +97 -0
  51. package/dist/interactive/controls.d.ts.map +1 -0
  52. package/dist/interactive/logit.d.ts +57 -0
  53. package/dist/interactive/logit.d.ts.map +1 -0
  54. package/dist/interactive/matrixInverse.d.ts +86 -0
  55. package/dist/interactive/matrixInverse.d.ts.map +1 -0
  56. package/dist/interactive/moderation3d.d.ts +103 -0
  57. package/dist/interactive/moderation3d.d.ts.map +1 -0
  58. package/dist/interactive/pca.d.ts +90 -0
  59. package/dist/interactive/pca.d.ts.map +1 -0
  60. package/dist/interactive/regression.d.ts +57 -0
  61. package/dist/interactive/regression.d.ts.map +1 -0
  62. package/dist/interactive/sampling.d.ts +78 -0
  63. package/dist/interactive/sampling.d.ts.map +1 -0
  64. package/dist/interactive/scatter3d.d.ts +124 -0
  65. package/dist/interactive/scatter3d.d.ts.map +1 -0
  66. package/dist/interactive/tTest.d.ts +69 -0
  67. package/dist/interactive/tTest.d.ts.map +1 -0
  68. package/dist/interactive/target.d.ts +132 -0
  69. package/dist/interactive/target.d.ts.map +1 -0
  70. package/dist/plot/axes.d.ts +128 -0
  71. package/dist/plot/axes.d.ts.map +1 -0
  72. package/dist/plot/draw.d.ts +46 -0
  73. package/dist/plot/draw.d.ts.map +1 -0
  74. package/dist/plot/format.d.ts +33 -0
  75. package/dist/plot/format.d.ts.map +1 -0
  76. package/dist/plot/logit.d.ts +68 -0
  77. package/dist/plot/logit.d.ts.map +1 -0
  78. package/dist/plot/matrixInverse.d.ts +62 -0
  79. package/dist/plot/matrixInverse.d.ts.map +1 -0
  80. package/dist/plot/moderation3d.d.ts +135 -0
  81. package/dist/plot/moderation3d.d.ts.map +1 -0
  82. package/dist/plot/pca.d.ts +79 -0
  83. package/dist/plot/pca.d.ts.map +1 -0
  84. package/dist/plot/plotly.d.ts +209 -0
  85. package/dist/plot/plotly.d.ts.map +1 -0
  86. package/dist/plot/regression.d.ts +52 -0
  87. package/dist/plot/regression.d.ts.map +1 -0
  88. package/dist/plot/sampleCi.d.ts +82 -0
  89. package/dist/plot/sampleCi.d.ts.map +1 -0
  90. package/dist/plot/sampling.d.ts +159 -0
  91. package/dist/plot/sampling.d.ts.map +1 -0
  92. package/dist/plot/scatter3d.d.ts +164 -0
  93. package/dist/plot/scatter3d.d.ts.map +1 -0
  94. package/dist/plot/tTest.d.ts +49 -0
  95. package/dist/plot/tTest.d.ts.map +1 -0
  96. package/dist/plot/target.d.ts +55 -0
  97. package/dist/plot/target.d.ts.map +1 -0
  98. package/package.json +71 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * The three-panel sampling demonstration: a population, the samples drawn
3
+ * from it, and how their statistic scatters.
4
+ *
5
+ * This is the drawing half of `plot_sampling()` in
6
+ * `../compstatslib/R/sampling_plot.R`. The panels, top to bottom:
7
+ *
8
+ * 1. the population's density, dotted;
9
+ * 2. this draw's samples — each sample's own density in translucent gray,
10
+ * with the density of all of them pooled drawn over the top;
11
+ * 3. a histogram of every statistic drawn so far, this call and all before it.
12
+ *
13
+ * All three share one horizontal window, frozen on the first call at the range
14
+ * of the population. Later calls keep it however wide the population passed to
15
+ * them happens to be, which is what lets the picture stay still while the
16
+ * statistics pile up. A bar or a curve outside that window is clipped.
17
+ *
18
+ * **The state is the caller's.** R returns a `vars` list and its gadget hands
19
+ * it back on the next call, which is how the window stays frozen and the
20
+ * statistics accumulate. Nothing is kept here between calls: `plotSampling`
21
+ * takes the state it was given, returns the state it made, and the caller —
22
+ * `interactiveSampling`, or a demo page — holds it in between. That is the
23
+ * port plan's rule against hidden accumulation.
24
+ *
25
+ * **`replot_population` is not ported.** R declares and documents it, and
26
+ * `interactive_sampling()` passes `FALSE` for it, but `plot_sampling()`'s body
27
+ * never reads it: the population panel is always redrawn. Porting a parameter
28
+ * that does nothing would carry the defect forward as if it were a feature.
29
+ */
30
+ import type { Histogram } from "../core/histogram";
31
+ import type { Rng } from "../core/rng";
32
+ import type { Extent, Scale } from "./axes";
33
+ import type { PlotTarget } from "./target";
34
+ /** Which of the three stacked panels a scale belongs to. */
35
+ export type SamplingPanel = "population" | "samples" | "statistic";
36
+ /**
37
+ * What one draw hands to the next.
38
+ *
39
+ * This is R's `vars` list, less the entries that are arguments anyway: R keeps
40
+ * the population, the sample size and the statistic in there as well, and this
41
+ * port takes all three afresh on every call, so holding them twice would let
42
+ * the two copies disagree.
43
+ */
44
+ export interface SamplingState {
45
+ /** The left edge of the frozen window. R's `xmin`. */
46
+ readonly xMin: number;
47
+ /** The right edge of the frozen window. R's `xmax`. */
48
+ readonly xMax: number;
49
+ /** Every statistic drawn so far, oldest first. R's `sample_theta`. */
50
+ readonly sampleTheta: readonly number[];
51
+ }
52
+ /** What to draw. The interactive layer forwards these untouched. */
53
+ export interface PlotSamplingOptions {
54
+ /**
55
+ * How many values in each sample. R's `sample_size`.
56
+ *
57
+ * R's `plot_sampling()` has no default here and fails without one; its
58
+ * gadget defaults to 10. This port takes the gadget's default so that
59
+ * `plotSampling(target, population)` draws something, which is the
60
+ * no-argument-works property the port plan asks bundled demos to keep.
61
+ */
62
+ readonly sampleSize?: number;
63
+ /** How many samples this draw takes. R's `reps`, 1 by default. */
64
+ readonly reps?: number;
65
+ /** The statistic to take from each sample. R's `theta`, the mean. */
66
+ readonly theta?: (sample: readonly number[]) => number;
67
+ /**
68
+ * Where the randomness comes from.
69
+ *
70
+ * R reads one global stream, so its repeated draws carry on where the last
71
+ * left off. A caller who draws more than once must pass one generator and
72
+ * keep passing it — the default builds a new one per call, and two calls
73
+ * that each build their own would each start from the beginning.
74
+ *
75
+ * The default is seeded from `Math.random()`, so a demo that says nothing
76
+ * about seeds still gets a different draw each time, as an R session does.
77
+ * Only the seed comes from there: pass `seededRng(42)` and every draw down
78
+ * that stream repeats exactly.
79
+ */
80
+ readonly rng?: Rng;
81
+ /**
82
+ * What the last call returned, or nothing on the first call.
83
+ *
84
+ * R's `vars` argument, which its gadget caches. This is what freezes the
85
+ * window and accumulates the statistics.
86
+ */
87
+ readonly state?: SamplingState | null;
88
+ /**
89
+ * Where every density curve puts its grid.
90
+ *
91
+ * `"data"`, the default, is R: each `density()` call spreads its 512 grid
92
+ * points over the range of the values it was given. That is right while the
93
+ * values and the window are of one size.
94
+ *
95
+ * `"frozen"` spreads them over the drawn window instead, through R's own
96
+ * `from` and `to` arguments. A population that reaches far outside the
97
+ * window needs this: at 512 points over a range a thousand times the window,
98
+ * one grid step is wider than the whole panel, and the curve draws as a
99
+ * straight line. The samples take the frozen grid as well, for the same
100
+ * reason and so that every curve in the picture is comparable.
101
+ */
102
+ readonly densityWindow?: "data" | "frozen";
103
+ }
104
+ /** Everything this draw produced, for the caller to hold and to read. */
105
+ export interface PlotSamplingResult {
106
+ /** The state to hand back on the next call. */
107
+ readonly state: SamplingState;
108
+ /** The samples this call drew, in draw order. */
109
+ readonly samples: readonly (readonly number[])[];
110
+ /** The statistic of each of those samples. */
111
+ readonly thetas: readonly number[];
112
+ /**
113
+ * The histogram the third panel drew, or null when there was nothing to
114
+ * count. Handed back so a caller need not bin the statistics again.
115
+ *
116
+ * It counts the statistics inside the window, not the whole pile. The panel
117
+ * clips a bar outside the window anyway, and a statistic it cannot draw must
118
+ * not set the width of the cells either — see `plotSampling`.
119
+ */
120
+ readonly histogram: Histogram | null;
121
+ }
122
+ /**
123
+ * Build the scale for one panel.
124
+ *
125
+ * The three panels are stacked in equal bands and share the window, so the
126
+ * same world x lands in the same pixel column in each. The interactive layer
127
+ * and any demo read their geometry from here rather than restating it.
128
+ *
129
+ * @param width The pixel width of the surface.
130
+ * @param height The pixel height of the surface.
131
+ * @param panel Which band to build.
132
+ * @param window The frozen horizontal window, shared by all three.
133
+ * @param yMax The tallest value the panel has to show. Zero is always the
134
+ * foot of the panel, as it is for a density and for a count.
135
+ * @returns The map between world values and pixels for that panel.
136
+ */
137
+ export declare function samplingScale(width: number, height: number, panel: SamplingPanel, window: Extent, yMax: number): Scale;
138
+ /**
139
+ * Draw one round of sampling, and hand back what the next round needs.
140
+ *
141
+ * A population of fewer than two values has no density, and R's `density()`
142
+ * stops there. A library cannot stop: this draws the three panels and their
143
+ * axes with nothing in them, takes no samples, and returns a state with the
144
+ * window set and no statistics. The same holds for the samples themselves —
145
+ * a sample of one value gets no curve of its own, though it still counts
146
+ * toward the pooled one and toward the histogram.
147
+ *
148
+ * @param target A canvas, or a context and a size. See `./target.ts`.
149
+ * @param population The values to sample from.
150
+ * @param options The sample size, the repetitions, the statistic, the
151
+ * generator, and the state of the last call.
152
+ * @returns This draw's samples and statistics, the histogram drawn from the
153
+ * accumulated statistics, and the state to pass back next time.
154
+ * @throws RangeError If the sample size is larger than the population, or if
155
+ * a count is negative or fractional — both from `drawSamples`, which is
156
+ * where R's own refusals live.
157
+ */
158
+ export declare function plotSampling(target: PlotTarget, population: readonly number[], options?: PlotSamplingOptions): PlotSamplingResult;
159
+ //# sourceMappingURL=sampling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampling.d.ts","sourceRoot":"","sources":["../../src/plot/sampling.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAOnD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG5C,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;IACvD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5C;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;IACjD,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CACtC;AA0CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,KAAK,CAiBP;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAiEpB"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * The 3D scatterplot: three numeric columns as a cloud of points, with an
3
+ * optional fourth column driving the color.
4
+ *
5
+ * This is `plot_scatter3d()` of `../compstatslib/R/scatter3d_plot.R`, drawn
6
+ * through Plotly as the R original is. The trace and the layout follow the
7
+ * object R actually builds, dumped in `.claude/plans/moderation-fixtures.md`
8
+ * section 5.
9
+ *
10
+ * Four things are worth knowing before reading the code.
11
+ *
12
+ * **The work is the specification.** `scatter3dSpec` builds the traces and the
13
+ * layout and touches nothing outside itself. `plotScatter3d` resolves the
14
+ * engine and draws that specification. The split keeps every rule of the port
15
+ * testable without a browser, and it gives the interactive layer a cheap way
16
+ * to ask what a set of options would draw.
17
+ *
18
+ * **Nothing is drawn until everything is checked.** R validates the style,
19
+ * then the axis arguments, then the columns, and only then calls Plotly. That
20
+ * order was confirmed by tracing `plot_ly()`: every error fires with the
21
+ * engine untouched. This module keeps the order and the wording, and the tests
22
+ * count the calls to prove it.
23
+ *
24
+ * **The default axes are the first three numeric columns, in frame order.**
25
+ * With the bundled `moderation_data` that is `y, x, z`, so the plot's own x
26
+ * axis is titled "y". The collision is confusing, and it is R's, so the port
27
+ * keeps it. A note names the chosen and the skipped columns, as R's
28
+ * `message()` does; a library cannot write to a console, so the note is
29
+ * returned and the caller decides whether to show it.
30
+ *
31
+ * **Color is the one place the port must invent.** R hands the color column
32
+ * to plotly-R, which decides by itself what a numeric or a categorical column
33
+ * means. Plotly.js decides nothing: the caller must build the traces. So a
34
+ * numeric column becomes one trace carrying a value per point with a color
35
+ * bar beside it, and a categorical column becomes one trace per level, named,
36
+ * listed in the legend, and colored from Plotly's own sequence. The rule
37
+ * follows what plotly-R does; the exact colors are Plotly's choice, in both
38
+ * languages.
39
+ */
40
+ import type { DataFrame } from "../core/frame";
41
+ import type { PlotlyCamera, PlotlyHTMLElement, PlotlyLayout, PlotlyLike, Scatter3dTrace } from "./plotly";
42
+ /** How the markers are drawn, apart from the data. */
43
+ export interface Scatter3dStyle {
44
+ /** The x, y and z proportions of the box the points sit in. */
45
+ readonly aspect: readonly number[];
46
+ /** How solid each marker is, in (0, 1]. */
47
+ readonly opacity: number;
48
+ /** How large each marker is, in pixels. */
49
+ readonly size: number;
50
+ }
51
+ /**
52
+ * R's own defaults: `aspect = c(1, 1, 1), opacity = 0.8, size = 5`.
53
+ *
54
+ * `interactive_scatter3d()` repeats these three numbers in its own signature.
55
+ * The port states them once, here, so the gadget's sliders and the plot they
56
+ * drive cannot start from different places.
57
+ */
58
+ export declare const DEFAULT_SCATTER3D_STYLE: Scatter3dStyle;
59
+ /** Titles to write on the axes instead of the column names. */
60
+ export interface Scatter3dTitles {
61
+ readonly x?: string;
62
+ readonly y?: string;
63
+ readonly z?: string;
64
+ }
65
+ /** What to draw, and how. Every option is R's, with R's default. */
66
+ export interface Scatter3dSpecOptions {
67
+ /** The column on the first horizontal axis. */
68
+ readonly x?: string;
69
+ /** The column on the second horizontal axis. */
70
+ readonly y?: string;
71
+ /** The column on the vertical axis. */
72
+ readonly z?: string;
73
+ /**
74
+ * Any column to map to color. A numeric column gives a continuous scale
75
+ * with a color bar; a text or true-or-false column gives one trace per
76
+ * level, with a legend.
77
+ */
78
+ readonly color?: string;
79
+ /**
80
+ * The x, y and z proportions of the box the points sit in: three positive
81
+ * numbers, `[1, 1, 1]` by default.
82
+ */
83
+ readonly aspect?: readonly number[];
84
+ /** How solid each marker is, in (0, 1]. */
85
+ readonly opacity?: number;
86
+ /** How large each marker is, in pixels. */
87
+ readonly size?: number;
88
+ /**
89
+ * Where the camera starts. Absent by default, which leaves Plotly's own
90
+ * view. Pass a camera to reopen a plot at an angle captured earlier.
91
+ */
92
+ readonly camera?: PlotlyCamera;
93
+ /** Axis titles. Each axis falls back to the name of its column. */
94
+ readonly titles?: Scatter3dTitles;
95
+ }
96
+ /** The options of `plotScatter3d`: the specification, and the engine. */
97
+ export interface PlotScatter3dOptions extends Scatter3dSpecOptions {
98
+ /**
99
+ * The Plotly engine. `loadPlotly()` by default, which fetches the library on
100
+ * first use. Pass your own to draw through a copy you already hold, or to
101
+ * record what would be drawn.
102
+ */
103
+ readonly plotly?: PlotlyLike;
104
+ }
105
+ /** What a set of options draws. */
106
+ export interface Scatter3dSpec {
107
+ /** One trace, or one for each level of a categorical color column. */
108
+ readonly traces: readonly Scatter3dTrace[];
109
+ readonly layout: PlotlyLayout;
110
+ /**
111
+ * What R says in its `message()`: which columns were chosen, and which were
112
+ * skipped. Null when the caller named every axis, or when no numeric column
113
+ * was left over.
114
+ */
115
+ readonly note: string | null;
116
+ }
117
+ /** A drawn scatterplot: its specification, its element, and its engine. */
118
+ export interface Scatter3dHandle extends Scatter3dSpec {
119
+ /**
120
+ * The element Plotly drew into. Plotly returns it with an event emitter
121
+ * attached, which is how the interactive layer hears about rotation.
122
+ */
123
+ readonly element: PlotlyHTMLElement;
124
+ /** The engine that drew, ready for the next redraw and for teardown. */
125
+ readonly plotly: PlotlyLike;
126
+ }
127
+ /**
128
+ * Build the traces and the layout of a 3D scatterplot.
129
+ *
130
+ * @param data The frame to read.
131
+ * @param options Which columns to draw, and how.
132
+ * @returns The traces, the layout, and the note about the column choice.
133
+ * @throws RangeError If the style is out of range, if the frame is ragged, if
134
+ * fewer than three numeric columns are available, or if a named column is
135
+ * absent or, on an axis, not numeric.
136
+ */
137
+ export declare function scatter3dSpec(data: DataFrame, options?: Scatter3dSpecOptions): Scatter3dSpec;
138
+ /**
139
+ * Draw a 3D scatterplot.
140
+ *
141
+ * @param target The element to draw into. Plotly fills it.
142
+ * @param data The frame to read.
143
+ * @param options Which columns to draw, how, and through which engine.
144
+ * @returns The drawn plot: its element, its specification, and its engine.
145
+ * @throws RangeError Everything `scatter3dSpec` throws, as a rejected promise.
146
+ * No option reaches the engine until every check has passed.
147
+ */
148
+ export declare function plotScatter3d(target: HTMLElement, data: DataFrame, options?: PlotScatter3dOptions): Promise<Scatter3dHandle>;
149
+ /**
150
+ * R's `scatter3d_validate_style()`, less the checks the compiler makes.
151
+ *
152
+ * Exported because R shares this check between the plot and the gadget, and
153
+ * the gadget runs it before it builds anything. Note what it does **not** do:
154
+ * it refuses a style no plot could be drawn with, and says nothing about the
155
+ * bounds of the gadget's sliders. An aspect of 12 passes here and is then
156
+ * clamped by the slider, which is R's behavior exactly.
157
+ *
158
+ * @param aspect The three axis proportions.
159
+ * @param opacity How solid a marker is.
160
+ * @param size How large a marker is.
161
+ * @throws RangeError With R's own wording, in R's own order.
162
+ */
163
+ export declare function validateScatter3dStyle(aspect: readonly number[], opacity: number, size: number): void;
164
+ //# sourceMappingURL=scatter3d.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter3d.d.ts","sourceRoot":"","sources":["../../src/plot/scatter3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH,OAAO,KAAK,EAAU,SAAS,EAAE,MAAM,eAAe,CAAC;AAEvD,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,UAAU,EAEV,cAAc,EACf,MAAM,UAAU,CAAC;AAelB,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAIrC,CAAC;AAEF,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;CAC9B;AAED,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,2EAA2E;AAC3E,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAkDf;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,SAAS,EACf,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,eAAe,CAAC,CAO1B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,IAAI,CAeN"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * The t-test plot: two distributions, the regions they decide between, and an
3
+ * optional matrix of the four outcomes.
4
+ *
5
+ * This is the drawing half of `plot_t_test()` in
6
+ * `../compstatslib/R/t_statistic_plot.R`, whose work is spread across
7
+ * `t_null_plot()`, `t_alt_lines()`, `plott()`, `plotdist()`, and
8
+ * `plot_error_matrix()`. Every number comes from `tTestStats` in
9
+ * `src/core/ttest.ts` and every curve height from `dt` in
10
+ * `src/core/tdist.ts`; this module computes no statistics of its own.
11
+ */
12
+ import type { TTestOptions, TTestStats } from "../core/ttest";
13
+ import type { Scale } from "./axes";
14
+ import type { PlotTarget } from "./target";
15
+ /**
16
+ * What to draw. The four test parameters pass straight through to
17
+ * `tTestStats`, which is the pass-through R does with its own arguments.
18
+ */
19
+ export interface PlotTTestOptions extends TTestOptions {
20
+ /** Show the matrix of the four outcomes. False by default, as in R. */
21
+ readonly errorMatrix?: boolean;
22
+ }
23
+ /**
24
+ * Build the scale that `plotTTest` draws through.
25
+ *
26
+ * The x window is R's fixed `c(-6, 6)`. The y window follows R's default,
27
+ * which is the range of the plotted density widened by four percent at each
28
+ * end, except that showing the error matrix raises the top enough to hold it.
29
+ * R leaves the window alone there and lets the matrix fall outside the plot
30
+ * region, where base graphics clip it away: at one degree of freedom the null
31
+ * curve only reaches 0.32 and the top row of cells is cut off. Growing the
32
+ * window instead keeps the panel whole.
33
+ *
34
+ * @param width The pixel width of the surface.
35
+ * @param height The pixel height of the surface.
36
+ * @param options The same options `plotTTest` takes.
37
+ * @returns The map between world values and pixels.
38
+ */
39
+ export declare function tTestScale(width: number, height: number, options?: PlotTTestOptions): Scale;
40
+ /**
41
+ * Draw the null and alternative distributions of a t test.
42
+ *
43
+ * @param target A canvas, or a context and a size. See `./target.ts`.
44
+ * @param options The test parameters, and whether to show the error matrix.
45
+ * @returns The statistics behind the picture. R returns these invisibly from
46
+ * `t_alt_lines()`; a browser caller wants them, so they come back here.
47
+ */
48
+ export declare function plotTTest(target: PlotTarget, options?: PlotTTestOptions): TTestStats;
49
+ //# sourceMappingURL=tTest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tTest.d.ts","sourceRoot":"","sources":["../../src/plot/tTest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,KAAK,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAI5C,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAiED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,KAAK,CAGP;AAuBD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,gBAAqB,GAC7B,UAAU,CAwBZ"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The drawing surface that every 2D plot writes to.
3
+ *
4
+ * R's base graphics draw to a current device. Nothing here does: a plot
5
+ * function receives its target and draws only to that target.
6
+ *
7
+ * `Context2D` lists the exact members of `CanvasRenderingContext2D` that this
8
+ * library uses. A real context satisfies the type, and a test can pass any
9
+ * object that implements those members. This matters because happy-dom has no
10
+ * 2D canvas context, so a DOM alone cannot exercise a plot function. See
11
+ * `test/recording-context.ts` for the stub the plot tests use.
12
+ */
13
+ /** The part of a canvas 2D context that the plot functions draw through. */
14
+ export type Context2D = Pick<CanvasRenderingContext2D, "fillStyle" | "strokeStyle" | "lineWidth" | "font" | "textAlign" | "textBaseline" | "save" | "restore" | "beginPath" | "moveTo" | "lineTo" | "arc" | "rect" | "fillRect" | "clip" | "fill" | "stroke" | "fillText" | "setLineDash" | "translate" | "rotate">;
15
+ /** A context together with the pixel size of its surface. */
16
+ export interface RenderTarget {
17
+ readonly ctx: Context2D;
18
+ readonly width: number;
19
+ readonly height: number;
20
+ }
21
+ /**
22
+ * What a plot function accepts.
23
+ *
24
+ * Pass a canvas in a browser. Pass a `RenderTarget` to draw through your own
25
+ * context, which is how the tests run without a DOM.
26
+ */
27
+ export type PlotTarget = HTMLCanvasElement | RenderTarget;
28
+ /**
29
+ * Reduce a plot target to a context and a size.
30
+ *
31
+ * A canvas reports the size of its pixel store, which is the size the plot
32
+ * draws in. On a dense screen those two part company: the store has to hold
33
+ * more pixels than the layout does, or the browser stretches the image and
34
+ * softens every edge.
35
+ *
36
+ * This function never touches a canvas the caller passed in — the caller owns
37
+ * it, and resizing it under them would throw away whatever else they drew. So
38
+ * a caller who wants a crisp picture on such a screen does three things:
39
+ *
40
+ * 1. size the store at the layout size times `devicePixelRatio`, and set the
41
+ * CSS width and height to the layout size;
42
+ * 2. call `ctx.scale(ratio, ratio)` once, so drawing carries on in layout
43
+ * pixels;
44
+ * 3. pass `{ ctx, width, height }` with the **layout** size, rather than the
45
+ * canvas.
46
+ *
47
+ * The third step matters. Handing over the canvas would report the store size
48
+ * on top of a context that already scales, and the picture would come out at
49
+ * the square of the ratio. Reporting layout pixels also keeps `eventPixel`
50
+ * right, since it divides the surface size by the size of the client
51
+ * rectangle. `resolveControlTarget` in `../interactive/target.ts` does all
52
+ * three for the canvas it builds itself.
53
+ */
54
+ export declare function resolveTarget(target: PlotTarget): RenderTarget;
55
+ //# sourceMappingURL=target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/plot/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,wBAAwB,EACtB,WAAW,GACX,aAAa,GACb,WAAW,GACX,MAAM,GACN,WAAW,GACX,cAAc,GACd,MAAM,GACN,SAAS,GACT,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,QAAQ,GACR,UAAU,GACV,aAAa,GACb,WAAW,GACX,QAAQ,CACX,CAAC;AAEF,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAY9D"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@compstats/core",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "Interactive 2D and 3D visualization of data and statistical concepts, in the browser.",
6
+ "license": "MIT",
7
+ "author": "Soumya Ray <soumya.ray@gmail.com>",
8
+ "contributors": [
9
+ "Daniele Melotti <danielemelotti@hotmail.com>"
10
+ ],
11
+ "keywords": [
12
+ "statistics",
13
+ "visualization",
14
+ "interactive",
15
+ "canvas",
16
+ "plotly",
17
+ "regression",
18
+ "logistic-regression",
19
+ "pca",
20
+ "moderation",
21
+ "sampling-distribution",
22
+ "confidence-interval",
23
+ "t-test",
24
+ "teaching",
25
+ "browser"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/compstatslib/compstatslib-ts.git"
30
+ },
31
+ "homepage": "https://github.com/compstatslib/compstatslib-ts",
32
+ "bugs": {
33
+ "url": "https://github.com/compstatslib/compstatslib-ts/issues"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "CHANGELOG.md"
38
+ ],
39
+ "main": "./dist/index.js",
40
+ "module": "./dist/index.js",
41
+ "types": "./dist/index.d.ts",
42
+ "exports": {
43
+ ".": {
44
+ "types": "./dist/index.d.ts",
45
+ "import": "./dist/index.js",
46
+ "default": "./dist/index.js"
47
+ },
48
+ "./3d": {
49
+ "types": "./dist/3d.d.ts",
50
+ "import": "./dist/3d.js",
51
+ "default": "./dist/3d.js"
52
+ },
53
+ "./package.json": "./package.json"
54
+ },
55
+ "scripts": {
56
+ "build": "bun build src/index.ts src/3d.ts --outdir dist --target browser --format esm --sourcemap=linked --external plotly.js-dist-min && bunx tsc -p tsconfig.build.json",
57
+ "typecheck": "bunx tsc --noEmit",
58
+ "test": "bun test",
59
+ "dev": "bun run demo/server.ts",
60
+ "prepublishOnly": "bun test && bun run typecheck && bun run build"
61
+ },
62
+ "devDependencies": {
63
+ "@happy-dom/global-registrator": "^20.0.0",
64
+ "@types/bun": "^1.3.0",
65
+ "happy-dom": "^20.0.0",
66
+ "typescript": "^5.9.0"
67
+ },
68
+ "dependencies": {
69
+ "plotly.js-dist-min": "^3.7.0"
70
+ }
71
+ }