@bicharts/chart-host 0.6.110 → 0.6.112

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/react.mjs CHANGED
@@ -1,27 +1,18 @@
1
1
  /*! @bicharts/chart-host — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; Natural Earth and US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
2
  import {
3
- LINKED_HOVER_CLASS,
4
3
  attachControls,
5
4
  badgeKey,
6
- bindFilter,
7
5
  createControls,
8
- createFilter,
9
- createFilterScope,
10
- filterScopeOf,
11
- fromVegaInteraction,
12
6
  noteBadges,
13
- notesFor,
14
- payloadRowReader,
15
- viewFromToken,
16
- viewToken
17
- } from "./chunk-FT75ONSB.mjs";
7
+ notesFor
8
+ } from "./chunk-GTJG3SMD.mjs";
18
9
  import {
19
10
  assembleD3,
20
11
  createChartGroup,
21
12
  createChartHost,
22
13
  syncMemberSelection,
23
14
  toSourceRows
24
- } from "./chunk-5VQ3IQF7.mjs";
15
+ } from "./chunk-TE54AFRN.mjs";
25
16
  import "./chunk-IL5M7K6Z.mjs";
26
17
  import "./chunk-AEO5SFEQ.mjs";
27
18
  import "./chunk-KGVNZR23.mjs";
@@ -29,10 +20,23 @@ import "./chunk-7XT5OJ6M.mjs";
29
20
  import {
30
21
  geoFromCache,
31
22
  loadGeo
32
- } from "./chunk-S564YXNE.mjs";
33
- import "./chunk-NJWR3DFK.mjs";
23
+ } from "./chunk-5YSZABCS.mjs";
24
+ import "./chunk-FIG5DIW7.mjs";
34
25
  import "./chunk-A2GMXZP7.mjs";
35
26
  import "./chunk-KY4FI2HA.mjs";
27
+ import {
28
+ ANY_VALUE,
29
+ LINKED_HOVER_CLASS,
30
+ bindFilter,
31
+ createFilter,
32
+ createFilterScope,
33
+ filterScopeOf,
34
+ fromVegaInteraction,
35
+ isAnyValue,
36
+ payloadRowReader,
37
+ viewFromToken,
38
+ viewToken
39
+ } from "./chunk-2KLFIGTQ.mjs";
36
40
  import "./chunk-GHODWOAL.mjs";
37
41
 
38
42
  // src/react.tsx
@@ -77,6 +81,8 @@ function BicChart(props) {
77
81
  onSelectionGlyphs,
78
82
  layoutPass,
79
83
  onInvalidSentinel,
84
+ builtForRows,
85
+ onRowGrowth,
80
86
  id,
81
87
  filteredBy,
82
88
  respondsWith,
@@ -153,6 +159,10 @@ function BicChart(props) {
153
159
  onSelectionGlyphsRef.current = onSelectionGlyphs;
154
160
  const onInvalidSentinelRef = useRef(onInvalidSentinel);
155
161
  onInvalidSentinelRef.current = onInvalidSentinel;
162
+ const builtForRowsRef = useRef(builtForRows);
163
+ builtForRowsRef.current = builtForRows;
164
+ const onRowGrowthRef = useRef(onRowGrowth);
165
+ onRowGrowthRef.current = onRowGrowth;
156
166
  const onAnnotationClickRef = useRef(onAnnotationClick);
157
167
  onAnnotationClickRef.current = onAnnotationClick;
158
168
  const annKey = useMemo(() => JSON.stringify(annotations ?? []), [annotations]);
@@ -200,6 +210,14 @@ function BicChart(props) {
200
210
  get onInvalidSentinel() {
201
211
  return onInvalidSentinelRef.current ? (info) => onInvalidSentinelRef.current?.(info) : void 0;
202
212
  },
213
+ // Getters, the onInvalidSentinel pattern: read at render time, so a new prop needs no
214
+ // rebuild, and an absent callback stays absent (the console fallback is decided by presence).
215
+ get builtForRows() {
216
+ return builtForRowsRef.current ?? null;
217
+ },
218
+ get onRowGrowth() {
219
+ return onRowGrowthRef.current ? (n) => onRowGrowthRef.current?.(n) : void 0;
220
+ },
203
221
  annotations: annotationsRef.current ?? [],
204
222
  onAnnotationClick: (a) => onAnnotationClickRef.current?.(a),
205
223
  // What a filtering lasso reaches: the page filter (`selects`), or the
@@ -513,6 +531,7 @@ function useMeasuredSize(ref) {
513
531
  return size;
514
532
  }
515
533
  export {
534
+ ANY_VALUE,
516
535
  BicChart,
517
536
  BicChartGroup,
518
537
  BicDevtools,
@@ -526,6 +545,7 @@ export {
526
545
  createFilterScope,
527
546
  filterScopeOf,
528
547
  fromVegaInteraction,
548
+ isAnyValue,
529
549
  noteBadges,
530
550
  notesFor,
531
551
  useBicControls,
@@ -115,6 +115,17 @@ export interface PageView {
115
115
  export declare function viewToken(view: PageView): string;
116
116
  /** A token from viewToken back to a view; null when it isn't one. */
