@mark1russell7/site-pages 0.2.0 → 0.2.1

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/README.md CHANGED
@@ -413,6 +413,41 @@ The file sets no look for the content. Buttons, cards, code and tables stay in t
413
413
 
414
414
  A site with its own look does not import `shell.css`. It uses only the plugin and `showBuild`, or nothing from this section.
415
415
 
416
+ ## The response explorer
417
+
418
+ The entry `@mark1russell7/site-pages/explorer` shows a measured response in the browser. A visitor chooses a measure, varies one or two dimensions, and holds or facets the others. The view shows the measured points, the fitted curve or surface, and its held-out error in plain words. The record has the format `response-records/1` of `@mark1russell7/rigor-statistics`.
419
+
420
+ ```ts
421
+ import { mountExplorer } from "@mark1russell7/site-pages/explorer";
422
+ import "@mark1russell7/site-pages/explorer.css";
423
+ import record from "./record.json";
424
+
425
+ mountExplorer(document.getElementById("chart")!, record, { initial: { x: "boxes" } });
426
+ ```
427
+
428
+ | Argument | Use |
429
+ | --- | --- |
430
+ | `host` | The element for the explorer |
431
+ | `recordJson` | The record, as JSON text or as parsed data |
432
+ | `options.initial` | The first measure, axes, panels and held values. The explorer corrects a value that does not apply. |
433
+ | `options.budgetMs` | The time limit of one surface, in milliseconds. The default is 50. |
434
+ | `options.now` | The clock, for tests |
435
+
436
+ `mountExplorer` gives a handle: `state()` reads the current state, and `destroy()` removes the view.
437
+
438
+ The explorer obeys these rules:
439
+
440
+ - **A bad record.** The explorer reads a record only through `parseResponseRecord`. It shows each fault with its path, and it does not throw.
441
+ - **Conditions.** A dimension with `when` has its parent at a level inside `when`. The controls disable a choice that a view refuses, and they tell why.
442
+ - **The band.** The band shows `low` to `high`. It fades with the distance from the nearest measured point.
443
+ - **The time of a surface.** The field `nearest` reads each point at each place. So `planSteps` bounds the grid from the point count before the call. After a surface that passes the budget, `nextStepsCap` makes the next grid smaller.
444
+ - **A table model.** A table model has no smooth surface, so the view shows cells.
445
+ - **No model.** A measure with no valid model shows only the points, and the view says so.
446
+
447
+ The view draws SVG, and it needs no framework, no font and no script from another server. It reads the tokens of a site when they exist, and it has its own colors for the light and the dark scheme. The keyboard reaches each control, and the arrow keys move a cursor on a chart. "Show the numbers" opens a table of the values.
448
+
449
+ The entry also exports the pure core, for a site with its own view. These functions are `settle`, `viewOf`, `axisChoices`, `facetChoices`, `holdControls`, `setMeasure`, `setAxis`, `setFacet`, `setHold`, `planSteps`, `nextStepsCap`, `openRecord` and `numberTable`.
450
+
416
451
  ## A GitHub Pages workflow
417
452
 
418
453
  This workflow builds the site, adds the two pages, and deploys. It also starts every 3 hours, so the status page stays current without a push. A scheduled run builds the newest commit of `main` that passed CI.
