@bicharts/chart-host 0.6.111 → 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/card.mjs CHANGED
@@ -1,8 +1,8 @@
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
  computeSelectionCard
4
- } from "./chunk-Q43WOKSV.mjs";
5
- import "./chunk-NJWR3DFK.mjs";
4
+ } from "./chunk-OLCUKXKL.mjs";
5
+ import "./chunk-FIG5DIW7.mjs";
6
6
  import "./chunk-GHODWOAL.mjs";
7
7
 
8
8
  // src/selectionCardChrome.ts
@@ -1,7 +1,4 @@
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
- import {
3
- LASSO_KNOB_KEY
4
- } from "./chunk-IL5M7K6Z.mjs";
5
2
 
6
3
  // src/filterScope.ts
7
4
  function viewToken(view) {
@@ -24,8 +21,15 @@ function viewFromToken(token) {
24
21
  return null;
25
22
  }
26
23
  }
24
+ var ANY_VALUE = Object.freeze({ __bicAny: true });
25
+ function isAnyValue(v) {
26
+ return !!v && typeof v === "object" && v.__bicAny === true;
27
+ }
27
28
  function keyString(values) {
28
- return JSON.stringify(values.map((v) => v instanceof Date ? `__date:${v.getTime()}` : v === void 0 ? null : v));
29
+ return JSON.stringify(values.map((v) => v instanceof Date ? `__date:${v.getTime()}` : isAnyValue(v) ? "__bic:any" : v === void 0 ? null : v));
30
+ }
31
+ function keyMatchesRow(key, row, columns) {
32
+ return columns.every((c, i) => isAnyValue(key[i]) || keyString([key[i]]) === keyString([row?.[c]]));
29
33
  }
