@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,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interactive 3D scatterplot: choose the columns, set the style, turn the
|
|
3
|
+
* cloud, and take the resulting call away with you.
|
|
4
|
+
*
|
|
5
|
+
* This is the port of `interactive_scatter3d()` in
|
|
6
|
+
* `../compstatslib/R/scatter3d_interactive.R`. R builds a shiny gadget with
|
|
7
|
+
* four pickers and five sliders and re-runs `plot_scatter3d()` on every
|
|
8
|
+
* change. This module does the same: it owns the controls, the state in them,
|
|
9
|
+
* and the camera the user turned to, and hands every draw to `plotScatter3d`.
|
|
10
|
+
* It builds no trace and no layout of its own.
|
|
11
|
+
*
|
|
12
|
+
* Four things are worth knowing before reading the code.
|
|
13
|
+
*
|
|
14
|
+
* **Everything is checked before anything is built.** R validates the style,
|
|
15
|
+
* then the axis arguments, then the frame, and only then opens the gadget, so
|
|
16
|
+
* a bad argument leaves no window and no plot. The order and the wording here
|
|
17
|
+
* are R's, and the style check is R's own function, imported from the plot
|
|
18
|
+
* layer rather than written again.
|
|
19
|
+
*
|
|
20
|
+
* **Out of range is not the same as invalid.** R's check refuses a style no
|
|
21
|
+
* plot could be drawn with — an opacity of 0, a negative aspect — and says
|
|
22
|
+
* nothing about the bounds of its own sliders. `aspect = 12` passes it, and
|
|
23
|
+
* the widget then clamps the handle to 10. So this component throws exactly
|
|
24
|
+
* where R throws, and clamps and snaps where R's widget clamps.
|
|
25
|
+
*
|
|
26
|
+
* **The camera is captured, not computed.** Plotly reports where the user
|
|
27
|
+
* turned the plot to through `plotly_relayout`; the component stores that
|
|
28
|
+
* camera and re-passes it into every later draw, so that changing a column
|
|
29
|
+
* does not throw the angle away. Turning the plot draws nothing: Plotly has
|
|
30
|
+
* already moved the picture. The captured camera is also written back into
|
|
31
|
+
* Plotly's own stored layout, because the modebar's buttons relayout the
|
|
32
|
+
* scene from that layout and would otherwise snap the view to the default —
|
|
33
|
+
* a Plotly quirk the R gadget shares, and one deliberate deviation here.
|
|
34
|
+
*
|
|
35
|
+
* **Done hands back a state, not a printed call.** R prints a copy-pasteable
|
|
36
|
+
* `plot_scatter3d(...)` line to the console and returns the same arguments
|
|
37
|
+
* invisibly. A library has no console, and a string would have to be parsed
|
|
38
|
+
* to be used again; so `getValues()` returns the options object that
|
|
39
|
+
* reproduces the picture, and `onDone` receives it. Feeding it back to
|
|
40
|
+
* `plotScatter3d` — or to this function — is R's `do.call` equivalent.
|
|
41
|
+
*
|
|
42
|
+
* One R behavior is absent for R's own reason: the gadget shows no message
|
|
43
|
+
* about the column choice. `plot_scatter3d()` writes one when it picks the
|
|
44
|
+
* columns itself, and neither gadget lets it: R passes `input$x`, `input$y`
|
|
45
|
+
* and `input$z` on every render, as this component passes its own state. The
|
|
46
|
+
* choice is visible in the pickers instead.
|
|
47
|
+
*/
|
|
48
|
+
import type { DataFrame } from "../core/frame";
|
|
49
|
+
import type { PlotScatter3dOptions, Scatter3dSpec, Scatter3dSpecOptions } from "../plot/scatter3d";
|
|
50
|
+
import type { Plot3dTarget } from "./target";
|
|
51
|
+
/**
|
|
52
|
+
* Everything the panel holds, and everything that reproduces the picture.
|
|
53
|
+
*
|
|
54
|
+
* This is `Scatter3dSpecOptions` with the parts the gadget always settles —
|
|
55
|
+
* the three axes and the three style numbers — made certain. Hand it to
|
|
56
|
+
* `plotScatter3d`, or back to `interactiveScatter3d`, to open at the same
|
|
57
|
+
* view. It is the port's answer to the call R prints on Done.
|
|
58
|
+
*/
|
|
59
|
+
export interface Scatter3dValues extends Scatter3dSpecOptions {
|
|
60
|
+
/** The column on the first horizontal axis. */
|
|
61
|
+
readonly x: string;
|
|
62
|
+
/** The column on the second horizontal axis. */
|
|
63
|
+
readonly y: string;
|
|
64
|
+
/** The column on the vertical axis. */
|
|
65
|
+
readonly z: string;
|
|
66
|
+
/** The three axis proportions. */
|
|
67
|
+
readonly aspect: readonly number[];
|
|
68
|
+
/** How solid each marker is. */
|
|
69
|
+
readonly opacity: number;
|
|
70
|
+
/** How large each marker is. */
|
|
71
|
+
readonly size: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* What the component accepts.
|
|
75
|
+
*
|
|
76
|
+
* Every option of `plotScatter3d` is a starting value, exactly as in R, and
|
|
77
|
+
* anything the plot grows later reaches it untouched.
|
|
78
|
+
*/
|
|
79
|
+
export interface InteractiveScatter3dOptions extends PlotScatter3dOptions {
|
|
80
|
+
/** What to run on `done()`. */
|
|
81
|
+
readonly onDone?: (values: Scatter3dValues) => void;
|
|
82
|
+
}
|
|
83
|
+
/** What the caller holds after the component starts. */
|
|
84
|
+
export interface InteractiveScatter3dHandle {
|
|
85
|
+
/**
|
|
86
|
+
* Return the state the panel stands at: the options that reproduce the
|
|
87
|
+
* picture, including a camera the user turned to.
|
|
88
|
+
*/
|
|
89
|
+
getValues(): Scatter3dValues;
|
|
90
|
+
/**
|
|
91
|
+
* Return what the last draw specified — its traces, its layout, and the
|
|
92
|
+
* plot layer's note. Null until the first picture is drawn.
|
|
93
|
+
*/
|
|
94
|
+
getSpec(): Scatter3dSpec | null;
|
|
95
|
+
/**
|
|
96
|
+
* Wait for the drawing now in flight. Drawing is asynchronous, so this is
|
|
97
|
+
* how a caller — or a test — knows the picture is on the screen.
|
|
98
|
+
*/
|
|
99
|
+
rendered(): Promise<void>;
|
|
100
|
+
/** Hand the current state to the `onDone` callback. */
|
|
101
|
+
done(): void;
|
|
102
|
+
/** Stop listening, purge the plot, and take back what was built. */
|
|
103
|
+
destroy(): void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Start an interactive 3D scatterplot on a target.
|
|
107
|
+
*
|
|
108
|
+
* The component builds its controls, draws once, and redraws on every change.
|
|
109
|
+
*
|
|
110
|
+
* @param target A container element, or a plot element and a controls host.
|
|
111
|
+
* See `./target.ts`.
|
|
112
|
+
* @param data The frame to read. It needs three numeric columns.
|
|
113
|
+
* @param options Starting values, a done callback, and the options of
|
|
114
|
+
* `plotScatter3d`.
|
|
115
|
+
* @returns The handle to the running component. Await `rendered()` for the
|
|
116
|
+
* first picture.
|
|
117
|
+
* @throws RangeError If the style is one no plot could be drawn with, if the
|
|
118
|
+
* frame has fewer than three numeric columns, or if an initial column is
|
|
119
|
+
* not one the picker could stand on. Nothing is built and nothing is drawn
|
|
120
|
+
* in any of those cases.
|
|
121
|
+
* @throws Error If a canvas is passed as the container.
|
|
122
|
+
*/
|
|
123
|
+
export declare function interactiveScatter3d(target: Plot3dTarget, data: DataFrame, options?: InteractiveScatter3dOptions): InteractiveScatter3dHandle;
|
|
124
|
+
//# sourceMappingURL=scatter3d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scatter3d.d.ts","sourceRoot":"","sources":["../../src/interactive/scatter3d.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM/C,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAe3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;;;GAOG;AACH,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D,+CAA+C;IAC/C,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;CACrD;AAED,wDAAwD;AACxD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,SAAS,IAAI,eAAe,CAAC;IAC7B;;;OAGG;IACH,OAAO,IAAI,aAAa,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,uDAAuD;IACvD,IAAI,IAAI,IAAI,CAAC;IACb,oEAAoE;IACpE,OAAO,IAAI,IAAI,CAAC;CACjB;AAmBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,SAAS,EACf,OAAO,GAAE,2BAAgC,GACxC,0BAA0B,CAoT5B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interactive t test: move the sliders and watch the power change.
|
|
3
|
+
*
|
|
4
|
+
* This is the port of `interactive_t_test()` in
|
|
5
|
+
* `../compstatslib/R/t_statistic_interactive.R`. R builds a miniUI gadget with
|
|
6
|
+
* four sliders and a checkbox, and re-runs `plot_t_test()` whenever one moves.
|
|
7
|
+
* This module does the same: it owns the controls and the values in them, and
|
|
8
|
+
* hands every draw to `plotTTest`. It contains no drawing code and no
|
|
9
|
+
* statistics.
|
|
10
|
+
*
|
|
11
|
+
* R's `runGadget()` blocks until "Done" and then returns nothing at all —
|
|
12
|
+
* `stopApp(NULL)`. Nothing blocks in a browser, so this returns a handle at
|
|
13
|
+
* once. `getValues()` reads the controls and `getStats()` reads what was last
|
|
14
|
+
* drawn. `done()` reports the current values to the `onDone` callback: R hands
|
|
15
|
+
* back nothing, but a callback with no argument would only send the caller
|
|
16
|
+
* back to the handle for the values it just asked about.
|
|
17
|
+
*/
|
|
18
|
+
import type { TTestStats } from "../core/ttest";
|
|
19
|
+
import type { PlotTTestOptions } from "../plot/tTest";
|
|
20
|
+
import type { ControlTarget } from "./target";
|
|
21
|
+
/** Everything the panel of controls holds. */
|
|
22
|
+
export interface TTestValues {
|
|
23
|
+
/** The difference the alternative hypothesis claims. */
|
|
24
|
+
readonly diff: number;
|
|
25
|
+
/** The population standard deviation. */
|
|
26
|
+
readonly sd: number;
|
|
27
|
+
/** The sample size. */
|
|
28
|
+
readonly n: number;
|
|
29
|
+
/** The significance level. */
|
|
30
|
+
readonly alpha: number;
|
|
31
|
+
/** Whether the matrix of the four outcomes is showing. */
|
|
32
|
+
readonly errorMatrix: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* What the component accepts.
|
|
36
|
+
*
|
|
37
|
+
* The options of `plotTTest` pass through to it, and the four test parameters
|
|
38
|
+
* double as the starting positions of the sliders. This is the equivalent of
|
|
39
|
+
* R's `...` forwarding.
|
|
40
|
+
*/
|
|
41
|
+
export interface InteractiveTTestOptions extends PlotTTestOptions {
|
|
42
|
+
/** What to run on `done()`. */
|
|
43
|
+
readonly onDone?: (values: TTestValues) => void;
|
|
44
|
+
}
|
|
45
|
+
/** What the caller holds after the component starts. */
|
|
46
|
+
export interface InteractiveTTestHandle {
|
|
47
|
+
/** Return where the controls stand now. */
|
|
48
|
+
getValues(): TTestValues;
|
|
49
|
+
/** Return the statistics behind the last picture drawn. */
|
|
50
|
+
getStats(): TTestStats;
|
|
51
|
+
/** Hand the current values to the `onDone` callback. */
|
|
52
|
+
done(): void;
|
|
53
|
+
/** Stop listening and take back the controls that were built. */
|
|
54
|
+
destroy(): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Start an interactive t test on a target.
|
|
58
|
+
*
|
|
59
|
+
* The component builds its controls, draws once, and redraws on every change.
|
|
60
|
+
*
|
|
61
|
+
* @param target A container element, or a surface and a controls host. See
|
|
62
|
+
* `./target.ts`.
|
|
63
|
+
* @param options Starting values, a done callback, and the options of
|
|
64
|
+
* `plotTTest`.
|
|
65
|
+
* @returns The handle to the running component.
|
|
66
|
+
* @throws Error If a canvas gives no 2D context.
|
|
67
|
+
*/
|
|
68
|
+
export declare function interactiveTTest(target: ControlTarget, options?: InteractiveTTestOptions): InteractiveTTestHandle;
|
|
69
|
+
//# sourceMappingURL=tTest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tTest.d.ts","sourceRoot":"","sources":["../../src/interactive/tTest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACjD;AAED,wDAAwD;AACxD,MAAM,WAAW,sBAAsB;IACrC,2CAA2C;IAC3C,SAAS,IAAI,WAAW,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,IAAI,UAAU,CAAC;IACvB,wDAAwD;IACxD,IAAI,IAAI,IAAI,CAAC;IACb,iEAAiE;IACjE,OAAO,IAAI,IAAI,CAAC;CACjB;AA6BD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CAyGxB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The target that every interactive component attaches to.
|
|
3
|
+
*
|
|
4
|
+
* An interactive component needs two things: a surface to draw on and an
|
|
5
|
+
* element that reports the clicks. A canvas is both, so a browser caller
|
|
6
|
+
* passes one canvas.
|
|
7
|
+
*
|
|
8
|
+
* A test cannot pass a canvas. happy-dom gives a canvas no 2D context, so
|
|
9
|
+
* nothing can draw to it. A test therefore passes the two things apart: a
|
|
10
|
+
* recording surface to draw to, and a real element to dispatch events at. This
|
|
11
|
+
* split is the pattern for every module in `src/interactive/`.
|
|
12
|
+
*/
|
|
13
|
+
import type { RenderTarget } from "../plot/target";
|
|
14
|
+
/** The part of an element that an interactive component listens to. */
|
|
15
|
+
export type ClickSource = Pick<HTMLElement, "addEventListener" | "removeEventListener" | "getBoundingClientRect">;
|
|
16
|
+
/** A surface and an element, held apart. */
|
|
17
|
+
export interface SplitTarget {
|
|
18
|
+
/** Where the component draws. */
|
|
19
|
+
readonly surface: RenderTarget;
|
|
20
|
+
/** Where the component listens. */
|
|
21
|
+
readonly element: ClickSource;
|
|
22
|
+
}
|
|
23
|
+
/** What an interactive component accepts. */
|
|
24
|
+
export type InteractiveTarget = HTMLCanvasElement | SplitTarget;
|
|
25
|
+
/**
|
|
26
|
+
* Reduce an interactive target to a surface and an element.
|
|
27
|
+
*
|
|
28
|
+
* @param target A canvas, or a surface and an element.
|
|
29
|
+
* @returns The two parts.
|
|
30
|
+
* @throws Error If a canvas gives no 2D context.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveInteractiveTarget(target: InteractiveTarget): SplitTarget;
|
|
33
|
+
/**
|
|
34
|
+
* Convert the position of a mouse event to a pixel of the surface.
|
|
35
|
+
*
|
|
36
|
+
* CSS may show a canvas at a size other than its pixel size. The function
|
|
37
|
+
* therefore scales the position by the ratio of the two. A rectangle of zero
|
|
38
|
+
* width or height carries no ratio, so the function reads the client position
|
|
39
|
+
* as a surface pixel. Only a hidden element and a stub report such a
|
|
40
|
+
* rectangle.
|
|
41
|
+
*
|
|
42
|
+
* @param element The element that received the event.
|
|
43
|
+
* @param surface The drawing surface and its pixel size.
|
|
44
|
+
* @param event The mouse event.
|
|
45
|
+
* @returns The pixel column and row of the event.
|
|
46
|
+
*/
|
|
47
|
+
export declare function eventPixel(element: ClickSource, surface: RenderTarget, event: MouseEvent): {
|
|
48
|
+
readonly x: number;
|
|
49
|
+
readonly y: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* A drawing surface and an element to build controls in, held apart.
|
|
53
|
+
*
|
|
54
|
+
* This is the `SplitTarget` idea again, for a component driven by a panel of
|
|
55
|
+
* controls rather than by clicks on the picture. A test passes the two parts,
|
|
56
|
+
* so it can drive the inputs without a real layout and without a canvas that
|
|
57
|
+
* happy-dom cannot give a context to.
|
|
58
|
+
*/
|
|
59
|
+
export interface PanelTarget {
|
|
60
|
+
/** Where the component draws. */
|
|
61
|
+
readonly surface: RenderTarget;
|
|
62
|
+
/** Where the component builds its inputs. The caller keeps this element. */
|
|
63
|
+
readonly controls: HTMLElement;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* What a control-driven component accepts.
|
|
67
|
+
*
|
|
68
|
+
* Pass a container element in a browser and the component fills it. Pass a
|
|
69
|
+
* `PanelTarget` to hold the two parts apart, which is how the tests run.
|
|
70
|
+
*/
|
|
71
|
+
export type ControlTarget = HTMLElement | PanelTarget;
|
|
72
|
+
/** A resolved panel, and a way to take back anything that was built for it. */
|
|
73
|
+
export interface ResolvedPanel {
|
|
74
|
+
readonly surface: RenderTarget;
|
|
75
|
+
readonly controls: HTMLElement;
|
|
76
|
+
/** Remove what this resolver created. A no-op when the caller supplied it. */
|
|
77
|
+
release(): void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reduce a control target to a surface and a place to build controls.
|
|
81
|
+
*
|
|
82
|
+
* Given a container, this builds the canvas and the controls column inside it
|
|
83
|
+
* in R's arrangement, and `release()` takes them out again. Given the parts,
|
|
84
|
+
* it passes them through and `release()` does nothing, because the caller owns
|
|
85
|
+
* what it supplied.
|
|
86
|
+
*
|
|
87
|
+
* @param target A container element, or a surface and a controls host.
|
|
88
|
+
* @returns The two parts and a way to undo what was built.
|
|
89
|
+
* @throws Error If a container is a canvas, or if a created canvas gives no 2D
|
|
90
|
+
* context.
|
|
91
|
+
*/
|
|
92
|
+
export declare function resolveControlTarget(target: ControlTarget): ResolvedPanel;
|
|
93
|
+
/**
|
|
94
|
+
* An element for Plotly to fill, and an element to build controls in.
|
|
95
|
+
*
|
|
96
|
+
* The third target shape of the port, after `SplitTarget` and `PanelTarget`.
|
|
97
|
+
* The 3D components need it because Plotly draws into an element of its own
|
|
98
|
+
* rather than onto a canvas: there is no context to hand around, and the
|
|
99
|
+
* element the plot lives in is the element the engine later purges.
|
|
100
|
+
*/
|
|
101
|
+
export interface Plot3dPanel {
|
|
102
|
+
/** Where Plotly draws. The component gives this element to the plot. */
|
|
103
|
+
readonly plot: HTMLElement;
|
|
104
|
+
/** Where the component builds its inputs. */
|
|
105
|
+
readonly controls: HTMLElement;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* What a 3D component accepts.
|
|
109
|
+
*
|
|
110
|
+
* Pass a container element in a browser and the component fills it. Pass the
|
|
111
|
+
* two parts to hold them apart, which is how the tests run.
|
|
112
|
+
*/
|
|
113
|
+
export type Plot3dTarget = HTMLElement | Plot3dPanel;
|
|
114
|
+
/** A resolved 3D panel, and a way to take back anything built for it. */
|
|
115
|
+
export interface ResolvedPlot3dPanel extends Plot3dPanel {
|
|
116
|
+
/** Remove what this resolver created. A no-op when the caller supplied it. */
|
|
117
|
+
release(): void;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Reduce a 3D target to a plot element and a place to build controls.
|
|
121
|
+
*
|
|
122
|
+
* Given a container, this builds the two elements in R's own arrangement: a
|
|
123
|
+
* strip of controls across the top, and the plot filling what is left. R's
|
|
124
|
+
* gadget lays both 3D families out that way (`flex-direction: column`, the
|
|
125
|
+
* control rows `flex-shrink: 0`, the plot `flex: 1`).
|
|
126
|
+
*
|
|
127
|
+
* @param target A container element, or the two parts.
|
|
128
|
+
* @returns The two parts and a way to undo what was built.
|
|
129
|
+
* @throws Error If a container is a canvas, which Plotly cannot draw into.
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolvePlot3dTarget(target: Plot3dTarget): ResolvedPlot3dPanel;
|
|
132
|
+
//# sourceMappingURL=target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/interactive/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,uEAAuE;AACvE,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,WAAW,EACX,kBAAkB,GAAG,qBAAqB,GAAG,uBAAuB,CACrE,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,mCAAmC;IACnC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,6CAA6C;AAC7C,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG,WAAW,CAAC;AAEhE;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,iBAAiB,GACxB,WAAW,CAKb;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,GAChB;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAQ5C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,8EAA8E;IAC9E,OAAO,IAAI,IAAI,CAAC;CACjB;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAoEzE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;AAErD,yEAAyE;AACzE,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,8EAA8E;IAC9E,OAAO,IAAI,IAAI,CAAC;CACjB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,mBAAmB,CA0C7E"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared 2D scales, ticks, and axis drawing.
|
|
3
|
+
*
|
|
4
|
+
* Every 2D plot in this library maps a world window onto a pixel rectangle and
|
|
5
|
+
* draws the same style of axis box. That work lives here so no plot repeats
|
|
6
|
+
* it. R gets the equivalent from `plot()` and `pretty()`.
|
|
7
|
+
*
|
|
8
|
+
* The scale is pure geometry: it holds numbers and returns numbers. Only
|
|
9
|
+
* `drawAxes` touches a context, and it receives that context as an argument.
|
|
10
|
+
*/
|
|
11
|
+
import type { Context2D } from "./target";
|
|
12
|
+
/** A closed range of world values. */
|
|
13
|
+
export interface Extent {
|
|
14
|
+
readonly min: number;
|
|
15
|
+
readonly max: number;
|
|
16
|
+
}
|
|
17
|
+
/** Pixels reserved outside the plot area for ticks, labels, and titles. */
|
|
18
|
+
export interface Margins {
|
|
19
|
+
readonly top: number;
|
|
20
|
+
readonly right: number;
|
|
21
|
+
readonly bottom: number;
|
|
22
|
+
readonly left: number;
|
|
23
|
+
}
|
|
24
|
+
/** The pixel rectangle that holds the data. */
|
|
25
|
+
export interface PlotArea {
|
|
26
|
+
readonly left: number;
|
|
27
|
+
readonly right: number;
|
|
28
|
+
readonly top: number;
|
|
29
|
+
readonly bottom: number;
|
|
30
|
+
readonly width: number;
|
|
31
|
+
readonly height: number;
|
|
32
|
+
}
|
|
33
|
+
/** What `createScale` needs: a surface size and a world window. */
|
|
34
|
+
export interface ScaleOptions {
|
|
35
|
+
readonly width: number;
|
|
36
|
+
readonly height: number;
|
|
37
|
+
readonly x: Extent;
|
|
38
|
+
readonly y: Extent;
|
|
39
|
+
readonly margins?: Margins;
|
|
40
|
+
}
|
|
41
|
+
/** A two-way map between world values and pixels. */
|
|
42
|
+
export interface Scale {
|
|
43
|
+
readonly area: PlotArea;
|
|
44
|
+
readonly world: {
|
|
45
|
+
readonly x: Extent;
|
|
46
|
+
readonly y: Extent;
|
|
47
|
+
};
|
|
48
|
+
/** Return the pixel column of a world x value. */
|
|
49
|
+
toPixelX(x: number): number;
|
|
50
|
+
/** Return the pixel row of a world y value. Pixel rows grow downward. */
|
|
51
|
+
toPixelY(y: number): number;
|
|
52
|
+
/** Return the world x value of a pixel column. */
|
|
53
|
+
toWorldX(px: number): number;
|
|
54
|
+
/** Return the world y value of a pixel row. */
|
|
55
|
+
toWorldY(py: number): number;
|
|
56
|
+
}
|
|
57
|
+
/** What to draw around the plot area. */
|
|
58
|
+
export interface AxesOptions {
|
|
59
|
+
/** Title under the x axis. Omit for no title. */
|
|
60
|
+
readonly xLabel?: string;
|
|
61
|
+
/** Title beside the y axis, rotated. Omit for no title. */
|
|
62
|
+
readonly yLabel?: string;
|
|
63
|
+
/** Ticks to aim for on each axis. The tick rule may give a few more or less. */
|
|
64
|
+
readonly tickCount?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Draw the box around the plot area. True by default.
|
|
67
|
+
*
|
|
68
|
+
* R's `plot()` draws the box under `frame.plot = TRUE` and drops it under
|
|
69
|
+
* `frame.plot = FALSE`, keeping the two axis lines either way. The t-test
|
|
70
|
+
* plot passes `frame = FALSE`, as its R original does.
|
|
71
|
+
*/
|
|
72
|
+
readonly frame?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Draw the y axis, its ticks and its labels. True by default.
|
|
75
|
+
*
|
|
76
|
+
* R's `yaxt = "n"` drops the vertical axis and leaves the horizontal one.
|
|
77
|
+
* The sampling plot asks for that on each of its three panels, where the
|
|
78
|
+
* height is a density or a count that no reader needs to measure.
|
|
79
|
+
*/
|
|
80
|
+
readonly yAxis?: boolean;
|
|
81
|
+
}
|
|
82
|
+
/** Margins wide enough for two-digit tick labels and an axis title. */
|
|
83
|
+
export declare const DEFAULT_MARGINS: Margins;
|
|
84
|
+
/** Read a pair of limits as a range, whichever way round it was written. */
|
|
85
|
+
export declare function extentOf(limits: readonly [number, number]): Extent;
|
|
86
|
+
/**
|
|
87
|
+
* Build a scale for one surface and one world window.
|
|
88
|
+
*
|
|
89
|
+
* A world range of zero width maps to the middle of the plot area, which keeps
|
|
90
|
+
* a degenerate data set visible instead of dividing by zero.
|
|
91
|
+
*/
|
|
92
|
+
export declare function createScale(options: ScaleOptions): Scale;
|
|
93
|
+
/**
|
|
94
|
+
* Report whether a pixel lies in the plot area. An edge counts as inside.
|
|
95
|
+
*
|
|
96
|
+
* The interactive components ask this of every click, to keep a click on the
|
|
97
|
+
* margin — the tick labels and the axis titles — from becoming a data point.
|
|
98
|
+
*
|
|
99
|
+
* @param area The plot area, from a scale.
|
|
100
|
+
* @param pixel A position on the surface, in layout pixels.
|
|
101
|
+
* @returns Whether the position is in the area, edges included.
|
|
102
|
+
*/
|
|
103
|
+
export declare function pixelInArea(area: PlotArea, pixel: {
|
|
104
|
+
readonly x: number;
|
|
105
|
+
readonly y: number;
|
|
106
|
+
}): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Choose readable tick values inside an extent.
|
|
109
|
+
*
|
|
110
|
+
* The step is 1, 2, or 5 times a power of ten, as in R's `pretty()`. Unlike
|
|
111
|
+
* `pretty()`, this keeps every tick inside the extent instead of widening the
|
|
112
|
+
* range to round numbers, because the plot window is fixed before the ticks
|
|
113
|
+
* are chosen.
|
|
114
|
+
*
|
|
115
|
+
* @param extent The range to cover. A reversed range gives the same ticks.
|
|
116
|
+
* @param count The number of intervals to aim for.
|
|
117
|
+
* @returns The tick values, ascending. A range of zero width gives one tick.
|
|
118
|
+
*/
|
|
119
|
+
export declare function prettyTicks(extent: Extent, count?: number): number[];
|
|
120
|
+
/**
|
|
121
|
+
* Draw the axis box, the ticks, the tick labels, and the axis titles.
|
|
122
|
+
*
|
|
123
|
+
* @param ctx The context to draw to.
|
|
124
|
+
* @param scale The scale that fixes the plot area and the world window.
|
|
125
|
+
* @param options Titles and tick count. All are optional.
|
|
126
|
+
*/
|
|
127
|
+
export declare function drawAxes(ctx: Context2D, scale: Scale, options?: AxesOptions): void;
|
|
128
|
+
//# sourceMappingURL=axes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axes.d.ts","sourceRoot":"","sources":["../../src/plot/axes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared drawing primitives for the 2D plots.
|
|
3
|
+
*
|
|
4
|
+
* The post-port reuse audit found each of these written out in most of the
|
|
5
|
+
* `plot/` modules, byte for byte. They live here so a change to any of them
|
|
6
|
+
* reaches every plot at once. `axes.ts` keeps what belongs to an axis: the
|
|
7
|
+
* world-to-pixel scale, the tick rule, and the frame.
|
|
8
|
+
*
|
|
9
|
+
* Nothing here reads a scale's world window. Each function takes pixels, so a
|
|
10
|
+
* caller keeps its own world geometry and this file stays about the canvas.
|
|
11
|
+
*/
|
|
12
|
+
import type { PlotArea, Scale } from "./axes";
|
|
13
|
+
import type { Context2D } from "./target";
|
|
14
|
+
import type { Point } from "../core/regression";
|
|
15
|
+
/** R: `lty = "dotted"`. */
|
|
16
|
+
export declare const DOTTED: number[];
|
|
17
|
+
/** Paint the whole surface white, the color of a fresh R device. */
|
|
18
|
+
export declare function clearSurface(ctx: Context2D, width: number, height: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Keep drawing inside the plot area, as base graphics does by default.
|
|
21
|
+
*
|
|
22
|
+
* R's device clips the plot region and canvas clips nothing, so every plot
|
|
23
|
+
* that can put ink outside its window needs this. The caller saves and
|
|
24
|
+
* restores around it: the clip lifts with the state it was set in.
|
|
25
|
+
*/
|
|
26
|
+
export declare function clipToArea(ctx: Context2D, area: PlotArea): void;
|
|
27
|
+
/** Draw each point as a filled dot. R: `pch = 19, cex = 2, col = "gray"`. */
|
|
28
|
+
export declare function drawDots(ctx: Context2D, scale: Scale, points: readonly Point[]): void;
|
|
29
|
+
/** How an arrow is drawn. The defaults are R's `arrows()` defaults. */
|
|
30
|
+
export interface ArrowOptions {
|
|
31
|
+
/** The length of an arrowhead edge, in pixels. R measures it in inches. */
|
|
32
|
+
readonly headLength: number;
|
|
33
|
+
/** The dash pattern. R's `lty` covers the head as well as the shaft. */
|
|
34
|
+
readonly dash?: readonly number[];
|
|
35
|
+
readonly color?: string;
|
|
36
|
+
readonly lineWidth?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Draw one arrow between two pixel positions.
|
|
40
|
+
*
|
|
41
|
+
* The head goes at the tip alone, which is what `arrows()` does with its
|
|
42
|
+
* default `code = 2`. An arrow too short to have a direction is skipped
|
|
43
|
+
* whole: see `MIN_ARROW_PIXELS`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function drawArrow(ctx: Context2D, tail: readonly [number, number], tip: readonly [number, number], options: ArrowOptions): void;
|
|
46
|
+
//# sourceMappingURL=draw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw.d.ts","sourceRoot":"","sources":["../../src/plot/draw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,2BAA2B;AAC3B,eAAO,MAAM,MAAM,UAAS,CAAC;AA6B7B,oEAAoE;AACpE,wBAAgB,YAAY,CAC1B,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,IAAI,CAIN;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAI/D;AAED,6EAA6E;AAC7E,wBAAgB,QAAQ,CACtB,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,SAAS,KAAK,EAAE,GACvB,IAAI,CAgBN;AAED,uEAAuE;AACvE,MAAM,WAAW,YAAY;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,YAAY,GACpB,IAAI,CAkCN"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number formatting shared by the plots.
|
|
3
|
+
*
|
|
4
|
+
* R writes numbers into a plot through `round(x, 2)` and its own coercion to
|
|
5
|
+
* text. Both the regression stats block and the t-test error matrix need that
|
|
6
|
+
* same treatment, so it lives here rather than in either of them.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Round to two decimals for display, and report a missing value as R does.
|
|
10
|
+
*
|
|
11
|
+
* R prints `round(x, 2)`, which drops a trailing zero, so 2.50 reads as "2.5".
|
|
12
|
+
* R rounds half to even and this rounds half away from zero; the two differ
|
|
13
|
+
* only on an exact half at the third decimal.
|
|
14
|
+
*
|
|
15
|
+
* @param value The number to show. Null and non-finite read as "NA".
|
|
16
|
+
* @returns The text to draw.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatStat(value: number | null): string;
|
|
19
|
+
/**
|
|
20
|
+
* Write a number the way R's `as.character()` does.
|
|
21
|
+
*
|
|
22
|
+
* R keeps 15 significant digits and drops what follows, so `1 - 0.07` prints
|
|
23
|
+
* as "0.93". JavaScript's `String()` instead keeps every digit needed to
|
|
24
|
+
* identify the double, and prints the same subtraction as
|
|
25
|
+
* "0.9299999999999999". The t-test error matrix draws `1 - alpha` untouched,
|
|
26
|
+
* and alpha steps in hundredths, so without this the panel shows that run of
|
|
27
|
+
* nines at one of its ten settings.
|
|
28
|
+
*
|
|
29
|
+
* @param value The number to show.
|
|
30
|
+
* @returns The text to draw. Non-finite reads as "NA", as elsewhere.
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatNumber(value: number): string;
|
|
33
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/plot/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAKvD;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The logistic-regression plot: the points, the fitted probability curve, and
|
|
3
|
+
* a small block of statistics.
|
|
4
|
+
*
|
|
5
|
+
* This is the drawing half of `plot_logit()` and `plot_points_logit()` in
|
|
6
|
+
* `../compstatslib/R/logit_plot.R`. Every number it draws comes from
|
|
7
|
+
* `logisticRegression` in `src/core/logit.ts`; this module computes no
|
|
8
|
+
* statistics of its own.
|
|
9
|
+
*/
|
|
10
|
+
import type { LogitFit } from "../core/logit";
|
|
11
|
+
import type { Point } from "../core/regression";
|
|
12
|
+
import type { Scale } from "./axes";
|
|
13
|
+
import type { PlotTarget } from "./target";
|
|
14
|
+
/**
|
|
15
|
+
* Which corner of the plot area the statistics block sits in.
|
|
16
|
+
*
|
|
17
|
+
* R's `legend()` takes nine positions. These four are the ones a block of
|
|
18
|
+
* text reads well in, and one of them is R's own default here.
|
|
19
|
+
*/
|
|
20
|
+
export type LegendLocation = "topleft" | "topright" | "bottomleft" | "bottomright";
|
|
21
|
+
/** What to draw. R's defaults throughout. */
|
|
22
|
+
export interface PlotLogitOptions {
|
|
23
|
+
/** Fit the model and draw its curve. True by default. */
|
|
24
|
+
readonly regression?: boolean;
|
|
25
|
+
/** List the statistics in a corner. Needs `regression`. True by default. */
|
|
26
|
+
readonly stats?: boolean;
|
|
27
|
+
/** Left edge of the window, before the data widen it. R's `min_x`, 0. */
|
|
28
|
+
readonly minX?: number;
|
|
29
|
+
/** Right edge of the window, before the data widen it. R's `max_x`, 1. */
|
|
30
|
+
readonly maxX?: number;
|
|
31
|
+
/** Corner for the statistics. R's `legend_loc`, "topleft". */
|
|
32
|
+
readonly legendLoc?: LegendLocation;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build the scale that `plotLogit` draws through.
|
|
36
|
+
*
|
|
37
|
+
* Unlike the regression plot, whose window is fixed, this one follows the
|
|
38
|
+
* data: R starts at `min_x` and `max_x` and then widens them to cover every
|
|
39
|
+
* point (`max_x <- max(max_x, points[[x_name]])`). The vertical window is
|
|
40
|
+
* always a probability, 0 to 1.
|
|
41
|
+
*
|
|
42
|
+
* The interactive layer reads the scale from here, so the window stays
|
|
43
|
+
* defined in one place. Nothing outside this module may restate it.
|
|
44
|
+
*
|
|
45
|
+
* @param width The pixel width of the surface.
|
|
46
|
+
* @param height The pixel height of the surface.
|
|
47
|
+
* @param points The observations the window has to cover.
|
|
48
|
+
* @param options The same options `plotLogit` takes.
|
|
49
|
+
* @returns The map between world values and pixels.
|
|
50
|
+
*/
|
|
51
|
+
export declare function logitScale(width: number, height: number, points: readonly Point[], options?: PlotLogitOptions): Scale;
|
|
52
|
+
/**
|
|
53
|
+
* Draw the points and their fitted probability curve.
|
|
54
|
+
*
|
|
55
|
+
* With fewer than two points the function draws what it has and fits nothing.
|
|
56
|
+
* R stops at the same two places: it returns before `glm()` on an empty frame,
|
|
57
|
+
* and again on a single point. The core would fit that single point — R's
|
|
58
|
+
* `glm()` does, reporting a saturated intercept and no slope — but the plot
|
|
59
|
+
* never asks it to, so neither does this.
|
|
60
|
+
*
|
|
61
|
+
* @param target A canvas, or a context and a size. See `./target.ts`.
|
|
62
|
+
* @param points The observations. Each y must be 0 or 1.
|
|
63
|
+
* @param options What to show and how wide to open the window.
|
|
64
|
+
* @returns The fit the plot drew, or null if it drew none. R returns the
|
|
65
|
+
* points instead, which the caller already holds.
|
|
66
|
+
*/
|
|
67
|
+
export declare function plotLogit(target: PlotTarget, points: readonly Point[], options?: PlotLogitOptions): LogitFit | null;
|
|
68
|
+
//# sourceMappingURL=logit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logit.d.ts","sourceRoot":"","sources":["../../src/plot/logit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,KAAK,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAI5C,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,UAAU,GACV,YAAY,GACZ,aAAa,CAAC;AAElB,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;CACrC;AAwBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,OAAO,GAAE,gBAAqB,GAC7B,KAAK,CAaP;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,OAAO,GAAE,gBAAqB,GAC7B,QAAQ,GAAG,IAAI,CA6BjB"}
|