@bicharts/chart-host 0.6.108 → 0.6.109
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 +3 -3
- package/dist/card.mjs +2 -2
- package/dist/{chunk-FCLPMC6Q.mjs → chunk-3EQOJHRA.mjs} +1 -1
- package/dist/{chunk-LGWTV5PB.mjs → chunk-3ER4C7TG.mjs} +1 -1
- package/dist/{chunk-ESBH2L6E.mjs → chunk-4DOKJ3R3.mjs} +2 -2
- package/dist/{chunk-MU4BWWO6.mjs → chunk-G4CKILIL.mjs} +1 -1
- package/dist/{chunk-UKXGOQMS.mjs → chunk-GQLEU3VC.mjs} +1 -1
- package/dist/{chunk-MO2GR56D.mjs → chunk-JQ7FFCOE.mjs} +371 -12
- package/dist/{chunk-JU2PQ22J.mjs → chunk-QAPZIFOB.mjs} +1 -1
- package/dist/{chunk-SYUJ4TPX.mjs → chunk-TH577JHI.mjs} +23 -23
- package/dist/{chunk-OSREEGBN.mjs → chunk-TN5JRULV.mjs} +1 -1
- package/dist/{chunk-PHUUFCJY.mjs → chunk-USZSHKIB.mjs} +3 -1
- package/dist/index.mjs +27 -9
- package/dist/legend-fit.mjs +3 -3
- package/dist/page.mjs +4 -4
- package/dist/provinces.mjs +1 -1
- package/dist/react.mjs +13 -9
- package/dist/testing.mjs +1 -1
- package/dist/types/annotations.d.ts +3 -1
- package/dist/types/contract.d.ts +6 -1
- package/dist/types/focusKeep.d.ts +12 -0
- package/dist/types/host.d.ts +10 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/keyboardMarks.d.ts +43 -0
- package/dist/zoom-memory.mjs +1 -1
- package/package.json +1 -1
package/dist/adapters.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
censusHitBands,
|
|
4
4
|
ensureCrossfilterHitTargets,
|
|
5
5
|
hitBandFlag
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-GQLEU3VC.mjs";
|
|
7
7
|
import {
|
|
8
8
|
clickWasDrag,
|
|
9
9
|
collectD3GlyphCenters,
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
markKeyOf,
|
|
13
13
|
rowIdxsFromMark,
|
|
14
14
|
selectionRuleOf
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3ER4C7TG.mjs";
|
|
16
16
|
import {
|
|
17
17
|
AXIS_FILTER_CLASS,
|
|
18
18
|
LEGEND_MARK_CLASS,
|
|
19
19
|
MARK_CLASS,
|
|
20
20
|
ROW_IDX_ATTR
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
22
22
|
import "./chunk-GHODWOAL.mjs";
|
|
23
23
|
|
|
24
24
|
// src/adapters/types.ts
|
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-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-G4CKILIL.mjs";
|
|
5
|
+
import "./chunk-TH577JHI.mjs";
|
|
6
6
|
import "./chunk-GHODWOAL.mjs";
|
|
7
7
|
|
|
8
8
|
// src/selectionCardChrome.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
SNAPSHOT_SVG_ATTR
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
5
5
|
|
|
6
6
|
// src/snapshot.ts
|
|
7
7
|
var DEFAULT_TIMEOUT_MS = 2e3;
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
gestureWasDrag,
|
|
5
5
|
isInsideControl,
|
|
6
6
|
rowIdxsFromMark
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3ER4C7TG.mjs";
|
|
8
8
|
import {
|
|
9
9
|
AXIS_FILTER_CLASS,
|
|
10
10
|
CONTROL_CLASS,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
MARK_CLASS,
|
|
13
13
|
ROW_IDX_ATTR,
|
|
14
14
|
SNAPSHOT_SVG_ATTR
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
16
16
|
|
|
17
17
|
// src/lasso.ts
|
|
18
18
|
var LASSO_ROW_CAP = 5e3;
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
claimParkedLasso,
|
|
5
5
|
installLasso,
|
|
6
6
|
lassoEffect
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4DOKJ3R3.mjs";
|
|
8
8
|
import {
|
|
9
9
|
censusHitBands,
|
|
10
10
|
ensureCrossfilterHitTargets
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GQLEU3VC.mjs";
|
|
12
12
|
import {
|
|
13
13
|
clearPress,
|
|
14
14
|
clearSelectionGlyphs,
|
|
@@ -25,14 +25,14 @@ import {
|
|
|
25
25
|
selectionRuleOf,
|
|
26
26
|
trackPress,
|
|
27
27
|
validRowSet
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3ER4C7TG.mjs";
|
|
29
29
|
import {
|
|
30
30
|
clipWindowOf,
|
|
31
31
|
fitRenderedChart,
|
|
32
32
|
rememberScroll,
|
|
33
33
|
takeScroll,
|
|
34
34
|
unpinScrolledAxis
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-TN5JRULV.mjs";
|
|
36
36
|
import {
|
|
37
37
|
geoFromCache
|
|
38
38
|
} from "./chunk-5WTQN5DL.mjs";
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
Rr,
|
|
44
44
|
Yn,
|
|
45
45
|
tt
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-TH577JHI.mjs";
|
|
47
47
|
import {
|
|
48
48
|
ACTIVE_TICK_CLASS,
|
|
49
49
|
ANIM_LOOP_DELAY_DEFAULT,
|
|
@@ -75,6 +75,7 @@ import {
|
|
|
75
75
|
HOST_CONTRACT_VERSION,
|
|
76
76
|
LEGEND_MARK_CLASS,
|
|
77
77
|
LIFT_SELECTED_CLASS,
|
|
78
|
+
MARKS_INERT_CLASS,
|
|
78
79
|
MARK_CLASS,
|
|
79
80
|
MARK_SELECTED_CLASS,
|
|
80
81
|
MAX_MAP_POINTS_DEFAULT,
|
|
@@ -87,7 +88,7 @@ import {
|
|
|
87
88
|
XFILTER_REFRESH_EVENT,
|
|
88
89
|
chartOwnsTimeline,
|
|
89
90
|
periodTickSuppressesFeedback
|
|
90
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
91
92
|
|
|
92
93
|
// src/labelContrast.ts
|
|
93
94
|
function parseRGBA(c) {
|
|
@@ -1159,6 +1160,8 @@ function resolveOptions(p) {
|
|
|
1159
1160
|
})(),
|
|
1160
1161
|
// A host FACT from the generate answer, true only for a literal true: silence never suppresses anything.
|
|
1161
1162
|
suppressSelectionGlyph: p.suppressSelectionGlyph === true ? true : void 0,
|
|
1163
|
+
// A host FACT (1.22.0): the chart works from the keyboard. True only for a literal true, like the one above.
|
|
1164
|
+
keyboardMarks: p.keyboardMarks === true ? true : void 0,
|
|
1162
1165
|
onSelect: p.onSelect,
|
|
1163
1166
|
// Control gestures (1.10.0). Passed straight through like onSelect: the host owns what a gesture MEANS,
|
|
1164
1167
|
// and a host that supplies nothing leaves every control behaving exactly as before.
|
|
@@ -2322,7 +2325,7 @@ var DOT = 8;
|
|
|
2322
2325
|
var RING = 1.5;
|
|
2323
2326
|
var DOT_HALF = DOT / 2 + RING;
|
|
2324
2327
|
var DOT_IN = 8;
|
|
2325
|
-
function createAnnotationLayer(container, onClick) {
|
|
2328
|
+
function createAnnotationLayer(container, onClick, opts) {
|
|
2326
2329
|
let list = [];
|
|
2327
2330
|
let report = { shown: 0, notShown: 0 };
|
|
2328
2331
|
let last = null;
|
|
@@ -2446,7 +2449,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2446
2449
|
const after = own.filter((t) => t.b.l >= run.r && t.b.b > run.t && t.b.t < run.b).map((t) => t.b.l);
|
|
2447
2450
|
return { r: Math.min(run.r, seen), y: (run.t + run.b) / 2, next: after.length ? Math.min(...after) : v.r };
|
|
2448
2451
|
};
|
|
2449
|
-
const clear = (v, len, mark) => {
|
|
2452
|
+
const clear = (v, len, mark, whole = v) => {
|
|
2450
2453
|
const hw = Math.max(16, len * 6 + 8) / 2, hh = 8, g = 2;
|
|
2451
2454
|
const cx = (v.l + v.r) / 2, cy = (v.t + v.b) / 2;
|
|
2452
2455
|
const at = (x, y) => ({ l: x - hw, t: y - hh, r: x + hw, b: y + hh });
|
|
@@ -2459,6 +2462,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2459
2462
|
const tries = [];
|
|
2460
2463
|
const add = (x, y, px = x, py = y) => tries.push({ x: clampX(x, hw), y: clampY(y, hh), px, py });
|
|
2461
2464
|
const label = rowLabel(v, mark);
|
|
2465
|
+
if (!label && whole !== v && rowLabel(whole, mark)) return null;
|
|
2462
2466
|
if (label) {
|
|
2463
2467
|
const x = label.r + g + hw;
|
|
2464
2468
|
if (x + hw <= label.next - g || label.next >= v.r) add(x, label.y, Math.min(x, v.r - 1), label.y);
|
|
@@ -2523,7 +2527,7 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2523
2527
|
}
|
|
2524
2528
|
}
|
|
2525
2529
|
const dot = wantsDot(bestMark ?? hits2.values().next().value ?? null);
|
|
2526
|
-
const pt = !best ? null : dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark);
|
|
2530
|
+
const pt = !best ? null : dot ? dotSpot(best, bestWhole) : clear(best, (a.label ?? "\u2022").length, bestMark, bestWhole ?? best);
|
|
2527
2531
|
if (laidOut && !pt) continue;
|
|
2528
2532
|
shown++;
|
|
2529
2533
|
const badge = doc.createElement("div");
|
|
@@ -2564,6 +2568,15 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2564
2568
|
e.stopPropagation();
|
|
2565
2569
|
onClick?.(a);
|
|
2566
2570
|
});
|
|
2571
|
+
if (opts?.keyboard?.()) {
|
|
2572
|
+
badge.setAttribute("tabindex", "0");
|
|
2573
|
+
badge.addEventListener("keydown", (e) => {
|
|
2574
|
+
if (e.key !== "Enter" && e.key !== " " && e.key !== "Spacebar") return;
|
|
2575
|
+
e.preventDefault();
|
|
2576
|
+
e.stopPropagation();
|
|
2577
|
+
onClick?.(a);
|
|
2578
|
+
});
|
|
2579
|
+
}
|
|
2567
2580
|
layer.appendChild(badge);
|
|
2568
2581
|
}
|
|
2569
2582
|
report = { shown, notShown: list.length - shown };
|
|
@@ -2590,6 +2603,222 @@ function createAnnotationLayer(container, onClick) {
|
|
|
2590
2603
|
};
|
|
2591
2604
|
}
|
|
2592
2605
|
|
|
2606
|
+
// src/focusKeep.ts
|
|
2607
|
+
function signatureOf(el) {
|
|
2608
|
+
const a = (n) => el.getAttribute(n) ?? "";
|
|
2609
|
+
const cls = Array.from(el.classList ?? []).filter((c) => !/^lch-|^bic-/.test(c)).sort().join(" ");
|
|
2610
|
+
return [el.localName, a("type"), cls, a("name"), a("placeholder"), a("aria-label"), a("role")].join("|");
|
|
2611
|
+
}
|
|
2612
|
+
function alike(container, sig) {
|
|
2613
|
+
const tag = sig.split("|", 1)[0];
|
|
2614
|
+
if (!tag) return [];
|
|
2615
|
+
return Array.from(container.querySelectorAll(tag)).filter((e) => signatureOf(e) === sig);
|
|
2616
|
+
}
|
|
2617
|
+
function rememberFocus(container) {
|
|
2618
|
+
try {
|
|
2619
|
+
const active = container.ownerDocument?.activeElement;
|
|
2620
|
+
if (!active || active === container || !container.contains(active)) return null;
|
|
2621
|
+
const sig = signatureOf(active);
|
|
2622
|
+
const nth = alike(container, sig).indexOf(active);
|
|
2623
|
+
const t = active;
|
|
2624
|
+
let start = null, end = null, dir = null;
|
|
2625
|
+
try {
|
|
2626
|
+
if (typeof t.selectionStart === "number") {
|
|
2627
|
+
start = t.selectionStart;
|
|
2628
|
+
end = t.selectionEnd;
|
|
2629
|
+
dir = t.selectionDirection ?? null;
|
|
2630
|
+
}
|
|
2631
|
+
} catch {
|
|
2632
|
+
}
|
|
2633
|
+
return { sig, nth: Math.max(0, nth), start, end, dir };
|
|
2634
|
+
} catch {
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
function restoreFocus(container, memory) {
|
|
2639
|
+
if (!memory) return false;
|
|
2640
|
+
try {
|
|
2641
|
+
const active = container.ownerDocument?.activeElement;
|
|
2642
|
+
if (active && active !== container && container.contains(active)) return false;
|
|
2643
|
+
const list = alike(container, memory.sig);
|
|
2644
|
+
const el = list[memory.nth] ?? (list.length === 1 ? list[0] : null);
|
|
2645
|
+
if (!el || typeof el.focus !== "function") return false;
|
|
2646
|
+
el.focus({ preventScroll: true });
|
|
2647
|
+
const t = el;
|
|
2648
|
+
if (memory.start != null && typeof t.setSelectionRange === "function") {
|
|
2649
|
+
const len = typeof t.value === "string" ? t.value.length : 0;
|
|
2650
|
+
try {
|
|
2651
|
+
t.setSelectionRange(Math.min(memory.start, len), Math.min(memory.end ?? memory.start, len), memory.dir ?? void 0);
|
|
2652
|
+
} catch {
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
return container.ownerDocument?.activeElement === el;
|
|
2656
|
+
} catch {
|
|
2657
|
+
return false;
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
// src/keyboardMarks.ts
|
|
2662
|
+
var KEYBOARD_STAMP = "// bic:keyboard-marks";
|
|
2663
|
+
var STAMP_RE = /^[ \t]*\/\/[ \t]*bic:keyboard-marks\b/;
|
|
2664
|
+
var STAMP_HEAD_LINES = 12;
|
|
2665
|
+
function codeHasKeyboardStamp(code) {
|
|
2666
|
+
if (typeof code !== "string" || !code) return false;
|
|
2667
|
+
let start = 0;
|
|
2668
|
+
for (let n = 0; n < STAMP_HEAD_LINES && start <= code.length; n++) {
|
|
2669
|
+
const end = code.indexOf("\n", start);
|
|
2670
|
+
const line = code.slice(start, end < 0 ? code.length : end);
|
|
2671
|
+
if (STAMP_RE.test(line)) return true;
|
|
2672
|
+
if (end < 0) break;
|
|
2673
|
+
start = end + 1;
|
|
2674
|
+
}
|
|
2675
|
+
return false;
|
|
2676
|
+
}
|
|
2677
|
+
var KEYBOARD_CLASS = "lch-keyboard";
|
|
2678
|
+
var WIRED_ATTR = "data-lch-kb";
|
|
2679
|
+
function rowNameOf(columns, row, culture) {
|
|
2680
|
+
if (!row) return null;
|
|
2681
|
+
const parts = [];
|
|
2682
|
+
(columns || []).forEach((c, i) => {
|
|
2683
|
+
const name = typeof c === "string" ? c : c?.name;
|
|
2684
|
+
const v = row[i];
|
|
2685
|
+
if (parts.length >= 4 || v == null || v === "" || typeof name === "string" && name.startsWith("__")) return;
|
|
2686
|
+
parts.push(typeof v === "number" ? v.toLocaleString(culture || void 0, { maximumFractionDigits: 2 }) : String(v));
|
|
2687
|
+
});
|
|
2688
|
+
return parts.length ? parts.join(", ") : null;
|
|
2689
|
+
}
|
|
2690
|
+
var isClearChord = (e) => !!e.ctrlKey && !!e.shiftKey && (e.key === "C" || e.key === "c");
|
|
2691
|
+
var NATIVE = /* @__PURE__ */ new Set(["input", "select", "textarea", "button", "a"]);
|
|
2692
|
+
var isNative = (el) => NATIVE.has((el.localName || "").toLowerCase()) || el.isContentEditable === true;
|
|
2693
|
+
function installKeyboard(env) {
|
|
2694
|
+
const { container } = env;
|
|
2695
|
+
let rovingKey = null;
|
|
2696
|
+
let destroyed = false;
|
|
2697
|
+
const marksNow = () => {
|
|
2698
|
+
if (env.inert()) return [];
|
|
2699
|
+
return Array.from(container.querySelectorAll(env.markSelector)).filter((m) => !m.closest(env.skipSelector) && (m.getAttribute("data-row-idx") ?? "") !== "");
|
|
2700
|
+
};
|
|
2701
|
+
const wired = (el) => el.hasAttribute(WIRED_ATTR);
|
|
2702
|
+
const wire = (el, tabindex, role) => {
|
|
2703
|
+
if (el.hasAttribute("tabindex") && !wired(el)) return false;
|
|
2704
|
+
el.setAttribute(WIRED_ATTR, "");
|
|
2705
|
+
el.setAttribute("tabindex", tabindex);
|
|
2706
|
+
if (!el.hasAttribute("role")) el.setAttribute("role", role);
|
|
2707
|
+
return true;
|
|
2708
|
+
};
|
|
2709
|
+
const setRoving = (list, to) => {
|
|
2710
|
+
for (const m of list) if (wired(m)) m.setAttribute("tabindex", m === to ? "0" : "-1");
|
|
2711
|
+
rovingKey = env.keyOf(to);
|
|
2712
|
+
};
|
|
2713
|
+
const refresh = () => {
|
|
2714
|
+
if (destroyed) return;
|
|
2715
|
+
try {
|
|
2716
|
+
container.classList?.add(KEYBOARD_CLASS);
|
|
2717
|
+
const list = marksNow();
|
|
2718
|
+
for (const m of list) {
|
|
2719
|
+
if (!wire(m, "-1", "button")) continue;
|
|
2720
|
+
m.setAttribute("aria-pressed", env.isSelected(m) ? "true" : "false");
|
|
2721
|
+
if (!m.hasAttribute("aria-label") && !m.querySelector(":scope > title")) {
|
|
2722
|
+
const name = env.labelOf(m);
|
|
2723
|
+
if (name) m.setAttribute("aria-label", name);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
if (!list.length) {
|
|
2727
|
+
for (const m of Array.from(container.querySelectorAll(`[${WIRED_ATTR}]`)))
|
|
2728
|
+
if (m.matches(env.markSelector)) {
|
|
2729
|
+
m.removeAttribute("tabindex");
|
|
2730
|
+
m.removeAttribute(WIRED_ATTR);
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
const own = list.filter(wired);
|
|
2734
|
+
if (own.length) {
|
|
2735
|
+
const keep = own.find((m) => env.keyOf(m) === rovingKey) ?? own.find((m) => env.isSelected(m)) ?? own[0];
|
|
2736
|
+
setRoving(own, keep);
|
|
2737
|
+
}
|
|
2738
|
+
for (const c of Array.from(container.querySelectorAll(env.pressSelector))) {
|
|
2739
|
+
if (isNative(c)) continue;
|
|
2740
|
+
wire(c, "0", "button");
|
|
2741
|
+
}
|
|
2742
|
+
} catch {
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
const onKey = (e) => {
|
|
2746
|
+
if (destroyed || e.defaultPrevented) return;
|
|
2747
|
+
const t = e.target;
|
|
2748
|
+
if (!t || !container.contains(t)) return;
|
|
2749
|
+
const k = e.key;
|
|
2750
|
+
if (isClearChord(e)) {
|
|
2751
|
+
e.preventDefault();
|
|
2752
|
+
env.clear();
|
|
2753
|
+
return;
|
|
2754
|
+
}
|
|
2755
|
+
const press = t.closest?.(env.pressSelector);
|
|
2756
|
+
if (press && wired(press) && container.contains(press)) {
|
|
2757
|
+
if (k === "Enter" || k === " " || k === "Spacebar") {
|
|
2758
|
+
e.preventDefault();
|
|
2759
|
+
const ME = container.ownerDocument.defaultView?.MouseEvent ?? MouseEvent;
|
|
2760
|
+
press.dispatchEvent(new ME("click", { bubbles: true, cancelable: true }));
|
|
2761
|
+
} else if (k === "Escape" && env.escapeClears !== false) env.clear();
|
|
2762
|
+
return;
|
|
2763
|
+
}
|
|
2764
|
+
const mark = t.closest?.(env.markSelector);
|
|
2765
|
+
if (!mark || !wired(mark) || !container.contains(mark)) return;
|
|
2766
|
+
const list = marksNow().filter(wired);
|
|
2767
|
+
const at = list.indexOf(mark);
|
|
2768
|
+
const go = (i) => {
|
|
2769
|
+
const to = list[Math.max(0, Math.min(list.length - 1, i))];
|
|
2770
|
+
if (!to) return;
|
|
2771
|
+
setRoving(list, to);
|
|
2772
|
+
try {
|
|
2773
|
+
to.focus({ preventScroll: false });
|
|
2774
|
+
} catch {
|
|
2775
|
+
}
|
|
2776
|
+
};
|
|
2777
|
+
switch (k) {
|
|
2778
|
+
case "ArrowRight":
|
|
2779
|
+
case "ArrowDown":
|
|
2780
|
+
e.preventDefault();
|
|
2781
|
+
go(at + 1);
|
|
2782
|
+
break;
|
|
2783
|
+
case "ArrowLeft":
|
|
2784
|
+
case "ArrowUp":
|
|
2785
|
+
e.preventDefault();
|
|
2786
|
+
go(at - 1);
|
|
2787
|
+
break;
|
|
2788
|
+
case "Home":
|
|
2789
|
+
e.preventDefault();
|
|
2790
|
+
go(0);
|
|
2791
|
+
break;
|
|
2792
|
+
case "End":
|
|
2793
|
+
e.preventDefault();
|
|
2794
|
+
go(list.length - 1);
|
|
2795
|
+
break;
|
|
2796
|
+
case "Enter":
|
|
2797
|
+
case " ":
|
|
2798
|
+
case "Spacebar":
|
|
2799
|
+
e.preventDefault();
|
|
2800
|
+
rovingKey = env.keyOf(mark);
|
|
2801
|
+
env.select(mark, { ctrl: !!(e.ctrlKey || e.metaKey), shift: !!e.shiftKey });
|
|
2802
|
+
break;
|
|
2803
|
+
case "Escape":
|
|
2804
|
+
if (env.escapeClears !== false) env.clear();
|
|
2805
|
+
break;
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
container.addEventListener("keydown", onKey);
|
|
2809
|
+
return {
|
|
2810
|
+
refresh,
|
|
2811
|
+
destroy() {
|
|
2812
|
+
destroyed = true;
|
|
2813
|
+
container.removeEventListener("keydown", onKey);
|
|
2814
|
+
try {
|
|
2815
|
+
container.classList?.remove(KEYBOARD_CLASS);
|
|
2816
|
+
} catch {
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2593
2822
|
// src/host.ts
|
|
2594
2823
|
function sessionViewStateProvider(container) {
|
|
2595
2824
|
const holder = container;
|
|
@@ -2738,6 +2967,9 @@ function createChartHost(container, config) {
|
|
|
2738
2967
|
}
|
|
2739
2968
|
}
|
|
2740
2969
|
let lassoClaimed = false;
|
|
2970
|
+
let ownBag = null;
|
|
2971
|
+
const seedKey = (s) => s && typeof s === "object" ? JSON.stringify(s) : void 0;
|
|
2972
|
+
let lastSeed = seedKey(raw.uiState);
|
|
2741
2973
|
if (typeof raw.setUiState !== "function") {
|
|
2742
2974
|
const provider = config.viewState ?? sessionViewStateProvider(container);
|
|
2743
2975
|
let bag;
|
|
@@ -2751,6 +2983,7 @@ function createChartHost(container, config) {
|
|
|
2751
2983
|
if (raw.uiState && typeof raw.uiState === "object" && Object.keys(bag).length === 0)
|
|
2752
2984
|
Object.assign(bag, raw.uiState);
|
|
2753
2985
|
raw.uiState = bag;
|
|
2986
|
+
ownBag = { bag, provider };
|
|
2754
2987
|
raw.setUiState = (s) => {
|
|
2755
2988
|
if (!s || typeof s !== "object") return;
|
|
2756
2989
|
try {
|
|
@@ -2759,6 +2992,26 @@ function createChartHost(container, config) {
|
|
|
2759
2992
|
}
|
|
2760
2993
|
};
|
|
2761
2994
|
}
|
|
2995
|
+
const takeSeed = (partial) => {
|
|
2996
|
+
if (typeof partial.setUiState === "function") {
|
|
2997
|
+
ownBag = null;
|
|
2998
|
+
return partial;
|
|
2999
|
+
}
|
|
3000
|
+
if (!ownBag || !("uiState" in partial)) return partial;
|
|
3001
|
+
const { uiState: seed, ...rest } = partial;
|
|
3002
|
+
const key = seedKey(seed);
|
|
3003
|
+
if (key !== void 0 && key !== lastSeed) {
|
|
3004
|
+
lastSeed = key;
|
|
3005
|
+
const { bag, provider } = ownBag;
|
|
3006
|
+
for (const k of Object.keys(bag)) delete bag[k];
|
|
3007
|
+
Object.assign(bag, seed);
|
|
3008
|
+
try {
|
|
3009
|
+
provider.save({ ...bag });
|
|
3010
|
+
} catch {
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
return rest;
|
|
3014
|
+
};
|
|
2762
3015
|
const resolveForHost = (input) => {
|
|
2763
3016
|
const out = resolveOptions(input);
|
|
2764
3017
|
return out.allowTooltips == null ? { ...out, allowTooltips: true } : out;
|
|
@@ -2773,7 +3026,9 @@ function createChartHost(container, config) {
|
|
|
2773
3026
|
let warnedLassoNoFilter = false;
|
|
2774
3027
|
const idScope = newIdScope();
|
|
2775
3028
|
let renderSeq = 0;
|
|
2776
|
-
const
|
|
3029
|
+
const keyboardOn = codeHasKeyboardStamp(config.code);
|
|
3030
|
+
let keyboard = null;
|
|
3031
|
+
const annotationLayer = createAnnotationLayer(container, (a) => config.onAnnotationClick?.(a), { keyboard: () => keyboardOn });
|
|
2777
3032
|
const drawAnnotations = () => annotationLayer.draw(
|
|
2778
3033
|
{ columns: data.columns, rows: data.rows },
|
|
2779
3034
|
{
|
|
@@ -2857,7 +3112,18 @@ function createChartHost(container, config) {
|
|
|
2857
3112
|
anomaly badge, a highlight stroke) and must keep dimming with its datum. */
|
|
2858
3113
|
.${HOST_CONTAINER_CLASS} .${MARK_CLASS} { cursor: pointer; transition: opacity 120ms ease-in-out, filter 100ms ease-in-out; }
|
|
2859
3114
|
.${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; }
|
|
2860
|
-
.${HOST_CONTAINER_CLASS}:has(.${MARK_CLASS}:not([${ROW_IDX_ATTR}=""]):hover) .${MARK_CLASS}:not(:hover):not([${ROW_IDX_ATTR}=""]) { opacity: 0.55; }
|
|
3115
|
+
.${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; }
|
|
3116
|
+
/* A MARK THAT SELECTS NOTHING DOESN'T LOOK CLICKABLE: no pointer, over the inline cursor generated code
|
|
3117
|
+
sets on its marks, and no dimming of the others on hover (the rule above). A control the chart draws keeps its own. */
|
|
3118
|
+
.${HOST_CONTAINER_CLASS}.${MARKS_INERT_CLASS} .${MARK_CLASS} { cursor: default !important; }
|
|
3119
|
+
/* THE KEYBOARD'S FOCUS: a ring on the mark, control or badge that holds keyboard focus, in the colour the
|
|
3120
|
+
chart's text is drawn in, so it reads in either theme. A pointer's focus shows none. */
|
|
3121
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS} [${WIRED_ATTR}]:focus:not(:focus-visible) { outline: none; }
|
|
3122
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS} [${WIRED_ATTR}]:focus-visible,
|
|
3123
|
+
.${HOST_CONTAINER_CLASS} .bic-annotation:focus-visible { outline: 2px solid var(--lch-focus-ring, currentColor) !important; outline-offset: 2px; }
|
|
3124
|
+
/* A dimmed mark that takes keyboard focus is drawn at full strength while it has it, ring included: the dim would
|
|
3125
|
+
otherwise fade the ring with the mark. */
|
|
3126
|
+
.${HOST_CONTAINER_CLASS}.${KEYBOARD_CLASS}.${SELECTION_ACTIVE_CLASS} .${MARK_CLASS}[${WIRED_ATTR}]:focus-visible:not(.${MARK_SELECTED_CLASS}) { opacity: 1 !important; }
|
|
2861
3127
|
.${HOST_CONTAINER_CLASS}.${SELECTION_ACTIVE_CLASS} .${MARK_CLASS}:not(.${MARK_SELECTED_CLASS}):not([${ROW_IDX_ATTR}=""]) {
|
|
2862
3128
|
opacity: var(${DIM_OPACITY_VAR}, ${DIM_OPACITY_DEFAULT}) !important;
|
|
2863
3129
|
}
|
|
@@ -2890,9 +3156,18 @@ function createChartHost(container, config) {
|
|
|
2890
3156
|
} catch {
|
|
2891
3157
|
}
|
|
2892
3158
|
};
|
|
3159
|
+
const marksInert = () => {
|
|
3160
|
+
if (typeof config.marksSelect !== "function") return false;
|
|
3161
|
+
try {
|
|
3162
|
+
return config.marksSelect() === false;
|
|
3163
|
+
} catch {
|
|
3164
|
+
return false;
|
|
3165
|
+
}
|
|
3166
|
+
};
|
|
2893
3167
|
const paintSelection = () => {
|
|
2894
3168
|
if (destroyed) return;
|
|
2895
3169
|
try {
|
|
3170
|
+
container.classList?.[marksInert() ? "add" : "remove"](MARKS_INERT_CLASS);
|
|
2896
3171
|
const sel = current;
|
|
2897
3172
|
const active = !!sel && sel.length > 0;
|
|
2898
3173
|
const dim = active && !selectionIsPeriod;
|
|
@@ -3161,6 +3436,7 @@ function createChartHost(container, config) {
|
|
|
3161
3436
|
factFresh = true;
|
|
3162
3437
|
paintSelection();
|
|
3163
3438
|
paintGlyphLayer();
|
|
3439
|
+
keyboard?.refresh();
|
|
3164
3440
|
if (publish) for (const cb of subs) {
|
|
3165
3441
|
try {
|
|
3166
3442
|
cb(rowIdxs, source, meta);
|
|
@@ -3196,6 +3472,7 @@ function createChartHost(container, config) {
|
|
|
3196
3472
|
const d = e?.detail || {};
|
|
3197
3473
|
xfAt = Date.now();
|
|
3198
3474
|
if (d.clear) notify([], d.source || "chart", void 0, false, selectionPublished || !(current && current.length));
|
|
3475
|
+
else if (marksInert()) return;
|
|
3199
3476
|
else if (d.mark) notify(parseRowIdxs(d.mark.getAttribute?.(ROW_IDX_ATTR)), d.source || "chart", d.mark, true);
|
|
3200
3477
|
else if (Array.isArray(d.rows)) notify(validRowSet(d.rows), d.source || "chart", null, true, true, d.keepHidden === true ? { keepHidden: true } : void 0);
|
|
3201
3478
|
};
|
|
@@ -3231,6 +3508,9 @@ function createChartHost(container, config) {
|
|
|
3231
3508
|
const wasDrag = clickWasDrag(container, e);
|
|
3232
3509
|
clearPress(container);
|
|
3233
3510
|
if (wasDrag) return;
|
|
3511
|
+
const inert = marksInert();
|
|
3512
|
+
container.classList?.[inert ? "add" : "remove"](MARKS_INERT_CLASS);
|
|
3513
|
+
if (inert) return;
|
|
3234
3514
|
if (Date.now() - xfAt < XF_ECHO_MS) return;
|
|
3235
3515
|
if (isInsideControl(e?.target, container)) return;
|
|
3236
3516
|
let el = resolver.findMark(e?.target, clickSel, e);
|
|
@@ -3258,6 +3538,27 @@ function createChartHost(container, config) {
|
|
|
3258
3538
|
container.addEventListener(XFILTER_REFRESH_EVENT, onXf);
|
|
3259
3539
|
const untrackPress = trackPress(container);
|
|
3260
3540
|
container.addEventListener("click", onClick);
|
|
3541
|
+
if (keyboardOn) {
|
|
3542
|
+
const nameOfRow = (m) => {
|
|
3543
|
+
const r = parseRowIdxs(m.getAttribute(ROW_IDX_ATTR))[0];
|
|
3544
|
+
return rowNameOf(data.columns || [], r == null ? null : data.rows?.[r], resolved.cultureCode);
|
|
3545
|
+
};
|
|
3546
|
+
keyboard = installKeyboard({
|
|
3547
|
+
container,
|
|
3548
|
+
markSelector: clickSel,
|
|
3549
|
+
pressSelector: `.${CONTROL_CLASS}`,
|
|
3550
|
+
skipSelector: `.${ANNOTATION_LAYER_CLASS}, .${GLYPH_LAYER_CLASS}, .${LASSO_OUTLINE_CLASS}`,
|
|
3551
|
+
inert: marksInert,
|
|
3552
|
+
select: (m, mods) => {
|
|
3553
|
+
const ME = win?.MouseEvent ?? MouseEvent;
|
|
3554
|
+
m.dispatchEvent(new ME("click", { bubbles: true, cancelable: true, ctrlKey: mods.ctrl, shiftKey: mods.shift }));
|
|
3555
|
+
},
|
|
3556
|
+
clear: clearFromGesture,
|
|
3557
|
+
isSelected: (m) => !!m.classList?.contains(MARK_SELECTED_CLASS),
|
|
3558
|
+
labelOf: nameOfRow,
|
|
3559
|
+
keyOf: (m) => m.getAttribute(ROW_IDX_ATTR) ?? ""
|
|
3560
|
+
});
|
|
3561
|
+
}
|
|
3261
3562
|
container.classList?.add(HOST_CONTAINER_CLASS);
|
|
3262
3563
|
ensureAffordanceStyles();
|
|
3263
3564
|
const fitOpts = config.fit ?? true;
|
|
@@ -3405,6 +3706,15 @@ function createChartHost(container, config) {
|
|
|
3405
3706
|
} catch {
|
|
3406
3707
|
}
|
|
3407
3708
|
paintGlyphLayer();
|
|
3709
|
+
installLassoHere();
|
|
3710
|
+
keyboard?.refresh();
|
|
3711
|
+
const fw = focusWas;
|
|
3712
|
+
focusWas = null;
|
|
3713
|
+
restoreFocus(container, fw);
|
|
3714
|
+
selfRedraw?.takeRecords();
|
|
3715
|
+
watchSelfRedraw();
|
|
3716
|
+
};
|
|
3717
|
+
function installLassoHere() {
|
|
3408
3718
|
try {
|
|
3409
3719
|
lasso = installLasso({
|
|
3410
3720
|
container,
|
|
@@ -3415,7 +3725,38 @@ function createChartHost(container, config) {
|
|
|
3415
3725
|
});
|
|
3416
3726
|
} catch {
|
|
3417
3727
|
}
|
|
3728
|
+
}
|
|
3729
|
+
let selfRedraw = null;
|
|
3730
|
+
let focusWas = null;
|
|
3731
|
+
let notesHeld = (config.annotations ?? []).length > 0;
|
|
3732
|
+
const takesMarks = (n) => n.nodeType === 1 && (!!n.classList?.contains(MARK_CLASS) || !!n.querySelector?.(`.${MARK_CLASS}`));
|
|
3733
|
+
const lassoLost = () => !!lasso?.surface && !lasso.surface.isConnected;
|
|
3734
|
+
const repaintAfterChart = () => {
|
|
3735
|
+
if (destroyed) return;
|
|
3736
|
+
try {
|
|
3737
|
+
ensureCrossfilterHitTargets(container, doc);
|
|
3738
|
+
} catch {
|
|
3739
|
+
}
|
|
3740
|
+
paintSelection();
|
|
3741
|
+
try {
|
|
3742
|
+
drawAnnotations();
|
|
3743
|
+
} catch {
|
|
3744
|
+
}
|
|
3745
|
+
paintGlyphLayer(false);
|
|
3746
|
+
if (lassoLost()) installLassoHere();
|
|
3747
|
+
keyboard?.refresh();
|
|
3748
|
+
selfRedraw?.takeRecords();
|
|
3418
3749
|
};
|
|
3750
|
+
function watchSelfRedraw() {
|
|
3751
|
+
const MO = win?.MutationObserver;
|
|
3752
|
+
if (selfRedraw || !MO || destroyed) return;
|
|
3753
|
+
selfRedraw = new MO((records) => {
|
|
3754
|
+
if (destroyed || !records.some((r) => Array.from(r.removedNodes).some(takesMarks))) return;
|
|
3755
|
+
if (!(current && current.length) && !notesHeld && !lassoLost()) return;
|
|
3756
|
+
repaintAfterChart();
|
|
3757
|
+
});
|
|
3758
|
+
selfRedraw.observe(container, { childList: true, subtree: true });
|
|
3759
|
+
}
|
|
3419
3760
|
const renderFailure = (err) => {
|
|
3420
3761
|
const message = String(err?.message ?? err ?? "");
|
|
3421
3762
|
if (config.onInvalidSentinel && isInvalidSentinelError(message)) {
|
|
@@ -3435,7 +3776,9 @@ function createChartHost(container, config) {
|
|
|
3435
3776
|
disposeLasso();
|
|
3436
3777
|
flushZoom();
|
|
3437
3778
|
if (hasRendered && keepScroll) rememberScroll(container, scrollKey());
|
|
3779
|
+
focusWas = rememberFocus(container);
|
|
3438
3780
|
container.innerHTML = "";
|
|
3781
|
+
selfRedraw?.takeRecords();
|
|
3439
3782
|
hasRendered = true;
|
|
3440
3783
|
if (!renderFn) {
|
|
3441
3784
|
if (!config.code) throw new Error("createChartHost: provide code or renderFn");
|
|
@@ -3461,6 +3804,7 @@ function createChartHost(container, config) {
|
|
|
3461
3804
|
if (resolved.dateCellsAreUtcDays === void 0 && data.dateCellsAreUtcDays) resolved = { ...resolved, dateCellsAreUtcDays: true };
|
|
3462
3805
|
if (resolved.suppressSelectionGlyph === void 0 && data.meta?.suppressSelectionGlyph === true)
|
|
3463
3806
|
resolved = { ...resolved, suppressSelectionGlyph: true };
|
|
3807
|
+
if (keyboardOn) resolved = { ...resolved, keyboardMarks: true };
|
|
3464
3808
|
let outcome;
|
|
3465
3809
|
zoomCap = null;
|
|
3466
3810
|
if (zoomMemory && config.code && !config.renderFn) {
|
|
@@ -3536,7 +3880,7 @@ function createChartHost(container, config) {
|
|
|
3536
3880
|
// callback) must not clear, stop or annotate the chart that is on screen now.
|
|
3537
3881
|
setOptions(partial) {
|
|
3538
3882
|
if (destroyed) return;
|
|
3539
|
-
raw = { ...raw, ...partial };
|
|
3883
|
+
raw = { ...raw, ...takeSeed(partial ?? {}) };
|
|
3540
3884
|
resolved = resolveForHost(raw);
|
|
3541
3885
|
host.render();
|
|
3542
3886
|
},
|
|
@@ -3551,6 +3895,7 @@ function createChartHost(container, config) {
|
|
|
3551
3895
|
},
|
|
3552
3896
|
setAnnotations(list) {
|
|
3553
3897
|
if (destroyed) return;
|
|
3898
|
+
notesHeld = (list ?? []).length > 0;
|
|
3554
3899
|
annotationLayer.set(list);
|
|
3555
3900
|
try {
|
|
3556
3901
|
drawAnnotations();
|
|
@@ -3612,6 +3957,12 @@ function createChartHost(container, config) {
|
|
|
3612
3957
|
if (destroyed) return;
|
|
3613
3958
|
destroyed = true;
|
|
3614
3959
|
stopAnim();
|
|
3960
|
+
if (selfRedraw) {
|
|
3961
|
+
selfRedraw.disconnect();
|
|
3962
|
+
selfRedraw = null;
|
|
3963
|
+
}
|
|
3964
|
+
keyboard?.destroy();
|
|
3965
|
+
keyboard = null;
|
|
3615
3966
|
container.removeEventListener(XFILTER_REFRESH_EVENT, onXf);
|
|
3616
3967
|
container.removeEventListener("click", onClick);
|
|
3617
3968
|
untrackPress();
|
|
@@ -3858,6 +4209,14 @@ export {
|
|
|
3858
4209
|
invalidSentinelReason,
|
|
3859
4210
|
ANNOTATION_LAYER_CLASS,
|
|
3860
4211
|
ANNOTATION_CLASS,
|
|
4212
|
+
rememberFocus,
|
|
4213
|
+
restoreFocus,
|
|
4214
|
+
KEYBOARD_STAMP,
|
|
4215
|
+
codeHasKeyboardStamp,
|
|
4216
|
+
KEYBOARD_CLASS,
|
|
4217
|
+
WIRED_ATTR,
|
|
4218
|
+
rowNameOf,
|
|
4219
|
+
installKeyboard,
|
|
3861
4220
|
sessionViewStateProvider,
|
|
3862
4221
|
noopViewStateProvider,
|
|
3863
4222
|
assembleD3,
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
LASSO_KNOB_KEY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4DOKJ3R3.mjs";
|
|
5
5
|
|
|
6
6
|
// src/filterScope.ts
|
|
7
7
|
function viewToken(view) {
|
|
@@ -1421,10 +1421,10 @@ function Sr2(e, t) {
|
|
|
1421
1421
|
return n;
|
|
1422
1422
|
}
|
|
1423
1423
|
function Rr(e, t, n, o2, a3) {
|
|
1424
|
-
let u3 = [], l2 = [], i = {},
|
|
1424
|
+
let u3 = [], l2 = [], i = {}, y3 = {}, h3 = new Set(e), b2 = (s2) => t.map((d2) => d2[s2]);
|
|
1425
1425
|
for (let s2 of ["city", "country"]) {
|
|
1426
1426
|
let d2 = n?.[s2];
|
|
1427
|
-
d2 &&
|
|
1427
|
+
d2 && h3.has(d2) && (i[s2] = d2);
|
|
1428
1428
|
}
|
|
1429
1429
|
let g5 = new Set(a3 ?? e);
|
|
1430
1430
|
for (let s2 of ["lat", "lon"]) {
|
|
@@ -1432,20 +1432,20 @@ function Rr(e, t, n, o2, a3) {
|
|
|
1432
1432
|
d2 && g5.has(d2) && (i[s2] = d2);
|
|
1433
1433
|
}
|
|
1434
1434
|
let f2 = n?.zip;
|
|
1435
|
-
if (f2 &&
|
|
1436
|
-
let s2 =
|
|
1435
|
+
if (f2 && h3.has(f2)) {
|
|
1436
|
+
let s2 = b2(f2), d2 = ie(s2);
|
|
1437
1437
|
d2 < 95 ? l2.push(`zip=${f2} (only ${d2}% of values read as ZIPs)`) : pe(s2, f2) ? i.zip = f2 : l2.push(`zip=${f2} (all values are 3-4 digits with nothing to say they are postal)`);
|
|
1438
1438
|
}
|
|
1439
1439
|
let c = n?.state;
|
|
1440
|
-
if (c &&
|
|
1441
|
-
let s2 =
|
|
1440
|
+
if (c && h3.has(c)) {
|
|
1441
|
+
let s2 = b2(c), d2 = F3(s2);
|
|
1442
1442
|
d2.length > 0 && d2.every((S) => fe(S, o2)) ? l2.push(`state=${c} (every value is "CA", which is both Canada and California)`) : N(s2) ? (l2.push(`state=${c} (every value is a country, not a state)`), i.country || (i.country = c)) : q4(s2) < 95 ? l2.push(`state=${c} (only ${q4(s2)}% of values are states/provinces)`) : i.state = c;
|
|
1443
1443
|
}
|
|
1444
|
-
let p3 = new Set(Object.values(i).filter(Boolean)),
|
|
1444
|
+
let p3 = new Set(Object.values(i).filter(Boolean)), C3 = e.filter((s2) => !p3.has(s2) && !s2.startsWith("__"));
|
|
1445
1445
|
if (!i.state) {
|
|
1446
1446
|
let s2 = null;
|
|
1447
|
-
for (let d2 of
|
|
1448
|
-
let S =
|
|
1447
|
+
for (let d2 of C3) {
|
|
1448
|
+
let S = b2(d2);
|
|
1449
1449
|
if (N(S)) continue;
|
|
1450
1450
|
let O2 = q4(S);
|
|
1451
1451
|
if (O2 < 95) continue;
|
|
@@ -1454,46 +1454,46 @@ function Rr(e, t, n, o2, a3) {
|
|
|
1454
1454
|
}
|
|
1455
1455
|
s2 && (i.state = s2.name, p3.add(s2.name), u3.push(`state=${s2.name} (${s2.pct}% states/provinces)`));
|
|
1456
1456
|
}
|
|
1457
|
-
if (!i.zip) for (let s2 of
|
|
1457
|
+
if (!i.zip) for (let s2 of C3) {
|
|
1458
1458
|
if (p3.has(s2)) continue;
|
|
1459
|
-
let d2 =
|
|
1459
|
+
let d2 = b2(s2), S = ie(d2);
|
|
1460
1460
|
if (!(S < 95) && pe(d2, s2) && !(Sr2(d2, (O2) => Gn(O2).length > 0) < ee)) {
|
|
1461
1461
|
i.zip = s2, p3.add(s2), u3.push(`zip=${s2} (${S}% ZIP codes)`);
|
|
1462
1462
|
break;
|
|
1463
1463
|
}
|
|
1464
1464
|
}
|
|
1465
1465
|
let T3 = i.country;
|
|
1466
|
-
if (!T3 || !N(
|
|
1466
|
+
if (!T3 || !N(b2(T3))) {
|
|
1467
1467
|
let s2 = null;
|
|
1468
|
-
for (let d2 of
|
|
1469
|
-
if (p3.has(d2) || !N(
|
|
1470
|
-
let S = re(
|
|
1468
|
+
for (let d2 of C3) {
|
|
1469
|
+
if (p3.has(d2) || !N(b2(d2))) continue;
|
|
1470
|
+
let S = re(b2(d2));
|
|
1471
1471
|
(!s2 || S > s2.pct) && (s2 = { name: d2, pct: S });
|
|
1472
1472
|
}
|
|
1473
|
-
s2 && (T3 && (l2.push(`country=${T3} (only ${re(
|
|
1473
|
+
s2 && (T3 && (l2.push(`country=${T3} (only ${re(b2(T3))}% of values are country identifiers; using ${s2.name} instead)`), y3.country = T3), i.country = s2.name, p3.add(s2.name), u3.push(`country=${s2.name}`));
|
|
1474
1474
|
}
|
|
1475
1475
|
if (!i.city) {
|
|
1476
1476
|
let s2 = null;
|
|
1477
|
-
for (let d2 of
|
|
1477
|
+
for (let d2 of C3) {
|
|
1478
1478
|
if (p3.has(d2)) continue;
|
|
1479
|
-
let S =
|
|
1479
|
+
let S = b2(d2), O2 = Tr2(S, o2);
|
|
1480
1480
|
O2 < ct || te(S, (H3) => Ht(H3, o2)) < ee || (!s2 || O2 > s2.pct) && (s2 = { name: d2, pct: O2 });
|
|
1481
1481
|
}
|
|
1482
1482
|
s2 && (i.city = s2.name, u3.push(`city=${s2.name} (${s2.pct}% known cities)`));
|
|
1483
1483
|
}
|
|
1484
|
-
let
|
|
1484
|
+
let A2 = i.country ? b2(i.country) : [], R3 = !!i.country && N(A2), v2 = R3 ? new Set(A2.map((s2) => I(s2 == null ? null : String(s2))).filter(Boolean)).size : 0, x3 = R3 && v2 >= 2, w4 = !!(i.lat && i.lon) && t.some((s2) => {
|
|
1485
1485
|
let d2 = +String(s2[i.lat] ?? "").trim(), S = +String(s2[i.lon] ?? "").trim();
|
|
1486
1486
|
return isFinite(d2) && isFinite(S) && d2 >= -90 && d2 <= 90 && S >= -180 && S <= 180 && String(s2[i.lat] ?? "").trim() !== "" && String(s2[i.lon] ?? "").trim() !== "";
|
|
1487
1487
|
});
|
|
1488
|
-
return i.lat && i.lon && !w4 && l2.push(`lat/lon=${i.lat}/${i.lon} (no row holds a usable coordinate pair)`), i.country && !x3 && !(i.city || i.state || i.zip || w4) && l2.push(R3 ? `country=${i.country} (every row resolves to the same country - nothing to place apart)` : `country=${i.country} (values are not country identifiers)`), { bind: !!(i.city || i.state || i.zip || x3 || w4) ? i : null, backfilled: u3, refused: l2, ...Object.keys(
|
|
1488
|
+
return i.lat && i.lon && !w4 && l2.push(`lat/lon=${i.lat}/${i.lon} (no row holds a usable coordinate pair)`), i.country && !x3 && !(i.city || i.state || i.zip || w4) && l2.push(R3 ? `country=${i.country} (every row resolves to the same country - nothing to place apart)` : `country=${i.country} (values are not country identifiers)`), { bind: !!(i.city || i.state || i.zip || x3 || w4) ? i : null, backfilled: u3, refused: l2, ...Object.keys(y3).length ? { labelFallback: y3 } : {} };
|
|
1489
1489
|
}
|
|
1490
1490
|
var r = (e, ...t) => ({ part: e, langs: Object.freeze(t) });
|
|
1491
1491
|
var ae = Object.freeze({ jaar: r("year", "nl"), kwartaal: r("quarter", "nl"), maand: r("month", "nl"), dag: r("day", "nl", "sv", "da", "nb"), jahr: r("year", "de"), quartal: r("quarter", "de"), monat: r("month", "de"), tag: r("day", "de"), ann\u00E9e: r("year", "fr"), mois: r("month", "fr"), jour: r("day", "fr"), trimestre: r("quarter", "fr", "es", "pt", "it"), a\u00F1o: r("year", "es"), mes: r("month", "es"), d\u00EDa: r("day", "es"), ano: r("year", "pt"), m\u00EAs: r("month", "pt"), dia: r("day", "pt"), anno: r("year", "it"), mese: r("month", "it"), giorno: r("day", "it"), \u0433\u043E\u0434: r("year", "ru"), \u043C\u0435\u0441\u044F\u0446: r("month", "ru"), \u0440\u0456\u043A: r("year", "uk"), \u043C\u0456\u0441\u044F\u0446\u044C: r("month", "uk"), \u043A\u0432\u0430\u0440\u0442\u0430\u043B: r("quarter", "ru", "uk"), \u0434\u0435\u043D\u044C: r("day", "ru", "uk"), rok: r("year", "pl", "cs", "sk"), kwarta\u0142: r("quarter", "pl"), miesi\u0105c: r("month", "pl"), dzie\u0144: r("day", "pl"), \u010Dtvrtlet\u00ED: r("quarter", "cs"), m\u011Bs\u00EDc: r("month", "cs"), den: r("day", "cs"), \u0161tvr\u0165rok: r("quarter", "sk"), mesiac: r("month", "sk"), de\u0148: r("day", "sk"), \u00E5r: r("year", "sv", "da", "nb"), kvartal: r("quarter", "sv", "da", "nb"), m\u00E5nad: r("month", "sv"), m\u00E5ned: r("month", "da", "nb"), vuosi: r("year", "fi"), vuosinelj\u00E4nnes: r("quarter", "fi"), kuukausi: r("month", "fi"), p\u00E4iv\u00E4: r("day", "fi"), \u00E9v: r("year", "hu"), negyed\u00E9v: r("quarter", "hu"), h\u00F3nap: r("month", "hu"), nap: r("day", "hu"), y\u0131l: r("year", "tr"), \u00E7eyrek: r("quarter", "tr"), ay: r("month", "tr"), g\u00FCn: r("day", "tr"), \u03AD\u03C4\u03BF\u03C2: r("year", "el"), \u03C4\u03C1\u03AF\u03BC\u03B7\u03BD\u03BF: r("quarter", "el"), \u03BC\u03AE\u03BD\u03B1\u03C2: r("month", "el"), \u03B7\u03BC\u03AD\u03C1\u03B1: r("day", "el"), an: r("year", "ro"), trimestru: r("quarter", "ro"), lun\u0103: r("month", "ro"), zi: r("day", "ro"), godina: r("year", "hr"), tromjese\u010Dje: r("quarter", "hr"), mjesec: r("month", "hr"), dan: r("day", "hr"), \u5E74: r("year", "ja", "zh"), \u56DB\u534A\u671F: r("quarter", "ja"), \u5B63\u5EA6: r("quarter", "zh"), \u6708: r("month", "ja", "zh"), \u65E5: r("day", "ja", "zh"), \uC5F0\uB3C4: r("year", "ko"), \uBD84\uAE30: r("quarter", "ko"), \uC6D4: r("month", "ko"), \uC77C: r("day", "ko"), tahun: r("year", "id"), kuartal: r("quarter", "id"), triwulan: r("quarter", "id"), bulan: r("month", "id"), hari: r("day", "id"), n\u0103m: r("year", "vi"), qu\u00FD: r("quarter", "vi"), th\u00E1ng: r("month", "vi"), ng\u00E0y: r("day", "vi"), \u0E1B\u0E35: r("year", "th"), \u0E44\u0E15\u0E23\u0E21\u0E32\u0E2A: r("quarter", "th"), \u0E40\u0E14\u0E37\u0E2D\u0E19: r("month", "th"), \u0E27\u0E31\u0E19: r("day", "th"), \u0627\u0644\u0633\u0646\u0629: r("year", "ar"), \u0633\u0646\u0629: r("year", "ar"), \u0627\u0644\u0639\u0627\u0645: r("year", "ar"), \u0639\u0627\u0645: r("year", "ar"), \u0627\u0644\u0631\u0628\u0639: r("quarter", "ar"), \u0631\u0628\u0639: r("quarter", "ar"), "\u0631\u0628\u0639 \u0627\u0644\u0633\u0646\u0629": r("quarter", "ar"), \u0627\u0644\u0634\u0647\u0631: r("month", "ar"), \u0634\u0647\u0631: r("month", "ar"), \u0627\u0644\u064A\u0648\u0645: r("day", "ar"), \u064A\u0648\u0645: r("day", "ar"), \u05E9\u05E0\u05D4: r("year", "he"), \u05E8\u05D1\u05E2\u05D5\u05DF: r("quarter", "he"), \u05D7\u05D5\u05D3\u05E9: r("month", "he"), \u05D9\u05D5\u05DD: r("day", "he"), \u0935\u0930\u094D\u0937: r("year", "hi"), \u0938\u093E\u0932: r("year", "hi"), \u0924\u093F\u092E\u093E\u0939\u0940: r("quarter", "hi"), \u092E\u0939\u0940\u0928\u093E: r("month", "hi"), \u092E\u093E\u0939: r("month", "hi"), \u0926\u093F\u0928: r("day", "hi"), \u0633\u0627\u0644: r("year", "fa"), \u0645\u0627\u0647: r("month", "fa"), \u0631\u0648\u0632: r("day", "fa") });
|
|
1492
1492
|
var xr = Object.freeze(Array.from(new Set(Object.values(ae).flatMap((e) => e.langs))));
|
|
1493
1493
|
var ye = Object.freeze(["fa", "ar", "he", "th"]);
|
|
1494
|
-
var
|
|
1495
|
-
var
|
|
1496
|
-
var
|
|
1494
|
+
var ro = Object.freeze({ integer: "number", decimal: "number", double: "number", datetime: "date", date: "date", boolean: "boolean", string: "text" });
|
|
1495
|
+
var mo = Object.freeze({ RENDER_START: "render-start", RENDER_OK: "render-ok", RENDER_ERROR: "render-error", VIEW: "view", VIEW_VERDICT: "view-verdict", REDRAW: "redraw", INTERACT: "interact" });
|
|
1496
|
+
var fo = Object.freeze(["open", "generate", "version", "rebind", "data", "sample", "fix", "resize", "other"]);
|
|
1497
1497
|
var Ne = 2 ** 31 - 1;
|
|
1498
1498
|
|
|
1499
1499
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
|
3
3
|
// src/contract.ts
|
|
4
|
-
var HOST_CONTRACT_VERSION = "1.
|
|
4
|
+
var HOST_CONTRACT_VERSION = "1.22.0";
|
|
5
5
|
var GEO_POINT_PRECISIONS = ["latlon", "city", "zip3", "state", "country"];
|
|
6
6
|
var MARK_CLASS = "d3-mark";
|
|
7
7
|
var LEGEND_MARK_CLASS = "d3-legend-mark";
|
|
@@ -34,6 +34,7 @@ function withoutViewOnlyKeys(bag) {
|
|
|
34
34
|
var HOST_CONTAINER_CLASS = "bic-chart-host";
|
|
35
35
|
var SELECTION_ACTIVE_CLASS = "lch-has-selection";
|
|
36
36
|
var MARK_SELECTED_CLASS = "lch-mark-selected";
|
|
37
|
+
var MARKS_INERT_CLASS = "lch-marks-inert";
|
|
37
38
|
var ACTIVE_TICK_CLASS = "lch-tick-active";
|
|
38
39
|
var DIM_OPACITY_VAR = "--lch-dim-opacity";
|
|
39
40
|
var DIM_OPACITY_DEFAULT = 0.25;
|
|
@@ -101,6 +102,7 @@ export {
|
|
|
101
102
|
HOST_CONTAINER_CLASS,
|
|
102
103
|
SELECTION_ACTIVE_CLASS,
|
|
103
104
|
MARK_SELECTED_CLASS,
|
|
105
|
+
MARKS_INERT_CLASS,
|
|
104
106
|
ACTIVE_TICK_CLASS,
|
|
105
107
|
DIM_OPACITY_VAR,
|
|
106
108
|
DIM_OPACITY_DEFAULT,
|
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
formatSourceDateFor,
|
|
6
6
|
isExcelDateFormat,
|
|
7
7
|
normaliseAggregation
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-G4CKILIL.mjs";
|
|
9
9
|
import {
|
|
10
10
|
captureSvgSnapshot,
|
|
11
11
|
chartSvgOf,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
svgNaturalSize,
|
|
16
16
|
svgToDataUrl,
|
|
17
17
|
tableHostOf
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-3EQOJHRA.mjs";
|
|
19
19
|
import {
|
|
20
20
|
ANNOTATION_CLASS,
|
|
21
21
|
ANNOTATION_LAYER_CLASS,
|
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
DARK_TEXT,
|
|
30
30
|
EXPORT_FORMATS,
|
|
31
31
|
GLYPH_SAMPLE_N,
|
|
32
|
+
KEYBOARD_CLASS,
|
|
33
|
+
KEYBOARD_STAMP,
|
|
32
34
|
LABEL_CONTRAST_CAP,
|
|
33
35
|
LABEL_CONTRAST_DONE_ATTR,
|
|
34
36
|
LABEL_PILL_CLASS,
|
|
@@ -47,6 +49,7 @@ import {
|
|
|
47
49
|
STRADDLE_TARGET_CONTRAST,
|
|
48
50
|
VALUE_AXIS_MIN_FIT,
|
|
49
51
|
WHITE_TEXT_BG_LUM,
|
|
52
|
+
WIRED_ATTR,
|
|
50
53
|
XLSX_MIME,
|
|
51
54
|
applyLabelContrast,
|
|
52
55
|
assembleD3,
|
|
@@ -65,6 +68,7 @@ import {
|
|
|
65
68
|
censusValuePlacement,
|
|
66
69
|
cleanHostSelection,
|
|
67
70
|
clippedTextFlag,
|
|
71
|
+
codeHasKeyboardStamp,
|
|
68
72
|
colourSpreadFlag,
|
|
69
73
|
compileRenderFn,
|
|
70
74
|
compositeOver,
|
|
@@ -80,6 +84,7 @@ import {
|
|
|
80
84
|
exportFormatsFor,
|
|
81
85
|
exportTableService,
|
|
82
86
|
glyphSampleGrid,
|
|
87
|
+
installKeyboard,
|
|
83
88
|
invalidSentinelReason,
|
|
84
89
|
isBlankRender,
|
|
85
90
|
isInvalidSentinelError,
|
|
@@ -90,9 +95,12 @@ import {
|
|
|
90
95
|
pickColorOver,
|
|
91
96
|
pillBacksGlyph,
|
|
92
97
|
relativeLuminance,
|
|
98
|
+
rememberFocus,
|
|
93
99
|
requiredD3Plugins,
|
|
94
100
|
resolveAutoColorScale,
|
|
95
101
|
resolveOptions,
|
|
102
|
+
restoreFocus,
|
|
103
|
+
rowNameOf,
|
|
96
104
|
scopeChartIds,
|
|
97
105
|
sessionViewStateProvider,
|
|
98
106
|
sheetName,
|
|
@@ -106,7 +114,7 @@ import {
|
|
|
106
114
|
toRGBA,
|
|
107
115
|
toSourceRows,
|
|
108
116
|
valuePlacementFlag
|
|
109
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-JQ7FFCOE.mjs";
|
|
110
118
|
import {
|
|
111
119
|
LASSO_AXES_SLOT,
|
|
112
120
|
LASSO_COUNT_CLASS,
|
|
@@ -133,13 +141,13 @@ import {
|
|
|
133
141
|
lassoVerdict,
|
|
134
142
|
pointInShape,
|
|
135
143
|
registerLassoAction
|
|
136
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-4DOKJ3R3.mjs";
|
|
137
145
|
import {
|
|
138
146
|
MIN_HIT_BAND_PX,
|
|
139
147
|
censusHitBands,
|
|
140
148
|
ensureCrossfilterHitTargets,
|
|
141
149
|
hitBandFlag
|
|
142
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-GQLEU3VC.mjs";
|
|
143
151
|
import {
|
|
144
152
|
CONTAINER_SLOT_PRESS_AT,
|
|
145
153
|
DRAG_NOT_CLICK_PX,
|
|
@@ -164,7 +172,7 @@ import {
|
|
|
164
172
|
selectionRuleOf,
|
|
165
173
|
trackPress,
|
|
166
174
|
validRowSet
|
|
167
|
-
} from "./chunk-
|
|
175
|
+
} from "./chunk-3ER4C7TG.mjs";
|
|
168
176
|
import {
|
|
169
177
|
AXIS_PIN_BAND_PAD_PX,
|
|
170
178
|
AXIS_PIN_MAX_BAND_FRACTION,
|
|
@@ -193,7 +201,7 @@ import {
|
|
|
193
201
|
svgInkReach,
|
|
194
202
|
takeScroll,
|
|
195
203
|
unpinScrolledAxis
|
|
196
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-TN5JRULV.mjs";
|
|
197
205
|
import {
|
|
198
206
|
clearGeoCache,
|
|
199
207
|
geoAssetFor,
|
|
@@ -206,7 +214,7 @@ import {
|
|
|
206
214
|
Kt,
|
|
207
215
|
l,
|
|
208
216
|
o
|
|
209
|
-
} from "./chunk-
|
|
217
|
+
} from "./chunk-TH577JHI.mjs";
|
|
210
218
|
import "./chunk-A2GMXZP7.mjs";
|
|
211
219
|
import {
|
|
212
220
|
ACTIVE_TICK_CLASS,
|
|
@@ -244,6 +252,7 @@ import {
|
|
|
244
252
|
HOST_CONTRACT_VERSION,
|
|
245
253
|
LEGEND_MARK_CLASS,
|
|
246
254
|
LIFT_SELECTED_CLASS,
|
|
255
|
+
MARKS_INERT_CLASS,
|
|
247
256
|
MARK_CLASS,
|
|
248
257
|
MARK_KEY_ATTR,
|
|
249
258
|
MARK_SELECTED_CLASS,
|
|
@@ -262,7 +271,7 @@ import {
|
|
|
262
271
|
chartOwnsTimeline,
|
|
263
272
|
periodTickSuppressesFeedback,
|
|
264
273
|
withoutViewOnlyKeys
|
|
265
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-USZSHKIB.mjs";
|
|
266
275
|
import "./chunk-GHODWOAL.mjs";
|
|
267
276
|
|
|
268
277
|
// src/hostLinks.ts
|
|
@@ -2368,6 +2377,9 @@ export {
|
|
|
2368
2377
|
HOST_CONTAINER_CLASS,
|
|
2369
2378
|
HOST_CONTRACT_VERSION,
|
|
2370
2379
|
INLINE_FILTER_MIN_ROWS,
|
|
2380
|
+
KEYBOARD_CLASS,
|
|
2381
|
+
KEYBOARD_STAMP,
|
|
2382
|
+
WIRED_ATTR as KEYBOARD_WIRED_ATTR,
|
|
2371
2383
|
LABEL_CONTRAST_CAP,
|
|
2372
2384
|
LABEL_CONTRAST_DONE_ATTR,
|
|
2373
2385
|
LABEL_PILL_CLASS,
|
|
@@ -2394,6 +2406,7 @@ export {
|
|
|
2394
2406
|
LIGHT_TEXT,
|
|
2395
2407
|
LIMIT_COUNT_MAX,
|
|
2396
2408
|
LIVE_OPTION_KEYS,
|
|
2409
|
+
MARKS_INERT_CLASS,
|
|
2397
2410
|
MARK_CLASS,
|
|
2398
2411
|
MARK_KEY_ATTR,
|
|
2399
2412
|
MARK_SELECTED_CLASS,
|
|
@@ -2487,6 +2500,7 @@ export {
|
|
|
2487
2500
|
clearSelectionGlyphs,
|
|
2488
2501
|
clickWasDrag,
|
|
2489
2502
|
clippedTextFlag,
|
|
2503
|
+
codeHasKeyboardStamp,
|
|
2490
2504
|
codeReadsDatesInLocalTime,
|
|
2491
2505
|
codeReadsOption,
|
|
2492
2506
|
collectD3GlyphCenters,
|
|
@@ -2537,6 +2551,7 @@ export {
|
|
|
2537
2551
|
htmlNaturalSize,
|
|
2538
2552
|
htmlToSvgDataUrl,
|
|
2539
2553
|
inlineFilterGate,
|
|
2554
|
+
installKeyboard,
|
|
2540
2555
|
installLasso,
|
|
2541
2556
|
invalidSentinelReason,
|
|
2542
2557
|
isBlankRender,
|
|
@@ -2630,11 +2645,14 @@ export {
|
|
|
2630
2645
|
registerGeoAsset,
|
|
2631
2646
|
registerLassoAction,
|
|
2632
2647
|
relativeLuminance,
|
|
2648
|
+
rememberFocus,
|
|
2633
2649
|
rememberScroll,
|
|
2634
2650
|
requiredD3Plugins,
|
|
2635
2651
|
resolveAutoColorScale,
|
|
2636
2652
|
resolveOptions,
|
|
2653
|
+
restoreFocus,
|
|
2637
2654
|
rowIdxsFromMark,
|
|
2655
|
+
rowNameOf,
|
|
2638
2656
|
sameMarker,
|
|
2639
2657
|
sameRowSet,
|
|
2640
2658
|
scopeChartIds,
|
package/dist/legend-fit.mjs
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
chartSvgOf,
|
|
4
4
|
tableHostOf
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3EQOJHRA.mjs";
|
|
6
6
|
import {
|
|
7
7
|
FIT_CONTENT_SELECTOR,
|
|
8
8
|
ctmScaleOf,
|
|
9
9
|
isPhantomBox
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-TN5JRULV.mjs";
|
|
11
|
+
import "./chunk-USZSHKIB.mjs";
|
|
12
12
|
import "./chunk-GHODWOAL.mjs";
|
|
13
13
|
|
|
14
14
|
// src/legendFit/legendReconcile.ts
|
package/dist/page.mjs
CHANGED
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
readControls,
|
|
15
15
|
viewFromToken,
|
|
16
16
|
viewToken
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-QAPZIFOB.mjs";
|
|
18
|
+
import "./chunk-4DOKJ3R3.mjs";
|
|
19
|
+
import "./chunk-3ER4C7TG.mjs";
|
|
20
|
+
import "./chunk-USZSHKIB.mjs";
|
|
21
21
|
import "./chunk-GHODWOAL.mjs";
|
|
22
22
|
export {
|
|
23
23
|
LINKED_HOVER_CLASS,
|
package/dist/provinces.mjs
CHANGED
package/dist/react.mjs
CHANGED
|
@@ -13,25 +13,25 @@ import {
|
|
|
13
13
|
payloadRowReader,
|
|
14
14
|
viewFromToken,
|
|
15
15
|
viewToken
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-QAPZIFOB.mjs";
|
|
17
17
|
import {
|
|
18
18
|
assembleD3,
|
|
19
19
|
createChartGroup,
|
|
20
20
|
createChartHost,
|
|
21
21
|
syncMemberSelection,
|
|
22
22
|
toSourceRows
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-JQ7FFCOE.mjs";
|
|
24
|
+
import "./chunk-4DOKJ3R3.mjs";
|
|
25
|
+
import "./chunk-GQLEU3VC.mjs";
|
|
26
|
+
import "./chunk-3ER4C7TG.mjs";
|
|
27
|
+
import "./chunk-TN5JRULV.mjs";
|
|
28
28
|
import {
|
|
29
29
|
geoFromCache,
|
|
30
30
|
loadGeo
|
|
31
31
|
} from "./chunk-5WTQN5DL.mjs";
|
|
32
|
-
import "./chunk-
|
|
32
|
+
import "./chunk-TH577JHI.mjs";
|
|
33
33
|
import "./chunk-A2GMXZP7.mjs";
|
|
34
|
-
import "./chunk-
|
|
34
|
+
import "./chunk-USZSHKIB.mjs";
|
|
35
35
|
import "./chunk-GHODWOAL.mjs";
|
|
36
36
|
|
|
37
37
|
// src/react.tsx
|
|
@@ -185,7 +185,11 @@ function BicChart(props) {
|
|
|
185
185
|
// siblings of a chart that has an id in a group. This binding always
|
|
186
186
|
// subscribes to the selection (for onSelect), so the host cannot count
|
|
187
187
|
// subscribers here; an onSelect callback alone is not the page's filter.
|
|
188
|
-
selectionReachesPage: () => !!reachRef.current.selects || !!(reachRef.current.group && reachRef.current.id)
|
|
188
|
+
selectionReachesPage: () => !!reachRef.current.selects || !!(reachRef.current.group && reachRef.current.id),
|
|
189
|
+
// Whether a click on a mark does anything at all: the same two,
|
|
190
|
+
// or an onSelect the page passed. A chart with none of them draws its marks
|
|
191
|
+
// inert rather than dimming the others for a click that filters nothing.
|
|
192
|
+
marksSelect: () => !!reachRef.current.selects || !!(reachRef.current.group && reachRef.current.id) || typeof onSelectRef.current === "function"
|
|
189
193
|
});
|
|
190
194
|
hostRef.current = host;
|
|
191
195
|
builtAnnKeyRef.current = annKey;
|
package/dist/testing.mjs
CHANGED
|
@@ -40,4 +40,6 @@ export interface AnnotationLayer {
|
|
|
40
40
|
readonly report: AnnotationReport;
|
|
41
41
|
destroy(): void;
|
|
42
42
|
}
|
|
43
|
-
export declare function createAnnotationLayer(container: HTMLElement, onClick?: (a: MarkAnnotation) => void
|
|
43
|
+
export declare function createAnnotationLayer(container: HTMLElement, onClick?: (a: MarkAnnotation) => void, opts?: {
|
|
44
|
+
keyboard?: () => boolean;
|
|
45
|
+
}): AnnotationLayer;
|
package/dist/types/contract.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExportFormat, ExportTableService, SaveFileService } from "./exportTable";
|
|
2
|
-
export declare const HOST_CONTRACT_VERSION = "1.
|
|
2
|
+
export declare const HOST_CONTRACT_VERSION = "1.22.0";
|
|
3
3
|
export type GeoPointPrecision = "latlon" | "city" | "zip3" | "state" | "country";
|
|
4
4
|
/** Every valid tier, ordered most precise → coarsest. Runtime form of GeoPointPrecision. */
|
|
5
5
|
export declare const GEO_POINT_PRECISIONS: readonly GeoPointPrecision[];
|
|
@@ -90,6 +90,7 @@ export interface ViewStateProvider {
|
|
|
90
90
|
export declare const HOST_CONTAINER_CLASS = "bic-chart-host";
|
|
91
91
|
export declare const SELECTION_ACTIVE_CLASS = "lch-has-selection";
|
|
92
92
|
export declare const MARK_SELECTED_CLASS = "lch-mark-selected";
|
|
93
|
+
export declare const MARKS_INERT_CLASS = "lch-marks-inert";
|
|
93
94
|
export declare const ACTIVE_TICK_CLASS = "lch-tick-active";
|
|
94
95
|
export declare const DIM_OPACITY_VAR = "--lch-dim-opacity";
|
|
95
96
|
export declare const DIM_OPACITY_DEFAULT = 0.25;
|
|
@@ -196,6 +197,10 @@ export interface RenderOptions {
|
|
|
196
197
|
selectionGlyph?: "none" | "dot" | "check";
|
|
197
198
|
/** A host FACT from the generate answer: this chart's family never takes a selection glyph. */
|
|
198
199
|
suppressSelectionGlyph?: boolean;
|
|
200
|
+
/** A host FACT: this chart works from the keyboard (its code carries the keyboard stamp), so the host has made its
|
|
201
|
+
* selectable marks focusable. A chart or helper drawing its own controls (a flip arrow, a sort header) gives them
|
|
202
|
+
* a tabindex, a role and an Enter / Space press when this is true. */
|
|
203
|
+
keyboardMarks?: boolean;
|
|
199
204
|
animAutoPlay?: boolean;
|
|
200
205
|
animPlaySpeedMs?: number;
|
|
201
206
|
animLoopDelaySec?: number;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface FocusMemory {
|
|
2
|
+
sig: string;
|
|
3
|
+
nth: number;
|
|
4
|
+
start: number | null;
|
|
5
|
+
end: number | null;
|
|
6
|
+
dir: "forward" | "backward" | "none" | null;
|
|
7
|
+
}
|
|
8
|
+
/** The focused element inside the container and its caret, or null when focus is elsewhere (or on the container). */
|
|
9
|
+
export declare function rememberFocus(container: HTMLElement): FocusMemory | null;
|
|
10
|
+
/** Give focus back to the same element of the new draw, with its caret. Nothing when the chart already moved focus into
|
|
11
|
+
* itself, or when the new draw has no such element. Returns whether focus was restored. */
|
|
12
|
+
export declare function restoreFocus(container: HTMLElement, memory: FocusMemory | null): boolean;
|
package/dist/types/host.d.ts
CHANGED
|
@@ -280,6 +280,16 @@ export interface ChartHostConfig {
|
|
|
280
280
|
* `selects` and the group itself. Never throws through: an answer that throws counts as reached.
|
|
281
281
|
*/
|
|
282
282
|
selectionReachesPage?: () => boolean;
|
|
283
|
+
/**
|
|
284
|
+
* WHETHER A CLICK ON A MARK SELECTS ANYTHING. False: nothing listens to this chart's selection - no
|
|
285
|
+
* page filter, no group sibling, no callback - so its marks are drawn inert: no pointer cursor (over the chart's own
|
|
286
|
+
* inline one), no hover dimming of the others, and the reader's click, or a selection the chart dispatches itself,
|
|
287
|
+
* lights and dims nothing. A selection the page hands in (selection.highlight) still paints. Read at every click and
|
|
288
|
+
* every paint, so a binding added later counts at once. Absent: true, which every host but React relies on (a Power
|
|
289
|
+
* BI click always reaches its selection manager; an Excel click always opens a selection card). An answer that
|
|
290
|
+
* throws counts as true.
|
|
291
|
+
*/
|
|
292
|
+
marksSelect?: () => boolean;
|
|
283
293
|
}
|
|
284
294
|
export interface ChartHost {
|
|
285
295
|
/** Replace the notes drawn on marks (see ChartHostConfig.annotations); redraws them at once. */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, NO_ROW_MARKS_ATTR, NOTE_STYLE_ATTR, SELECTION_RULE_ATTR, SELECTION_RULE_CLICKED_MARKS, MARK_KEY_ATTR, CONTAINER_SLOT_CLICKED_MARKS, SNAPSHOT_SVG_ATTR, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, CONTAINER_SLOT_SCROLL, CONTAINER_SLOT_HOST_SELECTION, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, DIM_OPACITY_MIN, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, FLIP_INTERVAL_MIN_MS, FLIP_INTERVAL_MAX_MS, FLIP_DIRECTION_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type FlipDirection, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, type XfilterRefreshDetail, type HostSelectionFact, } from "./contract";
|
|
1
|
+
export { HOST_CONTRACT_VERSION, GEO_POINT_PRECISIONS, MARK_CLASS, LEGEND_MARK_CLASS, AXIS_FILTER_CLASS, ROW_IDX_ATTR, LIFT_SELECTED_CLASS, CONTROL_CLASS, NO_ROW_MARKS_ATTR, NOTE_STYLE_ATTR, SELECTION_RULE_ATTR, SELECTION_RULE_CLICKED_MARKS, MARK_KEY_ATTR, CONTAINER_SLOT_CLICKED_MARKS, SNAPSHOT_SVG_ATTR, XFILTER_REFRESH_EVENT, CONTAINER_SLOT_ANIM_STOP, CONTAINER_SLOT_XF_CLEAR, CONTAINER_SLOT_INITIAL_XF_MARK, CONTAINER_SLOT_UI_STATE, CONTAINER_SLOT_SCROLL, CONTAINER_SLOT_HOST_SELECTION, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, MARKS_INERT_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, DIM_OPACITY_MIN, chartOwnsTimeline, periodTickSuppressesFeedback, ANIM_PLAY_SPEED_DEFAULT, ANIM_PLAY_SPEED_MIN, ANIM_PLAY_SPEED_MAX, ANIM_LOOP_DELAY_DEFAULT, ANIM_LOOP_DELAY_MIN, ANIM_MAX_IDEAL_FRAMES_DEFAULT, ANIM_MAX_IDEAL_FRAMES_MIN, ANIM_MAX_IDEAL_FRAMES_MAX, ANIMATION_OPTION_KEYS, COLOR_SCALE_SELF_CLAMP_PCT_DEFAULT, COLOR_SCALE_SELF_CLAMP_PCT_MIN, COLOR_SCALE_SELF_CLAMP_PCT_MAX, FLIP_MODE_DEFAULT, FLIP_INTERVAL_MIN_MS, FLIP_INTERVAL_MAX_MS, FLIP_DIRECTION_DEFAULT, APPROXIMATE_POSITIONS_DEFAULT, VALUE_AXIS_BASELINE_DEFAULT, SEASONAL_MARKERS_DEFAULT, MAX_MAP_POINTS_DEFAULT, type GeoPointPrecision, type GeoMapKind, type TimelineStyle, type FlipMode, type FlipDirection, type ApproximatePositions, type ValueAxisBaseline, type SeasonalMarkers, type ColorScaleScope, type RenderOptions, type ViewStateProvider, type ChartControlChange, type XfilterRefreshDetail, type HostSelectionFact, } from "./contract";
|
|
2
2
|
export { resolveOptions, cleanHostSelection, type ResolveOptionsInput } from "./defaults";
|
|
3
3
|
export { hostLinkServices, type HostLinkServices, type ClipboardLike } from "./hostLinks";
|
|
4
4
|
export { tableToCsv, tableToXlsx, buildExportFile, exportFileName, sheetName as exportSheetName, excelNumberFormat, excelSerial, bytesToBase64, exportFormatsFor, exportTableService, browserSaveFile, EXPORT_FORMATS, XLSX_MIME, CSV_MIME, type ExportTable, type ExportColumn, type ExportColumnType, type ExportCell, type ExportFormat, type ExportFile, type SaveFileService, type ExportTableService, } from "./exportTable";
|
|
@@ -11,6 +11,8 @@ export { buildRenderPayload, type RenderPayload, type GeoPointBinding, type GeoB
|
|
|
11
11
|
export { codeReadsDatesInLocalTime, vegaSpecReadsDatesInLocalTime } from "./dateCells";
|
|
12
12
|
export { createChartHost, compileRenderFn, stripEsmExports, requiredD3Plugins, explainRenderFailure, sessionViewStateProvider, noopViewStateProvider, assembleD3, D3_PLUGIN_PACKAGES, type ChartHost, type ChartHostConfig, type RenderFn, type SelectionPaintReport, type SelectionChangeMeta } from "./host";
|
|
13
13
|
export { ANNOTATION_CLASS, ANNOTATION_LAYER_CLASS, type MarkAnnotation, type AnnotationReport } from "./annotations";
|
|
14
|
+
export { KEYBOARD_STAMP, KEYBOARD_CLASS, WIRED_ATTR as KEYBOARD_WIRED_ATTR, codeHasKeyboardStamp, installKeyboard, rowNameOf, type KeyboardEnv, type KeyboardHandle } from "./keyboardMarks";
|
|
15
|
+
export { rememberFocus, restoreFocus, type FocusMemory } from "./focusKeep";
|
|
14
16
|
export type { MarkNoteLike, NoteBadgeOptions } from "./markNotes";
|
|
15
17
|
export type { Controls, ControlInfo, ControlsAttachment } from "./controls";
|
|
16
18
|
export { createChartGroup, toSourceRows, syncMemberSelection, type ChartGroup, type ChartGroupMember, type ChartGroupSelection, type ChartGroupChange, type ChartGroupMemberOptions, type ChartGroupSourceOptions, type ChartGroupPayload } from "./group";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare const KEYBOARD_STAMP = "// bic:keyboard-marks";
|
|
2
|
+
/** Whether the code carries the keyboard stamp in its header. */
|
|
3
|
+
export declare function codeHasKeyboardStamp(code: unknown): boolean;
|
|
4
|
+
/** On the container while its chart works from the keyboard. */
|
|
5
|
+
export declare const KEYBOARD_CLASS = "lch-keyboard";
|
|
6
|
+
/** On each element the host made focusable, so it never touches one the chart made focusable itself. */
|
|
7
|
+
export declare const WIRED_ATTR = "data-lch-kb";
|
|
8
|
+
export interface KeyboardEnv {
|
|
9
|
+
container: HTMLElement;
|
|
10
|
+
/** The elements a click selects (the host's click selector). */
|
|
11
|
+
markSelector: string;
|
|
12
|
+
/** Elements pressed with Enter: the chart's declared controls and the host's badges. */
|
|
13
|
+
pressSelector: string;
|
|
14
|
+
/** Elements never to treat as marks (the host's own layers). */
|
|
15
|
+
skipSelector: string;
|
|
16
|
+
/** True while a click on a mark selects nothing (the marks are then not made focusable). */
|
|
17
|
+
inert(): boolean;
|
|
18
|
+
/** Select a mark as a click on it would. */
|
|
19
|
+
select(mark: Element, mods: {
|
|
20
|
+
ctrl: boolean;
|
|
21
|
+
shift: boolean;
|
|
22
|
+
}): void;
|
|
23
|
+
/** The reader's clear: Ctrl+Shift+C on every host (Power BI's own clear-selection key), and Escape where the host
|
|
24
|
+
* lets it (escapeClears). */
|
|
25
|
+
clear(): void;
|
|
26
|
+
/** Whether Escape clears. False for a host whose frame uses Escape to move focus out of the chart (Power BI), so
|
|
27
|
+
* leaving the chart never wipes the reader's selection there. Default true. */
|
|
28
|
+
escapeClears?: boolean;
|
|
29
|
+
isSelected(mark: Element): boolean;
|
|
30
|
+
/** What a screen reader calls a mark that names nothing itself. */
|
|
31
|
+
labelOf(mark: Element): string | null;
|
|
32
|
+
/** A stable key for a mark across redraws (its rows). */
|
|
33
|
+
keyOf(mark: Element): string;
|
|
34
|
+
}
|
|
35
|
+
export interface KeyboardHandle {
|
|
36
|
+
/** Re-apply tab stops, roles, names and pressed state after a draw or a selection change. */
|
|
37
|
+
refresh(): void;
|
|
38
|
+
destroy(): void;
|
|
39
|
+
}
|
|
40
|
+
/** What a screen reader calls a row: its first few values, numbers in the reader's culture, internal columns left out.
|
|
41
|
+
* Shared so every host names a mark the same way. */
|
|
42
|
+
export declare function rowNameOf(columns: ReadonlyArray<unknown>, row: ReadonlyArray<unknown> | null | undefined, culture?: string): string | null;
|
|
43
|
+
export declare function installKeyboard(env: KeyboardEnv): KeyboardHandle;
|
package/dist/zoom-memory.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
K
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TH577JHI.mjs";
|
|
5
5
|
import "./chunk-GHODWOAL.mjs";
|
|
6
6
|
|
|
7
7
|
// src/zoomMemory/zoomMemory.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.109",
|
|
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",
|