30
34
  function keyOfRow(row, columns) {
31
35
  return columns.map((c) => row?.[c]);
@@ -47,6 +51,7 @@ function createFilter(columns, opts = {}) {
47
51
  const display = opts.display == null ? cols : Array.isArray(opts.display) ? opts.display.slice() : [opts.display];
48
52
  let keys = [];
49
53
  let keySet = /* @__PURE__ */ new Set();
54
+ let wildKeys = [];
50
55
  let rows = [];
51
56
  let reason = null;
52
57
  let version = 0;
@@ -62,6 +67,7 @@ function createFilter(columns, opts = {}) {
62
67
  }
63
68
  keys = nextKeys;
64
69
  keySet = nextSet;
70
+ wildKeys = nextKeys.filter((k) => k.some(isAnyValue));
65
71
  rows = nextRows;
66
72
  reason = why;
67
73
  version++;
@@ -84,8 +90,9 @@ function createFilter(columns, opts = {}) {
84
90
  const s = keyString(k);
85
91
  const row = (more ?? []).find((r) => keyString(keyOfRow(r, cols)) === s) ?? seen.get(s);
86
92
  const parts = row ? display.map((d) => row[d]) : k;
87
- const text = parts.filter((p) => p != null && p !== "").map(String).join(" \u2192 ");
88
- return text || k.filter((p) => p != null && p !== "").map(String).join(" \u2192 ");
93
+ const shown = (p) => p != null && p !== "" && !isAnyValue(p);
94
+ const text = parts.filter(shown).map(String).join(" \u2192 ");
95
+ return text || k.filter(shown).map(String).join(" \u2192 ");
89
96
  };
90
97
  let warnedKeep = false;
91
98
  const filter = {
@@ -166,7 +173,8 @@ function createFilter(columns, opts = {}) {
166
173
  if (cols.length === 1 && where.length > 1) {
167
174
  return where.some((c) => keySet.has(keyString([row[c]])));
168
175
  }
169
- return keySet.has(keyString(keyOfRow(row, where)));
176
+ if (keySet.has(keyString(keyOfRow(row, where)))) return true;
177
+ return wildKeys.some((k) => keyMatchesRow(k, row, where));
170
178
  },
171
179
  keep(input, on) {
172
180
  const list = input ?? [];
@@ -349,7 +357,14 @@ function bindFilter(host, filter, opts) {
349
357
  const r = opts.rowAt(i);
350
358
  if (r) carried.add(keyString(keyOfRow(r, filter.columns)));
351
359
  }
352
- return filter.keys.filter((k) => !carried.has(keyString(k)));
360
+ const anyRowMatches = (k) => {
361
+ for (let i = 0; i < n; i++) {
362
+ const r = opts.rowAt(i);
363
+ if (r && keyMatchesRow(k, r, filter.columns)) return true;
364
+ }
365
+ return false;
366
+ };
367
+ return filter.keys.filter((k) => k.some(isAnyValue) ? !anyRowMatches(k) : !carried.has(keyString(k)));
353
368
  };
354
369
  const paint = () => {
355
370
  const want = wanted();
@@ -369,8 +384,26 @@ function bindFilter(host, filter, opts) {
369
384
  }
370
385
  const rows = idxs.map((i) => opts.rowAt(i)).filter((r) => !!r);
371
386
  if (!rows.length && !keep.length) return;
387
+ const label = meta?.fromLabel && !keep.length ? labelKey(rows) : null;
388
+ if (label) {
389
+ filter.set([label], "click");
390
+ return;
391
+ }
372
392
  filter.selectRows(rows, "click", keep);
373
393
  });
394
+ const labelKey = (rows) => {
395
+ const n = opts.rowCount();
396
+ const key = filter.columns.map((c) => {
397
+ const v = rows[0][c];
398
+ if (!rows.every((r) => keyString([r[c]]) === keyString([v]))) return ANY_VALUE;
399
+ for (let i = 0; i < n; i++) {
400
+ const r = opts.rowAt(i);
401
+ if (r && keyString([r[c]]) !== keyString([v])) return v;
402
+ }
403
+ return ANY_VALUE;
404
+ });
405
+ return key.some(isAnyValue) && !key.every(isAnyValue) ? key : null;
406
+ };
374
407
  const offFilter = filter.onChange(() => paint());
375
408
  const el = opts.container ?? null;
376
409
  let offHoverDom = () => {
@@ -446,169 +479,16 @@ function fromVegaInteraction(filter, events) {
446
479
  return filter.version !== before;
447
480
  }
448
481
 
449
- // src/controls.ts
450
- var isKnob = (key) => key !== LASSO_KNOB_KEY;
451
- var same = (a, b) => a.length === b.length && a.every((x, i) => x.key === b[i].key && x.label === b[i].label && x.text === b[i].text && JSON.stringify(x.value) === JSON.stringify(b[i].value));
452
- function createControls(initial) {
453
- const ui = initial ? { knobs: { ...initial } } : {};
454
- let info = [];
455
- let version = 0;
456
- const subs = /* @__PURE__ */ new Set();
457
- const appliers = /* @__PURE__ */ new Set();
458
- const notify = () => {
459
- version++;
460
- for (const cb of Array.from(subs)) cb(c);
461
- };
462
- const c = {
463
- get values() {
464
- const out = {};
465
- for (const i of info) out[i.key] = i.value;
466
- if (!info.length && ui.knobs && typeof ui.knobs === "object") {
467
- for (const [k, v] of Object.entries(ui.knobs)) if (isKnob(k)) out[k] = v;
468
- }
469
- return out;
470
- },
471
- get info() {
472
- return info;
473
- },
474
- get summary() {
475
- return info.map((i) => [i.label, i.text].filter(Boolean).join(" ")).filter(Boolean).join(" \xB7 ");
476
- },
477
- get ready() {
478
- return info.length > 0;
479
- },
480
- get version() {
481
- return version;
482
- },
483
- set(values) {
484
- const knobs = { ...ui.knobs ?? {}, ...values };
485
- ui.knobs = knobs;
486
- for (const a of Array.from(appliers)) a();
487
- },
488
- reset() {
489
- const kept = ui.knobs?.[LASSO_KNOB_KEY];
490
- delete ui.knobs;
491
- if (kept !== void 0) ui.knobs = { [LASSO_KNOB_KEY]: kept };
492
- for (const a of Array.from(appliers)) a();
493
- },
494
- onChange(cb) {
495
- subs.add(cb);
496
- return () => {
497
- subs.delete(cb);
498
- };
499
- },
500
- _ui: ui,
501
- _attach(onApply) {
502
- appliers.add(onApply);
503
- return () => {
504
- appliers.delete(onApply);
505
- };
506
- },
507
- _report(next) {
508
- if (same(info, next)) return;
509
- info = next;
510
- notify();
511
- }
512
- };
513
- return c;
514
- }
515
- function readControls(container) {
516
- const bag = container.__lchKnobs;
517
- if (!bag || typeof bag !== "object") return [];
518
- const keys = Object.keys(bag).filter(isKnob);
519
- if (!keys.length) return [];
520
- const groups = Array.from(container.querySelectorAll("g.llm-slider"));
521
- return keys.map((key, i) => {
522
- const g = groups.find((x) => x.getAttribute("data-knob") === key) ?? groups[i] ?? null;
523
- const txt = (sel) => (g?.querySelector(sel)?.textContent ?? "").trim();
524
- return { key, value: bag[key], label: txt(".llm-slider-label"), text: txt(".llm-slider-readout") };
525
- });
526
- }
527
- function attachControls(getHost, container, controls) {
528
- const c = controls;
529
- const read = () => c._report(readControls(container));
530
- const setUiState = (s) => {
531
- if (!s || typeof s !== "object") return;
532
- for (const k of Object.keys(c._ui)) delete c._ui[k];
533
- Object.assign(c._ui, s);
534
- Promise.resolve().then(read);
535
- };
536
- const off = c._attach(() => {
537
- const host = getHost();
538
- if (!host) return;
539
- host.setOptions({ uiState: c._ui });
540
- host.rendered.then(read, () => {
541
- });
542
- });
543
- return {
544
- options: { uiState: c._ui, setUiState },
545
- read,
546
- detach: off
547
- };
548
- }
549
-
550
- // src/markNotes.ts
551
- var keyText = (k) => JSON.stringify(k.map((v) => v == null ? "" : String(v).trim()));
552
- function defaultKey(n, width) {
553
- return width > 1 ? [n.markKey, n.markKeyTo] : [n.markKey];
554
- }
555
- function noteBadges(notes, opts) {
556
- const cols = typeof opts.columns === "string" ? [opts.columns] : opts.columns.slice();
557
- const keyOf = opts.keyOf ?? ((n) => defaultKey(n, cols.length));
558
- const textOf = opts.textOf ?? ((n) => String(n.body ?? ""));
559
- const byKey = /* @__PURE__ */ new Map();
560
- for (const n of notes ?? []) {
561
- if (opts.chart !== void 0 && n.chart !== opts.chart) continue;
562
- const key = keyOf(n).slice(0, cols.length);
563
- if (key.length < cols.length || key.some((v) => v == null || v === "")) continue;
564
- const id = keyText(key);
565
- const hit = byKey.get(id);
566
- if (hit) hit.list.push(n);
567
- else byKey.set(id, { key, list: [n] });
568
- }
569
- return [...byKey.entries()].map(([id, { key, list }]) => {
570
- const title = list.length > 1 ? `${textOf(list[0])} (+${list.length - 1} more)` : textOf(list[0]);
571
- const base = { id, label: String(list.length), title };
572
- if (cols.length === 1) return { ...base, column: cols[0], value: key[0] };
573
- const where = {};
574
- cols.forEach((c, i) => {
575
- where[c] = key[i];
576
- });
577
- return { ...base, where };
578
- });
579
- }
580
- function badgeKey(a) {
581
- try {
582
- const v = JSON.parse(String(a.id ?? ""));
583
- if (Array.isArray(v)) return v;
584
- } catch {
585
- }
586
- if (a.where) return Object.values(a.where);
587
- return a.value !== void 0 ? [a.value] : [];
588
- }
589
- function notesFor(notes, key, opts) {
590
- const cols = typeof opts.columns === "string" ? [opts.columns] : opts.columns.slice();
591
- const want = !key ? null : Array.isArray(key) ? key : key.keys[0] ?? null;
592
- if (!want) return [];
593
- const keyOf = opts.keyOf ?? ((n) => defaultKey(n, cols.length));
594
- const target = keyText(want.slice(0, cols.length));
595
- return (notes ?? []).filter((n) => (opts.chart === void 0 || n.chart === opts.chart) && keyText(keyOf(n).slice(0, cols.length)) === target);
596
- }
597
-
598
482
  export {
599
483
  viewToken,
600
484
  viewFromToken,
485
+ ANY_VALUE,
486
+ isAnyValue,
601
487
  createFilter,
602
488
  createFilterScope,
603
489
  filterScopeOf,
604
490
  LINKED_HOVER_CLASS,
605
491
  payloadRowReader,
606
492
  bindFilter,
607
- fromVegaInteraction,
608
- createControls,
609
- readControls,
610
- attachControls,
611
- noteBadges,
612
- badgeKey,
613
- notesFor
493
+ fromVegaInteraction
614
494
  };
@@ -59,7 +59,7 @@ async function loadGeo(geoKind) {
59
59
  } else if (asset === "us-zip3") {
60
60
  byAsset.set(asset, (await import("./geoUsZip3.generated-VSWL7D6F.mjs")).US_ZIP3);
61
61
  } else {
62
- byAsset.set(asset, (await import("./geoWorld110m-3PRV3V4G.mjs")).WORLD_110M);
62
+ byAsset.set(asset, (await import("./geoWorld110m-YZ3JOUK2.mjs")).WORLD_110M);
63
63
  }
64
64
  return fromAssets(key);
65
65
  }