@bicharts/chart-host 0.6.56 → 0.6.59
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/dist/{chunk-CMHGGW3Y.mjs → chunk-5NSU3MYW.mjs} +41 -110
- package/dist/chunk-WNGJUPEI.mjs +114 -0
- package/dist/chunk-XIAL6EEC.mjs +598 -0
- package/dist/dax.mjs +60 -0
- package/dist/geo.mjs +3 -3
- package/dist/index.mjs +49 -47
- package/dist/page.mjs +34 -0
- package/dist/react.mjs +299 -9
- package/dist/testing.mjs +46 -1
- package/dist/types/controls.d.ts +50 -0
- package/dist/types/dax.d.ts +22 -0
- package/dist/types/filterScope.d.ts +173 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/markNotes.d.ts +30 -0
- package/dist/types/page.d.ts +4 -0
- package/dist/types/react.d.ts +100 -2
- package/dist/types/testing/index.d.ts +1 -0
- package/dist/types/testing/interact.d.ts +17 -0
- package/package.json +11 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Filter, FilterKey } from "./filterScope";
|
|
2
|
+
/** One value as a DAX literal: text quoted with "" doubled, numbers, TRUE()/FALSE(), dates, BLANK(). */
|
|
3
|
+
export declare function daxLiteral(v: unknown): string;
|
|
4
|
+
/**
|
|
5
|
+
* TREATAS over a filter's selected keys (or keys given directly), onto the named model columns -
|
|
6
|
+
* or null when nothing is selected, so `calculateTable` leaves the query unfiltered.
|
|
7
|
+
*/
|
|
8
|
+
export declare function treatAs(selection: Filter | readonly (FilterKey | unknown)[] | null | undefined, ...columnRefs: string[]): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* CALCULATETABLE(table, filters...) with the null filters dropped - the table expression unchanged
|
|
11
|
+
* when none is left. `table` is a table expression (SUMMARIZECOLUMNS(...)), not a whole query with
|
|
12
|
+
* EVALUATE.
|
|
13
|
+
*/
|
|
14
|
+
export declare function calculateTable(table: string, ...filters: Array<string | null | undefined | false>): string;
|
|
15
|
+
/**
|
|
16
|
+
* A whole query (`[DEFINE ...] EVALUATE <table> [ORDER BY ...]`, as a .dax file holds it) with its table filtered:
|
|
17
|
+
* the table expression goes inside CALCULATETABLE with the filters, DEFINE and ORDER BY stay where they are. With no
|
|
18
|
+
* live filter the query comes back unchanged. One EVALUATE only (throws on more).
|
|
19
|
+
*
|
|
20
|
+
* filterQuery(FORECAST_DAX, treatAs(region, "Geography[RegionCode]"))
|
|
21
|
+
*/
|
|
22
|
+
export declare function filterQuery(query: string, ...filters: Array<string | null | undefined | false>): string;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { ChartHost } from "./host";
|
|
2
|
+
import type { Controls } from "./controls";
|
|
3
|
+
/** Why a filter changed. */
|
|
4
|
+
export type FilterChangeReason = "click" | "clear" | "page" | "data";
|
|
5
|
+
/** One selected key: a value per key column, in the filter's column order. */
|
|
6
|
+
export type FilterKey = readonly unknown[];
|
|
7
|
+
export interface FilterOptions {
|
|
8
|
+
/** What a chip calls this filter ("Country"). Defaults to the key columns. */
|
|
9
|
+
label?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The column(s) a chip shows for a selected key, read from the selected rows ("Country" for a
|
|
12
|
+
* RegionCode key; ["OriginName", "DestinationName"] for a route, joined " → ").
|
|
13
|
+
* Defaults to the key columns.
|
|
14
|
+
*/
|
|
15
|
+
display?: string | readonly string[];
|
|
16
|
+
/** A stable id for this filter within its scope. Generated when absent. */
|
|
17
|
+
id?: string;
|
|
18
|
+
/** Its name in a saved view (scope.save / a link). Defaults to the key columns joined with "+". */
|
|
19
|
+
key?: string;
|
|
20
|
+
/**
|
|
21
|
+
* LINKED HOVER: hovering a mark on a chart bound to this filter lights the marks with the same key on every other
|
|
22
|
+
* chart bound to it (a glow, never a filter). Off by default.
|
|
23
|
+
*/
|
|
24
|
+
hover?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface Filter {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
/** Its name in a saved view. */
|
|
29
|
+
readonly key: string;
|
|
30
|
+
/** Whether linked hover is on (FilterOptions.hover). */
|
|
31
|
+
readonly hoverEnabled: boolean;
|
|
32
|
+
/** The key being hovered on a bound chart now, or null. */
|
|
33
|
+
readonly hovered: FilterKey | null;
|
|
34
|
+
/** Set or clear the hovered key (bound charts do this; a page may too). */
|
|
35
|
+
setHover(key: FilterKey | null): void;
|
|
36
|
+
/** Subscribe to hover changes. Returns the unsubscribe. */
|
|
37
|
+
onHover(cb: (key: FilterKey | null) => void): () => void;
|
|
38
|
+
/** The key column(s). */
|
|
39
|
+
readonly columns: readonly string[];
|
|
40
|
+
readonly label: string;
|
|
41
|
+
/** True while anything is selected. */
|
|
42
|
+
readonly active: boolean;
|
|
43
|
+
/** The selected keys, each one value per key column. */
|
|
44
|
+
readonly keys: readonly FilterKey[];
|
|
45
|
+
/** The rows the selection was made from (for display names); rows of keys set by value are absent. */
|
|
46
|
+
readonly rows: readonly Record<string, unknown>[];
|
|
47
|
+
/** The first selected row, or null. */
|
|
48
|
+
readonly row: Record<string, unknown> | null;
|
|
49
|
+
/** The first key's first value, or null - the common one-column, one-pick case. */
|
|
50
|
+
readonly value: unknown;
|
|
51
|
+
/** Every selected key's first value. */
|
|
52
|
+
readonly values: readonly unknown[];
|
|
53
|
+
/** What a chip shows: the display column(s) of each selected key, "A → B" within a key, ", " between keys. */
|
|
54
|
+
readonly text: string;
|
|
55
|
+
/**
|
|
56
|
+
* The display text for ANY key - a badge's, a key set by value - read from `rows` (a table carrying the display
|
|
57
|
+
* columns, e.g. the chart's own rows) or else from the rows this filter has seen; the key's values when neither
|
|
58
|
+
* has it.
|
|
59
|
+
*/
|
|
60
|
+
textOf(key: FilterKey | unknown, rows?: readonly Record<string, unknown>[]): string;
|
|
61
|
+
/** Why the last change happened (null before any). */
|
|
62
|
+
readonly reason: FilterChangeReason | null;
|
|
63
|
+
/** Bumped on every change: a cheap identity for memoising on the filter's state. */
|
|
64
|
+
readonly version: number;
|
|
65
|
+
/** Select these rows' keys (replacing the selection). An empty list clears. */
|
|
66
|
+
selectRows(rows: readonly Record<string, unknown>[], reason?: FilterChangeReason): void;
|
|
67
|
+
/** Select keys by value: one value per key (a one-column filter) or one array per key. */
|
|
68
|
+
set(keys: readonly unknown[] | readonly FilterKey[] | unknown, reason?: FilterChangeReason): void;
|
|
69
|
+
/** Clear the selection (and every bound chart's marks). */
|
|
70
|
+
clear(reason?: FilterChangeReason): void;
|
|
71
|
+
/** Does this row carry a selected key? Read on `columns` (default: the key columns). */
|
|
72
|
+
has(row: Record<string, unknown>, columns?: readonly string[]): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* The rows that carry a selected key - every row while nothing is selected. `columns` names
|
|
75
|
+
* where this table keeps the key when it differs from the filter's: a one-column filter
|
|
76
|
+
* matched against several columns keeps a row when ANY of them carries the key (a route
|
|
77
|
+
* table filtered by a country keeps routes from OR to it). The same array comes back while
|
|
78
|
+
* the input and the filter are unchanged, so it's safe to call during render.
|
|
79
|
+
*/
|
|
80
|
+
keep<T extends Record<string, unknown>>(rows: readonly T[], columns?: readonly string[]): T[];
|
|
81
|
+
/** Subscribe to changes. Returns the unsubscribe. */
|
|
82
|
+
onChange(cb: (filter: Filter, reason: FilterChangeReason) => void): () => void;
|
|
83
|
+
}
|
|
84
|
+
/** A page's filters: what a chip bar lists and what clear-all clears. */
|
|
85
|
+
export interface FilterScope {
|
|
86
|
+
readonly filters: readonly Filter[];
|
|
87
|
+
/** The filters with something selected. */
|
|
88
|
+
readonly active: readonly Filter[];
|
|
89
|
+
/** Make a filter in this scope (see createFilter). */
|
|
90
|
+
filter(columns: string | readonly string[], opts?: FilterOptions): Filter;
|
|
91
|
+
/** Add an existing filter. Returns the remove. */
|
|
92
|
+
add(filter: Filter): () => void;
|
|
93
|
+
/** Clear every filter. */
|
|
94
|
+
clearAll(reason?: FilterChangeReason): void;
|
|
95
|
+
/** Subscribe to any change of any filter or controls, and to either being added or removed. */
|
|
96
|
+
onChange(cb: (scope: FilterScope) => void): () => void;
|
|
97
|
+
/** A chart's controls, to be saved and restored with the page's view. Returns the remove. */
|
|
98
|
+
addControls(key: string, controls: Controls): () => void;
|
|
99
|
+
/** The registered controls, by key. */
|
|
100
|
+
readonly controls: ReadonlyMap<string, Controls>;
|
|
101
|
+
/** The page's view now: every filter's keys and every registered controls' values - JSON-safe. */
|
|
102
|
+
save(): PageView;
|
|
103
|
+
/** Put a saved view back: each filter set (or cleared when the view doesn't name it), each controls set. */
|
|
104
|
+
restore(view: PageView | null | undefined): void;
|
|
105
|
+
}
|
|
106
|
+
/** A saved page view: what save() returns and restore() takes. */
|
|
107
|
+
export interface PageView {
|
|
108
|
+
v: 1;
|
|
109
|
+
filters?: Record<string, unknown[][]>;
|
|
110
|
+
controls?: Record<string, Record<string, unknown>>;
|
|
111
|
+
}
|
|
112
|
+
/** A view as a URL-safe token (base64url of its JSON), for a link or a bookmark. */
|
|
113
|
+
export declare function viewToken(view: PageView): string;
|
|
114
|
+
/** A token from viewToken back to a view; null when it isn't one. */
|
|
115
|
+
export declare function viewFromToken(token: string | null | undefined): PageView | null;
|
|
116
|
+
/** Make a filter keyed by `columns` (one name, or several for a compound key such as a route). */
|
|
117
|
+
export declare function createFilter(columns: string | readonly string[], opts?: FilterOptions): Filter;
|
|
118
|
+
/** Make a page's filter scope. */
|
|
119
|
+
export declare function createFilterScope(): FilterScope;
|
|
120
|
+
export interface FilterBinding {
|
|
121
|
+
/**
|
|
122
|
+
* Call after the chart is handed new data. A selection whose key is still drawn is repainted;
|
|
123
|
+
* one whose key is gone is cleared (reason "data") when this chart made it. An empty payload is
|
|
124
|
+
* treated as data still arriving, not as the key being gone.
|
|
125
|
+
*/
|
|
126
|
+
reconcile(): void;
|
|
127
|
+
/** Repaint the filter's selection onto the chart's marks. */
|
|
128
|
+
paint(): void;
|
|
129
|
+
/** Unwire. The filter keeps its selection. */
|
|
130
|
+
detach(): void;
|
|
131
|
+
}
|
|
132
|
+
export interface BindFilterOptions {
|
|
133
|
+
/** The source row (keyed by column name) behind payload row `i`, or null. */
|
|
134
|
+
rowAt(i: number): Record<string, unknown> | null;
|
|
135
|
+
/** How many rows the chart is drawing now. */
|
|
136
|
+
rowCount(): number;
|
|
137
|
+
/** The chart's container, for linked hover (FilterOptions.hover). Without it the chart takes no part in hover. */
|
|
138
|
+
container?: HTMLElement | null;
|
|
139
|
+
}
|
|
140
|
+
/** The class a mark wears while its key is hovered on another chart bound to the same filter. */
|
|
141
|
+
export declare const LINKED_HOVER_CLASS = "bic-linked-hover";
|
|
142
|
+
/** The source row behind each payload row, from a payload of { columns, rows: unknown[][] }. */
|
|
143
|
+
export declare function payloadRowReader(getPayload: () => {
|
|
144
|
+
columns: readonly {
|
|
145
|
+
name: string;
|
|
146
|
+
}[];
|
|
147
|
+
rows: readonly unknown[][];
|
|
148
|
+
} | null | undefined): BindFilterOptions;
|
|
149
|
+
/**
|
|
150
|
+
* Wire one chart host to one filter. A click on the chart sets the filter (reason "click"), the
|
|
151
|
+
* chart's own clear gesture clears it (reason "clear"), and any change to the filter - from this
|
|
152
|
+
* chart, another chart, or the page - is painted onto this chart's marks. Paints notify the host's
|
|
153
|
+
* subscribers with source "host", which this binding (and a chart group) never republishes.
|
|
154
|
+
*/
|
|
155
|
+
export declare function bindFilter(host: ChartHost, filter: Filter, opts: BindFilterOptions): FilterBinding;
|
|
156
|
+
/** The interaction events @microsoft/fabric-visuals' VegaVisual and DataGrid emit (onInteraction). */
|
|
157
|
+
export interface VegaInteractionEvent {
|
|
158
|
+
action: string;
|
|
159
|
+
selections?: Array<{
|
|
160
|
+
predicates?: Array<{
|
|
161
|
+
type?: string;
|
|
162
|
+
name?: string;
|
|
163
|
+
values?: unknown[];
|
|
164
|
+
}>;
|
|
165
|
+
}>;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Apply a VegaVisual / DataGrid `onInteraction` event list to a filter, so Microsoft's charts take
|
|
169
|
+
* part in the same page filters as ours: `onInteraction={e => fromVegaInteraction(country, e)}`.
|
|
170
|
+
* A `select` sets the filter from the set predicates that name its key columns (a selection
|
|
171
|
+
* missing one of them is skipped); a `clear` clears it. Returns whether the filter changed.
|
|
172
|
+
*/
|
|
173
|
+
export declare function fromVegaInteraction(filter: Filter, events: readonly VegaInteractionEvent[] | null | undefined): boolean;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ export { buildRenderPayload, type RenderPayload, type GeoPointBinding } from "./
|
|
|
9
9
|
export { codeReadsDatesInLocalTime, vegaSpecReadsDatesInLocalTime } from "./dateCells";
|
|
10
10
|
export { createChartHost, compileRenderFn, stripEsmExports, requiredD3Plugins, explainRenderFailure, sessionViewStateProvider, noopViewStateProvider, assembleD3, D3_PLUGIN_PACKAGES, type ChartHost, type ChartHostConfig, type RenderFn } from "./host";
|
|
11
11
|
export { ANNOTATION_CLASS, ANNOTATION_LAYER_CLASS, type MarkAnnotation, type AnnotationReport } from "./annotations";
|
|
12
|
+
export type { MarkNoteLike, NoteBadgeOptions } from "./markNotes";
|
|
13
|
+
export type { Controls, ControlInfo, ControlsAttachment } from "./controls";
|
|
12
14
|
export { createChartGroup, toSourceRows, syncMemberSelection, type ChartGroup, type ChartGroupMember, type ChartGroupSelection, type ChartGroupChange, type ChartGroupMemberOptions, type ChartGroupSourceOptions, type ChartGroupPayload } from "./group";
|
|
15
|
+
export type { Filter, FilterScope, FilterOptions, FilterKey, FilterChangeReason, FilterBinding, BindFilterOptions, VegaInteractionEvent, PageView } from "./filterScope";
|
|
13
16
|
export { createMarkResolver, isInsideControl, rowIdxsFromMark, nextSelection, collectD3GlyphCenters, clearSelectionGlyphs, paintSelectionGlyphs, SELECTION_GLYPH_CLASS, type MarkResolver, type MarkResolverEnv, type GlyphCenter, type SelectionGlyphStyle, type SelectionModifiers, } from "./selection";
|
|
14
17
|
export { planTrivialChart, compileTrivialSource, type TrivialPlan, type TrivialShapeKind } from "./trivial";
|
|
15
18
|
export { captureSvgSnapshot, svgToDataUrl, svgNaturalSize, rasterizeSvgToPngDataUrl, tableHostOf, chartSvgOf, htmlToSvgDataUrl, htmlNaturalSize, type SnapshotOptions } from "./snapshot";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MarkAnnotation } from "./annotations";
|
|
2
|
+
import type { Filter, FilterKey } from "./filterScope";
|
|
3
|
+
export interface MarkNoteLike {
|
|
4
|
+
chart?: string | null;
|
|
5
|
+
markKey?: unknown;
|
|
6
|
+
markKeyTo?: unknown;
|
|
7
|
+
body?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface NoteBadgeOptions<N> {
|
|
10
|
+
/** The chart's key column(s) the note keys live in: "RegionCode", or a route's two ends. */
|
|
11
|
+
columns: string | readonly string[];
|
|
12
|
+
/** Only notes whose `chart` is this (one notes table serving several charts). */
|
|
13
|
+
chart?: string;
|
|
14
|
+
/** A note's key, one value per column. Default: [markKey] or [markKey, markKeyTo]. */
|
|
15
|
+
keyOf?: (note: N) => readonly unknown[];
|
|
16
|
+
/** A note's text. Default: body. */
|
|
17
|
+
textOf?: (note: N) => string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* One badge per noted mark: the count of its notes, the latest note as the tooltip (notes are
|
|
21
|
+
* taken in the order given - pass them newest first). Pass to a chart's `annotations`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function noteBadges<N extends MarkNoteLike>(notes: readonly N[] | null | undefined, opts: NoteBadgeOptions<N>): MarkAnnotation[];
|
|
24
|
+
/** The key values of a badge noteBadges made (for a click: which mark's notes to open). */
|
|
25
|
+
export declare function badgeKey(a: MarkAnnotation): FilterKey;
|
|
26
|
+
/**
|
|
27
|
+
* The notes on one mark - a key given directly, or the first key selected in a page filter - in
|
|
28
|
+
* the order given. Keys compare as trimmed text, so a numeric code and its string agree.
|
|
29
|
+
*/
|
|
30
|
+
export declare function notesFor<N extends MarkNoteLike>(notes: readonly N[] | null | undefined, key: Filter | FilterKey | null | undefined, opts: Omit<NoteBadgeOptions<N>, "textOf">): N[];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { viewToken, viewFromToken, LINKED_HOVER_CLASS, type PageView } from "./filterScope";
|
|
2
|
+
export { createFilter, createFilterScope, bindFilter, payloadRowReader, fromVegaInteraction, type Filter, type FilterScope, type FilterOptions, type FilterKey, type FilterChangeReason, type FilterBinding, type BindFilterOptions, type VegaInteractionEvent } from "./filterScope";
|
|
3
|
+
export { createControls, attachControls, readControls, type Controls, type ControlInfo, type ControlsAttachment } from "./controls";
|
|
4
|
+
export { noteBadges, badgeKey, notesFor, type MarkNoteLike, type NoteBadgeOptions } from "./markNotes";
|
package/dist/types/react.d.ts
CHANGED
|
@@ -2,7 +2,13 @@ import type { ReactNode, RefObject } from "react";
|
|
|
2
2
|
import { type ChartHostConfig } from "./host";
|
|
3
3
|
import type { ResolveOptionsInput } from "./defaults";
|
|
4
4
|
import type { GeoPointBinding } from "./payload";
|
|
5
|
+
import { type PageView, type Filter, type FilterOptions } from "./filterScope";
|
|
5
6
|
export { assembleD3 } from "./host";
|
|
7
|
+
import { type Controls } from "./controls";
|
|
8
|
+
export { createControls, type Controls, type ControlInfo } from "./controls";
|
|
9
|
+
export { noteBadges, badgeKey, notesFor, type MarkNoteLike, type NoteBadgeOptions } from "./markNotes";
|
|
10
|
+
export { viewToken, viewFromToken, LINKED_HOVER_CLASS, type PageView } from "./filterScope";
|
|
11
|
+
export { createFilter, createFilterScope, fromVegaInteraction, type Filter, type FilterOptions, type FilterScope, type FilterChangeReason } from "./filterScope";
|
|
6
12
|
export interface BicChartProps {
|
|
7
13
|
/** Generated render() source (an ES module's `code` export, or the raw string). */
|
|
8
14
|
code?: string;
|
|
@@ -59,11 +65,34 @@ export interface BicChartProps {
|
|
|
59
65
|
* now two props rather than a DOM workaround.
|
|
60
66
|
*/
|
|
61
67
|
respondsWith?: "filter" | "highlight";
|
|
62
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* THE PAGE FILTER THIS CHART SELECTS - from useBicFilter("RegionCode"). A click sets it, the
|
|
70
|
+
* same click or a click on empty canvas clears it, and the filter's state is painted onto the
|
|
71
|
+
* marks whoever changed it: `filter.clear()` from a page button clears the marks too. New data
|
|
72
|
+
* keeps a selection whose key is still drawn and clears (reason "data") one whose key is gone.
|
|
73
|
+
* The page reads `filter.value` / `filter.row` and never writes a select handler. With
|
|
74
|
+
* `selects`, the filter owns what this chart shows as selected.
|
|
75
|
+
*/
|
|
76
|
+
selects?: Filter;
|
|
77
|
+
/**
|
|
78
|
+
* THE CHART'S OWN CONTROLS AS PAGE STATE - from useBicControls(). For a chart that draws
|
|
79
|
+
* sliders (the What-if projection's rate and horizon): `controls.values` holds every
|
|
80
|
+
* knob's value from the first draw (no slider has to move first), `controls.info` / `summary`
|
|
81
|
+
* the chart's own label and readout for each ("growth per year +5.5%"), `controls.set(saved)`
|
|
82
|
+
* applies a saved scenario and `controls.reset()` returns to the defaults. It owns the chart's
|
|
83
|
+
* uiState / setUiState.
|
|
84
|
+
*/
|
|
85
|
+
controls?: Controls;
|
|
86
|
+
/**
|
|
87
|
+
* Selection callback in SOURCE row indices (group) or payload indices (standalone). An empty
|
|
88
|
+
* list means the selection was CLEARED: the same mark clicked again, a click on empty canvas,
|
|
89
|
+
* or new data that no longer draws what was selected. The chart toggles for you - set your
|
|
90
|
+
* state from exactly what this gives you, never toggle it again. Prefer `selects`.
|
|
91
|
+
*/
|
|
63
92
|
onSelect?: (rowIdxs: number[]) => void;
|
|
64
93
|
/**
|
|
65
94
|
* Notes on marks: a badge on each key's mark, redrawn after every render - e.g.
|
|
66
|
-
* `[{ column: "
|
|
95
|
+
* `[{ column: "RegionCode", value: "JPN", label: "2", title: "..." }]`. Keyed by a value in a column,
|
|
67
96
|
* never a row position, so a filter or a re-query never moves one.
|
|
68
97
|
*/
|
|
69
98
|
annotations?: ChartHostConfig["annotations"];
|
|
@@ -71,6 +100,8 @@ export interface BicChartProps {
|
|
|
71
100
|
onAnnotationClick?: ChartHostConfig["onAnnotationClick"];
|
|
72
101
|
className?: string;
|
|
73
102
|
style?: React.CSSProperties;
|
|
103
|
+
/** What a screen reader announces for the chart ("Occupancy vs average daily rate, by country"). */
|
|
104
|
+
ariaLabel?: string;
|
|
74
105
|
}
|
|
75
106
|
/** Read the group's selection from a page — for a "clear" button or a count. */
|
|
76
107
|
export declare function useBicSelection(): {
|
|
@@ -100,6 +131,73 @@ export interface BicChartGroupProps {
|
|
|
100
131
|
*/
|
|
101
132
|
export declare function BicChartGroup({ rows, columns, geo, point, destination, children }: BicChartGroupProps): import("react").JSX.Element;
|
|
102
133
|
export declare function BicChart(props: BicChartProps): import("react").JSX.Element;
|
|
134
|
+
/**
|
|
135
|
+
* A SEPARATE filter scope, for an app with several independent pages or panels mounted at once.
|
|
136
|
+
* Not needed otherwise: every filter joins the app's one default scope. Call useBicFilter in a
|
|
137
|
+
* component INSIDE it - a hook can't see a provider its own component renders.
|
|
138
|
+
*/
|
|
139
|
+
export declare function BicPage({ children }: {
|
|
140
|
+
children: ReactNode;
|
|
141
|
+
}): import("react").JSX.Element;
|
|
142
|
+
/**
|
|
143
|
+
* A page filter keyed by one model column ("RegionCode") or several (a route:
|
|
144
|
+
* ["OriginCode", "DestinationCode"]). Pass it to a chart's `selects` and read
|
|
145
|
+
* `value` / `values` / `row` / `active` for the rest of the page; `clear()` clears it and the
|
|
146
|
+
* chart's marks. Re-renders the component on every change. The key columns are read once.
|
|
147
|
+
*/
|
|
148
|
+
export declare function useBicFilter(columns: string | readonly string[], opts?: FilterOptions): Filter;
|
|
149
|
+
/**
|
|
150
|
+
* A chart's in-chart controls as page state: pass to the chart's `controls`, read `values`, `info`
|
|
151
|
+
* and `summary`, `set(saved)` to apply a saved scenario, `reset()` for the defaults. Re-renders the
|
|
152
|
+
* component on every change. `initial` seeds the values the chart first draws with.
|
|
153
|
+
*/
|
|
154
|
+
export declare function useBicControls(initial?: Readonly<Record<string, unknown>>, opts?: {
|
|
155
|
+
id?: string;
|
|
156
|
+
}): Controls;
|
|
157
|
+
/**
|
|
158
|
+
* THE PAGE'S VIEW, SAVED AND PUT BACK: every page filter's keys and every chart's controls (useBicControls). `save()`
|
|
159
|
+
* returns a JSON-safe view to store (a saved view, a user preference); `restore(view)` puts one back; `token()` /
|
|
160
|
+
* `restoreToken(t)` do the same as a URL-safe string for a link.
|
|
161
|
+
*/
|
|
162
|
+
export declare function useBicView(): {
|
|
163
|
+
save: () => PageView;
|
|
164
|
+
restore: (v: PageView | null | undefined) => void;
|
|
165
|
+
token: () => string;
|
|
166
|
+
restoreToken: (t: string | null | undefined) => void;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* THE VIEW IN THE ADDRESS BAR (opt-in): restores the page's filters and controls from `?<param>=` on mount, then keeps
|
|
170
|
+
* the parameter current as they change (history.replaceState - no navigation, no new history entries). A copied link
|
|
171
|
+
* opens the page as it was. Call once, in the page component, after its useBicFilter / useBicControls calls.
|
|
172
|
+
*/
|
|
173
|
+
export declare function useBicUrlState(param?: string): void;
|
|
174
|
+
/**
|
|
175
|
+
* A DEVELOPER'S VIEW OF THE PAGE'S STATE: every filter (its keys, its text, the last change and why), every chart's
|
|
176
|
+
* controls, and the last changes in order. Collapsed in a corner; render it only in development.
|
|
177
|
+
*/
|
|
178
|
+
export declare function BicDevtools({ max }: {
|
|
179
|
+
max?: number;
|
|
180
|
+
}): import("react").JSX.Element;
|
|
181
|
+
/** Every filter on the page (or the enclosing <BicPage>), and its clear-all - for a page's own chip bar or count. */
|
|
182
|
+
export declare function useBicFilters(): {
|
|
183
|
+
filters: readonly Filter[];
|
|
184
|
+
active: readonly Filter[];
|
|
185
|
+
clearAll: () => void;
|
|
186
|
+
};
|
|
187
|
+
export interface BicFilterChipsProps {
|
|
188
|
+
className?: string;
|
|
189
|
+
/** Each chip's class (the label, the value and its × are inside). */
|
|
190
|
+
chipClassName?: string;
|
|
191
|
+
/** The words on the clear-all button, shown when two or more filters are active. Default "Clear all". */
|
|
192
|
+
clearAllText?: string;
|
|
193
|
+
style?: React.CSSProperties;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* What the page is filtered by: one chip per active filter ("Country: Japan ×"), a × that
|
|
197
|
+
* clears it (and its chart's marks), and "Clear all" when two or more are active. Renders nothing
|
|
198
|
+
* while nothing is filtered. Plain markup with class names to style.
|
|
199
|
+
*/
|
|
200
|
+
export declare function BicFilterChips({ className, chipClassName, clearAllText, style }: BicFilterChipsProps): import("react").JSX.Element;
|
|
103
201
|
/**
|
|
104
202
|
* THE SIZE A CHART SHOULD DRAW AT: the element's measured box, kept current as it resizes.
|
|
105
203
|
*
|
|
@@ -12,3 +12,4 @@ export declare class ConformanceError extends Error {
|
|
|
12
12
|
* before returning, whether or not the check passed.
|
|
13
13
|
*/
|
|
14
14
|
export declare function assertMarkerStoreConformance(store: MarkerStore): Promise<void>;
|
|
15
|
+
export { chartContainers, marksOf, findMark, clickMark, clickEmpty, selectedRows } from "./interact";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Every hosted chart container under `root` (a page, a component's element). */
|
|
2
|
+
export declare function chartContainers(root: ParentNode): HTMLElement[];
|
|
3
|
+
/** The chart's data marks, in DOM order. */
|
|
4
|
+
export declare function marksOf(chart: ParentNode): Element[];
|
|
5
|
+
/**
|
|
6
|
+
* The mark drawing payload row `rowIdx` - or, given a predicate, the first mark it accepts (e.g.
|
|
7
|
+
* `m => m.getAttribute("data-code") === "JPN"` for a chart that labels its marks).
|
|
8
|
+
*/
|
|
9
|
+
export declare function findMark(chart: ParentNode, which: number | ((mark: Element) => boolean)): Element | null;
|
|
10
|
+
/** Click a mark as a reader does; `add` holds Ctrl to add it to the selection. */
|
|
11
|
+
export declare function clickMark(mark: Element, opts?: {
|
|
12
|
+
add?: boolean;
|
|
13
|
+
}): void;
|
|
14
|
+
/** Click the chart's empty canvas (no mark): clears its selection. */
|
|
15
|
+
export declare function clickEmpty(chart: Element): void;
|
|
16
|
+
/** The payload rows the chart shows as selected now. */
|
|
17
|
+
export declare function selectedRows(chart: ParentNode): number[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.59",
|
|
4
4
|
"description": "Run a BIC-generated D3 chart in any web host: compiles the generated render() function, applies the shared option defaults, resolves mark clicks (through tooltip overlays), owns the selection affordance, and translates row indices between cross-filtered charts. The same contract the BIC Power BI visual implements, minus Power BI. React bindings at @bicharts/chart-host/react.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -39,6 +39,16 @@
|
|
|
39
39
|
"import": "./dist/geo-us-zip3.mjs",
|
|
40
40
|
"default": "./dist/geo-us-zip3.mjs"
|
|
41
41
|
},
|
|
42
|
+
"./page": {
|
|
43
|
+
"types": "./dist/types/page.d.ts",
|
|
44
|
+
"import": "./dist/page.mjs",
|
|
45
|
+
"default": "./dist/page.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./dax": {
|
|
48
|
+
"types": "./dist/types/dax.d.ts",
|
|
49
|
+
"import": "./dist/dax.mjs",
|
|
50
|
+
"default": "./dist/dax.mjs"
|
|
51
|
+
},
|
|
42
52
|
"./testing": {
|
|
43
53
|
"types": "./dist/types/testing/index.d.ts",
|
|
44
54
|
"import": "./dist/testing.mjs",
|