117
117
  export declare function viewFromToken(token: string | null | undefined): PageView | null;
118
+ /**
119
+ * A KEY VALUE THAT MATCHES ANY VALUE. A label pick (an axis label naming a region on a chart of region by stage) selects on
120
+ * the label's own field, so the filter's other key columns are left free: the key is (EMEA, ANY_VALUE), "EMEA in any
121
+ * stage", and a stage that comes back once another filter clears is still in the pick. JSON-safe: a saved view's
122
+ * `{ "__bicAny": true }` reads back as the same wildcard.
123
+ */
124
+ export declare const ANY_VALUE: Readonly<{
125
+ __bicAny: true;
126
+ }>;
127
+ /** Whether a key value is the wildcard (ANY_VALUE, or its JSON round trip). */
128
+ export declare function isAnyValue(v: unknown): boolean;
118
129
  /** Make a filter keyed by `columns` (one name, or several for a compound key such as a route). */
119
130
  export declare function createFilter(columns: string | readonly string[], opts?: FilterOptions): Filter;
120
131
  /** Make a page's filter scope. */
@@ -4,9 +4,20 @@ export interface FocusMemory {
4
4
  start: number | null;
5
5
  end: number | null;
6
6
  dir: "forward" | "backward" | "none" | null;
7
+ /** The focused element's data-row-idx, when it carries one: the row it stands for, wherever a redraw puts it. */
8
+ row?: string;
7
9
  }
8
10
  /** The focused element inside the container and its caret, or null when focus is elsewhere (or on the container). */
9
11
  export declare function rememberFocus(container: HTMLElement): FocusMemory | null;
10
12
  /** Give focus back to the same element of the new draw, with its caret. Nothing when the chart already moved focus into
11
13
  * itself, or when the new draw has no such element. Returns whether focus was restored. */
12
14
  export declare function restoreFocus(container: HTMLElement, memory: FocusMemory | null): boolean;
15
+ export interface FocusTracker {
16
+ /** What had focus, when a redraw has since removed it and focus fell to nothing (the page body); null when the
17
+ * element is still there, focus went somewhere else, or nothing in the chart had focus. Consumed by the call. */
18
+ takeLost(): FocusMemory | null;
19
+ /** Drop the note (the host's own render remembers and restores focus itself). */
20
+ forget(): void;
21
+ dispose(): void;
22
+ }
23
+ export declare function trackFocus(container: HTMLElement): FocusTracker;
@@ -1 +1,10 @@
1
+ /** [minLon, minLat, maxLon, maxLat], in degrees: wide enough for the territory, clear of its sovereign's other parts. */
2
+ type Window = readonly [number, number, number, number];
3
+ export declare const TERRITORY_PARTS: ReadonlyArray<{
4
+ from: string;
5
+ to: string;
6
+ name: string;
7
+ window: Window;
8
+ }>;
1
9
  export declare const WORLD_110M: any;
10
+ export {};
@@ -6,6 +6,9 @@ import { type SelectionRule, type SelectionPaintMode } from "./selection";
6
6
  * the rows in view, so a subscriber that holds keys the data no longer carries keeps them. */
7
7
  export interface SelectionChangeMeta {
8
8
  keepHidden?: boolean;
9
+ /** The pick was a category label (an axis label carrying its category's rows), not a mark: a page filter selects on
10
+ * the label's own field (bindFilter), leaving the key columns the label doesn't name free. */
11
+ fromLabel?: boolean;
9
12
  }
10
13
  export interface SelectionPaintReport {
11
14
  rule: SelectionRule;
@@ -22,6 +25,7 @@ import { type ValuePlacementCensus } from "./valuePlacement";
22
25
  import { type FitRenderedChartOptions, type FitRenderedChartResult } from "./fitDom";
23
26
  import { type LabelContrastOptions, type LabelContrastReport } from "./labelContrastDom";
24
27
  import { type IdScopeReport } from "./idScope";
28
+ import { type RowGrowthNotice } from "./rowGrowth";
25
29
  import { type MarkAnnotation, type AnnotationReport } from "./annotations";
26
30
  import type { ZoomMemoryHook } from "./zoomMemory/zoomMemoryDom";
27
31
  export type RenderFn = (container: HTMLElement, data: any, options: RenderOptions) => void;
@@ -261,6 +265,14 @@ export interface ChartHostConfig {
261
265
  reason: string;
262
266
  message: string;
263
267
  }) => void;
