@bicharts/chart-host 0.6.83 → 0.6.84

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/adapters.mjs CHANGED
@@ -1,21 +1,24 @@
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
  censusHitBands,
4
+ ensureCrossfilterHitTargets,
5
+ hitBandFlag
6
+ } from "./chunk-7HKVV5T5.mjs";
7
+ import {
8
+ clickWasDrag,
4
9
  collectD3GlyphCenters,
5
10
  createMarkResolver,
6
- ensureCrossfilterHitTargets,
7
- hitBandFlag,
8
11
  isInsideControl,
9
12
  markKeyOf,
10
13
  rowIdxsFromMark,
11
14
  selectionRuleOf
12
- } from "./chunk-MGAO2DR7.mjs";
15
+ } from "./chunk-IURROJT7.mjs";
13
16
  import {
14
17
  AXIS_FILTER_CLASS,
15
18
  LEGEND_MARK_CLASS,
16
19
  MARK_CLASS,
17
20
  ROW_IDX_ATTR
18
- } from "./chunk-7JWL6LYE.mjs";
21
+ } from "./chunk-MR6TL7QZ.mjs";
19
22
  import "./chunk-GHODWOAL.mjs";
20
23
 
21
24
  // src/adapters/types.ts
@@ -41,6 +44,9 @@ function createD3Adapter() {
41
44
  if (isInsideControl(e?.target, scene.container)) return { kind: "control" };
42
45
  const x = event.clientX ?? e?.clientX;
43
46
  const y = event.clientY ?? e?.clientY;
47
+ if (clickWasDrag(scene.container, { clientX: x, clientY: y, detail: e?.detail })) {
48
+ return { kind: "ignored", reason: "a drag, not a click" };
49
+ }
44
50
  const resolver = createMarkResolver({
45
51
  root: scene.container,
46
52
  doc: scene.doc,
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-4KCSAHL5.mjs";
5
- import "./chunk-2XWE6YFO.mjs";
4
+ } from "./chunk-GG4U66E4.mjs";
5
+ import "./chunk-2ZUUIZWL.mjs";
6
6
  import "./chunk-GHODWOAL.mjs";
7
7
 
8
8
  // src/selectionCardChrome.ts
@@ -1,22 +1,33 @@
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_OUTLINE_CLASS,
4
+ installLasso
5
+ } from "./chunk-QIRLWJBI.mjs";
2
6
  import {
3
7
  Fn,
4
8
  J3,
5
9
  X,
6
10
  Xn,
7
11
  Yn
8
- } from "./chunk-2XWE6YFO.mjs";
12
+ } from "./chunk-2ZUUIZWL.mjs";
9
13
  import {
10
14
  censusHitBands,
15
+ ensureCrossfilterHitTargets
16
+ } from "./chunk-7HKVV5T5.mjs";
17
+ import {
18
+ clearPress,
19
+ clickWasDrag,
11
20
  createMarkResolver,
12
- ensureCrossfilterHitTargets,
13
21
  isInsideControl,
14
22
  markKeyOf,
15
23
  nextClickedMarks,
16
24
  nextSelection,
17
25
  planSelectionPaint,
18
- selectionRuleOf
19
- } from "./chunk-MGAO2DR7.mjs";
26
+ sameRowSet,
27
+ selectionRuleOf,
28
+ trackPress,
29
+ validRowSet
30
+ } from "./chunk-IURROJT7.mjs";
20
31
  import {
21
32
  NA_ISO3,
22
33
  NA_LAT_MAX,
@@ -63,7 +74,7 @@ import {
63
74
  XFILTER_REFRESH_EVENT,
64
75
  chartOwnsTimeline,
65
76
  periodTickSuppressesFeedback
66
- } from "./chunk-7JWL6LYE.mjs";
77
+ } from "./chunk-MR6TL7QZ.mjs";
67
78
 
68
79
  // src/labelContrast.ts
