@bicharts/chart-host 0.5.7 → 0.5.8
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/{chunk-RENIKQVS.mjs → chunk-K3LSWWFS.mjs} +158 -155
- package/dist/index.mjs +1 -1
- package/dist/react.mjs +1 -1
- package/package.json +1 -1
|
@@ -33,49 +33,49 @@ var COLOR_SCALE_SELF_CLAMP_PCT_MAX = 100;
|
|
|
33
33
|
|
|
34
34
|
// src/defaults.ts
|
|
35
35
|
var clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));
|
|
36
|
-
function resolveOptions(
|
|
36
|
+
function resolveOptions(p) {
|
|
37
37
|
return {
|
|
38
38
|
// ---- host fields: pass through exactly as supplied ----
|
|
39
|
-
width:
|
|
40
|
-
height:
|
|
41
|
-
palette:
|
|
42
|
-
geoUnmatched:
|
|
43
|
-
geo:
|
|
44
|
-
geoPoint:
|
|
45
|
-
maxMapPoints:
|
|
46
|
-
uiState:
|
|
47
|
-
setUiState:
|
|
48
|
-
backgroundColor:
|
|
49
|
-
themeBg:
|
|
50
|
-
themeFg:
|
|
51
|
-
isHighContrast:
|
|
52
|
-
themeAccent:
|
|
53
|
-
cultureCode:
|
|
54
|
-
allowTooltips:
|
|
55
|
-
noDataText:
|
|
56
|
-
onSelect:
|
|
39
|
+
width: p.width,
|
|
40
|
+
height: p.height,
|
|
41
|
+
palette: p.palette,
|
|
42
|
+
geoUnmatched: p.geoUnmatched,
|
|
43
|
+
geo: p.geo,
|
|
44
|
+
geoPoint: p.geoPoint,
|
|
45
|
+
maxMapPoints: p.maxMapPoints,
|
|
46
|
+
uiState: p.uiState,
|
|
47
|
+
setUiState: p.setUiState,
|
|
48
|
+
backgroundColor: p.backgroundColor,
|
|
49
|
+
themeBg: p.themeBg,
|
|
50
|
+
themeFg: p.themeFg,
|
|
51
|
+
isHighContrast: p.isHighContrast,
|
|
52
|
+
themeAccent: p.themeAccent,
|
|
53
|
+
cultureCode: p.cultureCode,
|
|
54
|
+
allowTooltips: p.allowTooltips,
|
|
55
|
+
noDataText: p.noDataText,
|
|
56
|
+
onSelect: p.onSelect,
|
|
57
57
|
// ---- live-restyle knobs: `raw || undefined` / `.toString() || undefined` ----
|
|
58
|
-
colorScaleLow:
|
|
59
|
-
colorScaleHigh:
|
|
58
|
+
colorScaleLow: p.colorScaleLow || void 0,
|
|
59
|
+
colorScaleHigh: p.colorScaleHigh || void 0,
|
|
60
60
|
// "" (global, the default), "frame", or "self"; anything else fails open to global.
|
|
61
|
-
colorScaleScope:
|
|
61
|
+
colorScaleScope: p.colorScaleScope === "frame" || p.colorScaleScope === "self" ? p.colorScaleScope : "",
|
|
62
62
|
// Math.max(50, Math.min(100, Number(raw) || 95)) — only meaningful under "self".
|
|
63
|
-
colorScaleSelfClampPct: clamp(Number(
|
|
63
|
+
colorScaleSelfClampPct: clamp(Number(p.colorScaleSelfClampPct) || COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX),
|
|
64
64
|
// Map fills: `raw || undefined` like the colour-scale endpoints. The no-data ->
|
|
65
65
|
// land cascade is left to the chart (so the fallback chain is visible in the
|
|
66
66
|
// generated code); HC substitution has already happened in the caller.
|
|
67
|
-
geoLandColor:
|
|
68
|
-
geoNoDataColor:
|
|
69
|
-
aggregation: (
|
|
67
|
+
geoLandColor: p.geoLandColor || void 0,
|
|
68
|
+
geoNoDataColor: p.geoNoDataColor || void 0,
|
|
69
|
+
aggregation: (p.aggregation == null ? "" : String(p.aggregation)) || void 0,
|
|
70
70
|
// ---- animation: booleans, default+clamp numerics, "" default enum ----
|
|
71
|
-
animAutoPlay: !!
|
|
71
|
+
animAutoPlay: !!p.animAutoPlay,
|
|
72
72
|
// Math.max(250, Math.min(5000, Number(raw) || 1000))
|
|
73
|
-
animPlaySpeedMs: clamp(Number(
|
|
73
|
+
animPlaySpeedMs: clamp(Number(p.animPlaySpeedMs) || ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX),
|
|
74
74
|
// Math.max(3, Math.min(500, Number(raw) || 60))
|
|
75
|
-
animMaxIdealFrames: clamp(Number(
|
|
76
|
-
animStopAtEnd: !!
|
|
77
|
-
filtersDuringPlay: !!
|
|
78
|
-
animTimelineStyle: (
|
|
75
|
+
animMaxIdealFrames: clamp(Number(p.animMaxIdealFrames) || ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX),
|
|
76
|
+
animStopAtEnd: !!p.animStopAtEnd,
|
|
77
|
+
filtersDuringPlay: !!p.filtersDuringPlay,
|
|
78
|
+
animTimelineStyle: (p.animTimelineStyle || "").toString()
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -85,12 +85,12 @@ var byAsset = /* @__PURE__ */ new Map();
|
|
|
85
85
|
var _na;
|
|
86
86
|
function geoAssetFor(geoKind) {
|
|
87
87
|
if (!geoKind) return null;
|
|
88
|
-
const
|
|
89
|
-
if (/^country/.test(
|
|
90
|
-
if (
|
|
91
|
-
if (
|
|
92
|
-
if (
|
|
93
|
-
if (
|
|
88
|
+
const k2 = geoKind.toLowerCase();
|
|
89
|
+
if (/^country/.test(k2)) return "world";
|
|
90
|
+
if (k2 === "north-america") return "world";
|
|
91
|
+
if (k2 === "world") return "world";
|
|
92
|
+
if (k2 === "us-state-code" || k2 === "us-state-name") return "us-states";
|
|
93
|
+
if (k2 === "us-zip5") return "us-zip3";
|
|
94
94
|
return null;
|
|
95
95
|
}
|
|
96
96
|
var _worldBase;
|
|
@@ -344,14 +344,14 @@ function r3(n) {
|
|
|
344
344
|
if (a2 && o && i3(a2) !== o && (a2 = null), n.city !== void 0 && n.city !== null) {
|
|
345
345
|
let r = u(String(n.city)), l = F[n.mapKind || "north-america"] ?? "N", f = Y(r);
|
|
346
346
|
if (f) {
|
|
347
|
-
let C = n.state === void 0 || n.state === null ? "" : String(n.state).trim(), d2 = C ? u(C) : "",
|
|
347
|
+
let C = n.state === void 0 || n.state === null ? "" : String(n.state).trim(), d2 = C ? u(C) : "", p = C ? H(C) : null, S = [], R = -1;
|
|
348
348
|
for (let s of f) {
|
|
349
|
-
let
|
|
350
|
-
if (!
|
|
349
|
+
let A = s.row;
|
|
350
|
+
if (!A.kinds.includes(l)) continue;
|
|
351
351
|
let c = 0;
|
|
352
|
-
if (C &&
|
|
352
|
+
if (C && A.a1 !== "") if (p && A.a1 === p || u(A.a1) === d2) c++;
|
|
353
353
|
else continue;
|
|
354
|
-
if (o) if (I(
|
|
354
|
+
if (o) if (I(A.cc) === o) c++;
|
|
355
355
|
else continue;
|
|
356
356
|
c > R ? (R = c, S = [s]) : c === R && S.push(s);
|
|
357
357
|
}
|
|
@@ -382,26 +382,26 @@ function r3(n) {
|
|
|
382
382
|
var U = { latlon: 0, city: 1, zip3: 2, state: 3, country: 4 };
|
|
383
383
|
var V = 8;
|
|
384
384
|
function N3(n, e) {
|
|
385
|
-
let t = new Array(n.length), i = new Array(n.length), o = /* @__PURE__ */ new Set(), a2 = [], r = /* @__PURE__ */ new Set(), l = [], f = /* @__PURE__ */ new Set(), C = [], d2 = { latlon: 0, city: 0, zip3: 0, state: 0, country: 0 },
|
|
385
|
+
let t = new Array(n.length), i = new Array(n.length), o = /* @__PURE__ */ new Set(), a2 = [], r = /* @__PURE__ */ new Set(), l = [], f = /* @__PURE__ */ new Set(), C = [], d2 = { latlon: 0, city: 0, zip3: 0, state: 0, country: 0 }, p = 0, S = 0, R = null;
|
|
386
386
|
for (let s = 0; s < n.length; ++s) {
|
|
387
|
-
let
|
|
387
|
+
let A = n[s], c = r3({ ...A, mapKind: e });
|
|
388
388
|
if (o3(c)) {
|
|
389
389
|
t[s] = null, i[s] = null, S++;
|
|
390
|
-
let M2 = E(
|
|
390
|
+
let M2 = E(A);
|
|
391
391
|
M2 && !f.has(M2.toLowerCase()) && (f.add(M2.toLowerCase()), C.length < V && C.push(M2));
|
|
392
392
|
} else if (c) {
|
|
393
|
-
if (t[s] = c.lat, i[s] = c.lon,
|
|
394
|
-
let M2 = E(
|
|
393
|
+
if (t[s] = c.lat, i[s] = c.lon, p++, d2[c.precision]++, (R === null || U[c.precision] > U[R]) && (R = c.precision), U[c.precision] > U.city) {
|
|
394
|
+
let M2 = E(A);
|
|
395
395
|
M2 && !r.has(M2.toLowerCase()) && (r.add(M2.toLowerCase()), l.length < V && l.push(M2));
|
|
396
396
|
}
|
|
397
397
|
} else {
|
|
398
398
|
t[s] = null, i[s] = null;
|
|
399
|
-
let M2 = E(
|
|
399
|
+
let M2 = E(A);
|
|
400
400
|
M2 && !o.has(M2.toLowerCase()) && (o.add(M2.toLowerCase()), a2.push(M2));
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
403
|
let N2 = !v() && n.some((s) => s.city !== null && s.city !== void 0 && String(s.city).trim() !== "");
|
|
404
|
-
return { lat: t, lon: i, precision: R, precisionCounts: d2, coarseExamples: l, unmatched: a2, ambiguousRows: S, ambiguousExamples: C, matchedRows:
|
|
404
|
+
return { lat: t, lon: i, precision: R, precisionCounts: d2, coarseExamples: l, unmatched: a2, ambiguousRows: S, ambiguousExamples: C, matchedRows: p, totalRows: n.length, ...N2 ? { cityTableMissing: true } : {} };
|
|
405
405
|
}
|
|
406
406
|
function E(n) {
|
|
407
407
|
return [n.city, n.state, n.zip, n.country].filter((e) => e != null && String(e).trim() !== "").map((e) => String(e).trim()).join(", ");
|
|
@@ -479,14 +479,14 @@ function hn(n) {
|
|
|
479
479
|
}
|
|
480
480
|
}
|
|
481
481
|
function An(n, i) {
|
|
482
|
-
let s = new Array(n.length), o = /* @__PURE__ */ new Set(), h2 = [],
|
|
482
|
+
let s = new Array(n.length), o = /* @__PURE__ */ new Set(), h2 = [], p = 0;
|
|
483
483
|
for (let S = 0; S < n.length; ++S) {
|
|
484
484
|
let T3 = ln(n[S], i);
|
|
485
|
-
if (s[S] = T3, T3 !== null)
|
|
485
|
+
if (s[S] = T3, T3 !== null) p++;
|
|
486
486
|
else {
|
|
487
|
-
let
|
|
488
|
-
if (
|
|
489
|
-
let N2 = String(
|
|
487
|
+
let A = n[S];
|
|
488
|
+
if (A != null) {
|
|
489
|
+
let N2 = String(A).trim();
|
|
490
490
|
if (N2.length > 0) {
|
|
491
491
|
let m2 = N2.toLowerCase();
|
|
492
492
|
o.has(m2) || (o.add(m2), h2.push(N2));
|
|
@@ -494,136 +494,139 @@ function An(n, i) {
|
|
|
494
494
|
}
|
|
495
495
|
}
|
|
496
496
|
}
|
|
497
|
-
return { iso: s, unmatched: h2, matchedRows:
|
|
497
|
+
return { iso: s, unmatched: h2, matchedRows: p, totalRows: n.length };
|
|
498
498
|
}
|
|
499
499
|
|
|
500
500
|
// ../shape-core/dist/index.mjs
|
|
501
501
|
/*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
|
|
502
|
-
var
|
|
503
|
-
|
|
504
|
-
|
|
502
|
+
var gt = /* @__PURE__ */ new Set(["n a", "none", "null", "nil", "unknown", "not applicable", "not available", "not specified", "unspecified", "missing", "blank", "empty", "tbd", "to be determined"]);
|
|
503
|
+
function M(i) {
|
|
504
|
+
return i ? gt.has(i) : true;
|
|
505
|
+
}
|
|
506
|
+
var v3 = 85;
|
|
507
|
+
var L2 = 2;
|
|
508
|
+
var ht = 100;
|
|
505
509
|
var N = 400;
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
return !!w(r);
|
|
510
|
+
function w2(i) {
|
|
511
|
+
return !!w(i);
|
|
509
512
|
}
|
|
510
|
-
function
|
|
513
|
+
function y2(i) {
|
|
511
514
|
let n = /* @__PURE__ */ new Set();
|
|
512
|
-
for (let e of
|
|
515
|
+
for (let e of i) {
|
|
513
516
|
if (e == null) continue;
|
|
514
|
-
let
|
|
515
|
-
if (
|
|
517
|
+
let r = u(String(e));
|
|
518
|
+
if (!M(r) && !n.has(r) && (n.add(r), n.size >= N)) break;
|
|
516
519
|
}
|
|
517
520
|
return Array.from(n);
|
|
518
521
|
}
|
|
519
|
-
function g2(
|
|
520
|
-
let n =
|
|
521
|
-
if (n.length === 0 ||
|
|
522
|
-
let e = n.filter((
|
|
523
|
-
return e >= 1 && e >=
|
|
522
|
+
function g2(i) {
|
|
523
|
+
let n = y2(i);
|
|
524
|
+
if (n.length === 0 || Pt(i) < 97) return false;
|
|
525
|
+
let e = n.filter((a2) => w2(a2) && !H(a2)).length, r = n.filter((a2) => !w2(a2) && !!H(a2)).length;
|
|
526
|
+
return e >= 1 && e >= r;
|
|
524
527
|
}
|
|
525
|
-
var
|
|
526
|
-
function
|
|
527
|
-
if (!H(
|
|
528
|
-
let e = w(
|
|
529
|
-
return e ? n === "world" ? true :
|
|
528
|
+
var Ct = /* @__PURE__ */ new Set(["USA", "CAN", "MEX"]);
|
|
529
|
+
function E3(i, n) {
|
|
530
|
+
if (!H(i)) return false;
|
|
531
|
+
let e = w(i);
|
|
532
|
+
return e ? n === "world" ? true : Ct.has(e) : false;
|
|
530
533
|
}
|
|
531
|
-
function
|
|
532
|
-
let n =
|
|
534
|
+
function Pt(i) {
|
|
535
|
+
let n = y2(i);
|
|
533
536
|
if (n.length === 0) return 0;
|
|
534
537
|
let e = 0;
|
|
535
|
-
for (let
|
|
538
|
+
for (let r of n) w2(r) && e++;
|
|
536
539
|
return Math.round(e / n.length * 1e3) / 10;
|
|
537
540
|
}
|
|
538
|
-
function
|
|
539
|
-
let n =
|
|
541
|
+
function T2(i) {
|
|
542
|
+
let n = y2(i);
|
|
540
543
|
if (n.length === 0) return 0;
|
|
541
544
|
let e = 0;
|
|
542
|
-
for (let
|
|
545
|
+
for (let r of n) H(r) && e++;
|
|
543
546
|
return Math.round(e / n.length * 1e3) / 10;
|
|
544
547
|
}
|
|
545
|
-
function
|
|
548
|
+
function $2(i) {
|
|
546
549
|
let n = /* @__PURE__ */ new Set();
|
|
547
|
-
for (let e of
|
|
550
|
+
for (let e of i) {
|
|
548
551
|
if (e == null) continue;
|
|
549
|
-
let
|
|
550
|
-
if (
|
|
552
|
+
let r = String(e).trim();
|
|
553
|
+
if (!M(u(r)) && !n.has(r) && (n.add(r), n.size >= N)) break;
|
|
551
554
|
}
|
|
552
555
|
return Array.from(n);
|
|
553
556
|
}
|
|
554
|
-
function
|
|
555
|
-
let n =
|
|
557
|
+
function B3(i) {
|
|
558
|
+
let n = $2(i);
|
|
556
559
|
if (n.length === 0) return 0;
|
|
557
560
|
let e = 0;
|
|
558
|
-
for (let
|
|
561
|
+
for (let r of n) x(r).length > 0 && e++;
|
|
559
562
|
return Math.round(e / n.length * 1e3) / 10;
|
|
560
563
|
}
|
|
561
|
-
function
|
|
562
|
-
let e =
|
|
564
|
+
function bt(i, n) {
|
|
565
|
+
let e = y2(i);
|
|
563
566
|
if (e.length === 0) return 0;
|
|
564
|
-
let
|
|
565
|
-
for (let
|
|
566
|
-
return Math.round(
|
|
567
|
+
let r = 0;
|
|
568
|
+
for (let a2 of e) s3(a2, n) && r++;
|
|
569
|
+
return Math.round(r / e.length * 1e3) / 10;
|
|
567
570
|
}
|
|
568
|
-
function
|
|
571
|
+
function G2(i, n) {
|
|
569
572
|
let e = 0;
|
|
570
|
-
for (let
|
|
573
|
+
for (let r of y2(i)) n(r) && e++;
|
|
571
574
|
return e;
|
|
572
575
|
}
|
|
573
|
-
function
|
|
576
|
+
function At(i, n) {
|
|
574
577
|
let e = 0;
|
|
575
|
-
for (let
|
|
578
|
+
for (let r of $2(i)) n(r) && e++;
|
|
576
579
|
return e;
|
|
577
580
|
}
|
|
578
|
-
function
|
|
579
|
-
let
|
|
581
|
+
function Mt(i, n, e, r) {
|
|
582
|
+
let a2 = [], m2 = [], o = {}, I2 = new Set(i), d2 = (t) => n.map((s) => s[t]);
|
|
580
583
|
for (let t of ["city", "zip", "lat", "lon", "country"]) {
|
|
581
584
|
let s = e?.[t];
|
|
582
|
-
s &&
|
|
585
|
+
s && I2.has(s) && (o[t] = s);
|
|
583
586
|
}
|
|
584
587
|
let l = e?.state;
|
|
585
|
-
if (l &&
|
|
586
|
-
let t =
|
|
587
|
-
s.length > 0 && s.every((
|
|
588
|
+
if (l && I2.has(l)) {
|
|
589
|
+
let t = d2(l), s = y2(t);
|
|
590
|
+
s.length > 0 && s.every((c) => E3(c, r)) ? m2.push(`state=${l} (every value is "CA", which is both Canada and California)`) : g2(t) ? (m2.push(`state=${l} (every value is a country, not a state)`), o.country || (o.country = l)) : T2(t) < v3 ? m2.push(`state=${l} (only ${T2(t)}% of values are states/provinces)`) : o.state = l;
|
|
588
591
|
}
|
|
589
|
-
let
|
|
592
|
+
let p = new Set(Object.values(o).filter(Boolean)), h2 = i.filter((t) => !p.has(t) && !t.startsWith("__"));
|
|
590
593
|
if (!o.state) {
|
|
591
594
|
let t = null;
|
|
592
595
|
for (let s of h2) {
|
|
593
|
-
let
|
|
594
|
-
if (g2(
|
|
595
|
-
let u2 =
|
|
596
|
-
if (u2 <
|
|
597
|
-
let
|
|
598
|
-
|
|
596
|
+
let c = d2(s);
|
|
597
|
+
if (g2(c)) continue;
|
|
598
|
+
let u2 = T2(c);
|
|
599
|
+
if (u2 < v3) continue;
|
|
600
|
+
let R = G2(c, (C) => !!H(C)), H2 = G2(c, (C) => !!H(C) && !E3(C, r));
|
|
601
|
+
R < L2 && H2 < 1 || (!t || u2 > t.pct) && (t = { name: s, pct: u2 });
|
|
599
602
|
}
|
|
600
|
-
t && (o.state = t.name,
|
|
603
|
+
t && (o.state = t.name, p.add(t.name), a2.push(`state=${t.name} (${t.pct}% states/provinces)`));
|
|
601
604
|
}
|
|
602
605
|
if (!o.zip) for (let t of h2) {
|
|
603
|
-
if (
|
|
604
|
-
let s =
|
|
605
|
-
if (!(
|
|
606
|
-
o.zip = t,
|
|
606
|
+
if (p.has(t)) continue;
|
|
607
|
+
let s = d2(t), c = B3(s);
|
|
608
|
+
if (!(c < ht) && !(At(s, (u2) => x(u2).length > 0) < L2)) {
|
|
609
|
+
o.zip = t, p.add(t), a2.push(`zip=${t} (${c}% ZIP codes)`);
|
|
607
610
|
break;
|
|
608
611
|
}
|
|
609
612
|
}
|
|
610
613
|
if (!o.country) {
|
|
611
|
-
for (let t of h2) if (!
|
|
612
|
-
o.country = t,
|
|
614
|
+
for (let t of h2) if (!p.has(t) && g2(d2(t))) {
|
|
615
|
+
o.country = t, p.add(t), a2.push(`country=${t}`);
|
|
613
616
|
break;
|
|
614
617
|
}
|
|
615
618
|
}
|
|
616
619
|
if (!o.city) {
|
|
617
620
|
let t = null;
|
|
618
621
|
for (let s of h2) {
|
|
619
|
-
if (
|
|
620
|
-
let
|
|
621
|
-
u2 <
|
|
622
|
+
if (p.has(s)) continue;
|
|
623
|
+
let c = d2(s), u2 = bt(c, r);
|
|
624
|
+
u2 < v3 || G2(c, (R) => s3(R, r)) < L2 || (!t || u2 > t.pct) && (t = { name: s, pct: u2 });
|
|
622
625
|
}
|
|
623
|
-
t && (o.city = t.name,
|
|
626
|
+
t && (o.city = t.name, a2.push(`city=${t.name} (${t.pct}% known cities)`));
|
|
624
627
|
}
|
|
625
|
-
let
|
|
626
|
-
return o.country && !
|
|
628
|
+
let _2 = o.country ? d2(o.country) : [], x2 = !!o.country && g2(_2), D = x2 ? new Set(_2.map((t) => w(t == null ? null : String(t))).filter(Boolean)).size : 0, z2 = x2 && D >= 2;
|
|
629
|
+
return o.country && !z2 && !(o.city || o.state || o.zip || o.lat && o.lon) && m2.push(x2 ? `country=${o.country} (every row resolves to the same country - nothing to place apart)` : `country=${o.country} (values are not country identifiers)`), { bind: !!(o.city || o.state || o.zip || z2 || o.lat && o.lon) ? o : null, backfilled: a2, refused: m2 };
|
|
627
630
|
}
|
|
628
631
|
|
|
629
632
|
// src/payload.ts
|
|
@@ -637,21 +640,21 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
637
640
|
let rolesRefused = [];
|
|
638
641
|
if (bind) {
|
|
639
642
|
const dims = cols.filter((c) => !c.isMeasure).map((c) => c.name);
|
|
640
|
-
const res =
|
|
643
|
+
const res = Mt(dims, rowObjs, bind, point?.mapKind);
|
|
641
644
|
bind = res.bind;
|
|
642
645
|
rolesBackfilled = res.backfilled;
|
|
643
646
|
rolesRefused = res.refused;
|
|
644
647
|
}
|
|
645
648
|
const hasPointBind = !!bind && !!(bind.city || bind.state || bind.zip || bind.country || bind.lat && bind.lon);
|
|
646
649
|
if (hasPointBind) {
|
|
647
|
-
const
|
|
650
|
+
const p = bind;
|
|
648
651
|
const built = N3(rowObjs.map((r) => ({
|
|
649
|
-
lat:
|
|
650
|
-
lon:
|
|
651
|
-
city:
|
|
652
|
-
state:
|
|
653
|
-
zip:
|
|
654
|
-
country:
|
|
652
|
+
lat: p.lat ? r[p.lat] : null,
|
|
653
|
+
lon: p.lon ? r[p.lon] : null,
|
|
654
|
+
city: p.city ? r[p.city] : null,
|
|
655
|
+
state: p.state ? r[p.state] : null,
|
|
656
|
+
zip: p.zip ? r[p.zip] : null,
|
|
657
|
+
country: p.country ? r[p.country] : null
|
|
655
658
|
})), point?.mapKind);
|
|
656
659
|
pLat = built.lat;
|
|
657
660
|
pLon = built.lon;
|
|
@@ -690,19 +693,19 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
690
693
|
const row = rowObjs[r];
|
|
691
694
|
const a2 = new Array(cols.length + extra);
|
|
692
695
|
for (let c = 0; c < cols.length; c++) {
|
|
693
|
-
const
|
|
694
|
-
if (
|
|
695
|
-
a2[c] =
|
|
696
|
+
const v4 = row[colNames[c]];
|
|
697
|
+
if (v4 instanceof Date) {
|
|
698
|
+
a2[c] = v4.toISOString();
|
|
696
699
|
} else {
|
|
697
|
-
a2[c] =
|
|
700
|
+
a2[c] = v4 ?? null;
|
|
698
701
|
}
|
|
699
702
|
}
|
|
700
|
-
let
|
|
701
|
-
a2[
|
|
702
|
-
if (geoIso) a2[
|
|
703
|
+
let k2 = cols.length;
|
|
704
|
+
a2[k2++] = r;
|
|
705
|
+
if (geoIso) a2[k2++] = geoIso[r];
|
|
703
706
|
if (pLat && pLon) {
|
|
704
|
-
a2[
|
|
705
|
-
a2[
|
|
707
|
+
a2[k2++] = pLat[r];
|
|
708
|
+
a2[k2++] = pLon[r];
|
|
706
709
|
}
|
|
707
710
|
out[r] = a2;
|
|
708
711
|
}
|
|
@@ -719,8 +722,8 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
719
722
|
function createMarkResolver(env) {
|
|
720
723
|
const { root, doc, log } = env;
|
|
721
724
|
const isElement = (t) => {
|
|
722
|
-
const
|
|
723
|
-
if (
|
|
725
|
+
const E4 = doc?.defaultView?.Element ?? globalThis.Element;
|
|
726
|
+
if (E4 && t instanceof E4) return true;
|
|
724
727
|
return !!t && typeof t.closest === "function" && typeof t.getAttribute === "function";
|
|
725
728
|
};
|
|
726
729
|
const viewStyle = (n) => {
|
|
@@ -739,7 +742,7 @@ function createMarkResolver(env) {
|
|
|
739
742
|
const so = parseFloat(el.getAttribute("stroke-opacity") || "1");
|
|
740
743
|
return s === "transparent" || s === "none" || so <= 0.01;
|
|
741
744
|
};
|
|
742
|
-
const distToPathCenterline = (el, x2,
|
|
745
|
+
const distToPathCenterline = (el, x2, y3) => {
|
|
743
746
|
const L3 = el.getTotalLength();
|
|
744
747
|
if (!(L3 > 0)) return Number.MAX_VALUE;
|
|
745
748
|
const m2 = el.getScreenCTM();
|
|
@@ -747,18 +750,18 @@ function createMarkResolver(env) {
|
|
|
747
750
|
let best = Number.MAX_VALUE;
|
|
748
751
|
const N2 = 64;
|
|
749
752
|
for (let i = 0; i <= N2; i++) {
|
|
750
|
-
const
|
|
751
|
-
const dx = m2.a *
|
|
752
|
-
const dy = m2.b *
|
|
753
|
+
const pt = el.getPointAtLength(L3 * i / N2);
|
|
754
|
+
const dx = m2.a * pt.x + m2.c * pt.y + m2.e - x2;
|
|
755
|
+
const dy = m2.b * pt.x + m2.d * pt.y + m2.f - y3;
|
|
753
756
|
const d2 = dx * dx + dy * dy;
|
|
754
757
|
if (d2 < best) best = d2;
|
|
755
758
|
}
|
|
756
759
|
return Math.sqrt(best);
|
|
757
760
|
};
|
|
758
|
-
const refineHitCorridor = (mark, x2,
|
|
761
|
+
const refineHitCorridor = (mark, x2, y3, sel) => {
|
|
759
762
|
try {
|
|
760
763
|
if (!mark || !isInvisibleStrokePath(mark) || !mark.getAttribute("data-row-idx")) return mark;
|
|
761
|
-
const stack = doc.elementsFromPoint(x2,
|
|
764
|
+
const stack = doc.elementsFromPoint(x2, y3);
|
|
762
765
|
const candidates = [];
|
|
763
766
|
for (const el of stack) {
|
|
764
767
|
if (!root.contains(el)) continue;
|
|
@@ -772,7 +775,7 @@ function createMarkResolver(env) {
|
|
|
772
775
|
let best = mark;
|
|
773
776
|
let bestD = Number.MAX_VALUE;
|
|
774
777
|
for (const el of candidates) {
|
|
775
|
-
const d2 = distToPathCenterline(el, x2,
|
|
778
|
+
const d2 = distToPathCenterline(el, x2, y3);
|
|
776
779
|
if (d2 < bestD) {
|
|
777
780
|
bestD = d2;
|
|
778
781
|
best = el;
|
|
@@ -809,9 +812,9 @@ function createMarkResolver(env) {
|
|
|
809
812
|
}
|
|
810
813
|
return out;
|
|
811
814
|
};
|
|
812
|
-
const penetrateOverlayAt = (x2,
|
|
815
|
+
const penetrateOverlayAt = (x2, y3, sel) => {
|
|
813
816
|
try {
|
|
814
|
-
const stack = doc.elementsFromPoint(x2,
|
|
817
|
+
const stack = doc.elementsFromPoint(x2, y3);
|
|
815
818
|
for (const el of stack) {
|
|
816
819
|
if (!root.contains(el) || !isElement(el)) continue;
|
|
817
820
|
const cand = el.matches(sel) ? el : el.closest(sel);
|
|
@@ -823,7 +826,7 @@ function createMarkResolver(env) {
|
|
|
823
826
|
}
|
|
824
827
|
return null;
|
|
825
828
|
};
|
|
826
|
-
const resolveByGeometry = (x2,
|
|
829
|
+
const resolveByGeometry = (x2, y3, sel) => {
|
|
827
830
|
try {
|
|
828
831
|
const cands = root.querySelectorAll(sel);
|
|
829
832
|
let best = null, bestArea = Number.MAX_VALUE;
|
|
@@ -832,7 +835,7 @@ function createMarkResolver(env) {
|
|
|
832
835
|
if (!el.getAttribute("data-row-idx")) continue;
|
|
833
836
|
const r = el.getBoundingClientRect ? el.getBoundingClientRect() : null;
|
|
834
837
|
if (!r || r.width <= 0 || r.height <= 0) continue;
|
|
835
|
-
if (x2 < r.left || x2 > r.right ||
|
|
838
|
+
if (x2 < r.left || x2 > r.right || y3 < r.top || y3 > r.bottom) continue;
|
|
836
839
|
const area = r.width * r.height;
|
|
837
840
|
if (area < bestArea) {
|
|
838
841
|
bestArea = area;
|
|
@@ -931,7 +934,7 @@ function createChartHost(container, config) {
|
|
|
931
934
|
let data = config.data;
|
|
932
935
|
{
|
|
933
936
|
const stamped = config.data?.meta?.hostContract;
|
|
934
|
-
const major = (
|
|
937
|
+
const major = (v4) => (v4 || "").split(".")[0];
|
|
935
938
|
if (stamped && major(stamped) !== major(HOST_CONTRACT_VERSION)) {
|
|
936
939
|
try {
|
|
937
940
|
(win?.console ?? console)?.warn(
|
package/dist/index.mjs
CHANGED
package/dist/react.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
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",
|