@bicharts/chart-host 0.6.115 → 0.6.116

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.
Files changed (35) hide show
  1. package/README.md +18 -0
  2. package/dist/adapters.mjs +3 -3
  3. package/dist/card.mjs +2 -2
  4. package/dist/category-colours.mjs +275 -0
  5. package/dist/{chunk-AQO4ROMU.mjs → chunk-63IUMWY2.mjs} +40 -3
  6. package/dist/{chunk-YOCYWON4.mjs → chunk-EFKGSDFF.mjs} +1 -1
  7. package/dist/{chunk-7K3F3RZ6.mjs → chunk-GZSYTDFN.mjs} +68 -275
  8. package/dist/{chunk-QLIRQJ6B.mjs → chunk-IW6BKFF5.mjs} +1 -1
  9. package/dist/{chunk-YSRMSDRP.mjs → chunk-JMLSNV5Q.mjs} +1 -1
  10. package/dist/chunk-JTZTTJJK.mjs +244 -0
  11. package/dist/{chunk-VPFP35XI.mjs → chunk-K2TH7D5V.mjs} +299 -299
  12. package/dist/{chunk-GXR7T6G5.mjs → chunk-QG5TENI3.mjs} +4 -0
  13. package/dist/{chunk-PQKLWYKK.mjs → chunk-RLOIA7QK.mjs} +1 -1
  14. package/dist/{chunk-CVTCR7HQ.mjs → chunk-TUZCM7SX.mjs} +2 -2
  15. package/dist/{chunk-DILJDN6C.mjs → chunk-VGJH63LZ.mjs} +1 -1
  16. package/dist/{chunk-2GW3S5VD.mjs → chunk-ZZBX5ZJ6.mjs} +15 -2
  17. package/dist/dax.mjs +23 -1
  18. package/dist/index.mjs +63 -16
  19. package/dist/legend-fit.mjs +3 -3
  20. package/dist/page.mjs +5 -5
  21. package/dist/provinces.mjs +4 -4
  22. package/dist/react.mjs +12 -11
  23. package/dist/testing.mjs +1 -1
  24. package/dist/types/categoryColours.d.ts +71 -0
  25. package/dist/types/contract.d.ts +2 -0
  26. package/dist/types/dax.d.ts +26 -0
  27. package/dist/types/filterScope.d.ts +10 -1
  28. package/dist/types/fit.d.ts +6 -1
  29. package/dist/types/fitDom.d.ts +13 -0
  30. package/dist/types/host.d.ts +10 -0
  31. package/dist/types/index.d.ts +4 -3
  32. package/dist/types/qualifyTable.d.ts +52 -0
  33. package/dist/zoom-memory.mjs +1 -1
  34. package/package.json +6 -1
  35. /package/dist/{chunk-5YSZABCS.mjs → chunk-LXTW6YII.mjs} +0 -0
@@ -22,6 +22,7 @@ var CONTAINER_SLOT_XF_CLEAR = "__llmXfClear";
22
22
  var CONTAINER_SLOT_INITIAL_XF_MARK = "__llmInitialXfMark";
23
23
  var CONTAINER_SLOT_UI_STATE = "__lchUiState";
24
24
  var CONTAINER_SLOT_SCROLL = "__lchScroll";
25
+ var TABLE_SCROLLER_CLASS = "lch-table-body";
25
26
  var CONTAINER_SLOT_CLICKED_MARKS = "__lchClickedMarks";
26
27
  var VIEW_ONLY_UI_STATE_KEYS = Object.freeze(["camera", "llmZoom"]);
