apex-analyst 0.1.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/LICENSE +97 -0
- package/README.md +184 -0
- package/apex-analyst.es.min.js +1 -0
- package/apex-analyst.min.js +1 -0
- package/demo/index.html +127 -0
- package/index.d.ts +15 -0
- package/index.d.ts.map +1 -0
- package/lib/Analyst.d.ts +69 -0
- package/lib/Analyst.d.ts.map +1 -0
- package/lib/AnalystPanel.d.ts +81 -0
- package/lib/AnalystPanel.d.ts.map +1 -0
- package/lib/SeriesModel.d.ts +39 -0
- package/lib/SeriesModel.d.ts.map +1 -0
- package/lib/clip.d.ts +25 -0
- package/lib/clip.d.ts.map +1 -0
- package/lib/emitLike.d.ts +73 -0
- package/lib/emitLike.d.ts.map +1 -0
- package/lib/format.d.ts +27 -0
- package/lib/format.d.ts.map +1 -0
- package/lib/plugin.d.ts +37 -0
- package/lib/plugin.d.ts.map +1 -0
- package/lib/registry.d.ts +40 -0
- package/lib/registry.d.ts.map +1 -0
- package/lib/stats/Descriptive.d.ts +50 -0
- package/lib/stats/Descriptive.d.ts.map +1 -0
- package/lib/stats/Regression.d.ts +42 -0
- package/lib/stats/Regression.d.ts.map +1 -0
- package/lib/testing/fakeWeave.d.ts +59 -0
- package/lib/testing/fakeWeave.d.ts.map +1 -0
- package/lib/testing/jsdomSetup.d.ts +31 -0
- package/lib/testing/jsdomSetup.d.ts.map +1 -0
- package/lib/testing/realChart.d.ts +95 -0
- package/lib/testing/realChart.d.ts.map +1 -0
- package/lib/tools/DataTable.d.ts +5 -0
- package/lib/tools/DataTable.d.ts.map +1 -0
- package/lib/tools/SummaryStats.d.ts +5 -0
- package/lib/tools/SummaryStats.d.ts.map +1 -0
- package/lib/tools/TrendLine.d.ts +5 -0
- package/lib/tools/TrendLine.d.ts.map +1 -0
- package/lib/tools/types.d.ts +45 -0
- package/lib/tools/types.d.ts.map +1 -0
- package/lib/weave.d.ts +169 -0
- package/lib/weave.d.ts.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Analyst toolbar and result panel.
|
|
3
|
+
*
|
|
4
|
+
* Rendered into a Shadow DOM host, which is not decoration. This layer is meant
|
|
5
|
+
* to be dropped onto pages we did not write, so two things have to be true:
|
|
6
|
+
* host CSS must not be able to restyle the toolbar into uselessness, and the
|
|
7
|
+
* toolbar's own CSS must not leak out. A global `:root` token from an add-on has
|
|
8
|
+
* broken a real host page before (apexstock shipped one and the website still
|
|
9
|
+
* carries a guard for it), so an add-on rendering UI on customer pages gets a
|
|
10
|
+
* closed styling boundary from the start rather than after the first bug report.
|
|
11
|
+
*
|
|
12
|
+
* Theming still works: CSS custom properties pierce the shadow boundary, so a
|
|
13
|
+
* host sets `--apx-analyst-*` on the chart container and every fallback here
|
|
14
|
+
* gives way. Colors are declared once as tokens on `:host` so the dark scheme is
|
|
15
|
+
* a token swap rather than a second copy of the rules.
|
|
16
|
+
*
|
|
17
|
+
* The DOM is built with createElement and textContent throughout. Series names,
|
|
18
|
+
* category labels and title text all come from user data, and an innerHTML
|
|
19
|
+
* template would make an XSS sink out of a chart label.
|
|
20
|
+
*
|
|
21
|
+
* @module AnalystPanel
|
|
22
|
+
*/
|
|
23
|
+
export default class AnalystPanel {
|
|
24
|
+
private container;
|
|
25
|
+
/** The toolbar's shadow host. Retained so a re-render can put the same node back. */
|
|
26
|
+
readonly host: HTMLElement;
|
|
27
|
+
/** The readout's shadow host, which lives on the far side of the chart. */
|
|
28
|
+
readonly panelHost: HTMLElement;
|
|
29
|
+
private bar;
|
|
30
|
+
private panel;
|
|
31
|
+
private buttons;
|
|
32
|
+
/**
|
|
33
|
+
* Two hosts rather than one, because they belong on opposite sides of a chart
|
|
34
|
+
* this layer does not own.
|
|
35
|
+
*
|
|
36
|
+
* The buttons have to sit above the chart, where a toolbar is looked for. The
|
|
37
|
+
* readout must not: opening a panel above the chart pushes the chart down the
|
|
38
|
+
* page by the panel's height, so the thing you were reading moves out from
|
|
39
|
+
* under the pointer at the moment you asked to learn more about it. A summary
|
|
40
|
+
* table is tall enough to shift the chart off screen entirely.
|
|
41
|
+
*
|
|
42
|
+
* Putting the readout after the chart means a second shadow root, and the
|
|
43
|
+
* stylesheet is duplicated into it, which is a few hundred bytes for the
|
|
44
|
+
* chart staying where the reader left it.
|
|
45
|
+
*
|
|
46
|
+
* @param container the chart's own container element
|
|
47
|
+
* @param before insert the toolbar before this node, or append
|
|
48
|
+
*/
|
|
49
|
+
constructor(container: HTMLElement, before: Element | null);
|
|
50
|
+
/** Attach a shadow root carrying the stylesheet, once per host. */
|
|
51
|
+
private static rootFor;
|
|
52
|
+
/** Toolbar before the chart, readout after it. */
|
|
53
|
+
private insert;
|
|
54
|
+
/**
|
|
55
|
+
* Put the host back after a re-render detached it.
|
|
56
|
+
*
|
|
57
|
+
* Every `updateSeries()` / `updateOptions()` empties the chart's container
|
|
58
|
+
* outright (the core clears every child of the caller's element, not just the
|
|
59
|
+
* SVG), so anything a plugin puts there is removed on every update and the
|
|
60
|
+
* toolbar vanished the first time a tool changed the chart. Only the parent
|
|
61
|
+
* link is cut, and the host element object is still held here, so re-inserting
|
|
62
|
+
* the SAME node restores the shadow root, its stylesheet and the open panel in
|
|
63
|
+
* one DOM operation. Rebuilding it would drop the readout and leak a shadow
|
|
64
|
+
* root per update.
|
|
65
|
+
*/
|
|
66
|
+
reattach(container: HTMLElement, before: Element | null): void;
|
|
67
|
+
/**
|
|
68
|
+
* (Re)build the button row.
|
|
69
|
+
* @param tools already filtered to the tools that apply to this chart
|
|
70
|
+
*/
|
|
71
|
+
setTools(tools: Array<{
|
|
72
|
+
id: string;
|
|
73
|
+
label: string;
|
|
74
|
+
}>, onClick: (id: string) => void): void;
|
|
75
|
+
setPressed(id: string, on: boolean): void;
|
|
76
|
+
/** Clear the panel and return the element a tool should render into. */
|
|
77
|
+
openPanel(): HTMLElement;
|
|
78
|
+
closePanel(): void;
|
|
79
|
+
teardown(): void;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=AnalystPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalystPanel.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/AnalystPanel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA6GH,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,SAAS,CAAc;IAC/B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,OAAO,CAAwC;IAEvD;;;;;;;;;;;;;;;;OAgBG;gBACS,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IA4B1D,mEAAmE;IACnE,OAAO,CAAC,MAAM,CAAC,OAAO;IAQtB,kDAAkD;IAClD,OAAO,CAAC,MAAM;IAcd;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI;IAM9D;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAcxF,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI;IAKzC,wEAAwE;IACxE,SAAS,IAAI,WAAW;IAMxB,UAAU,IAAI,IAAI;IAKlB,QAAQ,IAAI,IAAI;CAMjB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { WeaveAPI } from './weave';
|
|
2
|
+
|
|
3
|
+
export interface AnalystSeries {
|
|
4
|
+
/** index into the chart's series array */
|
|
5
|
+
index: number;
|
|
6
|
+
name: string;
|
|
7
|
+
/** false when the viewer has toggled it off */
|
|
8
|
+
visible: boolean;
|
|
9
|
+
/** y values, gaps preserved as null */
|
|
10
|
+
values: Array<number | null>;
|
|
11
|
+
/**
|
|
12
|
+
* The x per position, as the host parsed it: the basis `api.scales.x()`
|
|
13
|
+
* projects, so a drawing tool can hand these straight to the scales.
|
|
14
|
+
*/
|
|
15
|
+
xs: number[];
|
|
16
|
+
/** finite (x,y) pairs for fitting, gaps dropped */
|
|
17
|
+
points: Array<{
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
export interface AnalystModel {
|
|
23
|
+
/** true for line/area/bar/..., false for pie/donut */
|
|
24
|
+
axis: boolean;
|
|
25
|
+
/** the type the caller asked for */
|
|
26
|
+
type: string;
|
|
27
|
+
timeX: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Bar chart with horizontal:true, which swaps the value axis onto x, so a
|
|
30
|
+
* tool projecting y values through the scales would draw sideways.
|
|
31
|
+
*/
|
|
32
|
+
horizontalBars: boolean;
|
|
33
|
+
series: AnalystSeries[];
|
|
34
|
+
/** x labels (axis charts) or slice labels */
|
|
35
|
+
categories: string[];
|
|
36
|
+
}
|
|
37
|
+
/** Snapshot a chart into the Analyst model. */
|
|
38
|
+
export declare function buildModel(api: WeaveAPI): AnalystModel;
|
|
39
|
+
//# sourceMappingURL=SeriesModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeriesModel.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/SeriesModel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,uCAAuC;IACvC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7B;;;OAGG;IACH,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,mDAAmD;IACnD,MAAM,EAAE,KAAK,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,IAAI,EAAE,OAAO,CAAC;IACd,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAaD,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,YAAY,CAsDtD"}
|
package/lib/clip.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clipping drawn geometry to the chart's grid.
|
|
3
|
+
*
|
|
4
|
+
* Plugin layers are not covered by the chart's own grid clip mask, so anything
|
|
5
|
+
* drawn past the grid edge paints over the axes. A fitted line does exactly
|
|
6
|
+
* that whenever its endpoints fall outside the visible y range, which zooming
|
|
7
|
+
* makes routine, so overlay tools clip in pixel space before drawing.
|
|
8
|
+
*
|
|
9
|
+
* @module clip
|
|
10
|
+
*/
|
|
11
|
+
/** The grid rectangle in pixel space, as the scales report it. */
|
|
12
|
+
export interface PixelRect {
|
|
13
|
+
left: number;
|
|
14
|
+
top: number;
|
|
15
|
+
right: number;
|
|
16
|
+
bottom: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Clip a line segment to a rectangle (Liang-Barsky).
|
|
20
|
+
*
|
|
21
|
+
* @returns the visible part as `[x1, y1, x2, y2]`, or null when the segment
|
|
22
|
+
* misses the rectangle entirely.
|
|
23
|
+
*/
|
|
24
|
+
export declare function clipSegment(x1: number, y1: number, x2: number, y2: number, rect: PixelRect): [number, number, number, number] | null;
|
|
25
|
+
//# sourceMappingURL=clip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clip.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/clip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,SAAS,GACd,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAgCzC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emit a derived datum in the same shape as the series it was derived from.
|
|
3
|
+
*
|
|
4
|
+
* ## Why not infer the axis
|
|
5
|
+
*
|
|
6
|
+
* A derived series has to match the axis: `{x,y}` pairs on a positional axis
|
|
7
|
+
* parse to all-null y, and a flat array on a datetime axis parses to all-null
|
|
8
|
+
* x. Both fail silently, so getting it wrong means a series sits on the chart
|
|
9
|
+
* drawing nothing.
|
|
10
|
+
*
|
|
11
|
+
* The first attempt inferred which case applied from the chart's internals, and
|
|
12
|
+
* every candidate signal turned out to be unusable:
|
|
13
|
+
*
|
|
14
|
+
* - `config.xaxis.type` is rewritten to 'numeric' even when the caller passed
|
|
15
|
+
* `xaxis.categories`
|
|
16
|
+
* - `globals.isXNumeric` is true for every axis chart
|
|
17
|
+
* - `globals.seriesX` is populated with 1-based slots on a category axis, so
|
|
18
|
+
* its presence proves nothing about the axis
|
|
19
|
+
* - `globals.categoryLabels` is correct on mount and EMPTY after an
|
|
20
|
+
* `updateSeries()`, so the same chart classified differently depending on
|
|
21
|
+
* which render path had just run
|
|
22
|
+
*
|
|
23
|
+
* That last one is the reason this module exists. Inference read state that is
|
|
24
|
+
* not stable across render paths, so a trend line emitted correctly on mount
|
|
25
|
+
* was emitted in the broken shape after any update.
|
|
26
|
+
*
|
|
27
|
+
* So nothing is inferred. The source datum IS the template: whatever shape the
|
|
28
|
+
* chart already accepts for this series, the derived series reuses, carrying
|
|
29
|
+
* the source's own x across verbatim. A string x ('Mon') travels as a string, an
|
|
30
|
+
* epoch number as an epoch number, and a bare value stays bare.
|
|
31
|
+
*
|
|
32
|
+
* @module emitLike
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* @param datum the source series datum at the same position
|
|
36
|
+
* @param y the derived value
|
|
37
|
+
* @returns a datum in the source's shape
|
|
38
|
+
*/
|
|
39
|
+
export declare function emitLike(datum: unknown, y: number): unknown;
|
|
40
|
+
/** How many decimal places the source values actually use. */
|
|
41
|
+
export declare function decimalsOf(values: ReadonlyArray<number | null | undefined> | undefined): number;
|
|
42
|
+
/**
|
|
43
|
+
* Round a computed value to the precision of the data it was derived from.
|
|
44
|
+
*
|
|
45
|
+
* A fitted value lands on 29.999999999999996 rather than 30, and an axis sizes
|
|
46
|
+
* its tick labels to the decimal count present in the data, so adding a trend
|
|
47
|
+
* line turned a bar chart whose ticks read 0 / 10 / 20 / 30 into one reading
|
|
48
|
+
* 0.0000000000000000 / 10.0000000000000000. Rounding to 12 significant digits
|
|
49
|
+
* was not enough: 100.434782608696 still asks the axis for nine decimals.
|
|
50
|
+
*
|
|
51
|
+
* Matching the source's own precision is also the honest rule. A least-squares
|
|
52
|
+
* fit over integer counts is not more precise than integer counts, and the
|
|
53
|
+
* residual visual error is half of one unit of a resolution the chart was
|
|
54
|
+
* already rounding to. Full precision stays available to a readout, which is
|
|
55
|
+
* where it belongs.
|
|
56
|
+
*
|
|
57
|
+
* @param decimals from decimalsOf() on the source series
|
|
58
|
+
*/
|
|
59
|
+
export declare function roundLike(y: number, decimals: number): number;
|
|
60
|
+
/**
|
|
61
|
+
* The numeric x to fit against for a datum at position `index`.
|
|
62
|
+
*
|
|
63
|
+
* Derived from the source data rather than from the chart's parsed x array, for
|
|
64
|
+
* the same stability reason as above: that array is empty on some render paths,
|
|
65
|
+
* which silently changed the x basis of a refit.
|
|
66
|
+
*
|
|
67
|
+
* A non-numeric x (a category name) falls back to the ordinal position, which
|
|
68
|
+
* is the honest reading: a trend across named categories is a trend against
|
|
69
|
+
* their order. The fit and the prediction use the same basis either way, so a
|
|
70
|
+
* uniform shift in x leaves the predicted y values unchanged.
|
|
71
|
+
*/
|
|
72
|
+
export declare function xFor(datum: unknown, index: number): number;
|
|
73
|
+
//# sourceMappingURL=emitLike.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitLike.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/emitLike.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAa3D;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,MAAM,CAqB/F;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAY1D"}
|
package/lib/format.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number formatting for Analyst readouts.
|
|
3
|
+
*
|
|
4
|
+
* Analysis output is read side by side with the chart, so a statistic printed
|
|
5
|
+
* at full float precision (`3.3000000000000003`) reads as a bug in the library
|
|
6
|
+
* rather than as floating point. These helpers are shared so every tool rounds
|
|
7
|
+
* the same way and a mean in the summary panel matches the same mean quoted in
|
|
8
|
+
* a trend readout.
|
|
9
|
+
*
|
|
10
|
+
* @module format
|
|
11
|
+
*/
|
|
12
|
+
/** Shown wherever a statistic has no defined value. */
|
|
13
|
+
export declare const NO_VALUE = "n/a";
|
|
14
|
+
/**
|
|
15
|
+
* Format a statistic for display.
|
|
16
|
+
*
|
|
17
|
+
* Significant digits rather than fixed decimals, because a chart's y values may
|
|
18
|
+
* be percentages (0.043), counts (128) or revenue (1284000) and one fixed
|
|
19
|
+
* decimal count is wrong for at least two of those. Locale-aware grouping,
|
|
20
|
+
* since these are numbers a person reads rather than parses.
|
|
21
|
+
*
|
|
22
|
+
* @param sig significant digits, default 6
|
|
23
|
+
*/
|
|
24
|
+
export declare function formatNumber(v: number | null | undefined, sig?: number): string;
|
|
25
|
+
/** Format a 0..1 ratio as a percentage. */
|
|
26
|
+
export declare function formatPercent(v: number | null | undefined): string;
|
|
27
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,uDAAuD;AACvD,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAE9B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,SAAI,GAAG,MAAM,CAkB1E;AAED,2CAA2C;AAC3C,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGlE"}
|
package/lib/plugin.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ApexChartsCtor, WeavePluginDefinition } from './weave';
|
|
2
|
+
import { AnalystOptions } from './Analyst';
|
|
3
|
+
|
|
4
|
+
export declare const PLUGIN_NAME = "analyst";
|
|
5
|
+
/** The Weave plugin definition. */
|
|
6
|
+
export declare const analystPlugin: WeavePluginDefinition;
|
|
7
|
+
/**
|
|
8
|
+
* Register the plugin with an ApexCharts constructor.
|
|
9
|
+
*
|
|
10
|
+
* Idempotent. Charts opt in individually with `plugins: [{name: 'analyst'}]`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function install(ApexCharts: ApexChartsCtor): void;
|
|
13
|
+
/**
|
|
14
|
+
* Register the plugin AND make every chart created afterwards use it.
|
|
15
|
+
*
|
|
16
|
+
* Writes the plugin into the library's global chart defaults, so no chart needs
|
|
17
|
+
* a `plugins` entry of its own.
|
|
18
|
+
*
|
|
19
|
+
* One caveat, stated because it is silent otherwise: a chart that declares its
|
|
20
|
+
* own top-level `plugins` array overrides the global default rather than
|
|
21
|
+
* merging with it, so such a chart must list `analyst` itself.
|
|
22
|
+
*
|
|
23
|
+
* @param options passed to every chart's Analyst instance
|
|
24
|
+
*/
|
|
25
|
+
export declare function installOnEveryChart(ApexCharts: ApexChartsCtor, options?: AnalystOptions): void;
|
|
26
|
+
/**
|
|
27
|
+
* Show the toolbar on every chart that already has the plugin.
|
|
28
|
+
*
|
|
29
|
+
* Only useful alongside `plugins: [{name: 'analyst', options: {enabled: false}}]`,
|
|
30
|
+
* where charts carry the plugin but render no toolbar until this is called.
|
|
31
|
+
* Charts created before the plugin was installed cannot be reached at all;
|
|
32
|
+
* this reports how many were missed rather than pretending to cover them.
|
|
33
|
+
*
|
|
34
|
+
* @returns how many charts the toolbar was attached to
|
|
35
|
+
*/
|
|
36
|
+
export declare function page(): number;
|
|
37
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,WAAW,CAAC;AAE9C,OAAO,KAAK,EAAC,cAAc,EAAY,qBAAqB,EAAC,MAAM,SAAS,CAAC;AAE7E,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,mCAAmC;AACnC,eAAO,MAAM,aAAa,EAAE,qBAW3B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAExD;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAS9F;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,IAAI,MAAM,CA0B7B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page-level registry of live Analyst instances.
|
|
3
|
+
*
|
|
4
|
+
* `page()` needs every chart on the page, and the chart library's own
|
|
5
|
+
* `Apex._chartInstances` cannot supply that: a chart joins it only when the
|
|
6
|
+
* caller declares `chart.id`, which is optional and uncommon.
|
|
7
|
+
*
|
|
8
|
+
* Instances self-register from their constructor and unregister on teardown, so
|
|
9
|
+
* the set holds only mounted charts.
|
|
10
|
+
*
|
|
11
|
+
* Stored on a versioned `globalThis` slot, matching the registries inside the
|
|
12
|
+
* chart library itself. A module-level Set would live once per copy of this
|
|
13
|
+
* module, and a page can hold two (a bundled import plus a script tag).
|
|
14
|
+
*
|
|
15
|
+
* @module registry
|
|
16
|
+
*/
|
|
17
|
+
type Registrable = {
|
|
18
|
+
attach(): void;
|
|
19
|
+
};
|
|
20
|
+
export declare function register(analyst: Registrable): void;
|
|
21
|
+
export declare function unregister(analyst: Registrable): void;
|
|
22
|
+
/**
|
|
23
|
+
* Every registered Analyst, in creation order (a Set preserves insertion order,
|
|
24
|
+
* which is the order the charts were created and so the reading order of the
|
|
25
|
+
* page in the overwhelmingly common case).
|
|
26
|
+
*/
|
|
27
|
+
export declare function all(): Registrable[];
|
|
28
|
+
/**
|
|
29
|
+
* How many ApexCharts charts are actually in the document.
|
|
30
|
+
*
|
|
31
|
+
* Compared against the registry size to detect the load-order mistake: a chart
|
|
32
|
+
* created before the plugin was installed never got an Analyst instance and
|
|
33
|
+
* cannot be reached. Counts `.apexcharts-canvas` nodes, the wrap element the
|
|
34
|
+
* chart library creates for every chart on every render path.
|
|
35
|
+
*
|
|
36
|
+
* @returns -1 when there is no document to count (SSR)
|
|
37
|
+
*/
|
|
38
|
+
export declare function countChartsInDom(): number;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../libs/analyst/src/lib/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,KAAK,WAAW,GAAG;IAAC,MAAM,IAAI,IAAI,CAAA;CAAC,CAAC;AAYpC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAEnD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAErD;AAED;;;;GAIG;AACH,wBAAgB,GAAG,IAAI,WAAW,EAAE,CAEnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descriptive statistics.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions over `Array<number|null|undefined>`, because that is what a
|
|
5
|
+
* chart series actually holds: a null is a gap, and every one of these
|
|
6
|
+
* summaries has to skip gaps rather than read them as zero. Each function
|
|
7
|
+
* filters internally instead of trusting the caller to have cleaned the input,
|
|
8
|
+
* and reports how many values it dropped.
|
|
9
|
+
*
|
|
10
|
+
* No dependencies and no chart knowledge. The panel, a derived series and (in a
|
|
11
|
+
* later phase) an AI payload all read the same numbers from here rather than
|
|
12
|
+
* each reimplementing a mean.
|
|
13
|
+
*
|
|
14
|
+
* @module stats/Descriptive
|
|
15
|
+
*/
|
|
16
|
+
export interface Summary {
|
|
17
|
+
/** finite values used */
|
|
18
|
+
count: number;
|
|
19
|
+
/** values skipped (null / NaN / non-numeric) */
|
|
20
|
+
missing: number;
|
|
21
|
+
min: number;
|
|
22
|
+
max: number;
|
|
23
|
+
range: number;
|
|
24
|
+
sum: number;
|
|
25
|
+
mean: number;
|
|
26
|
+
median: number;
|
|
27
|
+
q1: number;
|
|
28
|
+
q3: number;
|
|
29
|
+
iqr: number;
|
|
30
|
+
/** sample variance (n-1) */
|
|
31
|
+
variance: number;
|
|
32
|
+
stdDev: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The finite numbers in a raw series, in order.
|
|
36
|
+
*
|
|
37
|
+
* `Number.isFinite` rather than `!= null` on purpose: NaN and Infinity reach a
|
|
38
|
+
* series through user formatters and arithmetic on missing values, and either
|
|
39
|
+
* one poisons a mean into NaN for the whole chart.
|
|
40
|
+
*/
|
|
41
|
+
export declare function finite(values: ReadonlyArray<number | null | undefined> | undefined): number[];
|
|
42
|
+
/**
|
|
43
|
+
* Summarize one series.
|
|
44
|
+
*
|
|
45
|
+
* Returns null rather than a zero-filled object when there is nothing to
|
|
46
|
+
* summarize, so a caller has to decide what to show for an empty series instead
|
|
47
|
+
* of silently rendering "mean 0" for no data.
|
|
48
|
+
*/
|
|
49
|
+
export declare function summarize(values: ReadonlyArray<number | null | undefined> | undefined): Summary | null;
|
|
50
|
+
//# sourceMappingURL=Descriptive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Descriptive.d.ts","sourceRoot":"","sources":["../../../../libs/analyst/src/lib/stats/Descriptive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,OAAO;IACtB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,MAAM,EAAE,CAQ7F;AAgBD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CA+CtG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordinary-least-squares line fitting.
|
|
3
|
+
*
|
|
4
|
+
* Used by the trend tool now and by the forecast tool later, which is why the
|
|
5
|
+
* fit is returned as a describable object (slope, intercept, r2, predict)
|
|
6
|
+
* rather than as the two endpoints the trend line happens to need. A forecast
|
|
7
|
+
* extrapolates from the same fit, and a readout needs to say how well the line
|
|
8
|
+
* actually explains the data.
|
|
9
|
+
*
|
|
10
|
+
* @module stats/Regression
|
|
11
|
+
*/
|
|
12
|
+
export interface LinearFit {
|
|
13
|
+
/** change in y per unit x */
|
|
14
|
+
slope: number;
|
|
15
|
+
/** y at x = 0 */
|
|
16
|
+
intercept: number;
|
|
17
|
+
/** coefficient of determination, 0..1 */
|
|
18
|
+
r2: number;
|
|
19
|
+
/** points used */
|
|
20
|
+
n: number;
|
|
21
|
+
predict(x: number): number;
|
|
22
|
+
}
|
|
23
|
+
export interface FitPoint {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fit y = slope*x + intercept by least squares.
|
|
29
|
+
*
|
|
30
|
+
* Pairs where either coordinate is non-finite are dropped: a series gap must
|
|
31
|
+
* not contribute a point at y=0, and an x gap has no position to contribute at
|
|
32
|
+
* all. Returns null when fewer than two usable pairs remain, or when every x is
|
|
33
|
+
* identical (a vertical line has no finite slope) rather than returning an
|
|
34
|
+
* Infinity a caller would then have to detect.
|
|
35
|
+
*
|
|
36
|
+
* x is centered before accumulating the sums. Chart x values are frequently
|
|
37
|
+
* epoch milliseconds, where x^2 is around 1e24 and the textbook
|
|
38
|
+
* `n*Sxy - Sx*Sy` form loses most of its significant digits to cancellation.
|
|
39
|
+
* Centering keeps the magnitudes small and costs one extra pass.
|
|
40
|
+
*/
|
|
41
|
+
export declare function linearFit(points: ReadonlyArray<FitPoint> | undefined): LinearFit | null;
|
|
42
|
+
//# sourceMappingURL=Regression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Regression.d.ts","sourceRoot":"","sources":["../../../../libs/analyst/src/lib/stats/Regression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,SAAS;IACxB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB;IAClB,CAAC,EAAE,MAAM,CAAC;IACV,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAwDvF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { WeaveAPI, WeaveChartInfo } from '../weave';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The fixed grid the fake scales project into. Exported so tests can predict
|
|
5
|
+
* pixels. `left`/`top` are non-zero ON PURPOSE: the real rc.2 host bakes the
|
|
6
|
+
* layout translate into its scales while the layer group is already translated,
|
|
7
|
+
* and Analyst has to rebase them to layer space. A fake whose scales started at
|
|
8
|
+
* zero could not tell a rebased drawing from an unrebased one.
|
|
9
|
+
*/
|
|
10
|
+
export declare const FAKE_GRID: {
|
|
11
|
+
left: number;
|
|
12
|
+
top: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
};
|
|
16
|
+
export interface FakeChartSpec {
|
|
17
|
+
/** Series as the caller wrote them. */
|
|
18
|
+
series: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
data: unknown[];
|
|
21
|
+
hidden?: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
categories?: string[];
|
|
24
|
+
info?: Partial<WeaveChartInfo>;
|
|
25
|
+
options?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface FakeChart {
|
|
28
|
+
api: WeaveAPI;
|
|
29
|
+
el: HTMLElement;
|
|
30
|
+
/** Every series currently on the chart, in order. */
|
|
31
|
+
seriesNames(): string[];
|
|
32
|
+
seriesData(name: string): unknown[] | undefined;
|
|
33
|
+
/** Simulate the caller changing the data. */
|
|
34
|
+
update(series: Array<{
|
|
35
|
+
name: string;
|
|
36
|
+
data: unknown[];
|
|
37
|
+
}>): Promise<void>;
|
|
38
|
+
/** Fire the initial render hook. */
|
|
39
|
+
draw(): void;
|
|
40
|
+
destroy(): void;
|
|
41
|
+
}
|
|
42
|
+
export declare function makeFakeChart(spec: FakeChartSpec): FakeChart;
|
|
43
|
+
/** The toolbar's shadow root for a given fake chart, or null. */
|
|
44
|
+
export declare function shadowOf(chart: FakeChart): ShadowRoot | null;
|
|
45
|
+
/**
|
|
46
|
+
* The readout's shadow root, which is a SEPARATE host from the toolbar's: the
|
|
47
|
+
* buttons go above the chart and the panel below it, so opening a readout
|
|
48
|
+
* cannot push the chart down the page.
|
|
49
|
+
*/
|
|
50
|
+
export declare function panelRootOf(chart: FakeChart): ShadowRoot | null;
|
|
51
|
+
/** The readout element itself, or null when no toolbar is mounted. */
|
|
52
|
+
export declare function panelOf(chart: FakeChart): HTMLElement | null;
|
|
53
|
+
/** The plugin's drawing group inside the fake chart's SVG, or null. */
|
|
54
|
+
export declare function overlayOf(chart: FakeChart): SVGGElement | null;
|
|
55
|
+
/** The `<line>` elements currently drawn on the overlay. */
|
|
56
|
+
export declare function overlayLines(chart: FakeChart): SVGLineElement[];
|
|
57
|
+
export declare function buttonLabels(chart: FakeChart): string[];
|
|
58
|
+
export declare function clickButton(chart: FakeChart, label: string): HTMLButtonElement;
|
|
59
|
+
//# sourceMappingURL=fakeWeave.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fakeWeave.d.ts","sourceRoot":"","sources":["../../../../libs/analyst/src/lib/testing/fakeWeave.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAC,QAAQ,EAAE,cAAc,EAAkD,MAAM,UAAU,CAAC;AAIxG;;;;;;GAMG;AACH,eAAO,MAAM,SAAS;;;;;CAA+C,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,MAAM,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC,CAAC;IACjE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,QAAQ,CAAC;IACd,EAAE,EAAE,WAAW,CAAC;IAChB,qDAAqD;IACrD,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC;IAChD,6CAA6C;IAC7C,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,oCAAoC;IACpC,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,IAAI,IAAI,CAAC;CACjB;AA8ED,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,CA4J5D;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,IAAI,CAG5D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,IAAI,CAG/D;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,IAAI,CAE5D;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,IAAI,CAE9D;AAED,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,cAAc,EAAE,CAE/D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAIvD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB,CAS9E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shims a real ApexCharts instance needs to render under jsdom.
|
|
3
|
+
*
|
|
4
|
+
* jsdom implements the SVG DOM but none of its geometry, so anything that
|
|
5
|
+
* measures (`getBBox`) returns undefined and the chart throws while laying out
|
|
6
|
+
* axis labels. `ResizeObserver` is missing outright. Both are the same shims the
|
|
7
|
+
* chart library uses for its own jsdom suite; they are here rather than imported
|
|
8
|
+
* because the library does not publish its test scaffolding.
|
|
9
|
+
*
|
|
10
|
+
* The fixed 10x10 box means nothing rendered here is a claim about layout. These
|
|
11
|
+
* tests assert what the plugin puts INTO the chart and gets back out of it, and
|
|
12
|
+
* a real browser is where pixels are checked.
|
|
13
|
+
*
|
|
14
|
+
* @module testing/jsdomSetup
|
|
15
|
+
*/
|
|
16
|
+
declare const BOX: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
top: number;
|
|
22
|
+
right: number;
|
|
23
|
+
bottom: number;
|
|
24
|
+
left: number;
|
|
25
|
+
};
|
|
26
|
+
/** TypeScript's DOM lib has no `getBBox`, so the prototype is widened to add it. */
|
|
27
|
+
type Measurable = {
|
|
28
|
+
getBBox?: () => typeof BOX;
|
|
29
|
+
};
|
|
30
|
+
declare function stubBBox(proto: object | undefined): void;
|
|
31
|
+
//# sourceMappingURL=jsdomSetup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsdomSetup.d.ts","sourceRoot":"","sources":["../../../../libs/analyst/src/lib/testing/jsdomSetup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,QAAA,MAAM,GAAG;;;;;;;;;CAA8E,CAAC;AAExF,oFAAoF;AACpF,KAAK,UAAU,GAAG;IAAC,OAAO,CAAC,EAAE,MAAM,OAAO,GAAG,CAAA;CAAC,CAAC;AAE/C,iBAAS,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAKjD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mounting a real ApexCharts instance, for the tests that have to.
|
|
3
|
+
*
|
|
4
|
+
* The chart library is a peer dependency of the published package and a dev
|
|
5
|
+
* dependency of this workspace. See the note in fakeWeave for which tests belong
|
|
6
|
+
* here and which belong against the fake host.
|
|
7
|
+
*
|
|
8
|
+
* The dev dependency is pinned exactly to `7.2.0-rc.2`. Exactly, not a range:
|
|
9
|
+
* this package declares `apiVersion: 2`, so the host it is tested against is
|
|
10
|
+
* the contract, and moving off it should be a decision rather than something an
|
|
11
|
+
* install does on its own. Moving the pin means running this file's tests
|
|
12
|
+
* against the new host and reading what changed under `src/modules/weave`.
|
|
13
|
+
*
|
|
14
|
+
* The peer range stays `>=7.2.0-rc.1`, which is the earliest host that carries
|
|
15
|
+
* Weave v2 and is the honest floor for a consumer. It is deliberately wider
|
|
16
|
+
* than the pin: the pin says what we test, the range says what works.
|
|
17
|
+
*
|
|
18
|
+
* When 7.2.0 stable lands, move the pin to it and tighten the peer range to
|
|
19
|
+
* `>=7.2.0`, so a consumer is not pointed at a prerelease.
|
|
20
|
+
*
|
|
21
|
+
* @module testing/realChart
|
|
22
|
+
*/
|
|
23
|
+
/** The chart internals these tests read. Not part of any public contract. */
|
|
24
|
+
interface ChartInternals {
|
|
25
|
+
w: {
|
|
26
|
+
config: {
|
|
27
|
+
series: Array<{
|
|
28
|
+
name?: string;
|
|
29
|
+
data?: unknown[];
|
|
30
|
+
}>;
|
|
31
|
+
dataLabels?: {
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
enabledOnSeries?: number[];
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
globals: {
|
|
37
|
+
series: number[][];
|
|
38
|
+
seriesX: number[][];
|
|
39
|
+
initialSeries: Array<{
|
|
40
|
+
name?: string;
|
|
41
|
+
data?: unknown[];
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
render(): Promise<unknown>;
|
|
46
|
+
updateSeries(series: unknown[]): Promise<unknown>;
|
|
47
|
+
resetSeries(): void;
|
|
48
|
+
destroy(): void;
|
|
49
|
+
}
|
|
50
|
+
export interface RealChart {
|
|
51
|
+
chart: ChartInternals;
|
|
52
|
+
el: HTMLElement;
|
|
53
|
+
/** Every series on the chart, in order, derived ones included. */
|
|
54
|
+
names(): string[];
|
|
55
|
+
/** The data array as it sits in config: the shape the plugin emitted. */
|
|
56
|
+
raw(name: string): unknown[] | undefined;
|
|
57
|
+
/** Parsed y values. A wrong emitted shape shows up here as all-null. */
|
|
58
|
+
y(name: string): Array<number | null> | undefined;
|
|
59
|
+
/** Parsed x positions. A derived series must land on the source's. */
|
|
60
|
+
x(name: string): number[] | undefined;
|
|
61
|
+
destroy(): void;
|
|
62
|
+
}
|
|
63
|
+
/** Let a queued chart update and the render it causes finish. */
|
|
64
|
+
export declare function settle(rounds?: number): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Render a chart with the analyst plugin attached.
|
|
67
|
+
*
|
|
68
|
+
* Animations are off because an animated update resolves on a timer, and a test
|
|
69
|
+
* that waits for one is measuring the machine.
|
|
70
|
+
*/
|
|
71
|
+
export declare function mountChart(options: Record<string, unknown>): Promise<RealChart>;
|
|
72
|
+
/** The toolbar's shadow root for a real chart, or null when none attached. */
|
|
73
|
+
export declare function shadowOf(chart: RealChart): ShadowRoot | null;
|
|
74
|
+
export declare function buttonLabels(chart: RealChart): string[];
|
|
75
|
+
/** Click a toolbar button and wait for whatever it queued against the chart. */
|
|
76
|
+
export declare function clickButton(chart: RealChart, label: string): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* The readout's shadow root, which is a SEPARATE host from the toolbar's: the
|
|
79
|
+
* buttons go above the chart and the panel below it, so opening a readout
|
|
80
|
+
* cannot push the chart down the page.
|
|
81
|
+
*/
|
|
82
|
+
export declare function panelRootOf(chart: RealChart): ShadowRoot | null;
|
|
83
|
+
/** Text of the open readout panel. */
|
|
84
|
+
export declare function panelText(chart: RealChart): string;
|
|
85
|
+
/**
|
|
86
|
+
* The plugin's drawing group inside the REAL chart's SVG, or null. Its
|
|
87
|
+
* placement is the host's `_layer()` contract: a `<g class="apexcharts-plugin-
|
|
88
|
+
* analyst">` appended to the chart's graphical group, so it ships in the
|
|
89
|
+
* chart's own exports and needs no position syncing.
|
|
90
|
+
*/
|
|
91
|
+
export declare function overlayOf(chart: RealChart): SVGGElement | null;
|
|
92
|
+
/** The `<line>` elements currently drawn on the overlay. */
|
|
93
|
+
export declare function overlayLines(chart: RealChart): SVGLineElement[];
|
|
94
|
+
export {};
|
|
95
|
+
//# sourceMappingURL=realChart.d.ts.map
|