@@ -0,0 +1,212 @@
1
+ import { ParsedResponseRecord, ResponseHeldOutError, ResponseMeasure, ResponseRecord, ResponseSlice, ResponseSurface, ResponseValue } from "@mark1russell7/rigor-statistics";
2
+ /** The largest number of values on a continuous axis. It is the default of `ResponseViewOptions.steps`. */
3
+ export declare const MAX_STEPS = 33;
4
+ /** The smallest number of values on a continuous axis. A smaller grid shows too little of the response. */
5
+ export declare const MIN_STEPS = 5;
6
+ /**
7
+ * The largest number of point reads of one view. The field `nearest` of each place reads each point, so the cost of a
8
+ * view is its number of places times the number of points. This number is a first bound, not a measured time.
9
+ * `SURFACE_BUDGET_MS` corrects the grid when a surface takes too long on the device.
10
+ */
11
+ export declare const READ_BUDGET = 4e5;
12
+ /** The time of one surface in milliseconds. A longer surface gives a smaller grid for the next surface. */
13
+ export declare const SURFACE_BUDGET_MS = 50;
14
+ /** The largest number of panels of one view. */
15
+ export declare const MAX_PANELS = 8;
16
+ /** The choices of a visitor. */
17
+ interface ExplorerState {
18
+ /** The id of the measure. */
19
+ readonly measure: string;
20
+ /** The id of the dimension of the horizontal axis. */
21
+ readonly x: string;
22
+ /** The id of the dimension of the vertical axis of a surface. The value `null` gives a curve. */
23
+ readonly y: string | null;
24
+ /** The id of the dimension with one panel for each of its values. The value `null` gives one panel. */
25
+ readonly facet: string | null;
26
+ /** The held value of each dimension. A dimension on an axis keeps its value for a later view. */
27
+ readonly hold: Readonly<Record<string, ResponseValue>>;
28
+ }
29
+ /** The two axes of a view. */
30
+ type AxisSlot = "x" | "y";
31
+ /** A dimension that a control offers. */
32
+ interface DimensionChoice {
33
+ readonly id: string;
34
+ readonly label: string;
35
+ readonly disabled: boolean;
36
+ /** The reason of a disabled choice. A good choice has an empty string. */
37
+ readonly reason: string;
38
+ }
39
+ /** A value that a hold control offers. */
40
+ interface HoldOption {
41
+ readonly value: ResponseValue;
42
+ readonly text: string;
43
+ readonly disabled: boolean;
44
+ readonly reason: string;
45
+ }
46
+ /** The control of one held dimension. */
47
+ interface HoldControl {
48
+ readonly id: string;
49
+ readonly label: string;
50
+ /** The value `levels` gives one button for each level. The value `stops` gives a slider over the measured values. */
51
+ readonly kind: "levels" | "stops";
52
+ /** The value `false` means that the dimension has no value at the held level of its parent. */
53
+ readonly applies: boolean;
54
+ /** The condition of the dimension, as text. A dimension with no condition has an empty string. */
55
+ readonly note: string;
56
+ readonly options: readonly HoldOption[];
57
+ readonly value: ResponseValue;
58
+ }
59
+ /** One axis of a chart. A number axis has a linear or log place. A level axis has one equal band for each level. */
60
+ interface AxisSpec {
61
+ readonly id: string;
62
+ readonly label: string;
63
+ readonly kind: "number" | "levels";
64
+ readonly log: boolean;
65
+ /** The two ends of a number axis. */
66
+ readonly range: readonly [number, number];
67
+ /** The levels of a level axis. */
68
+ readonly levels: readonly ResponseValue[];
69
+ }
70
+ /** The fields of each kind of panel. */
71
+ interface PanelBase {
72
+ /** The name of the panel in a view with panels. The only panel of a view has an empty string. */
73
+ readonly title: string;
74
+ /** The value of the facet dimension in this panel. */
75
+ readonly level: ResponseValue | null;
76
+ }
77
+ /** A fitted curve with its band and the measured points. */
78
+ interface CurvePanel extends PanelBase {
79
+ readonly kind: "curve";
80
+ readonly slice: ResponseSlice;
81
+ }
82
+ /** A fitted surface. With `cells`, the view shows separate cells with their values, not a smooth surface. */
83
+ interface SurfacePanel extends PanelBase {
84
+ readonly kind: "surface";
85
+ readonly cells: boolean;
86
+ readonly surface: ResponseSurface;
87
+ }
88
+ /** A measured point of a panel with no model. */
89
+ interface PlainPoint {
90
+ readonly id: string;
91
+ /** The value of each varied dimension. */
92
+ readonly at: readonly ResponseValue[];
93
+ readonly value: number;
94
+ }
95
+ /** The measured points of a measure with no model. */
96
+ interface PointsPanel extends PanelBase {
97
+ readonly kind: "points";
98
+ readonly points: readonly PlainPoint[];
99
+ }
100
+ /** One panel of a view. */
101
+ type ExplorerPanel = CurvePanel | SurfacePanel | PointsPanel;
102
+ /** The data of one view. */
103
+ interface ExplorerView {
104
+ readonly measure: ResponseMeasure;
105
+ readonly x: AxisSpec;
106
+ readonly y: AxisSpec | null;
107
+ readonly panels: readonly ExplorerPanel[];
108
+ /** The value `true` gives a log value axis. */
109
+ readonly log: boolean;
110
+ /** The held-out error. A measure with no model has none. */
111
+ readonly error: ResponseHeldOutError | null;
112
+ /** The held-out error in plain words. */
113
+ readonly errorText: string;
114
+ /** The kind of the model in plain words. */
115
+ readonly modelText: string;
116
+ /** The size of the grid of a surface in plain words. A curve has an empty string. */
117
+ readonly gridText: string;
118
+ /** The text of a request that the record refused. A good view has an empty string. */
119
+ readonly problem: string;
120
+ /** The number of values on a continuous axis of this view. */
121
+ readonly steps: number;
122
+ /** The time of this view in milliseconds. */
123
+ readonly elapsedMs: number;
124
+ /** The largest number of steps of the next view. */
125
+ readonly nextCap: number;
126
+ }
127
+ /** The inputs of `viewOf`. */
128
+ interface ViewOptions {
129
+ /** The largest number of steps. The value of `nextCap` of the last view goes here. */
130
+ readonly stepsCap?: number;
131
+ /** The time of a surface in milliseconds. The default is `SURFACE_BUDGET_MS`. */
132
+ readonly budgetMs?: number;
133
+ /** The clock in milliseconds. The default gives 0, so a view with no clock does not drop its grid. */
134
+ readonly now?: () => number;
135
+ }
136
+ /** A rectangle of a table of numbers. */
137
+ interface NumberTable {
138
+ readonly columns: readonly string[];
139
+ readonly rows: readonly (readonly string[])[];
140
+ }
141
+ /**
142
+ * This function reads a record from JSON text or from parsed data. It does not throw: bad data gives faults with
143
+ * their paths.
144
+ */
145
+ export declare function openRecord(value: unknown): ParsedResponseRecord;
146
+ /**
147
+ * This function gives the nearest good state for a wanted state. Each unknown or missing field takes its usual value.
148
+ * A parent moves to a level that a varied conditional dimension needs. A combination that a view refuses loses its
149
+ * second axis or its panels.
150
+ */
151
+ export declare function settle(record: ResponseRecord, wanted?: Partial<ExplorerState>): ExplorerState;
152
+ /** This function gives each dimension as a choice for an axis. A disabled choice tells its reason. */
153
+ export declare function axisChoices(record: ResponseRecord, state: ExplorerState, slot: AxisSlot): readonly DimensionChoice[];
154
+ /** This function gives each dimension as a choice for panels. A disabled choice tells its reason. */
155
+ export declare function facetChoices(record: ResponseRecord, state: ExplorerState): readonly DimensionChoice[];
156
+ /** This function gives the control of each held dimension. A dimension on an axis or in panels has no control. */
157
+ export declare function holdControls(record: ResponseRecord, state: ExplorerState): readonly HoldControl[];
158
+ /** This function gives the state with a new measure. */
159
+ export declare function setMeasure(record: ResponseRecord, state: ExplorerState, measure: string): ExplorerState;
160
+ /** This function gives the state with a new axis. It does not take a disabled choice. The value `null` removes the y axis. */
161
+ export declare function setAxis(record: ResponseRecord, state: ExplorerState, slot: AxisSlot, id: string | null): ExplorerState;
162
+ /** This function gives the state with new panels. It does not take a disabled choice. The value `null` gives one panel. */
163
+ export declare function setFacet(record: ResponseRecord, state: ExplorerState, id: string | null): ExplorerState;
164
+ /** This function gives the state with a new held value. It does not take a disabled value. */
165
+ export declare function setHold(record: ResponseRecord, state: ExplorerState, id: string, value: ResponseValue): ExplorerState;
166
+ /**
167
+ * This function gives the number of steps of a view, from the number of points, before the call. The field `nearest`
168
+ * reads each point at each place, so the number of places comes from `READ_BUDGET`.
169
+ *
170
+ * @param points - The number of points of the record.
171
+ * @param panels - The number of panels of the view.
172
+ * @param continuous - The number of continuous axes of the view.
173
+ * @param levels - The number of levels of a level axis of a surface, or 1.
174
+ * @param cap - The largest result.
175
+ */
176
+ export declare function planSteps(points: number, panels: number, continuous: number, levels: number, cap?: number): number;
177
+ /** This function gives the cap of the next view: a smaller grid when this surface took more than the budget. */
178
+ export declare function nextStepsCap(steps: number, elapsedMs: number, budgetMs: number): number;
179
+ /**
180
+ * This function gives the data of a view. It does not throw. A request that the record refuses gives the text in
181
+ * `problem`, and no panels. A measure with no model gives only the measured points, and a table model gives cells.
182
+ */
183
+ export declare function viewOf(record: ResponseRecord, state: ExplorerState, options?: ViewOptions): ExplorerView;
184
+ /** This function gives the numbers of a panel: each place of a curve, or the measured points of a surface. */
185
+ export declare function numberTable(view: ExplorerView, panel: ExplorerPanel): NumberTable;
186
+ /** The options of `mountExplorer`. */
187
+ interface ExplorerOptions {
188
+ /** The first state. The explorer corrects a state that a record refuses. */
189
+ readonly initial?: Partial<ExplorerState>;
190
+ /** The time of a surface in milliseconds. The default is `SURFACE_BUDGET_MS`. */
191
+ readonly budgetMs?: number;
192
+ /** The clock in milliseconds. The default is `performance.now`. */
193
+ readonly now?: () => number;
194
+ }
195
+ /** The result of `mountExplorer`. */
196
+ interface ExplorerHandle {
197
+ /** This method gives the choices of the visitor. It gives `null` for a record with faults. */
198
+ state(): ExplorerState | null;
199
+ /** This method removes the explorer from its host. */
200
+ destroy(): void;
201
+ }
202
+ /**
203
+ * This function shows a record of the format `response-records/1` in a host element. It reads the record only with
204
+ * `parseResponseRecord`. A bad record shows its faults with their paths, and the function does not throw.
205
+ *
206
+ * @param host - The element of the explorer. The function replaces its children.
207
+ * @param recordJson - The record as JSON text, or as parsed data.
208
+ * @param options - The first state, the time of a surface and the clock.
209
+ */
210
+ export declare function mountExplorer(host: HTMLElement, recordJson: unknown, options?: ExplorerOptions): ExplorerHandle;
211
+ export type { AxisSlot, AxisSpec, CurvePanel, DimensionChoice, ExplorerHandle, ExplorerOptions, ExplorerPanel, ExplorerState, ExplorerView, HoldControl, HoldOption, NumberTable, PlainPoint, PointsPanel, SurfacePanel, ViewOptions };
212
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/explorer/model.ts","../../src/explorer/view.ts"],"mappings":";;qBAgCa;;qBAEA;;;;;;qBAMA;;qBAEA;;qBAEA;;UASI;;WAEN;;WAEA;;WAEA;;WAEA;;WAEA,MAAM,SAAS,eAAe;;;KAI7B;;UAGK;WACN;WACA;WACA;;WAEA;;;UAIM;WACN,OAAO;WACP;WACA;WACA;;;UAIM;WACN;WACA;;WAEA;;WAEA;;WAEA;WACA,kBAAkB;WAClB,OAAO;;;UAID;WACN;WACA;WACA;WACA;;WAEA;;WAEA,iBAAiB;;;UAIlB;;WAEC;;WAEA,OAAO;;;UAID,mBAAmB;WACzB;WACA,OAAO;;;UAID,qBAAqB;WAC3B;WACA;WACA,SAAS;;;UAIH;WACN;;WAEA,aAAa;WACb;;;UAIM,oBAAoB;WAC1B;WACA,iBAAiB;;;KAIhB,gBAAgB,aAAa,eAAe;;UAGvC;WACN,SAAS;WACT,GAAG;WACH,GAAG;WACH,iBAAiB;;WAEjB;;WAEA,OAAO;;WAEP;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;;UAIM;;WAEN;;WAEA;;WAEA;;;UAIM;WACN;WACA;;;;;;wBAcK,WAAW,iBAAiB;;;;;;wBA0K5B,OAAO,QAAQ,gBAAgB,SAAQ,QAAQ,iBAAsB;;wBAqBrE,YAAY,QAAQ,gBAAgB,OAAO,eAAe,MAAM,oBAAoB;;wBAQpF,aAAa,QAAQ,gBAAgB,OAAO,yBAAyB;;wBAQrE,aAAa,QAAQ,gBAAgB,OAAO,yBAAyB;;wBAmBrE,WAAW,QAAQ,gBAAgB,OAAO,eAAe,kBAAkB;;wBAK3E,QAAQ,QAAQ,gBAAgB,OAAO,eAAe,MAAM,UAAU,oBAAoB;;wBAO1F,SAAS,QAAQ,gBAAgB,OAAO,eAAe,oBAAoB;;wBAM3E,QAAQ,QAAQ,gBAAgB,OAAO,eAAe,YAAY,OAAO,gBAAgB;;;;;;;;;;;wBAiBzF,UAAU,gBAAgB,gBAAgB,oBAAoB,gBAAgB;;wBAO9E,aAAa,eAAe,mBAAmB;;;;;wBAuF/C,OAAO,QAAQ,gBAAgB,OAAO,eAAe,UAAS,cAAmB;;wBAmLjF,YAAY,MAAM,cAAc,OAAO,gBAAgB;;UC9qBtD;;WAEN,UAAU,QAAQ;;WAElB;;WAEA;;;UAIM;;EAEf,SAAS;;EAET;;;;;;;;;;wBAmZc,cAAc,MAAM,aAAa,qBAAqB,UAAS,kBAAuB"}