268
+ /**
269
+ * The rows this chart's code was generated on (the request's row count). When set, every render compares the rows it
270
+ * drew with it and calls onRowGrowth when the chart now draws on far more rows than it was built for (rowGrowthNotice).
271
+ * Absent or null: no comparison - a chart from before the count was kept, or an example.
272
+ */
273
+ builtForRows?: number | null;
274
+ /** Called after a render that drew on far more rows than builtForRows. Absent: the host says it once in the console. */
275
+ onRowGrowth?: (notice: RowGrowthNotice) => void;
264
276
  /**
265
277
  * NOTES ON MARKS. Each annotation names a key - a value in a column of this chart's data, such as a
266
278
  * country code - and the host draws a badge on that key's mark after every render, wherever a filter,
@@ -12,7 +12,7 @@ export { codeReadsDatesInLocalTime, vegaSpecReadsDatesInLocalTime } from "./date
12
12
  export { createChartHost, compileRenderFn, stripEsmExports, requiredD3Plugins, explainRenderFailure, sessionViewStateProvider, noopViewStateProvider, assembleD3, D3_PLUGIN_PACKAGES, type ChartHost, type ChartHostConfig, type RenderFn, type SelectionPaintReport, type SelectionChangeMeta } from "./host";
13
13
  export { ANNOTATION_CLASS, ANNOTATION_LAYER_CLASS, type MarkAnnotation, type AnnotationReport } from "./annotations";
14
14
  export { KEYBOARD_STAMP, KEYBOARD_CLASS, WIRED_ATTR as KEYBOARD_WIRED_ATTR, codeHasKeyboardStamp, installKeyboard, rowNameOf, type KeyboardEnv, type KeyboardHandle } from "./keyboardMarks";
15
- export { rememberFocus, restoreFocus, type FocusMemory } from "./focusKeep";
15
+ export { rememberFocus, restoreFocus, trackFocus, type FocusMemory, type FocusTracker } from "./focusKeep";
16
16
  export type { MarkNoteLike, NoteBadgeOptions } from "./markNotes";
17
17
  export type { Controls, ControlInfo, ControlsAttachment } from "./controls";
18
18
  export { createChartGroup, toSourceRows, syncMemberSelection, type ChartGroup, type ChartGroupMember, type ChartGroupSelection, type ChartGroupChange, type ChartGroupMemberOptions, type ChartGroupSourceOptions, type ChartGroupPayload } from "./group";
@@ -39,6 +39,7 @@ export { scopeChartIds, newIdScope, type IdScopeReport } from "./idScope";
39
39
  export { decideLabelColor, toRGBA, compositeOver, relativeLuminance, contrastRatio, isPillBackdropAlpha, pillBacksGlyph, backingHoldsGlyph, cellSuppressesNormalize, glyphSampleGrid, DARK_TEXT, LIGHT_TEXT, MIN_CONTRAST, WHITE_TEXT_BG_LUM, PILL_MIN_ALPHA, PILL_OPAQUE_ALPHA, PILL_MIN_COVERAGE, PAGE_MATCH_TOLERANCE, BACKING_MAJORITY, GLYPH_SAMPLE_N, straddles, straddleSampleGrid, minContrastOver, pickColorOver, STRADDLE_COLS, STRADDLE_ROWS, STRADDLE_MIN_SHARE, STRADDLE_TARGET_CONTRAST, STRADDLE_PILL_ALPHA, type LabelDecision, } from "./labelContrast";
40
40
  export { censusMarks, isBlankRender, blankRenderFlag, type MarkCensus, type BlankVerdictInput } from "./blankRender";
41
41
  export { isInvalidSentinelError, invalidSentinelReason } from "./invalidSentinel";
42
+ export { rowGrowthNotice, ROW_GROWTH_MIN_RATIO, ROW_GROWTH_MIN_EXTRA, type RowGrowthNotice } from "./rowGrowth";
42
43
  export { censusHitBands, hitBandFlag, MIN_HIT_BAND_PX, type HitBandCensus } from "./hitBands";
43
44
  export { censusClippedText, clippedTextFlag, CLIP_TOLERANCE_PX, type ClippedTextCensus, type ClippedText } from "./clippedText";
44
45
  export { censusColourSpread, colourSpreadFlag, SAME_SHADE_DELTA_E, MIN_RAMP_FILLS, type ColourSpreadCensus } from "./colourSpread";
@@ -1,4 +1,4 @@
1
1
  export { viewToken, viewFromToken, LINKED_HOVER_CLASS, type PageView } from "./filterScope";
2
- export { createFilter, createFilterScope, bindFilter, payloadRowReader, fromVegaInteraction, filterScopeOf, type Filter, type FilterScope, type FilterOptions, type FilterKey, type FilterChangeReason, type FilterBinding, type BindFilterOptions, type VegaInteractionEvent } from "./filterScope";
2
+ export { createFilter, createFilterScope, bindFilter, payloadRowReader, fromVegaInteraction, filterScopeOf, ANY_VALUE, isAnyValue, type Filter, type FilterScope, type FilterOptions, type FilterKey, type FilterChangeReason, type FilterBinding, type BindFilterOptions, type VegaInteractionEvent } from "./filterScope";
3
3
  export { createControls, attachControls, readControls, type Controls, type ControlInfo, type ControlsAttachment } from "./controls";
4
4
  export { noteBadges, badgeKey, notesFor, type MarkNoteLike, type NoteBadgeOptions } from "./markNotes";
@@ -8,7 +8,7 @@ import { type Controls } from "./controls";
8
8
  export { createControls, type Controls, type ControlInfo } from "./controls";
9
9
  export { noteBadges, badgeKey, notesFor, type MarkNoteLike, type NoteBadgeOptions } from "./markNotes";
10
10
  export { viewToken, viewFromToken, LINKED_HOVER_CLASS, type PageView } from "./filterScope";
11
- export { createFilter, createFilterScope, fromVegaInteraction, filterScopeOf, type Filter, type FilterOptions, type FilterScope, type FilterChangeReason } from "./filterScope";
11
+ export { createFilter, createFilterScope, fromVegaInteraction, filterScopeOf, ANY_VALUE, isAnyValue, type Filter, type FilterOptions, type FilterScope, type FilterChangeReason } from "./filterScope";
12
12
  export interface BicChartProps {
13
13
  /** Generated render() source (an ES module's `code` export, or the raw string). */
