@bicharts/chart-host 0.6.77 → 0.6.79

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/index.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  formatSourceDateFor,
6
6
  isExcelDateFormat,
7
7
  normaliseAggregation
8
- } from "./chunk-QOKQUXVV.mjs";
8
+ } from "./chunk-M7VM6F73.mjs";
9
9
  import {
10
10
  ANNOTATION_CLASS,
11
11
  ANNOTATION_LAYER_CLASS,
@@ -28,7 +28,6 @@ import {
28
28
  LIGHT_TEXT,
29
29
  MAX_FRAME_GROW_FACTOR,
30
30
  MIN_CONTRAST,
31
- MIN_HIT_BAND_PX,
32
31
  MIN_RAMP_FILLS,
33
32
  PAGE_MATCH_TOLERANCE,
34
33
  PHANTOM_FRACTION,
@@ -37,7 +36,6 @@ import {
37
36
  PILL_OPAQUE_ALPHA,
38
37
  SAME_SHADE_DELTA_E,
39
38
  SCROLL_SLACK_PX,
40
- SELECTION_GLYPH_CLASS,
41
39
  STRADDLE_COLS,
42
40
  STRADDLE_MIN_SHARE,
43
41
  STRADDLE_PILL_ALPHA,
@@ -56,13 +54,10 @@ import {
56
54
  cellSuppressesNormalize,
57
55
  censusClippedText,
58
56
  censusColourSpread,
59
- censusHitBands,
60
57
  censusMarks,
61
58
  censusValuePlacement,
62
59
  clearGeoCache,
63
- clearSelectionGlyphs,
64
60
  clippedTextFlag,
65
- collectD3GlyphCenters,
66
61
  colourSpreadFlag,
67
62
  compileRenderFn,
68
63
  compositeOver,
@@ -70,53 +65,41 @@ import {
70
65
  contrastRatio,
71
66
  createChartGroup,
72
67
  createChartHost,
73
- createMarkResolver,
74
68
  ctmScaleOf,
75
69
  decideLabelColor,
76
70
  deltaEHex,
77
- ensureCrossfilterHitTargets,
78
71
  explainRenderFailure,
79
72
  fitReadingFor,
80
73
  fitRenderedChart,
81
74
  geoAssetFor,
82
75
  geoFromCache,
83
76
  glyphSampleGrid,
84
- hitBandFlag,
85
77
  invalidSentinelReason,
86
78
  isBlankRender,
87
79
  isHorizontalLabelRow,
88
- isInsideControl,
89
80
  isInvalidSentinelError,
90
81
  isPhantomBox,
91
82
  isPillBackdropAlpha,
92
83
  labelBand,
93
84
  loadGeo,
94
- markKeyOf,
95
85
  measureContainerBoxes,
96
86
  minContrastOver,
97
87
  needsScroll,
98
88
  newIdScope,
99
- nextClickedMarks,
100
- nextSelection,
101
89
  noopViewStateProvider,
102
- paintSelectionGlyphs,
103
90
  pickColorOver,
104
91
  pillBacksGlyph,
105
92
  pinScrolledAxis,
106
93
  planAxisPin,
107
94
  planFrameGrow,
108
- planSelectionPaint,
109
95
  registerGeo,
110
96
  registerGeoAsset,
111
97
  relativeLuminance,
112
98
  requiredD3Plugins,
113
99
  resolveAutoColorScale,
114
100
  resolveOptions,
115
- rowIdxsFromMark,
116
- sameRowSet,
117
101
  scopeChartIds,
118
102
  scrollFitFor,
119
- selectionRuleOf,
120
103
  sessionViewStateProvider,
121
104
  straddleSampleGrid,
122
105
  straddles,
@@ -128,12 +111,31 @@ import {
128
111
  toSourceRows,
129
112
  unpinScrolledAxis,
130
113
  valuePlacementFlag
131
- } from "./chunk-IMNZYSIC.mjs";
114
+ } from "./chunk-BFN4NY22.mjs";
132
115
  import {
133
116
  _3,
134
117
  l,
135
118
  o
136
- } from "./chunk-H2P63UMG.mjs";
119
+ } from "./chunk-L554L6HF.mjs";
120
+ import {
121
+ MIN_HIT_BAND_PX,
122
+ SELECTION_GLYPH_CLASS,
123
+ censusHitBands,
124
+ clearSelectionGlyphs,
125
+ collectD3GlyphCenters,
126
+ createMarkResolver,
127
+ ensureCrossfilterHitTargets,
128
+ hitBandFlag,
129
+ isInsideControl,
130
+ markKeyOf,
131
+ nextClickedMarks,
132
+ nextSelection,
133
+ paintSelectionGlyphs,
134
+ planSelectionPaint,
135
+ rowIdxsFromMark,
136
+ sameRowSet,
137
+ selectionRuleOf
138
+ } from "./chunk-MGAO2DR7.mjs";
137
139
  import "./chunk-A2GMXZP7.mjs";
138
140
  import {
139
141
  ACTIVE_TICK_CLASS,
@@ -259,6 +261,10 @@ var OPTIONS_VOCABULARY = Object.freeze({
259
261
  var LIVE_OPTION_KEYS = Object.freeze(
260
262
  Object.keys(OPTIONS_VOCABULARY).filter((k2) => OPTIONS_VOCABULARY[k2].timing === "live" || OPTIONS_VOCABULARY[k2].timing === "live-and-next-generate")
261
263
  );
264
+ function codeReadsOption(code, key) {
265
+ if (!code || !Object.prototype.hasOwnProperty.call(OPTIONS_VOCABULARY, key)) return false;
266
+ return new RegExp(`\\boptions\\.${key}\\b`).test(code);
267
+ }
262
268
  function wireLimitCount(count) {
263
269
  const n2 = typeof count === "number" ? count : count == null || count === "" ? NaN : Number(count);
264
270
  return Number.isFinite(n2) && n2 > 0 ? n2 : null;
@@ -2430,6 +2436,7 @@ export {
2430
2436
  clearSelectionGlyphs,
2431
2437
  clippedTextFlag,
2432
2438
  codeReadsDatesInLocalTime,
2439
+ codeReadsOption,
2433
2440
  collectD3GlyphCenters,
2434
2441
  colourSpreadFlag,
2435
2442
  compileRenderFn,
package/dist/react.mjs CHANGED
@@ -22,8 +22,9 @@ import {
22
22
  loadGeo,
23
23
  syncMemberSelection,
24
24
  toSourceRows
25
- } from "./chunk-IMNZYSIC.mjs";
26
- import "./chunk-H2P63UMG.mjs";
25
+ } from "./chunk-BFN4NY22.mjs";
26
+ import "./chunk-L554L6HF.mjs";
27
+ import "./chunk-MGAO2DR7.mjs";
27
28
  import "./chunk-A2GMXZP7.mjs";
28
29
  import "./chunk-7JWL6LYE.mjs";
29
30
  import "./chunk-GHODWOAL.mjs";
@@ -0,0 +1,3 @@
1
+ import type { RendererAdapter } from "./types";
2
+ /** The adapter for a chart drawn with D3: a mark is a DOM element, and its rows are in `data-row-idx`. */
3
+ export declare function createD3Adapter(): RendererAdapter<Element>;
@@ -0,0 +1,3 @@
1
+ export { NULL_ADAPTER } from "./types";
2
+ export type { AdapterEvent, AdapterHit, AdapterScene, MarkHandle, MarkInfo, MarkRole, PaintRequest, RendererAdapter, AdapterId, RowTable, } from "./types";
3
+ export { createD3Adapter } from "./d3";
@@ -0,0 +1,108 @@
1
+ import type { RendererId } from "../host/services";
2
+ import type { SelectionModifiers, SelectionPaintPlan, SelectionRule, GlyphCenter } from "../selection";
3
+ /** What a renderer calls a mark. Opaque to the core: D3 an Element, Plotly {curve, point}, Vega a scenegraph item. */
4
+ export type MarkHandle = unknown;
5
+ /** What a mark is for: a data mark, a legend swatch, or an axis label that filters. */
6
+ export type MarkRole = "mark" | "legend" | "axis";
7
+ /** Which renderer an adapter binds: the same vocabulary a host declares it supports (host/services.ts). */
8
+ export type AdapterId = RendererId | "NONE";
9
+ /** The rows a renderer that works in values (Vega) resolves a click against. */
10
+ export interface RowTable {
11
+ rows: readonly Record<string, unknown>[];
12
+ columns: readonly {
13
+ name?: string;
14
+ isMeasure?: boolean;
15
+ }[];
16
+ }
17
+ /** Everything an adapter may need about the chart it is bound to. */
18
+ export interface AdapterScene {
19
+ container: HTMLElement;
20
+ doc: Document;
21
+ /** How many rows the chart has: the bound a renderer that reads row numbers from its own data must check. */
22
+ rowCount?: number;
23
+ /** The row table, for a renderer whose marks name values. */
24
+ table?: RowTable;
25
+ /** The diagnostics sink; the resolution logic logs through it and never throws. */
26
+ log(tag: string, data?: object): void;
27
+ }
28
+ /** One mark as the core sees it. */
29
+ export interface MarkInfo<H = MarkHandle> {
30
+ handle: H;
31
+ role: MarkRole;
32
+ /** The data rows the mark stands for. */
33
+ rows: readonly number[];
34
+ /** The mark's identity under the "clicked-marks" selection rule. */
35
+ key: string;
36
+ }
37
+ /** A click as the core hands it over. `native` is whatever the renderer's own event is. */
38
+ export interface AdapterEvent {
39
+ native: unknown;
40
+ clientX?: number;
41
+ clientY?: number;
42
+ modifiers: SelectionModifiers;
43
+ }
44
+ /**
45
+ * What a click turned out to be. The four are different gestures and the core answers each differently, so an
46
+ * adapter must say which:
47
+ * mark - a mark (furniture included; `role` says which);
48
+ * control - inside a control the chart drew: neither a selection nor a click on empty canvas;
49
+ * empty - the empty canvas: the core MAY clear the selection (D3);
50
+ * ignored - a click that resolves to nothing the adapter can use: log it and change nothing (Vega).
51
+ */
52
+ export type AdapterHit<H = MarkHandle> = {
53
+ kind: "mark";
54
+ mark: MarkInfo<H>;
55
+ } | {
56
+ kind: "control";
57
+ } | {
58
+ kind: "empty";
59
+ } | {
60
+ kind: "ignored";
61
+ reason: string;
62
+ };
63
+ /** A request to draw a selection. `plan` is present when the renderer's marks can be listed (D3). */
64
+ export interface PaintRequest<H = MarkHandle> {
65
+ selection: ReadonlySet<number>;
66
+ active: boolean;
67
+ dimOpacity: number;
68
+ plan?: {
69
+ marks: readonly MarkInfo<H>[];
70
+ result: SelectionPaintPlan;
71
+ };
72
+ }
73
+ /**
74
+ * One renderer's binding. Every capability but identity is optional, because renderers differ in what they own: a
75
+ * renderer that subscribes to its own click events implements `bind` and leaves `hit` out; one the core's container
76
+ * listener serves implements `hit`.
77
+ */
78
+ export interface RendererAdapter<H = MarkHandle> {
79
+ readonly id: AdapterId;
80
+ /** Who delivers clicks: the core's container listener, the adapter's own subscription, or nobody. */
81
+ readonly input: "container-click" | "adapter-bound" | "none";
82
+ /** Subscribe to the renderer's own click events; returns the unsubscribe. */
83
+ bind?(scene: AdapterScene, onHit: (hit: AdapterHit<H>, modifiers: SelectionModifiers) => void): () => void;
84
+ /** Every mark the chart drew, as opaque handles. */
85
+ marks?(scene: AdapterScene): readonly MarkInfo<H>[];
86
+ /** Resolve a click to what it hit. */
87
+ hit?(event: AdapterEvent, scene: AdapterScene): AdapterHit<H>;
88
+ /** The data rows a mark stands for. */
89
+ rowsOf?(handle: H, scene: AdapterScene, role?: MarkRole): number[];
90
+ /** How a selection lights this chart's marks; "any-row" when the chart declared nothing. */
91
+ declaredRule?(scene: AdapterScene): SelectionRule;
92
+ /** Draw a selection. */
93
+ paint?(request: PaintRequest<H>, scene: AdapterScene): void | Promise<void>;
94
+ /** Where each selected mark's glyph goes, in pixels from `base`. */
95
+ glyphAnchors?(base: {
96
+ left: number;
97
+ top: number;
98
+ }, scene: AdapterScene): GlyphCenter[];
99
+ /** Make the render hittable after it draws; returns what it changed. */
100
+ prepare?(scene: AdapterScene): unknown;
101
+ /** A behavior tag and detail for the render, or null when there is nothing to say. */
102
+ census?(scene: AdapterScene): {
103
+ flag: string;
104
+ detail: object;
105
+ } | null;
106
+ }
107
+ /** No marks and no binding: legal, and what a chart that cannot be selected from is. */
108
+ export declare const NULL_ADAPTER: RendererAdapter;
@@ -1,6 +1,6 @@
1
1
  export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, NO_ROW_MARKS_ATTR, SELECTION_RULE_ATTR, SELECTION_RULE_CLICKED_MARKS, MARK_KEY_ATTR, CONTAINER_SLOT_CLICKED_MARKS, SNAPSHOT_SVG_ATTR, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, FLIP_INTERVAL_MIN_MS, FLIP_INTERVAL_MAX_MS, FLIP_DIRECTION_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type FlipDirection, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, } from "./contract";
2
2
  export { resolveOptions, type ResolveOptionsInput } from "./defaults";
3
- export { OPTIONS_VOCABULARY, LIVE_OPTION_KEYS, MAX_MAP_POINTS_MIN, MAX_MAP_POINTS_MAX, LIMIT_COUNT_MAX, wireLimitCount, type OptionVocabularyEntry, type OptionTiming, type OptionWire, type OptionKey, } from "./optionsVocabulary";
3
+ export { OPTIONS_VOCABULARY, LIVE_OPTION_KEYS, MAX_MAP_POINTS_MIN, MAX_MAP_POINTS_MAX, LIMIT_COUNT_MAX, wireLimitCount, codeReadsOption, type OptionVocabularyEntry, type OptionTiming, type OptionWire, type OptionKey, } from "./optionsVocabulary";
4
4
  export { loadGeo, geoFromCache, registerGeo, registerGeoAsset, geoAssetFor, clearGeoCache, type GeoAssetName, } from "./geoLazy";
5
5
  /** REPLACE the bundled city gazetteer with another packed table. Rarely needed — see the
6
6
  * note above registerCityTable in shape-core's geoPoint.ts before using it. */
@@ -14,6 +14,7 @@ export type { Controls, ControlInfo, ControlsAttachment } from "./controls";
14
14
  export { createChartGroup, toSourceRows, syncMemberSelection, type ChartGroup, type ChartGroupMember, type ChartGroupSelection, type ChartGroupChange, type ChartGroupMemberOptions, type ChartGroupSourceOptions, type ChartGroupPayload } from "./group";
15
15
  export type { Filter, FilterScope, FilterOptions, FilterKey, FilterChangeReason, FilterBinding, BindFilterOptions, VegaInteractionEvent, PageView } from "./filterScope";
16
16
  export { createMarkResolver, isInsideControl, rowIdxsFromMark, nextSelection, selectionRuleOf, markKeyOf, planSelectionPaint, nextClickedMarks, sameRowSet, type SelectionRule, type ClickedMarks, type SelectionPaintMark, type SelectionPaintMode, type SelectionPaintPlan, collectD3GlyphCenters, clearSelectionGlyphs, paintSelectionGlyphs, SELECTION_GLYPH_CLASS, type MarkResolver, type MarkResolverEnv, type GlyphCenter, type SelectionGlyphStyle, type SelectionModifiers, } from "./selection";
17
+ export type { AdapterEvent, AdapterHit, AdapterId, AdapterScene, MarkHandle, MarkInfo, MarkRole, PaintRequest, RendererAdapter, RowTable, } from "./adapters/types";
17
18
  export { planTrivialChart, compileTrivialSource, type TrivialPlan, type TrivialShapeKind } from "./trivial";
18
19
  export { captureSvgSnapshot, svgToDataUrl, svgNaturalSize, rasterizeSvgToPngDataUrl, tableHostOf, chartSvgOf, htmlToSvgDataUrl, htmlNaturalSize, type SnapshotOptions } from "./snapshot";
19
20
  export { shouldReview, buildReviewWire, bareBase64, actionFor, type ReviewGate, type ReviewWire, type ReviewVerdict, type ReviewAction } from "./review";
@@ -91,6 +91,14 @@ export declare const OPTIONS_VOCABULARY: Readonly<{
91
91
  export type OptionKey = keyof typeof OPTIONS_VOCABULARY;
92
92
  /** The keys whose change repaints the chart on screen, in table order. */
93
93
  export declare const LIVE_OPTION_KEYS: readonly OptionKey[];
94
+ /**
95
+ * Does this chart's code read the shared option `key`?
96
+ * A host uses it to show a control only for a chart that
97
+ * will respond to it - a switch on a chart that ignores it
98
+ * does nothing. Generated code reads options as
99
+ * `options.<key>`, so the property access is the test.
100
+ */
101
+ export declare function codeReadsOption(code: string | null | undefined, key: OptionKey): boolean;
94
102
  /**
95
103
  * THE LIMIT COUNT A REQUEST CARRIES: a positive count, or null - never 0. The server reads any value it
96
104
  * receives as the reader's own limit (and 0 as a limit of zero), so "no limit" must arrive as no value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.6.77",
3
+ "version": "0.6.79",
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",
@@ -49,6 +49,11 @@
49
49
  "import": "./dist/card.mjs",
50
50
  "default": "./dist/card.mjs"
51
51
  },
52
+ "./adapters": {
53
+ "types": "./dist/types/adapters/index.d.ts",
54
+ "import": "./dist/adapters.mjs",
55
+ "default": "./dist/adapters.mjs"
56
+ },
52
57
  "./dax": {
53
58
  "types": "./dist/types/dax.d.ts",
54
59
  "import": "./dist/dax.mjs",