@bicharts/chart-host 0.6.120 → 0.6.121

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.
@@ -2485,6 +2485,9 @@ var DOT = 8;
2485
2485
  var RING = 1.5;
2486
2486
  var DOT_HALF = DOT / 2 + RING;
2487
2487
  var DOT_IN = 8;
2488
+ var COUNT_H = 14;
2489
+ var countW = (digits) => Math.max(COUNT_H, digits * 6 + 6);
2490
+ var countOf = (label) => /^\d{1,3}$/.test(label) && Number(label) >= 1 ? label : null;
2488
2491
  function createAnnotationLayer(container, onClick, opts) {
2489
2492
  let list = [];
2490
2493
  let report = { shown: 0, notShown: 0 };
@@ -2668,6 +2671,18 @@ function createAnnotationLayer(container, onClick, opts) {
2668
2671
  placed.push(g);
2669
2672
  return [x, y];
2670
2673
  };
2674
+ const countSpot = (v, whole, digits) => {
2675
+ const w = countW(digits), hw = w / 2 + RING, hh = COUNT_H / 2 + RING;
2676
+ const roomy = (b) => b.r - b.l >= 2 * w && b.b - b.t >= 2 * COUNT_H;
2677
+ if (!roomy(whole) || !roomy(v)) return null;
2678
+ const x = clampX(v.r - Math.max(DOT_IN, w / 2 + 2), Math.ceil(hw));
2679
+ const y = clampY(v.t + Math.max(DOT_IN, COUNT_H / 2 + 2), Math.ceil(hh));
2680
+ const g = { l: x - hw, t: y - hh, r: x + hw, b: y + hh };
2681
+ if (g.l < v.l || g.r > v.r || g.t < v.t || g.b > v.b) return null;
2682
+ if (controls.some((c) => hits(g, c)) || placed.some((p) => hits(g, p)) || textsNow().some((t) => hits(g, t.b))) return null;
2683
+ placed.push(g);
2684
+ return [x, y];
2685
+ };
2671
2686
  const offX = -origin.left - (container.clientLeft || 0) + (container.scrollLeft || 0);
2672
2687
  const offY = -origin.top - (container.clientTop || 0) + (container.scrollTop || 0);
2673
2688
  let shown = 0;
@@ -2707,7 +2722,9 @@ function createAnnotationLayer(container, onClick, opts) {
2707
2722
  }
2708
2723
  }
2709
2724
  const dot = wantsDot(bestMark ?? hits2.values().next().value ?? null);
2710
- const pt = !best ? null : dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark, bestWhole ?? best);
2725
+ const count = dot && best ? countOf(text(a.label)) : null;
2726
+ const countPt = count ? countSpot(best, bestWhole, count.length) : null;
2727
+ const pt = !best ? null : countPt ?? (dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark, bestWhole ?? best));
2711
2728
  if (laidOut && !pt) continue;
2712
2729
  shown++;
2713
2730
  const badge = doc.createElement("div");
@@ -2715,6 +2732,7 @@ function createAnnotationLayer(container, onClick, opts) {
2715
2732
  badge.setAttribute("role", "button");
2716
2733
  if (dot) {
2717
2734
  const label = text(a.label), title = text(a.title);
2735
+ if (countPt) badge.textContent = count;
2718
2736
  badge.setAttribute("title", title ? label ? `(${label}) ${title}` : title : `Note on ${want}${label ? `: ${label}` : ""}`);
2719
2737
  badge.setAttribute("aria-label", `Note on ${want}${label ? `: ${label}` : ""}${title ? `. ${title}` : ""}`);
2720
2738
  } else {
@@ -2727,7 +2745,15 @@ function createAnnotationLayer(container, onClick, opts) {
2727
2745
  left: `${Math.round(pt ? pt[0] + offX : 0)}px`,
2728
2746
  top: `${Math.round(pt ? pt[1] + offY : 0)}px`,
2729
2747
  transform: "translate(-50%, -50%)",
2730
- ...dot ? { width: `${DOT}px`, height: `${DOT}px`, boxSizing: "border-box", borderRadius: "50%" } : {
2748
+ ...countPt ? {
2749
+ width: `${countW(count.length)}px`,
2750
+ height: `${COUNT_H}px`,
2751
+ boxSizing: "border-box",
2752
+ borderRadius: `${COUNT_H / 2}px`,
2753
+ font: `600 9px/${COUNT_H}px system-ui, sans-serif`,
2754
+ textAlign: "center",
2755
+ color: theme.bg || "#ffffff"
2756
+ } : dot ? { width: `${DOT}px`, height: `${DOT}px`, boxSizing: "border-box", borderRadius: "50%" } : {
2731
2757
  minWidth: "16px",
2732
2758
  height: "16px",
2733
2759
  padding: "0 4px",
@@ -3422,8 +3448,12 @@ function createChartHost(container, config) {
3422
3448
  .${HOST_CONTAINER_CLASS} .${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover { filter: brightness(1.1) drop-shadow(0 0 1.5px rgba(0,0,0,0.5)) !important; }
3423
3449
  .${HOST_CONTAINER_CLASS}:not(.${MARKS_INERT_CLASS}):has(.${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover) .${MARK_CLASS}:not(:hover):not([${ROW_IDX_ATTR}=""]) { opacity: 0.55; }
3424
3450
  /* A MARK THAT SELECTS NOTHING DOESN'T LOOK CLICKABLE: no pointer, over the inline cursor generated code
3425
- sets on its marks, and no dimming of the others on hover (the rule above). A control the chart draws keeps its own. */
3426
- .${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${MARK_CLASS} { cursor: default !important; }
3451
+ sets on its marks, and no dimming of the others on hover (the rule above). A control the chart draws keeps its own.
3452
+ The same for a legend swatch and an axis filter: on an inert chart the click handler drops their clicks too, so a
3453
+ month label drawn with a pointer promised a filter that never came. */
3454
+ .${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${MARK_CLASS},
3455
+ .${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${LEGEND_MARK_CLASS},
3456
+ .${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${AXIS_FILTER_CLASS} { cursor: default !important; }
3427
3457
  /* THE KEYBOARD'S FOCUS: a ring on the mark, control or badge that holds keyboard focus, in the colour the
3428
3458
  chart's text is drawn in, so it reads in either theme. A pointer's focus shows none. */
3429
3459
  .${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS} [${WIRED_ATTR}]:focus:not(:focus-visible) { outline: none; }
package/dist/index.mjs CHANGED
@@ -131,7 +131,7 @@ import {
131
131
  toSourceRows,
132
132
  trackFocus,
133
133
  valuePlacementFlag
134
- } from "./chunk-V7UHNWJ6.mjs";
134
+ } from "./chunk-ZBSPEYLK.mjs";
135
135
  import {
136
136
  LASSO_AXES_SLOT,
137
137
  LASSO_COUNT_CLASS,
package/dist/react.mjs CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  createChartHost,
13
13
  syncMemberSelection,
14
14
  toSourceRows
15
- } from "./chunk-V7UHNWJ6.mjs";
15
+ } from "./chunk-ZBSPEYLK.mjs";
16
16
  import "./chunk-HW3WK7SL.mjs";
17
17
  import "./chunk-4AJYIAAJ.mjs";
18
18
  import "./chunk-HEXJGF42.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.6.120",
3
+ "version": "0.6.121",
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",