14
14
  code?: string;
@@ -74,6 +74,10 @@ export interface BicChartProps {
74
74
  * throw propagates as before. See createChartHost's `onInvalidSentinel`.
75
75
  */
76
76
  onInvalidSentinel?: ChartHostConfig["onInvalidSentinel"];
77
+ /** The rows this chart's code was generated on. Every render compares the rows it drew against it (see createChartHost). */
78
+ builtForRows?: ChartHostConfig["builtForRows"];
79
+ /** Called when the rows drawn far outnumber builtForRows. Absent: chart-host says it once in the console. */
80
+ onRowGrowth?: ChartHostConfig["onRowGrowth"];
77
81
  /** Identity within a <BicChartGroup> — the key other charts filter by. */
78
82
  id?: string;
79
83
  /** Take this group member's selection as a filter on THIS chart's rows. */
@@ -0,0 +1,17 @@
1
+ export declare const ROW_GROWTH_MIN_RATIO = 10;
2
+ export declare const ROW_GROWTH_MIN_EXTRA = 500;
3
+ export interface RowGrowthNotice {
4
+ code: "row-growth";
5
+ /** The reader's priority, in the vocabulary of a generate result's notices: a fact about the data. */
6
+ severity: "data";
7
+ builtFor: number;
8
+ rendered: number;
9
+ /** The sentence a host shows when it does not word it itself (English). */
10
+ text: string;
11
+ /** The render row's Location token, `grow:<builtFor>` - kept per render row, so the population is countable. */
12
+ locationToken: string;
13
+ }
14
+ export declare function rowGrowthNotice(builtFor: number | null | undefined, rendered: number | null | undefined, opts?: {
15
+ canGenerate?: boolean;
16
+ formatCount?: (n: number) => string;
17
+ }): RowGrowthNotice | null;
@@ -1,7 +1,7 @@
1
1
  /*! @bicharts/chart-host — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; Natural Earth and US Census/TIGER (public domain). Full text: NOTICE in this package. */
2
2
  import {
3
3
  K
4
- } from "./chunk-NJWR3DFK.mjs";
4
+ } from "./chunk-FIG5DIW7.mjs";
5
5
  import "./chunk-GHODWOAL.mjs";
6
6
 
7
7
  // src/zoomMemory/zoomMemory.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.6.110",
3
+ "version": "0.6.112",
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",