@bicharts/chart-host 0.5.8 → 0.5.10
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-K3LSWWFS.mjs → chunk-OI5SSTYV.mjs} +191 -192
- 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(p2) {
|
|
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: p2.width,
|
|
40
|
+
height: p2.height,
|
|
41
|
+
palette: p2.palette,
|
|
42
|
+
geoUnmatched: p2.geoUnmatched,
|
|
43
|
+
geo: p2.geo,
|
|
44
|
+
geoPoint: p2.geoPoint,
|
|
45
|
+
maxMapPoints: p2.maxMapPoints,
|
|
46
|
+
uiState: p2.uiState,
|
|
47
|
+
setUiState: p2.setUiState,
|
|
48
|
+
backgroundColor: p2.backgroundColor,
|
|
49
|
+
themeBg: p2.themeBg,
|
|
50
|
+
themeFg: p2.themeFg,
|
|
51
|
+
isHighContrast: p2.isHighContrast,
|
|
52
|
+
themeAccent: p2.themeAccent,
|
|
53
|
+
cultureCode: p2.cultureCode,
|
|
54
|
+
allowTooltips: p2.allowTooltips,
|
|
55
|
+
noDataText: p2.noDataText,
|
|
56
|
+
onSelect: p2.onSelect,
|
|
57
57
|
// ---- live-restyle knobs: `raw || undefined` / `.toString() || undefined` ----
|
|
58
|
-
colorScaleLow:
|
|
59
|
-
colorScaleHigh:
|
|
58
|
+
colorScaleLow: p2.colorScaleLow || void 0,
|
|
59
|
+
colorScaleHigh: p2.colorScaleHigh || void 0,
|
|
60
60
|
// "" (global, the default), "frame", or "self"; anything else fails open to global.
|
|
61
|
-
colorScaleScope:
|
|
61
|
+
colorScaleScope: p2.colorScaleScope === "frame" || p2.colorScaleScope === "self" ? p2.colorScaleScope : "",
|
|
62
62
|
// Math.max(50, Math.min(100, Number(raw) || 95)) — only meaningful under "self".
|
|
63
|
-
colorScaleSelfClampPct: clamp(Number(
|
|
63
|
+
colorScaleSelfClampPct: clamp(Number(p2.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: p2.geoLandColor || void 0,
|
|
68
|
+
geoNoDataColor: p2.geoNoDataColor || void 0,
|
|
69
|
+
aggregation: (p2.aggregation == null ? "" : String(p2.aggregation)) || void 0,
|
|
70
70
|
// ---- animation: booleans, default+clamp numerics, "" default enum ----
|
|
71
|
-
animAutoPlay: !!
|
|
71
|
+
animAutoPlay: !!p2.animAutoPlay,
|
|
72
72
|
// Math.max(250, Math.min(5000, Number(raw) || 1000))
|
|
73
|
-
animPlaySpeedMs: clamp(Number(
|
|
73
|
+
animPlaySpeedMs: clamp(Number(p2.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(p2.animMaxIdealFrames) || ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX),
|
|
76
|
+
animStopAtEnd: !!p2.animStopAtEnd,
|
|
77
|
+
filtersDuringPlay: !!p2.filtersDuringPlay,
|
|
78
|
+
animTimelineStyle: (p2.animTimelineStyle || "").toString()
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -344,16 +344,16 @@ 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(),
|
|
347
|
+
let C = n.state === void 0 || n.state === null ? "" : String(n.state).trim(), d = C ? u(C) : "", p2 = C ? H(C) : null, S = [], R2 = -1;
|
|
348
348
|
for (let s of f) {
|
|
349
349
|
let A = s.row;
|
|
350
350
|
if (!A.kinds.includes(l)) continue;
|
|
351
351
|
let c = 0;
|
|
352
|
-
if (C && A.a1 !== "") if (
|
|
352
|
+
if (C && A.a1 !== "") if (p2 && A.a1 === p2 || u(A.a1) === d) c++;
|
|
353
353
|
else continue;
|
|
354
354
|
if (o) if (I(A.cc) === o) c++;
|
|
355
355
|
else continue;
|
|
356
|
-
c >
|
|
356
|
+
c > R2 ? (R2 = c, S = [s]) : c === R2 && S.push(s);
|
|
357
357
|
}
|
|
358
358
|
S.some((s) => s.primary) && (S = S.filter((s) => s.primary));
|
|
359
359
|
let N2 = /* @__PURE__ */ new Map();
|
|
@@ -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 = [],
|
|
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 = [], d = { latlon: 0, city: 0, zip3: 0, state: 0, country: 0 }, p2 = 0, S = 0, R2 = null;
|
|
386
386
|
for (let s = 0; s < n.length; ++s) {
|
|
387
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
|
|
391
|
-
|
|
390
|
+
let M = E(A);
|
|
391
|
+
M && !f.has(M.toLowerCase()) && (f.add(M.toLowerCase()), C.length < V && C.push(M));
|
|
392
392
|
} else if (c) {
|
|
393
|
-
if (t[s] = c.lat, i[s] = c.lon,
|
|
394
|
-
let
|
|
395
|
-
|
|
393
|
+
if (t[s] = c.lat, i[s] = c.lon, p2++, d[c.precision]++, (R2 === null || U[c.precision] > U[R2]) && (R2 = c.precision), U[c.precision] > U.city) {
|
|
394
|
+
let M = E(A);
|
|
395
|
+
M && !r.has(M.toLowerCase()) && (r.add(M.toLowerCase()), l.length < V && l.push(M));
|
|
396
396
|
}
|
|
397
397
|
} else {
|
|
398
398
|
t[s] = null, i[s] = null;
|
|
399
|
-
let
|
|
400
|
-
|
|
399
|
+
let M = E(A);
|
|
400
|
+
M && !o.has(M.toLowerCase()) && (o.add(M.toLowerCase()), a2.push(M));
|
|
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:
|
|
404
|
+
return { lat: t, lon: i, precision: R2, precisionCounts: d, coarseExamples: l, unmatched: a2, ambiguousRows: S, ambiguousExamples: C, matchedRows: p2, 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(", ");
|
|
@@ -414,29 +414,34 @@ function s3(n, e) {
|
|
|
414
414
|
return t.some((o) => o.row.kinds.includes(i));
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
// ../shape-core/dist/chunk-
|
|
417
|
+
// ../shape-core/dist/chunk-3VJWHB2I.mjs
|
|
418
418
|
/*! @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. */
|
|
419
|
-
var
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
419
|
+
var rn = /* @__PURE__ */ new Set(["n a", "none", "null", "nil", "unknown", "not applicable", "not available", "not specified", "unspecified", "missing", "blank", "empty", "tbd", "to be determined"]);
|
|
420
|
+
function mn(n) {
|
|
421
|
+
return n ? rn.has(n) : true;
|
|
422
|
+
}
|
|
423
|
+
var j2 = 80;
|
|
424
|
+
var Q2 = [["AL", "Alabama"], ["AK", "Alaska"], ["AZ", "Arizona"], ["AR", "Arkansas"], ["CA", "California"], ["CO", "Colorado"], ["CT", "Connecticut"], ["DE", "Delaware"], ["FL", "Florida"], ["GA", "Georgia"], ["HI", "Hawaii"], ["ID", "Idaho"], ["IL", "Illinois"], ["IN", "Indiana"], ["IA", "Iowa"], ["KS", "Kansas"], ["KY", "Kentucky"], ["LA", "Louisiana"], ["ME", "Maine"], ["MD", "Maryland"], ["MA", "Massachusetts"], ["MI", "Michigan"], ["MN", "Minnesota"], ["MS", "Mississippi"], ["MO", "Missouri"], ["MT", "Montana"], ["NE", "Nebraska"], ["NV", "Nevada"], ["NH", "New Hampshire"], ["NJ", "New Jersey"], ["NM", "New Mexico"], ["NY", "New York"], ["NC", "North Carolina"], ["ND", "North Dakota"], ["OH", "Ohio"], ["OK", "Oklahoma"], ["OR", "Oregon"], ["PA", "Pennsylvania"], ["RI", "Rhode Island"], ["SC", "South Carolina"], ["SD", "South Dakota"], ["TN", "Tennessee"], ["TX", "Texas"], ["UT", "Utah"], ["VT", "Vermont"], ["VA", "Virginia"], ["WA", "Washington"], ["WV", "West Virginia"], ["WI", "Wisconsin"], ["WY", "Wyoming"], ["DC", "District of Columbia"], ["PR", "Puerto Rico"], ["GU", "Guam"], ["VI", "U.S. Virgin Islands"], ["AS", "American Samoa"], ["MP", "Northern Mariana Islands"]];
|
|
425
|
+
var nn = new Set(Q2.map((n) => n[0]));
|
|
426
|
+
var an = { "Ala.": "AL", "Alab.": "AL", "Ariz.": "AZ", "Ark.": "AR", "Calif.": "CA", "Cal.": "CA", "Colo.": "CO", "Col.": "CO", "Conn.": "CT", "Del.": "DE", "Fla.": "FL", "Flor.": "FL", "Ga.": "GA", "Ill.": "IL", "Ind.": "IN", "Kan.": "KS", "Kans.": "KS", "Ky.": "KY", "La.": "LA", "Md.": "MD", "Mass.": "MA", "Mich.": "MI", "Minn.": "MN", "Miss.": "MS", "Mo.": "MO", "Mont.": "MT", "Neb.": "NE", "Nebr.": "NE", "Nev.": "NV", "N.H.": "NH", "N.J.": "NJ", "N.M.": "NM", "N.Mex.": "NM", "N. Mex.": "NM", "N.Y.": "NY", "N.C.": "NC", "N.D.": "ND", "N.Dak.": "ND", "N. Dak.": "ND", "Okla.": "OK", "Ore.": "OR", "Oreg.": "OR", "Pa.": "PA", "Penn.": "PA", "Penna.": "PA", "R.I.": "RI", "S.C.": "SC", "S.D.": "SD", "S.Dak.": "SD", "S. Dak.": "SD", "Tenn.": "TN", "Tex.": "TX", "Vt.": "VT", "Va.": "VA", "Wash.": "WA", "W.Va.": "WV", "W. Va.": "WV", "Wis.": "WI", "Wisc.": "WI", "Wyo.": "WY", "D.C.": "DC", "Wash. D.C.": "DC", "Wash., D.C.": "DC", "P.R.": "PR", "V.I.": "VI" };
|
|
427
|
+
var tn = (() => {
|
|
423
428
|
let n = /* @__PURE__ */ new Map();
|
|
424
|
-
for (let [i, s] of
|
|
425
|
-
n.set(
|
|
426
|
-
for (let [i, s] of Object.entries(
|
|
427
|
-
let o =
|
|
429
|
+
for (let [i, s] of Q2) n.set(p(s), i);
|
|
430
|
+
n.set(p("Washington DC"), "DC"), n.set(p("Washington D.C."), "DC"), n.set(p("US Virgin Islands"), "VI");
|
|
431
|
+
for (let [i, s] of Object.entries(an)) {
|
|
432
|
+
let o = p(i);
|
|
428
433
|
o && !n.has(o) && n.set(o, s);
|
|
429
434
|
}
|
|
430
435
|
return n;
|
|
431
436
|
})();
|
|
432
|
-
var
|
|
437
|
+
var en = /* @__PURE__ */ new Set(["01", "02", "04", "05", "06", "08", "09", "10", "11", "12", "13", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "44", "45", "46", "47", "48", "49", "50", "51", "53", "54", "55", "56", "60", "66", "69", "72", "78"]);
|
|
433
438
|
function E2(n) {
|
|
434
439
|
return n.trim().toUpperCase();
|
|
435
440
|
}
|
|
436
|
-
function
|
|
441
|
+
function p(n) {
|
|
437
442
|
return u(n);
|
|
438
443
|
}
|
|
439
|
-
function
|
|
444
|
+
function Sn(n, i) {
|
|
440
445
|
if (n == null) return null;
|
|
441
446
|
let s = String(n).trim();
|
|
442
447
|
if (s.length === 0) return null;
|
|
@@ -448,23 +453,23 @@ function ln(n, i) {
|
|
|
448
453
|
case "country-iso2":
|
|
449
454
|
return m.get(E2(s)) ?? null;
|
|
450
455
|
case "country-name":
|
|
451
|
-
return Q().get(
|
|
456
|
+
return Q().get(p(s)) ?? null;
|
|
452
457
|
case "us-state-code":
|
|
453
458
|
case "us-state-name": {
|
|
454
459
|
let o = E2(s);
|
|
455
|
-
return
|
|
460
|
+
return nn.has(o) ? o : tn.get(p(s)) ?? null;
|
|
456
461
|
}
|
|
457
462
|
case "us-zip5": {
|
|
458
463
|
let o = /^(\d{5})(-\d{4})?$/.exec(s);
|
|
459
464
|
return o ? o[1] : /^\d{3,4}$/.test(s) ? s.padStart(5, "0") : null;
|
|
460
465
|
}
|
|
461
466
|
case "us-county-fips":
|
|
462
|
-
return /^\d{5}$/.test(s) &&
|
|
467
|
+
return /^\d{5}$/.test(s) && en.has(s.slice(0, 2)) ? s : null;
|
|
463
468
|
default:
|
|
464
469
|
return null;
|
|
465
470
|
}
|
|
466
471
|
}
|
|
467
|
-
function
|
|
472
|
+
function _n(n) {
|
|
468
473
|
switch (n) {
|
|
469
474
|
case "country-iso3":
|
|
470
475
|
case "country-iso2":
|
|
@@ -478,155 +483,149 @@ function hn(n) {
|
|
|
478
483
|
return false;
|
|
479
484
|
}
|
|
480
485
|
}
|
|
481
|
-
function
|
|
482
|
-
let s = new Array(n.length), o = /* @__PURE__ */ new Set(),
|
|
483
|
-
for (let
|
|
484
|
-
let
|
|
485
|
-
if (s[
|
|
486
|
+
function Dn(n, i) {
|
|
487
|
+
let s = new Array(n.length), o = /* @__PURE__ */ new Set(), A = [], S = 0;
|
|
488
|
+
for (let g2 = 0; g2 < n.length; ++g2) {
|
|
489
|
+
let I3 = Sn(n[g2], i);
|
|
490
|
+
if (s[g2] = I3, I3 !== null) S++;
|
|
486
491
|
else {
|
|
487
|
-
let
|
|
488
|
-
if (
|
|
489
|
-
let
|
|
490
|
-
if (
|
|
491
|
-
let
|
|
492
|
-
o.has(
|
|
492
|
+
let h3 = n[g2];
|
|
493
|
+
if (h3 != null) {
|
|
494
|
+
let m3 = String(h3).trim();
|
|
495
|
+
if (m3.length > 0) {
|
|
496
|
+
let N2 = m3.toLowerCase();
|
|
497
|
+
o.has(N2) || (o.add(N2), A.push(m3));
|
|
493
498
|
}
|
|
494
499
|
}
|
|
495
500
|
}
|
|
496
501
|
}
|
|
497
|
-
return { iso: s, unmatched:
|
|
502
|
+
return { iso: s, unmatched: A, matchedRows: S, totalRows: n.length };
|
|
498
503
|
}
|
|
499
504
|
|
|
500
505
|
// ../shape-core/dist/index.mjs
|
|
501
506
|
/*! @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 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
507
|
var L2 = 2;
|
|
508
|
-
var
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
return !!w(i);
|
|
508
|
+
var $2 = 400;
|
|
509
|
+
function w2(r) {
|
|
510
|
+
return !!w(r);
|
|
512
511
|
}
|
|
513
|
-
function
|
|
512
|
+
function m2(r) {
|
|
514
513
|
let n = /* @__PURE__ */ new Set();
|
|
515
|
-
for (let e of
|
|
514
|
+
for (let e of r) {
|
|
516
515
|
if (e == null) continue;
|
|
517
|
-
let
|
|
518
|
-
if (!
|
|
516
|
+
let i = u(String(e));
|
|
517
|
+
if (!mn(i) && !n.has(i) && (n.add(i), n.size >= $2)) break;
|
|
519
518
|
}
|
|
520
519
|
return Array.from(n);
|
|
521
520
|
}
|
|
522
|
-
function
|
|
523
|
-
let n =
|
|
524
|
-
if (n.length === 0 ||
|
|
525
|
-
let e = n.filter((a2) => w2(a2) && !H(a2)).length,
|
|
526
|
-
return e >= 1 && e >=
|
|
521
|
+
function h2(r) {
|
|
522
|
+
let n = m2(r);
|
|
523
|
+
if (n.length === 0 || ht(r) < 96) return false;
|
|
524
|
+
let e = n.filter((a2) => w2(a2) && !H(a2)).length, i = n.filter((a2) => !w2(a2) && !!H(a2)).length;
|
|
525
|
+
return e >= 1 && e >= i;
|
|
527
526
|
}
|
|
528
|
-
var
|
|
529
|
-
function
|
|
530
|
-
if (!H(
|
|
531
|
-
let e = w(
|
|
532
|
-
return e ? n === "world" ? true :
|
|
527
|
+
var gt = /* @__PURE__ */ new Set(["USA", "CAN", "MEX"]);
|
|
528
|
+
function N(r, n) {
|
|
529
|
+
if (!H(r)) return false;
|
|
530
|
+
let e = w(r);
|
|
531
|
+
return e ? n === "world" ? true : gt.has(e) : false;
|
|
533
532
|
}
|
|
534
|
-
function
|
|
535
|
-
let n =
|
|
533
|
+
function ht(r) {
|
|
534
|
+
let n = m2(r);
|
|
536
535
|
if (n.length === 0) return 0;
|
|
537
536
|
let e = 0;
|
|
538
|
-
for (let
|
|
537
|
+
for (let i of n) w2(i) && e++;
|
|
539
538
|
return Math.round(e / n.length * 1e3) / 10;
|
|
540
539
|
}
|
|
541
|
-
function
|
|
542
|
-
let n =
|
|
540
|
+
function R(r) {
|
|
541
|
+
let n = m2(r);
|
|
543
542
|
if (n.length === 0) return 0;
|
|
544
543
|
let e = 0;
|
|
545
|
-
for (let
|
|
544
|
+
for (let i of n) H(i) && e++;
|
|
546
545
|
return Math.round(e / n.length * 1e3) / 10;
|
|
547
546
|
}
|
|
548
|
-
function
|
|
547
|
+
function O2(r) {
|
|
549
548
|
let n = /* @__PURE__ */ new Set();
|
|
550
|
-
for (let e of
|
|
549
|
+
for (let e of r) {
|
|
551
550
|
if (e == null) continue;
|
|
552
|
-
let
|
|
553
|
-
if (!
|
|
551
|
+
let i = String(e).trim();
|
|
552
|
+
if (!mn(u(i)) && !n.has(i) && (n.add(i), n.size >= $2)) break;
|
|
554
553
|
}
|
|
555
554
|
return Array.from(n);
|
|
556
555
|
}
|
|
557
|
-
function
|
|
558
|
-
let n =
|
|
556
|
+
function B2(r) {
|
|
557
|
+
let n = O2(r);
|
|
559
558
|
if (n.length === 0) return 0;
|
|
560
559
|
let e = 0;
|
|
561
|
-
for (let
|
|
560
|
+
for (let i of n) x(i).length > 0 && e++;
|
|
562
561
|
return Math.round(e / n.length * 1e3) / 10;
|
|
563
562
|
}
|
|
564
|
-
function
|
|
565
|
-
let e =
|
|
563
|
+
function Ct(r, n) {
|
|
564
|
+
let e = m2(r);
|
|
566
565
|
if (e.length === 0) return 0;
|
|
567
|
-
let
|
|
568
|
-
for (let a2 of e) s3(a2, n) &&
|
|
569
|
-
return Math.round(
|
|
566
|
+
let i = 0;
|
|
567
|
+
for (let a2 of e) s3(a2, n) && i++;
|
|
568
|
+
return Math.round(i / e.length * 1e3) / 10;
|
|
570
569
|
}
|
|
571
|
-
function
|
|
570
|
+
function I2(r, n) {
|
|
572
571
|
let e = 0;
|
|
573
|
-
for (let
|
|
572
|
+
for (let i of m2(r)) n(i) && e++;
|
|
574
573
|
return e;
|
|
575
574
|
}
|
|
576
|
-
function
|
|
575
|
+
function Pt(r, n) {
|
|
577
576
|
let e = 0;
|
|
578
|
-
for (let
|
|
577
|
+
for (let i of O2(r)) n(i) && e++;
|
|
579
578
|
return e;
|
|
580
579
|
}
|
|
581
|
-
function Mt(
|
|
582
|
-
let a2 = [],
|
|
580
|
+
function Mt(r, n, e, i) {
|
|
581
|
+
let a2 = [], g2 = [], o = {}, G2 = new Set(r), p2 = (t) => n.map((s) => s[t]);
|
|
583
582
|
for (let t of ["city", "zip", "lat", "lon", "country"]) {
|
|
584
583
|
let s = e?.[t];
|
|
585
|
-
s &&
|
|
584
|
+
s && G2.has(s) && (o[t] = s);
|
|
586
585
|
}
|
|
587
586
|
let l = e?.state;
|
|
588
|
-
if (l &&
|
|
589
|
-
let t =
|
|
590
|
-
s.length > 0 && s.every((c) =>
|
|
587
|
+
if (l && G2.has(l)) {
|
|
588
|
+
let t = p2(l), s = m2(t);
|
|
589
|
+
s.length > 0 && s.every((c) => N(c, i)) ? g2.push(`state=${l} (every value is "CA", which is both Canada and California)`) : h2(t) ? (g2.push(`state=${l} (every value is a country, not a state)`), o.country || (o.country = l)) : R(t) < 96 ? g2.push(`state=${l} (only ${R(t)}% of values are states/provinces)`) : o.state = l;
|
|
591
590
|
}
|
|
592
|
-
let
|
|
591
|
+
let d = new Set(Object.values(o).filter(Boolean)), C = r.filter((t) => !d.has(t) && !t.startsWith("__"));
|
|
593
592
|
if (!o.state) {
|
|
594
593
|
let t = null;
|
|
595
|
-
for (let s of
|
|
596
|
-
let c =
|
|
597
|
-
if (
|
|
598
|
-
let u2 =
|
|
599
|
-
if (u2 <
|
|
600
|
-
let
|
|
601
|
-
|
|
594
|
+
for (let s of C) {
|
|
595
|
+
let c = p2(s);
|
|
596
|
+
if (h2(c)) continue;
|
|
597
|
+
let u2 = R(c);
|
|
598
|
+
if (u2 < 96) continue;
|
|
599
|
+
let S = I2(c, (P2) => !!H(P2)), E3 = I2(c, (P2) => !!H(P2) && !N(P2, i));
|
|
600
|
+
S < L2 && E3 < 1 || (!t || u2 > t.pct) && (t = { name: s, pct: u2 });
|
|
602
601
|
}
|
|
603
|
-
t && (o.state = t.name,
|
|
602
|
+
t && (o.state = t.name, d.add(t.name), a2.push(`state=${t.name} (${t.pct}% states/provinces)`));
|
|
604
603
|
}
|
|
605
|
-
if (!o.zip) for (let t of
|
|
606
|
-
if (
|
|
607
|
-
let s =
|
|
608
|
-
if (!(c <
|
|
609
|
-
o.zip = t,
|
|
604
|
+
if (!o.zip) for (let t of C) {
|
|
605
|
+
if (d.has(t)) continue;
|
|
606
|
+
let s = p2(t), c = B2(s);
|
|
607
|
+
if (!(c < 96) && !(Pt(s, (u2) => x(u2).length > 0) < L2)) {
|
|
608
|
+
o.zip = t, d.add(t), a2.push(`zip=${t} (${c}% ZIP codes)`);
|
|
610
609
|
break;
|
|
611
610
|
}
|
|
612
611
|
}
|
|
613
612
|
if (!o.country) {
|
|
614
|
-
for (let t of
|
|
615
|
-
o.country = t,
|
|
613
|
+
for (let t of C) if (!d.has(t) && h2(p2(t))) {
|
|
614
|
+
o.country = t, d.add(t), a2.push(`country=${t}`);
|
|
616
615
|
break;
|
|
617
616
|
}
|
|
618
617
|
}
|
|
619
618
|
if (!o.city) {
|
|
620
619
|
let t = null;
|
|
621
|
-
for (let s of
|
|
622
|
-
if (
|
|
623
|
-
let c =
|
|
624
|
-
u2 <
|
|
620
|
+
for (let s of C) {
|
|
621
|
+
if (d.has(s)) continue;
|
|
622
|
+
let c = p2(s), u2 = Ct(c, i);
|
|
623
|
+
u2 < j2 || I2(c, (S) => s3(S, i)) < L2 || (!t || u2 > t.pct) && (t = { name: s, pct: u2 });
|
|
625
624
|
}
|
|
626
625
|
t && (o.city = t.name, a2.push(`city=${t.name} (${t.pct}% known cities)`));
|
|
627
626
|
}
|
|
628
|
-
let _2 = o.country ?
|
|
629
|
-
return o.country && !z2 && !(o.city || o.state || o.zip || o.lat && o.lon) &&
|
|
627
|
+
let _2 = o.country ? p2(o.country) : [], v2 = !!o.country && h2(_2), D = v2 ? new Set(_2.map((t) => w(t == null ? null : String(t))).filter(Boolean)).size : 0, z2 = v2 && D >= 2;
|
|
628
|
+
return o.country && !z2 && !(o.city || o.state || o.zip || o.lat && o.lon) && g2.push(v2 ? `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: g2 };
|
|
630
629
|
}
|
|
631
630
|
|
|
632
631
|
// src/payload.ts
|
|
@@ -647,14 +646,14 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
647
646
|
}
|
|
648
647
|
const hasPointBind = !!bind && !!(bind.city || bind.state || bind.zip || bind.country || bind.lat && bind.lon);
|
|
649
648
|
if (hasPointBind) {
|
|
650
|
-
const
|
|
649
|
+
const p2 = bind;
|
|
651
650
|
const built = N3(rowObjs.map((r) => ({
|
|
652
|
-
lat:
|
|
653
|
-
lon:
|
|
654
|
-
city:
|
|
655
|
-
state:
|
|
656
|
-
zip:
|
|
657
|
-
country:
|
|
651
|
+
lat: p2.lat ? r[p2.lat] : null,
|
|
652
|
+
lon: p2.lon ? r[p2.lon] : null,
|
|
653
|
+
city: p2.city ? r[p2.city] : null,
|
|
654
|
+
state: p2.state ? r[p2.state] : null,
|
|
655
|
+
zip: p2.zip ? r[p2.zip] : null,
|
|
656
|
+
country: p2.country ? r[p2.country] : null
|
|
658
657
|
})), point?.mapKind);
|
|
659
658
|
pLat = built.lat;
|
|
660
659
|
pLon = built.lon;
|
|
@@ -681,8 +680,8 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
681
680
|
let geoIso = null;
|
|
682
681
|
let geoUnmatched;
|
|
683
682
|
let geoUnmatchedDistinct;
|
|
684
|
-
if (geo && geo.column && geo.kind &&
|
|
685
|
-
const built =
|
|
683
|
+
if (geo && geo.column && geo.kind && _n(geo.kind)) {
|
|
684
|
+
const built = Dn(rowObjs.map((r) => r[geo.column]), geo.kind);
|
|
686
685
|
geoIso = built.iso;
|
|
687
686
|
geoUnmatched = { count: built.totalRows - built.matchedRows, examples: built.unmatched.slice(0, 8) };
|
|
688
687
|
geoUnmatchedDistinct = built.unmatched.length;
|
|
@@ -693,11 +692,11 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
693
692
|
const row = rowObjs[r];
|
|
694
693
|
const a2 = new Array(cols.length + extra);
|
|
695
694
|
for (let c = 0; c < cols.length; c++) {
|
|
696
|
-
const
|
|
697
|
-
if (
|
|
698
|
-
a2[c] =
|
|
695
|
+
const v2 = row[colNames[c]];
|
|
696
|
+
if (v2 instanceof Date) {
|
|
697
|
+
a2[c] = v2.toISOString();
|
|
699
698
|
} else {
|
|
700
|
-
a2[c] =
|
|
699
|
+
a2[c] = v2 ?? null;
|
|
701
700
|
}
|
|
702
701
|
}
|
|
703
702
|
let k2 = cols.length;
|
|
@@ -722,8 +721,8 @@ function buildRenderPayload(cols, rowObjs, geo, point) {
|
|
|
722
721
|
function createMarkResolver(env) {
|
|
723
722
|
const { root, doc, log } = env;
|
|
724
723
|
const isElement = (t) => {
|
|
725
|
-
const
|
|
726
|
-
if (
|
|
724
|
+
const E3 = doc?.defaultView?.Element ?? globalThis.Element;
|
|
725
|
+
if (E3 && t instanceof E3) return true;
|
|
727
726
|
return !!t && typeof t.closest === "function" && typeof t.getAttribute === "function";
|
|
728
727
|
};
|
|
729
728
|
const viewStyle = (n) => {
|
|
@@ -742,26 +741,26 @@ function createMarkResolver(env) {
|
|
|
742
741
|
const so = parseFloat(el.getAttribute("stroke-opacity") || "1");
|
|
743
742
|
return s === "transparent" || s === "none" || so <= 0.01;
|
|
744
743
|
};
|
|
745
|
-
const distToPathCenterline = (el, x2,
|
|
744
|
+
const distToPathCenterline = (el, x2, y2) => {
|
|
746
745
|
const L3 = el.getTotalLength();
|
|
747
746
|
if (!(L3 > 0)) return Number.MAX_VALUE;
|
|
748
|
-
const
|
|
749
|
-
if (!
|
|
747
|
+
const m3 = el.getScreenCTM();
|
|
748
|
+
if (!m3) return Number.MAX_VALUE;
|
|
750
749
|
let best = Number.MAX_VALUE;
|
|
751
750
|
const N2 = 64;
|
|
752
751
|
for (let i = 0; i <= N2; i++) {
|
|
753
752
|
const pt = el.getPointAtLength(L3 * i / N2);
|
|
754
|
-
const dx =
|
|
755
|
-
const dy =
|
|
756
|
-
const
|
|
757
|
-
if (
|
|
753
|
+
const dx = m3.a * pt.x + m3.c * pt.y + m3.e - x2;
|
|
754
|
+
const dy = m3.b * pt.x + m3.d * pt.y + m3.f - y2;
|
|
755
|
+
const d = dx * dx + dy * dy;
|
|
756
|
+
if (d < best) best = d;
|
|
758
757
|
}
|
|
759
758
|
return Math.sqrt(best);
|
|
760
759
|
};
|
|
761
|
-
const refineHitCorridor = (mark, x2,
|
|
760
|
+
const refineHitCorridor = (mark, x2, y2, sel) => {
|
|
762
761
|
try {
|
|
763
762
|
if (!mark || !isInvisibleStrokePath(mark) || !mark.getAttribute("data-row-idx")) return mark;
|
|
764
|
-
const stack = doc.elementsFromPoint(x2,
|
|
763
|
+
const stack = doc.elementsFromPoint(x2, y2);
|
|
765
764
|
const candidates = [];
|
|
766
765
|
for (const el of stack) {
|
|
767
766
|
if (!root.contains(el)) continue;
|
|
@@ -775,9 +774,9 @@ function createMarkResolver(env) {
|
|
|
775
774
|
let best = mark;
|
|
776
775
|
let bestD = Number.MAX_VALUE;
|
|
777
776
|
for (const el of candidates) {
|
|
778
|
-
const
|
|
779
|
-
if (
|
|
780
|
-
bestD =
|
|
777
|
+
const d = distToPathCenterline(el, x2, y2);
|
|
778
|
+
if (d < bestD) {
|
|
779
|
+
bestD = d;
|
|
781
780
|
best = el;
|
|
782
781
|
}
|
|
783
782
|
}
|
|
@@ -797,9 +796,9 @@ function createMarkResolver(env) {
|
|
|
797
796
|
const findMark = (target, sel = ".d3-mark", ev) => {
|
|
798
797
|
if (!isElement(target)) return null;
|
|
799
798
|
const el = target;
|
|
800
|
-
const
|
|
801
|
-
if (
|
|
802
|
-
return
|
|
799
|
+
const m3 = el.closest(sel);
|
|
800
|
+
if (m3 && ev) return refineHitCorridor(m3, ev.clientX, ev.clientY, sel);
|
|
801
|
+
return m3;
|
|
803
802
|
};
|
|
804
803
|
const rowIdxsFromMark = (el) => {
|
|
805
804
|
if (!el) return [];
|
|
@@ -812,9 +811,9 @@ function createMarkResolver(env) {
|
|
|
812
811
|
}
|
|
813
812
|
return out;
|
|
814
813
|
};
|
|
815
|
-
const penetrateOverlayAt = (x2,
|
|
814
|
+
const penetrateOverlayAt = (x2, y2, sel) => {
|
|
816
815
|
try {
|
|
817
|
-
const stack = doc.elementsFromPoint(x2,
|
|
816
|
+
const stack = doc.elementsFromPoint(x2, y2);
|
|
818
817
|
for (const el of stack) {
|
|
819
818
|
if (!root.contains(el) || !isElement(el)) continue;
|
|
820
819
|
const cand = el.matches(sel) ? el : el.closest(sel);
|
|
@@ -826,7 +825,7 @@ function createMarkResolver(env) {
|
|
|
826
825
|
}
|
|
827
826
|
return null;
|
|
828
827
|
};
|
|
829
|
-
const resolveByGeometry = (x2,
|
|
828
|
+
const resolveByGeometry = (x2, y2, sel) => {
|
|
830
829
|
try {
|
|
831
830
|
const cands = root.querySelectorAll(sel);
|
|
832
831
|
let best = null, bestArea = Number.MAX_VALUE;
|
|
@@ -835,7 +834,7 @@ function createMarkResolver(env) {
|
|
|
835
834
|
if (!el.getAttribute("data-row-idx")) continue;
|
|
836
835
|
const r = el.getBoundingClientRect ? el.getBoundingClientRect() : null;
|
|
837
836
|
if (!r || r.width <= 0 || r.height <= 0) continue;
|
|
838
|
-
if (x2 < r.left || x2 > r.right ||
|
|
837
|
+
if (x2 < r.left || x2 > r.right || y2 < r.top || y2 > r.bottom) continue;
|
|
839
838
|
const area = r.width * r.height;
|
|
840
839
|
if (area < bestArea) {
|
|
841
840
|
bestArea = area;
|
|
@@ -883,8 +882,8 @@ var D3_PLUGIN_PACKAGES = {
|
|
|
883
882
|
};
|
|
884
883
|
function requiredD3Plugins(code) {
|
|
885
884
|
const out = /* @__PURE__ */ new Set();
|
|
886
|
-
for (const
|
|
887
|
-
const pkg = D3_PLUGIN_PACKAGES[
|
|
885
|
+
for (const m3 of String(code || "").matchAll(/\bd3\s*\.\s*(\w+)\s*\(/g)) {
|
|
886
|
+
const pkg = D3_PLUGIN_PACKAGES[m3[1]];
|
|
888
887
|
if (pkg) out.add(pkg);
|
|
889
888
|
}
|
|
890
889
|
return [...out].sort();
|
|
@@ -896,8 +895,8 @@ function explainRenderFailure(err, d3) {
|
|
|
896
895
|
"[@bicharts/chart-host] no d3 was provided, so the generated chart could not run. Pass it explicitly \u2014 createChartHost(el, { d3 }) / <BicChart d3={d3} /> \u2014 or set window.d3. The chart needs D3 v7 (npm install d3@7). Original error: " + msg
|
|
897
896
|
);
|
|
898
897
|
}
|
|
899
|
-
const
|
|
900
|
-
const name =
|
|
898
|
+
const m3 = /d3\.(\w+) is not a function|(\w+) is not a function/.exec(msg);
|
|
899
|
+
const name = m3?.[1] ?? m3?.[2] ?? "";
|
|
901
900
|
const pkg = D3_PLUGIN_PACKAGES[name];
|
|
902
901
|
if (pkg) {
|
|
903
902
|
return new Error(
|
|
@@ -934,7 +933,7 @@ function createChartHost(container, config) {
|
|
|
934
933
|
let data = config.data;
|
|
935
934
|
{
|
|
936
935
|
const stamped = config.data?.meta?.hostContract;
|
|
937
|
-
const major = (
|
|
936
|
+
const major = (v2) => (v2 || "").split(".")[0];
|
|
938
937
|
if (stamped && major(stamped) !== major(HOST_CONTRACT_VERSION)) {
|
|
939
938
|
try {
|
|
940
939
|
(win?.console ?? console)?.warn(
|
|
@@ -985,10 +984,10 @@ function createChartHost(container, config) {
|
|
|
985
984
|
container.classList?.[active ? "add" : "remove"](SELECTION_ACTIVE_CLASS);
|
|
986
985
|
const wanted = new Set(sel ?? []);
|
|
987
986
|
const marks = container.querySelectorAll(`.${MARK_CLASS}[${ROW_IDX_ATTR}], .${LEGEND_MARK_CLASS}[${ROW_IDX_ATTR}]`);
|
|
988
|
-
for (const
|
|
989
|
-
const rows = parseRowIdxs(
|
|
987
|
+
for (const m3 of Array.from(marks)) {
|
|
988
|
+
const rows = parseRowIdxs(m3.getAttribute(ROW_IDX_ATTR));
|
|
990
989
|
const on = active && rows.some((r) => wanted.has(r));
|
|
991
|
-
|
|
990
|
+
m3.classList?.[on ? "add" : "remove"](MARK_SELECTED_CLASS);
|
|
992
991
|
}
|
|
993
992
|
} catch {
|
|
994
993
|
}
|
|
@@ -1006,10 +1005,10 @@ function createChartHost(container, config) {
|
|
|
1006
1005
|
let xfAt = 0;
|
|
1007
1006
|
const XF_ECHO_MS = 150;
|
|
1008
1007
|
const onXf = (e) => {
|
|
1009
|
-
const
|
|
1008
|
+
const d = e?.detail || {};
|
|
1010
1009
|
xfAt = Date.now();
|
|
1011
|
-
if (
|
|
1012
|
-
else if (
|
|
1010
|
+
if (d.clear) notify([], d.source || "chart");
|
|
1011
|
+
else if (d.mark) notify(parseRowIdxs(d.mark.getAttribute?.(ROW_IDX_ATTR)), d.source || "chart");
|
|
1013
1012
|
};
|
|
1014
1013
|
const resolver = createMarkResolver({
|
|
1015
1014
|
root: container,
|
|
@@ -1064,8 +1063,8 @@ function createChartHost(container, config) {
|
|
|
1064
1063
|
renderFn = compileRenderFn(config.code, win, doc, d3);
|
|
1065
1064
|
}
|
|
1066
1065
|
if (resolved.geo === void 0 && config.geoKind) {
|
|
1067
|
-
const
|
|
1068
|
-
if (
|
|
1066
|
+
const g2 = config.geoProvider?.(config.geoKind) ?? geoFromCache(config.geoKind);
|
|
1067
|
+
if (g2) resolved = { ...resolved, geo: g2 };
|
|
1069
1068
|
else if (!warnedGeo) {
|
|
1070
1069
|
warnedGeo = true;
|
|
1071
1070
|
try {
|
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.10",
|
|
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",
|