@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.
- package/CHANGELOG.md +110 -0
- package/LICENSE +21 -0
- package/README.md +310 -0
- package/dist/3d.d.ts +33 -0
- package/dist/3d.d.ts.map +1 -0
- package/dist/3d.js +1984 -0
- package/dist/3d.js.map +22 -0
- package/dist/core/arith.d.ts +133 -0
- package/dist/core/arith.d.ts.map +1 -0
- package/dist/core/frame.d.ts +98 -0
- package/dist/core/frame.d.ts.map +1 -0
- package/dist/core/histogram.d.ts +68 -0
- package/dist/core/histogram.d.ts.map +1 -0
- package/dist/core/kde.d.ts +106 -0
- package/dist/core/kde.d.ts.map +1 -0
- package/dist/core/logit.d.ts +109 -0
- package/dist/core/logit.d.ts.map +1 -0
- package/dist/core/matrix.d.ts +135 -0
- package/dist/core/matrix.d.ts.map +1 -0
- package/dist/core/moderation.d.ts +127 -0
- package/dist/core/moderation.d.ts.map +1 -0
- package/dist/core/ols.d.ts +76 -0
- package/dist/core/ols.d.ts.map +1 -0
- package/dist/core/pca.d.ts +99 -0
- package/dist/core/pca.d.ts.map +1 -0
- package/dist/core/precision.d.ts +10 -0
- package/dist/core/precision.d.ts.map +1 -0
- package/dist/core/pretty.d.ts +51 -0
- package/dist/core/pretty.d.ts.map +1 -0
- package/dist/core/regression.d.ts +68 -0
- package/dist/core/regression.d.ts.map +1 -0
- package/dist/core/rng.d.ts +206 -0
- package/dist/core/rng.d.ts.map +1 -0
- package/dist/core/sampling.d.ts +157 -0
- package/dist/core/sampling.d.ts.map +1 -0
- package/dist/core/special.d.ts +92 -0
- package/dist/core/special.d.ts.map +1 -0
- package/dist/core/tdist.d.ts +53 -0
- package/dist/core/tdist.d.ts.map +1 -0
- package/dist/core/ttest.d.ts +146 -0
- package/dist/core/ttest.d.ts.map +1 -0
- package/dist/data/moderationData.d.ts +40 -0
- package/dist/data/moderationData.d.ts.map +1 -0
- package/dist/data/pcaDegenerate.d.ts +18 -0
- package/dist/data/pcaDegenerate.d.ts.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4195 -0
- package/dist/index.js.map +47 -0
- package/dist/interactive/controls.d.ts +97 -0
- package/dist/interactive/controls.d.ts.map +1 -0
- package/dist/interactive/logit.d.ts +57 -0
- package/dist/interactive/logit.d.ts.map +1 -0
- package/dist/interactive/matrixInverse.d.ts +86 -0
- package/dist/interactive/matrixInverse.d.ts.map +1 -0
- package/dist/interactive/moderation3d.d.ts +103 -0
- package/dist/interactive/moderation3d.d.ts.map +1 -0
- package/dist/interactive/pca.d.ts +90 -0
- package/dist/interactive/pca.d.ts.map +1 -0
- package/dist/interactive/regression.d.ts +57 -0
- package/dist/interactive/regression.d.ts.map +1 -0
- package/dist/interactive/sampling.d.ts +78 -0
- package/dist/interactive/sampling.d.ts.map +1 -0
- package/dist/interactive/scatter3d.d.ts +124 -0
- package/dist/interactive/scatter3d.d.ts.map +1 -0
- package/dist/interactive/tTest.d.ts +69 -0
- package/dist/interactive/tTest.d.ts.map +1 -0
- package/dist/interactive/target.d.ts +132 -0
- package/dist/interactive/target.d.ts.map +1 -0
- package/dist/plot/axes.d.ts +128 -0
- package/dist/plot/axes.d.ts.map +1 -0
- package/dist/plot/draw.d.ts +46 -0
- package/dist/plot/draw.d.ts.map +1 -0
- package/dist/plot/format.d.ts +33 -0
- package/dist/plot/format.d.ts.map +1 -0
- package/dist/plot/logit.d.ts +68 -0
- package/dist/plot/logit.d.ts.map +1 -0
- package/dist/plot/matrixInverse.d.ts +62 -0
- package/dist/plot/matrixInverse.d.ts.map +1 -0
- package/dist/plot/moderation3d.d.ts +135 -0
- package/dist/plot/moderation3d.d.ts.map +1 -0
- package/dist/plot/pca.d.ts +79 -0
- package/dist/plot/pca.d.ts.map +1 -0
- package/dist/plot/plotly.d.ts +209 -0
- package/dist/plot/plotly.d.ts.map +1 -0
- package/dist/plot/regression.d.ts +52 -0
- package/dist/plot/regression.d.ts.map +1 -0
- package/dist/plot/sampleCi.d.ts +82 -0
- package/dist/plot/sampleCi.d.ts.map +1 -0
- package/dist/plot/sampling.d.ts +159 -0
- package/dist/plot/sampling.d.ts.map +1 -0
- package/dist/plot/scatter3d.d.ts +164 -0
- package/dist/plot/scatter3d.d.ts.map +1 -0
- package/dist/plot/tTest.d.ts +49 -0
- package/dist/plot/tTest.d.ts.map +1 -0
- package/dist/plot/target.d.ts +55 -0
- package/dist/plot/target.d.ts.map +1 -0
- 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
|
+
}
|