27
28
  function withoutViewOnlyKeys(bag) {
@@ -39,6 +40,7 @@ var ACTIVE_TICK_CLASS = "lch-tick-active";
39
40
  var DIM_OPACITY_VAR = "--lch-dim-opacity";
40
41
  var DIM_OPACITY_DEFAULT = 0.25;
41
42
  var DIM_OPACITY_MIN = 0.01;
43
+ var CATEGORY_DELTA_E_FLOOR = 25;
42
44
  function chartOwnsTimeline(container) {
43
45
  return !!container && (!!container[CONTAINER_SLOT_XF_CLEAR] || !!container[CONTAINER_SLOT_ANIM_STOP]);
44
46
  }
@@ -96,6 +98,7 @@ export {
96
98
  CONTAINER_SLOT_INITIAL_XF_MARK,
97
99
  CONTAINER_SLOT_UI_STATE,
98
100
  CONTAINER_SLOT_SCROLL,
101
+ TABLE_SCROLLER_CLASS,
99
102
  CONTAINER_SLOT_CLICKED_MARKS,
100
103
  VIEW_ONLY_UI_STATE_KEYS,
101
104
  withoutViewOnlyKeys,
@@ -107,6 +110,7 @@ export {
107
110
  DIM_OPACITY_VAR,
108
111
  DIM_OPACITY_DEFAULT,
109
112
  DIM_OPACITY_MIN,
113
+ CATEGORY_DELTA_E_FLOOR,
110
114
  chartOwnsTimeline,
111
115
  periodTickSuppressesFeedback,
112
116
  ANIM_PLAY_SPEED_DEFAULT,
@@ -8,7 +8,7 @@ import {
8
8
  SELECTION_RULE_ATTR,
9
9
  SELECTION_RULE_CLICKED_MARKS,
10
10
  XFILTER_REFRESH_EVENT
11
- } from "./chunk-GXR7T6G5.mjs";
11
+ } from "./chunk-QG5TENI3.mjs";
12
12
 
13
13
  // src/selection.ts
14
14
  function rowIdxsFromMark(el) {
@@ -4,7 +4,7 @@ import {
4
4
  gestureWasDrag,
5
5
  isInsideControl,
6
6
  rowIdxsFromMark
7
- } from "./chunk-PQKLWYKK.mjs";
7
+ } from "./chunk-RLOIA7QK.mjs";
8
8
  import {
9
9
  AXIS_FILTER_CLASS,
10
10
  CONTROL_CLASS,
@@ -12,7 +12,7 @@ import {
12
12
  MARK_CLASS,
13
13
  ROW_IDX_ATTR,
14
14
  SNAPSHOT_SVG_ATTR
15
- } from "./chunk-GXR7T6G5.mjs";
15
+ } from "./chunk-QG5TENI3.mjs";
16
16
 
17
17
  // src/lasso.ts
18
18
  var LASSO_ROW_CAP = 5e3;
@@ -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
  LASSO_KNOB_KEY
4
- } from "./chunk-CVTCR7HQ.mjs";
4
+ } from "./chunk-TUZCM7SX.mjs";
5
5
 
6
6
  // src/controls.ts
7
7
  var isKnob = (key) => key !== LASSO_KNOB_KEY;
@@ -245,6 +245,14 @@ function createFilterScope() {
245
245
  for (const cb of Array.from(subs)) cb(scope);
246
246
  };
247
247
  const groups = /* @__PURE__ */ new Map();