69
80
  function parseRGBA(c) {
@@ -560,6 +571,11 @@ function resolveOptions(p) {
560
571
  geoPointDest: p.geoPointDest,
561
572
  // A host FACT about the data it serialised (contract 1.9.0), passed through untouched.
562
573
  dateCellsAreUtcDays: p.dateCellsAreUtcDays,
574
+ // Host FACTS about whether every row arrived (contract 1.15.0), passed through untouched: an
575
+ // absent flag means the host does not know, and must stay absent rather than become true.
576
+ dataComplete: p.dataComplete,
577
+ rowsWithheld: p.rowsWithheld,
578
+ rowsFilteredOut: p.rowsFilteredOut,
563
579
  // NO LONGER A PASS-THROUGH. A host without a Max Map Points setting used to leave this
564
580
  // undefined, and every map chart then fell back to whatever number its own code carried -
565
581
  // 1000 in every archetype written so far - while the offer gate used the server's. One
@@ -592,6 +608,9 @@ function resolveOptions(p) {
592
608
  // Control gestures (1.10.0). Passed straight through like onSelect: the host owns what a gesture MEANS,
593
609
  // and a host that supplies nothing leaves every control behaving exactly as before.
594
610
  onControlChange: p.onControlChange,
611
+ // The host lasso setting (1.16.0): the host's own facts and choices - what the server sent, what the reader
612
+ // chose - passed through untouched. lasso.ts reads it as untrusted, so there is nothing to clamp here.
613
+ lasso: p.lasso,
595
614
  // ---- live-restyle knobs: `raw || undefined` / `.toString() || undefined` ----
596
615
  colorScaleLow: p.colorScaleLow || void 0,
597
616
  colorScaleHigh: p.colorScaleHigh || void 0,
@@ -2282,7 +2301,7 @@ function createAnnotationLayer(container, onClick) {
2282
2301
  const MO = win?.MutationObserver;
2283
2302
  if (on && !observer && MO) {
2284
2303
  observer = new MO((records) => {
2285
- if (records.some((r) => !r.target.closest?.(`.${ANNOTATION_LAYER_CLASS}`))) redrawSoon();
2304
+ if (records.some((r) => !r.target.closest?.(`.${ANNOTATION_LAYER_CLASS}, .${LASSO_OUTLINE_CLASS}`))) redrawSoon();
2286
2305
  });
2287
2306
  observer.observe(container, { subtree: true, attributes: true, attributeFilter: ["transform", "d", "cx", "cy", "x", "y", "points"] });
2288
2307
  } else if (!on && observer) {
@@ -2738,6 +2757,7 @@ function createChartHost(container, config) {
2738
2757
  xfAt = Date.now();
2739
2758
  if (d.clear) notify([], d.source || "chart");
2740
2759
  else if (d.mark) notify(parseRowIdxs(d.mark.getAttribute?.(ROW_IDX_ATTR)), d.source || "chart", d.mark, true);
2760
+ else if (Array.isArray(d.rows)) notify(validRowSet(d.rows), d.source || "chart", null, true);
2741
2761
  };
2742
2762
  const resolver = createMarkResolver({
2743
2763
  root: container,
@@ -2745,24 +2765,39 @@ function createChartHost(container, config) {
2745
2765
  log: () => {
2746
2766
  }
2747
2767
  });
2768
+ const clearFromGesture = () => {
2769
+ if (current && current.length) {
2770
+ const slot = container[CONTAINER_SLOT_XF_CLEAR];
2771
+ if (selectionFromChart && typeof slot === "function") {
2772
+ try {
2773
+ slot();
2774
+ } catch {
2775
+ }
2776
+ }
2777
+ if (current && current.length) notify([], "user");
2778
+ }
2779
+ };
2780
+ let lasso = null;
2781
+ const disposeLasso = () => {
2782
+ const l = lasso;
2783
+ lasso = null;
2784
+ try {
2785
+ l?.destroy();
2786
+ } catch {
2787
+ }
2788
+ };
2748
2789
  const clickSel = `.${MARK_CLASS}[${ROW_IDX_ATTR}], .${LEGEND_MARK_CLASS}[${ROW_IDX_ATTR}], .${AXIS_FILTER_CLASS}[${ROW_IDX_ATTR}]`;
2749
2790
  const onClick = (e) => {
2791
+ const wasDrag = clickWasDrag(container, e);
2792
+ clearPress(container);
2793
+ if (wasDrag) return;
2750
2794
  if (Date.now() - xfAt < XF_ECHO_MS) return;
2751
2795
  if (isInsideControl(e?.target, container)) return;
2752
2796
  let el = resolver.findMark(e?.target, clickSel, e);
2753
2797
  if (!el) el = resolver.penetrateOverlayAt(e?.clientX, e?.clientY, clickSel);
2754
2798
  if (!el) el = resolver.resolveByGeometry(e?.clientX, e?.clientY, clickSel);
2755
2799
  if (!el) {
2756
- if (current && current.length) {
2757
- const slot = container[CONTAINER_SLOT_XF_CLEAR];
2758
- if (selectionFromChart && typeof slot === "function") {
2759
- try {
2760
- slot();
2761
- } catch {
2762
- }
2763
- }
2764
- if (current && current.length) notify([], "user");
2765
- }
2800
+ clearFromGesture();
2766
2801
  return;
2767
2802
  }
2768
2803
  const rows = parseRowIdxs(el.getAttribute(ROW_IDX_ATTR));
@@ -2781,6 +2816,7 @@ function createChartHost(container, config) {
2781
2816
  notify(next, "user", toggledOff ? null : tick);
2782
2817
  };
2783
2818
  container.addEventListener(XFILTER_REFRESH_EVENT, onXf);
2819
+ const untrackPress = trackPress(container);
2784
2820
  container.addEventListener("click", onClick);
2785
2821
  container.classList?.add(HOST_CONTAINER_CLASS);
2786
2822
  ensureAffordanceStyles();
@@ -2881,6 +2917,16 @@ function createChartHost(container, config) {
2881
2917
  drawAnnotations();
2882
2918
  } catch {
2883
2919
  }
2920
+ try {
2921
+ lasso = installLasso({
2922
+ container,
2923
+ options: () => resolved,
2924
+ rows: data.rows ? data.rows.length : 0,
2925
+ select: (rows) => notify(rows, "user", null, true),
2926
+ clearSelection: clearFromGesture
2927
+ });
2928
+ } catch {
2929
+ }
2884
2930
  };
2885
2931
  const renderFailure = (err) => {
2886
2932
  const message = String(err?.message ?? err ?? "");
@@ -2897,6 +2943,7 @@ function createChartHost(container, config) {
2897
2943
  if (destroyed) return;
2898
2944
  const seq2 = ++renderSeq;
2899
2945
  stopAnim();
2946
+ disposeLasso();
2900
2947
  container.innerHTML = "";
2901
2948
  if (!renderFn) {
2902
2949
  if (!config.code) throw new Error("createChartHost: provide code or renderFn");
@@ -3008,10 +3055,13 @@ function createChartHost(container, config) {
3008
3055
  }
3009
3056
  }
3010
3057
  setClickedMarks(null);
3058
+ lasso?.clear({ publish: false, source: "host" });
3011
3059
  notify([], "host");
3012
3060
  },
3013
3061
  highlight(rowIdxs) {
3014
- notify(Array.isArray(rowIdxs) ? rowIdxs.slice() : [], "host");
3062
+ const rows = Array.isArray(rowIdxs) ? rowIdxs.slice() : [];
3063
+ if (lasso && lasso.rows().length && !sameRowSet(rows, lasso.rows())) lasso.clear({ publish: false, source: "host" });
3064
+ notify(rows, "host");
3015
3065
  },
3016
3066
  get current() {
3017
3067
  return current;
@@ -3027,6 +3077,9 @@ function createChartHost(container, config) {
3027
3077
  stopAnim();
3028
3078
  container.removeEventListener(XFILTER_REFRESH_EVENT, onXf);
3029
3079
  container.removeEventListener("click", onClick);
3080
+ untrackPress();
3081
+ clearPress(container);
3082
+ disposeLasso();
3030
3083
  subs.clear();
3031
3084
  annotationLayer.destroy();
3032
3085
  unpinScrolledAxis(container);