248
+ const names = /* @__PURE__ */ new Map();
249
+ const nameFor = (f) => {
250
+ const taken = new Set(names.values());
251
+ let k = f.key, n = 1;
252
+ while (taken.has(k)) k = `${f.key}-${++n}`;
253
+ names.set(f, k);
254
+ };
255
+ const nameOf = (f) => names.get(f) ?? f.key;
248
256
  const join = (f) => {
249
257
  const name = f.group;
250
258
  if (!name) return;
@@ -288,6 +296,7 @@ function createFilterScope() {
288
296
  add(f) {
289
297
  if (!offs.has(f)) {
290
298
  list.push(f);
299
+ nameFor(f);
291
300
  offs.set(f, f.onChange(() => notify()));
292
301
  join(f);
293
302
  notify();
@@ -299,6 +308,7 @@ function createFilterScope() {
299
308
  offs.delete(f);
300
309
  const i = list.indexOf(f);
301
310
  if (i >= 0) list.splice(i, 1);
311
+ names.delete(f);
302
312
  leave(f);
303
313
  notify();
304
314
  };
@@ -312,6 +322,9 @@ function createFilterScope() {
312
322
  subs.delete(cb);
313
323
  };
314
324
  },
325
+ keyOf(f) {
326
+ return offs.has(f) ? nameOf(f) : null;
327
+ },
315
328
  get controls() {
316
329
  return ctl;
317
330
  },
@@ -333,7 +346,7 @@ function createFilterScope() {
333
346
  },
334
347
  save() {
335
348
  const view = { v: 1 };
336
- for (const f of list) if (f.active) (view.filters ??= {})[f.key] = f.keys.map((k) => k.slice());
349
+ for (const f of list) if (f.active) (view.filters ??= {})[nameOf(f)] = f.keys.map((k) => k.slice());
337
350
  for (const [k, c] of ctl) {
338
351
  const values = c.values;
339
352
  if (Object.keys(values).length) (view.controls ??= {})[k] = { ...values };
@@ -344,7 +357,7 @@ function createFilterScope() {
344
357
  if (!view || view.v !== 1) return;
345
358
  const restored = /* @__PURE__ */ new Set();
346
359
  for (const f of list) {
347
- const keys = view.filters?.[f.key];
360
+ const keys = view.filters?.[nameOf(f)];
348
361
  const g = f.group && peersOf.get(f) ? f.group : null;
349
362
  if (g && restored.has(g)) continue;
350
363
  if (keys && keys.length) {
package/dist/dax.mjs CHANGED
@@ -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
  isAnyValue
4
- } from "./chunk-2GW3S5VD.mjs";
4
+ } from "./chunk-ZZBX5ZJ6.mjs";
5
5
  import "./chunk-GHODWOAL.mjs";
6
6
 
7
7
  // src/dax.ts
@@ -64,9 +64,31 @@ ${tail}`.replace(/\n$/, "");
64
64
  function isFilter(x) {
65
65
  return !!x && typeof x === "object" && Array.isArray(x.keys) && typeof x.has === "function";
66
66
  }
67
+ var HEADER = /^(?:'(?:[^']|'')*'|[^[\]']*)\[((?:[^\]]|\]\])+)\]$/;
68
+ function columnName(header) {
69
+ const m = HEADER.exec(String(header ?? "").trim());
70
+ return m ? m[1].replace(/\]\]/g, "]") : String(header ?? "");
71
+ }
72
+ function queryRows(result) {
73
+ const table = result && "columns" in result ? result : result && "table" in result ? result.table : void 0;
74
+ if (!table || !Array.isArray(table.columns) || !Array.isArray(table.rows)) return [];
75
+ const bare = table.columns.map((c) => columnName(c?.name ?? ""));
76
+ const count = /* @__PURE__ */ new Map();
77
+ for (const b of bare) count.set(b, (count.get(b) ?? 0) + 1);
78
+ const names = bare.map((b, i) => (count.get(b) ?? 0) > 1 ? String(table.columns[i]?.name ?? b) : b);
79
+ return table.rows.map((r) => {
80
+ const o = {};
81
+ names.forEach((n, k) => {
82
+ o[n] = r?.[k];
83
+ });
84
+ return o;
85
+ });
86
+ }
67
87
  export {
68
88
  calculateTable,
89
+ columnName,
69
90
  daxLiteral,
70
91
  filterQuery,
92
+ queryRows,
71
93
  treatAs
72
94
  };
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  formatSourceDateFor,
6
6
  isExcelDateFormat,
7
7
  normaliseAggregation
8
- } from "./chunk-YSRMSDRP.mjs";
8
+ } from "./chunk-JMLSNV5Q.mjs";
9
9
  import {
10
10
  captureSvgSnapshot,
11
11
  chartSvgOf,
@@ -15,7 +15,7 @@ import {
15
15
  svgNaturalSize,
16
16
  svgToDataUrl,
17
17
  tableHostOf
18
- } from "./chunk-QLIRQJ6B.mjs";
18
+ } from "./chunk-IW6BKFF5.mjs";
19
19
  import {
20
20
  ANNOTATION_CLASS,
21
21
  ANNOTATION_LAYER_CLASS,
@@ -38,7 +38,6 @@ import {
38
38
  MAP_SELECTION_MARKER_DEFAULT,
39
39
  MARK_MOVE_ATTRIBUTES,
40
40
  MIN_CONTRAST,
41
- MIN_RAMP_FILLS,
42
41
  NEUTRAL_CENTRE_RAMP_SELECTOR,
43
42
  PAGE_MATCH_TOLERANCE,
44
43
  PILL_MIN_ALPHA,
@@ -47,7 +46,6 @@ import {
47
46
  REGION_JOIN_COLUMN,
48
47
  ROW_GROWTH_MIN_EXTRA,
49
48
  ROW_GROWTH_MIN_RATIO,
50
- SAME_SHADE_DELTA_E,
51
49
  SELECTION_MARKER_DEFAULT,
52
50
  SELECTION_OUTLINE_CLASS,
53
51
  STRADDLE_COLS,
@@ -71,7 +69,6 @@ import {
71
69
  bytesToBase64,
72
70
  cellSuppressesNormalize,
73
71
  censusClippedText,
74
- censusColourSpread,
75
72
  censusMarks,
76
73
  censusValuePlacement,
77
74
  cleanFilterScope,
@@ -79,7 +76,6 @@ import {
79
76
  clippedTextFlag,
80
77
  codeHasKeyboardStamp,
81
78
  collectOutlineMarks,
82
- colourSpreadFlag,
83
79
  compileRenderFn,
84
80
  compositeOver,
85
81
  contrastRatio,
@@ -87,7 +83,6 @@ import {
87
83
  createChartGroup,
88
84
  createChartHost,
89
85
  decideLabelColor,
90
- deltaEHex,
91
86
  excelNumberFormat,
92
87
  excelSerial,
93
88
  explainRenderFailure,
@@ -136,7 +131,7 @@ import {
136
131
  toSourceRows,
137
132
  trackFocus,
138
133
  valuePlacementFlag
139
- } from "./chunk-7K3F3RZ6.mjs";
134
+ } from "./chunk-GZSYTDFN.mjs";
140
135
  import {
141
136
  LASSO_AXES_SLOT,
142
137
  LASSO_COUNT_CLASS,
@@ -163,13 +158,13 @@ import {
163
158
  lassoVerdict,
164
159
  pointInShape,
165
160
  registerLassoAction
166
- } from "./chunk-CVTCR7HQ.mjs";
161
+ } from "./chunk-TUZCM7SX.mjs";
167
162
  import {
168
163
  MIN_HIT_BAND_PX,
169
164
  censusHitBands,
170
165
  ensureCrossfilterHitTargets,
171
166
  hitBandFlag
172
- } from "./chunk-YOCYWON4.mjs";
167
+ } from "./chunk-EFKGSDFF.mjs";
173
168
  import {
174
169
  CONTAINER_SLOT_PRESS_AT,
175
170
  DRAG_NOT_CLICK_PX,
@@ -194,7 +189,7 @@ import {
194
189
  selectionRuleOf,
195
190
  trackPress,
196
191
  validRowSet
197
- } from "./chunk-PQKLWYKK.mjs";
192
+ } from "./chunk-RLOIA7QK.mjs";
198
193
  import {
199
194
  AXIS_PIN_BAND_PAD_PX,
200
195
  AXIS_PIN_MAX_BAND_FRACTION,
@@ -219,11 +214,12 @@ import {
219
214
  planFrameGrow,
220
215
  planScrollRestore,
221
216
  rememberScroll,
217
+ restoreInnerScroll,
222
218
  scrollFitFor,
223
219
  svgInkReach,
224
220
  takeScroll,
225
221
  unpinScrolledAxis
226
- } from "./chunk-AQO4ROMU.mjs";
222
+ } from "./chunk-63IUMWY2.mjs";
227
223
  import {
228
224
  clearGeoCache,
229
225
  geoAssetFor,
@@ -231,12 +227,19 @@ import {
231
227
  loadGeo,
232
228
  registerGeo,
233
229
  registerGeoAsset
234
- } from "./chunk-5YSZABCS.mjs";
230
+ } from "./chunk-LXTW6YII.mjs";
235
231
  import {
236
232
  Ot,
237
233
  l,
238
234
  o
239
- } from "./chunk-VPFP35XI.mjs";
235
+ } from "./chunk-K2TH7D5V.mjs";
236
+ import {
237
+ MIN_RAMP_FILLS,
238
+ SAME_SHADE_DELTA_E,
239
+ censusColourSpread,
240
+ colourSpreadFlag,
241
+ deltaEHex
242
+ } from "./chunk-JTZTTJJK.mjs";
240
243
  import "./chunk-A2GMXZP7.mjs";
241
244
  import {
242
245
  ACTIVE_TICK_CLASS,
@@ -251,6 +254,7 @@ import {
251
254
  ANIM_PLAY_SPEED_MIN,
252
255
  APPROXIMATE_POSITIONS_DEFAULT,
253
256
  AXIS_FILTER_CLASS,
257
+ CATEGORY_DELTA_E_FLOOR,
254
258
  COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT,
255
259
  COLOR_SCALE_SELF_CLAMP_PCT_MAX,
256
260
  COLOR_SCALE_SELF_CLAMP_PCT_MIN,
@@ -287,13 +291,14 @@ import {
287
291
  SELECTION_RULE_ATTR,
288
292
  SELECTION_RULE_CLICKED_MARKS,
289
293
  SNAPSHOT_SVG_ATTR,
294
+ TABLE_SCROLLER_CLASS,
290
295
  VALUE_AXIS_BASELINE_DEFAULT,
291
296
  VIEW_ONLY_UI_STATE_KEYS,
292
297
  XFILTER_REFRESH_EVENT,
293
298
  chartOwnsTimeline,
294
299
  periodTickSuppressesFeedback,
295
300
  withoutViewOnlyKeys
296
- } from "./chunk-GXR7T6G5.mjs";
301
+ } from "./chunk-QG5TENI3.mjs";
297
302
  import "./chunk-GHODWOAL.mjs";
298
303
 
299
304
  // src/hostLinks.ts
@@ -1389,6 +1394,42 @@ function inlineFilterGate(rowCount) {
1389
1394
  var INLINE_FILTER_MIN_ROWS = 8;
1390
1395
 
1391
1396
  // src/qualifyTable.ts
1397
+ var QUALIFY_KIND_BADGES = Object.freeze({
1398
+ app: Object.freeze({
1399
+ label: "App",
1400
+ light: Object.freeze({ background: "#FCE7E3", text: "#923121" }),
1401
+ dark: Object.freeze({ background: "#612116", text: "#FCE7E3" })
1402
+ }),
1403
+ table: Object.freeze({
1404
+ label: "Table",
1405
+ light: Object.freeze({ background: "#E6EBF2", text: "#35445A" }),
1406
+ dark: Object.freeze({ background: "#232D3C", text: "#E6EBF2" })
1407
+ }),
1408
+ map: Object.freeze({
1409
+ label: "Map",
1410
+ light: Object.freeze({ background: "#E1F3EF", text: "#175C52" }),
1411
+ dark: Object.freeze({ background: "#103D37", text: "#E1F3EF" })
1412
+ }),
1413
+ kpi: Object.freeze({
1414
+ label: "KPI",
1415
+ light: Object.freeze({ background: "#FBF0D6", text: "#7E560C" }),
1416
+ dark: Object.freeze({ background: "#543A08", text: "#FBF0D6" })
1417
+ })
1418
+ });
1419
+ function qualifyKindBadgeStyle(kind, pane) {
1420
+ const k2 = knownKind(kind);
1421
+ if (!k2) return null;
1422
+ const badge = QUALIFY_KIND_BADGES[k2];
1423
+ if (typeof pane === "object") {
1424
+ const fg = pane.highContrastForeground;
1425
+ return { label: badge.label, background: "transparent", color: fg, border: `1px solid ${fg}` };
1426
+ }
1427
+ const c2 = pane === "dark" ? badge.dark : badge.light;
1428
+ return { label: badge.label, background: c2.background, color: c2.text, border: "none" };
1429
+ }
1430
+ function knownKind(v2) {
1431
+ return typeof v2 === "string" && Object.prototype.hasOwnProperty.call(QUALIFY_KIND_BADGES, v2) ? v2 : null;
1432
+ }
1392
1433
  function qualifyTableRows(rows) {
1393
1434
  return rows.map((r2) => ({
1394
1435
  rank: typeof r2.rank === "number" && Number.isFinite(r2.rank) ? r2.rank : null,
@@ -1398,7 +1439,8 @@ function qualifyTableRows(rows) {
1398
1439
  description: r2.description ?? "",
1399
1440
  language: r2.language ? r2.language : null,
1400
1441
  renderer: r2.renderer ? r2.renderer : null,
1401
- alsoWorthALook: r2.alsoWorthALook === true
1442
+ alsoWorthALook: r2.alsoWorthALook === true,
1443
+ kind: knownKind(r2.kind)
1402
1444
  }));
1403
1445
  }
1404
1446
 
@@ -2355,6 +2397,7 @@ export {
2355
2397
  AXIS_PIN_MIN_LABELS,
2356
2398
  AXIS_PIN_TRACK_REACH_PX,
2357
2399
  BACKING_MAJORITY,
2400
+ CATEGORY_DELTA_E_FLOOR,
2358
2401
  CHOOSER_MIN_HEIGHT_PX,
2359
2402
  CHOOSER_MIN_WIDTH_PX,
2360
2403
  CLIP_TOLERANCE_PX,
@@ -2461,6 +2504,7 @@ export {
2461
2504
  PILL_OPAQUE_ALPHA,
2462
2505
  PRODUCT_FEEDBACK_MAX_CHARS,
2463
2506
  PRODUCT_FEEDBACK_MIN_CHARS,
2507
+ QUALIFY_KIND_BADGES,
2464
2508
  QUALIFY_REFUSAL_UNSPECIFIED,
2465
2509
  QUALIFY_TILE_REFUSAL_CODES,
2466
2510
  QUALIFY_TOO_SMALL_HEADING,
@@ -2485,6 +2529,7 @@ export {
2485
2529
  STRADDLE_PILL_ALPHA,
2486
2530
  STRADDLE_ROWS,
2487
2531
  STRADDLE_TARGET_CONTRAST,
2532
+ TABLE_SCROLLER_CLASS,
2488
2533
  TRANSPORT_LOST_CHECKING_MESSAGE,
2489
2534
  VALUE_AXIS_BASELINE_DEFAULT,
2490
2535
  VALUE_AXIS_MIN_FIT,
@@ -2660,6 +2705,7 @@ export {
2660
2705
  qualifyFilterCountText,
2661
2706
  qualifyFilterGate,
2662
2707
  qualifyGroupHeadingFor,
2708
+ qualifyKindBadgeStyle,
2663
2709
  qualifyPick,
2664
2710
  qualifyRefusalHeadingFor,
2665
2711
  qualifyRefusalReason,
@@ -2692,6 +2738,7 @@ export {
2692
2738
  resolveAutoColorScale,
2693
2739
  resolveOptions,
2694
2740
  restoreFocus,
2741
+ restoreInnerScroll,
2695
2742
  rowGrowthNotice,
2696
2743
  rowIdxsFromMark,
2697
2744
  rowNameOf,
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  chartSvgOf,
4
4
  tableHostOf
5
- } from "./chunk-QLIRQJ6B.mjs";
5
+ } from "./chunk-IW6BKFF5.mjs";
6
6
  import {
7
7
  FIT_CONTENT_SELECTOR,
8
8
  ctmScaleOf,
9
9
  isPhantomBox
10
- } from "./chunk-AQO4ROMU.mjs";
11
- import "./chunk-GXR7T6G5.mjs";
10
+ } from "./chunk-63IUMWY2.mjs";
11
+ import "./chunk-QG5TENI3.mjs";
12
12
  import "./chunk-GHODWOAL.mjs";
13
13
 
14
14
  // src/legendFit/legendReconcile.ts
package/dist/page.mjs CHANGED
@@ -6,10 +6,10 @@ import {
6
6
  noteBadges,
7
7
  notesFor,
8
8
  readControls
9
- } from "./chunk-DILJDN6C.mjs";
10
- import "./chunk-CVTCR7HQ.mjs";
11
- import "./chunk-PQKLWYKK.mjs";
12
- import "./chunk-GXR7T6G5.mjs";
9
+ } from "./chunk-VGJH63LZ.mjs";
10
+ import "./chunk-TUZCM7SX.mjs";
11
+ import "./chunk-RLOIA7QK.mjs";
12
+ import "./chunk-QG5TENI3.mjs";
13
13
  import {
14
14
  ANY_VALUE,
15
15
  LINKED_HOVER_CLASS,
@@ -23,7 +23,7 @@ import {
23
23
  scopeFilterOf,
24
24
  viewFromToken,
25
25
  viewToken
26
- } from "./chunk-2GW3S5VD.mjs";
26
+ } from "./chunk-ZZBX5ZJ6.mjs";
27
27
  import "./chunk-GHODWOAL.mjs";
28
28
  export {
29
29
  ANY_VALUE,
@@ -2,13 +2,13 @@
2
2
  import {
3
3
  geoFromCache,
4
4
  registerGeo
5
- } from "./chunk-5YSZABCS.mjs";
5
+ } from "./chunk-LXTW6YII.mjs";
6
6
  import {
7
7
  Mi,
8
- Rt,
8
+ Nt,
9
9
  W,
10
10
  bt
11
- } from "./chunk-VPFP35XI.mjs";
11
+ } from "./chunk-K2TH7D5V.mjs";
12
12
  import "./chunk-A2GMXZP7.mjs";
13
13
  import "./chunk-GHODWOAL.mjs";
14
14
 
@@ -199,7 +199,7 @@ function provinceBinding(res, cols, opts) {
199
199
  const words = (n) => n.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z]+/);
200
200
  const named = (re) => cols.find((c) => words(c.name).some((w) => re.test(w)))?.name ?? null;
201
201
  const accentWords = (n) => n.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-zÀ-ɏ]+/);
202
- const localized = (axis) => cols.find((c) => Rt(accentWords(c.name)) === axis)?.name ?? null;
202
+ const localized = (axis) => cols.find((c) => Nt(accentWords(c.name)) === axis)?.name ?? null;
203
203
  const lat = named(/^(lat|latitude)$/), lon = named(/^(lon|lng|long|longitude)$/);
204
204
  const localLat = localized("lat"), localLon = localized("lon");
205
205
  const usePair = localLat !== null && localLon !== null;
package/dist/react.mjs CHANGED
@@ -5,25 +5,26 @@ import {
5
5
  createControls,
6
6
  noteBadges,
7
7
  notesFor
8
- } from "./chunk-DILJDN6C.mjs";
8
+ } from "./chunk-VGJH63LZ.mjs";
9
9
  import {
10
10
  assembleD3,
11
11
  createChartGroup,
12
12
  createChartHost,
13
13
  syncMemberSelection,
14
14
  toSourceRows
15
- } from "./chunk-7K3F3RZ6.mjs";
16
- import "./chunk-CVTCR7HQ.mjs";
17
- import "./chunk-YOCYWON4.mjs";
18
- import "./chunk-PQKLWYKK.mjs";
19
- import "./chunk-AQO4ROMU.mjs";
15
+ } from "./chunk-GZSYTDFN.mjs";
16
+ import "./chunk-TUZCM7SX.mjs";
17
+ import "./chunk-EFKGSDFF.mjs";
18
+ import "./chunk-RLOIA7QK.mjs";
19
+ import "./chunk-63IUMWY2.mjs";
20
20
  import {
21
21
  geoFromCache,
22
22
  loadGeo
23
- } from "./chunk-5YSZABCS.mjs";
24
- import "./chunk-VPFP35XI.mjs";
23
+ } from "./chunk-LXTW6YII.mjs";
24
+ import "./chunk-K2TH7D5V.mjs";
25
+ import "./chunk-JTZTTJJK.mjs";
25
26
  import "./chunk-A2GMXZP7.mjs";
26
- import "./chunk-GXR7T6G5.mjs";
27
+ import "./chunk-QG5TENI3.mjs";
27
28
  import {
28
29
  ANY_VALUE,
29
30
  LINKED_HOVER_CLASS,
@@ -37,7 +38,7 @@ import {
37
38
  scopeFilterOf,
38
39
  viewFromToken,
39
40
  viewToken
40
- } from "./chunk-2GW3S5VD.mjs";
41
+ } from "./chunk-ZZBX5ZJ6.mjs";
41
42
  import "./chunk-GHODWOAL.mjs";
42
43
 
43
44
  // src/react.tsx
@@ -413,7 +414,7 @@ function BicDevtools({ max = 20 }) {
413
414
  scope.filters.map((f) => /* @__PURE__ */ jsxs("div", { children: [
414
415
  /* @__PURE__ */ jsx("b", { children: f.label }),
415
416
  " [",
416
- f.key,
417
+ scope.keyOf?.(f) ?? f.key,
417
418
  "] ",
418
419
  f.active ? JSON.stringify(f.keys) : "(none)",
419
420
  " ",
package/dist/testing.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  MARK_CLASS,
5
5
  MARK_SELECTED_CLASS,
6
6
  ROW_IDX_ATTR
7
- } from "./chunk-GXR7T6G5.mjs";
7
+ } from "./chunk-QG5TENI3.mjs";
8
8
  import "./chunk-GHODWOAL.mjs";
9
9
 
10
10
  // src/testing/interact.ts
@@ -0,0 +1,71 @@
1
+ /** More distinct colours than this is a continuous colour channel, not categories: the census declines. */
2
+ export declare const MAX_CATEGORY_SLOTS = 24;
3
+ /**
4
+ * From this many colours a set lying on one path, its lightness rising or falling along it (turning at most once, as
5
+ * a diverging ramp's does at its centre), is declined as a ramp. Below it the shape is reported
6
+ * (`rampLike`) but not declined: four or five categorical colours can sit on one path by chance, and a set of
7
+ * categories that does is exactly the too-close case this census exists to see (two greens and two blue-greys read
8
+ * as a ramp, yet were drawn as four categories).
9
+ */
10
+ export declare const RAMP_DECLINE_MIN_SLOTS = 6;
11
+ /** At most this many pairs under the floor are listed (the closest first); `pairsBelowFloorCount` counts them all. */
12
+ export declare const MAX_LISTED_PAIRS = 10;
13
+ export interface CategoryColourCensusOptions {
14
+ /** The page background the chart is painted on; white when absent or unreadable. */
15
+ pageBg?: string;
16
+ /** The opacity a selection leaves on the other categories (0..1); chart-host's default when absent. */
17
+ dimOpacity?: number;
18
+ }
19
+ export interface CategoryColourCensus {
20
+ /** Where the colours came from: "legend" (one per swatch), "marks" (the distinct mark colours), or "" for none. */
21
+ source: string;
22
+ /** Why nothing is reported: "" when reported, else "none" (fewer than two colours), "ramp" or "too-many". */
23
+ declined: string;
24
+ /** Distinct category colours found (0 when declined for having none). */
25
+ slots: number;
26
+ /** The closest two colours, as painted hex at full strength; empty when not reported. */
27
+ closestPair: string[];
28
+ /** CIEDE2000 of the closest pair at full strength (one decimal); null when not reported. */
29
+ closestDeltaE: number | null;
30
+ /** The same, after each colour is blended at its element's own opacity over the page; null when not reported. */
31
+ closestDeltaEPainted: number | null;
32
+ /** The same at the dim level (own opacity times the dim level, over the page); null when not reported. */
33
+ closestDeltaEDimmed: number | null;
34
+ /** The dim level used. */
35
+ dimOpacity: number;
36
+ /** True when the colours lie on one path, as a sequential ramp's do (reported below RAMP_DECLINE_MIN_SLOTS). */
37
+ rampLike: boolean;
38
+ /** With a legend: true when every legend colour is painted on some mark; null without a legend or marks. */
39
+ legendMatchesMarks: boolean | null;
40
+ /** The floor the painted colours are held to (CATEGORY_DELTA_E_FLOOR). */
41
+ floor: number;
42
+ /** True when the closest pair AS PAINTED is under the floor; false when it clears it; null when not reported. */
43
+ belowFloor: boolean | null;
44
+ /** How many pairs, as painted, are under the floor (0 when not reported). */
45
+ pairsBelowFloorCount: number;
46
+ /** Those pairs, closest first (at most MAX_LISTED_PAIRS): each colour at full strength and the painted distance. */
47
+ pairsBelowFloor: CategoryColourPair[];
48
+ /** The closest pair as painted (the colours at full strength); empty when not reported. */
49
+ closestPairPainted: string[];
50
+ /** The closest painted distance under simulated deuteranopia (Machado 2009, severity 1); null when not reported. */
51
+ closestDeltaEDeutan: number | null;
52
+ /** The same under simulated protanopia; null when not reported. */
53
+ closestDeltaEProtan: number | null;
54
+ }
55
+ /** Two category colours (at full strength) and their CIEDE2000 distance as painted. */
56
+ export interface CategoryColourPair {
57
+ colours: [string, string];
58
+ deltaE: number;
59
+ }
60
+ /**
61
+ * How close are the two closest category colours, as painted? Prefers the legend (one colour per swatch) and falls
62
+ * back to the distinct colours of the marks. Never throws and never changes the chart: an environment that cannot
63
+ * report a colour reports nothing.
64
+ *
65
+ * KNOWN LIMITS, stated rather than hidden: a selection's dimming is applied by a stylesheet rule, so "painted" is the
66
+ * resting chart and the dimmed figure is computed from the dim level; colours set only by a stylesheet class are
67
+ * read through computed style, which a headless DOM without layout may not resolve; six or more categorical colours
68
+ * on one path (shades of one hue) are declined as a ramp; a binned diverging ramp, whose two arms do not lie on one
69
+ * path, is measured as categories, so its neighbouring bins are reported under the floor.
70
+ */
71
+ export declare function censusCategoryColours(container: any, doc?: any, options?: CategoryColourCensusOptions): CategoryColourCensus;
@@ -68,6 +68,7 @@ export declare const CONTAINER_SLOT_XF_CLEAR = "__llmXfClear";
68
68
  export declare const CONTAINER_SLOT_INITIAL_XF_MARK = "__llmInitialXfMark";
69
69
  export declare const CONTAINER_SLOT_UI_STATE = "__lchUiState";
70
70
  export declare const CONTAINER_SLOT_SCROLL = "__lchScroll";
71
+ export declare const TABLE_SCROLLER_CLASS = "lch-table-body";
71
72
  export declare const CONTAINER_SLOT_CLICKED_MARKS = "__lchClickedMarks";
72
73
  export declare const VIEW_ONLY_UI_STATE_KEYS: readonly string[];
73
74
  /** The bag with every view-only key removed: what a host persists when the reader has not asked
@@ -107,6 +108,7 @@ export declare const ACTIVE_TICK_CLASS = "lch-tick-active";
107
108
  export declare const DIM_OPACITY_VAR = "--lch-dim-opacity";
108
109
  export declare const DIM_OPACITY_DEFAULT = 0.25;
109
110
  export declare const DIM_OPACITY_MIN = 0.01;
111
+ export declare const CATEGORY_DELTA_E_FLOOR = 25;
110
112
  export declare function chartOwnsTimeline(container: any): boolean;
111
113
  export declare function periodTickSuppressesFeedback(isAxisTick: boolean, ownsTimeline: boolean): boolean;
112
114
  export declare const ANIM_PLAY_SPEED_DEFAULT = 1000;
@@ -20,3 +20,29 @@ export declare function calculateTable(table: string, ...filters: Array<string |
20
20
  * filterQuery(FORECAST_DAX, treatAs(region, "Geography[RegionCode]"))
21
21
  */
22
22
  export declare function filterQuery(query: string, ...filters: Array<string | null | undefined | false>): string;
23
+ /** A DAX query's result as the semantic-model query hooks return it: headers, then rows of values in header order. */
24
+ export interface QueryTable {
25
+ columns: readonly {
26
+ name: string;
27
+ }[];
28
+ rows: readonly (readonly unknown[])[];
29
+ }
30
+ /**
31
+ * A result header's bare name: "Accounts[Account Number]" and "'Sales Owners'[Owner]" give the column's name,
32
+ * "[Total Revenue]" the measure's; a header that isn't a reference comes back as it is.
33
+ */
34
+ export declare function columnName(header: string): string;
35
+ /**
36
+ * A QUERY'S ROWS BY COLUMN NAME, for a query that feeds no chart: a form's choice list, a lookup, a count beside a
37
+ * chart. A DAX result names its columns "Table[Column]" and its measures "[Measure]"; each row comes back as an object
38
+ * keyed by the bare name, so `row["Account Number"]` reads Accounts[Account Number]. Two headers with one bare name
39
+ * (Accounts[Name] beside Owners[Name]) keep their whole headers, so neither hides the other. Takes the table or the
40
+ * query hook's `data` (a failed or pending result gives no rows):
41
+ *
42
+ * const owners = queryRows(useSemanticModelQuery({ connection, query: OWNERS_DAX }).data);
43
+ * owners.map(r => r["Sales owner"])
44
+ */
45
+ export declare function queryRows(result: QueryTable | {
46
+ status?: string;
47
+ table?: QueryTable;
48
+ } | null | undefined): Record<string, unknown>[];