@bicharts/chart-host 0.6.87 → 0.6.89
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/README.md +45 -0
- package/dist/adapters.mjs +3 -3
- package/dist/{chunk-HZNMMRQ3.mjs → chunk-562LF7XM.mjs} +248 -5
- package/dist/{chunk-IURROJT7.mjs → chunk-DJ5IJV57.mjs} +8 -2
- package/dist/{chunk-DTOGTKAJ.mjs → chunk-GOIG756B.mjs} +1 -1
- package/dist/{chunk-QIRLWJBI.mjs → chunk-OG6RR2AJ.mjs} +2 -2
- package/dist/{chunk-BQFG5HWZ.mjs → chunk-QHIPRAZK.mjs} +1 -1
- package/dist/{chunk-ZGQURBRJ.mjs → chunk-UBB5LNH4.mjs} +1 -1
- package/dist/{chunk-7HKVV5T5.mjs → chunk-XNS34AMM.mjs} +1 -1
- package/dist/{chunk-MR6TL7QZ.mjs → chunk-YDHXOIAI.mjs} +2 -0
- package/dist/index.mjs +9 -7
- package/dist/legend-fit.mjs +3 -3
- package/dist/page.mjs +4 -4
- package/dist/react.mjs +11 -7
- package/dist/testing.mjs +1 -1
- package/dist/types/contract.d.ts +8 -0
- package/dist/types/host.d.ts +15 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/react.d.ts +3 -0
- package/dist/types/selection.d.ts +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,6 +267,51 @@ would show its selected lines at 38%, which the eye reads as dimmed. Such a char
|
|
|
267
267
|
painted at full opacity. Undeclared charts are unchanged, so alpha used as an encoding (a depth
|
|
268
268
|
cue, a hierarchy level) is never flattened by a fix meant for another chart.
|
|
269
269
|
|
|
270
|
+
**How far the rest dims, per chart.** `options.dimOpacity` (a share of full opacity, `0.01`-`1`;
|
|
271
|
+
`DIM_OPACITY_MIN` is the floor) sets the level for one host without writing CSS, and it is live
|
|
272
|
+
through `setOptions`. The host writes it as `--lch-dim-opacity` on its own container and removes
|
|
273
|
+
only what it wrote, so with the option absent nothing is written and the CSS above decides: the
|
|
274
|
+
stylesheet's `0.25`, or whatever your page sets on the variable.
|
|
275
|
+
|
|
276
|
+
```js
|
|
277
|
+
createChartHost(el, { code, data, options: { dimOpacity: 0.15 } });
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**A glyph on each selected mark.** `options.selectionGlyph` (`"dot"` or `"check"`; absent or
|
|
281
|
+
`"none"` draws nothing, the default) puts a small glyph on every selected mark, in a layer the host
|
|
282
|
+
owns inside the container (`.bic-selection-glyphs`, each glyph `.lch-sel-glyph`, never hit-tested).
|
|
283
|
+
It is painted after every selection change and, on a redraw, after the layout pass and the fit, so
|
|
284
|
+
nothing measures it as part of the chart. Only a mark the reader can see gets one: a mark hidden by
|
|
285
|
+
`visibility` or `opacity` (a legend toggle) and a mark outside its svg's frame or its plot's
|
|
286
|
+
`clip-path` (a point panned into the axis margin) get none. While a selection is lit, a mark that
|
|
287
|
+
moves or hides without a redraw (a pan or zoom, a transition, an animation frame, a legend toggle)
|
|
288
|
+
takes its glyph with it on the next frame; a write that holds no mark (a hover dot, a tooltip)
|
|
289
|
+
repaints nothing, and that repaint is not reported again. Where the browser has a `ResizeObserver`,
|
|
290
|
+
a container resized without a redraw (a responsive chart, a hidden tab shown) is repainted too, and
|
|
291
|
+
reported when it drew a different count. The layer clips at the container's scroll area, so a
|
|
292
|
+
glyph never widens what the container scrolls, and it sits under the note badges, under a chart's
|
|
293
|
+
own tooltip or control that sets a `z-index` above 1, and under a pinned axis, so a glyph on a row
|
|
294
|
+
scrolled beneath the axis is covered with its row. When the page left the container
|
|
295
|
+
`position: static`, the host makes it `relative` so the layer scrolls and clips with the marks, and
|
|
296
|
+
`destroy()` puts back what the page had. A period picked on a chart's own timeline dims nothing and
|
|
297
|
+
marks nothing.
|
|
298
|
+
|
|
299
|
+
Some charts never take a glyph: on a flow or relationship chart a selected series would get one on
|
|
300
|
+
every point. The generate answer says so (`suppressSelectionGlyph`, read by shape-core's
|
|
301
|
+
`parseGenerateResponse`); pass it as `options.suppressSelectionGlyph`, or leave it in the payload's
|
|
302
|
+
`meta` (`data.meta.suppressSelectionGlyph`) and the host promotes it, the way it promotes
|
|
303
|
+
`geoPoint`. Keep it with the chart's code, so a redraw from a cache honors it too.
|
|
304
|
+
`onSelectionGlyphs` reports what each paint did (`{ mode, drawn, total, suppressed }`), and is
|
|
305
|
+
called only when a glyph mode is set:
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
createChartHost(el, {
|
|
309
|
+
code, data,
|
|
310
|
+
options: { selectionGlyph: "dot", suppressSelectionGlyph: answer.suppressSelectionGlyph },
|
|
311
|
+
onSelectionGlyphs: r => console.debug("glyphs", r),
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
270
315
|
**Which marks count as selected.** By default a mark is selected when *any* of the rows in its
|
|
271
316
|
`data-row-idx` list is selected, which is what lights a legend swatch together with its series. A
|
|
272
317
|
chart whose marks share rows declares the other rule by stamping
|
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-XNS34AMM.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-DJ5IJV57.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-YDHXOIAI.mjs";
|
|
22
22
|
import "./chunk-GHODWOAL.mjs";
|
|
23
23
|
|
|
24
24
|
// src/adapters/types.ts
|
|
@@ -2,30 +2,33 @@
|
|
|
2
2
|
import {
|
|
3
3
|
LASSO_OUTLINE_CLASS,
|
|
4
4
|
installLasso
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OG6RR2AJ.mjs";
|
|
6
6
|
import {
|
|
7
7
|
censusHitBands,
|
|
8
8
|
ensureCrossfilterHitTargets
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-XNS34AMM.mjs";
|
|
10
10
|
import {
|
|
11
11
|
clearPress,
|
|
12
|
+
clearSelectionGlyphs,
|
|
12
13
|
clickWasDrag,
|
|
14
|
+
collectGlyphCentersWhere,
|
|
13
15
|
createMarkResolver,
|
|
14
16
|
isInsideControl,
|
|
15
17
|
markKeyOf,
|
|
16
18
|
nextClickedMarks,
|
|
17
19
|
nextSelection,
|
|
20
|
+
paintSelectionGlyphs,
|
|
18
21
|
planSelectionPaint,
|
|
19
22
|
sameRowSet,
|
|
20
23
|
selectionRuleOf,
|
|
21
24
|
trackPress,
|
|
22
25
|
validRowSet
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-DJ5IJV57.mjs";
|
|
24
27
|
import {
|
|
25
28
|
clipWindowOf,
|
|
26
29
|
fitRenderedChart,
|
|
27
30
|
unpinScrolledAxis
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-QHIPRAZK.mjs";
|
|
29
32
|
import {
|
|
30
33
|
Fn,
|
|
31
34
|
J3,
|
|
@@ -60,6 +63,7 @@ import {
|
|
|
60
63
|
CONTAINER_SLOT_XF_CLEAR,
|
|
61
64
|
CONTROL_CLASS,
|
|
62
65
|
DIM_OPACITY_DEFAULT,
|
|
66
|
+
DIM_OPACITY_MIN,
|
|
63
67
|
DIM_OPACITY_VAR,
|
|
64
68
|
FLIP_DIRECTION_DEFAULT,
|
|
65
69
|
FLIP_MODE_DEFAULT,
|
|
@@ -78,7 +82,7 @@ import {
|
|
|
78
82
|
XFILTER_REFRESH_EVENT,
|
|
79
83
|
chartOwnsTimeline,
|
|
80
84
|
periodTickSuppressesFeedback
|
|
81
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-YDHXOIAI.mjs";
|
|
82
86
|
|
|
83
87
|
// src/labelContrast.ts
|
|
84
88
|
function parseRGBA(c) {
|
|
@@ -608,6 +612,20 @@ function resolveOptions(p) {
|
|
|
608
612
|
cultureCode: p.cultureCode,
|
|
609
613
|
allowTooltips: p.allowTooltips,
|
|
610
614
|
noDataText: p.noDataText,
|
|
615
|
+
// A finite number is clamped to DIM_OPACITY_MIN-1; absent, blank or junk stays undefined so the stylesheet - and a
|
|
616
|
+
// page's own CSS override - still decides. Never defaulted here: that would override every page's CSS.
|
|
617
|
+
dimOpacity: (() => {
|
|
618
|
+
const n = numberOr(p.dimOpacity, NaN);
|
|
619
|
+
return Number.isFinite(n) ? clamp(n, DIM_OPACITY_MIN, 1) : void 0;
|
|
620
|
+
})(),
|
|
621
|
+
// A recognised glyph or none: an unknown string must never reach the painter as a live mode, and "none" is
|
|
622
|
+
// undefined rather than a value, so a host that passes nothing and one that passes "none" resolve alike.
|
|
623
|
+
selectionGlyph: (() => {
|
|
624
|
+
const v = (p.selectionGlyph == null ? "" : String(p.selectionGlyph)).toLowerCase();
|
|
625
|
+
return v === "dot" || v === "check" ? v : void 0;
|
|
626
|
+
})(),
|
|
627
|
+
// A host FACT from the generate answer, true only for a literal true: silence never suppresses anything.
|
|
628
|
+
suppressSelectionGlyph: p.suppressSelectionGlyph === true ? true : void 0,
|
|
611
629
|
onSelect: p.onSelect,
|
|
612
630
|
// Control gestures (1.10.0). Passed straight through like onSelect: the host owns what a gesture MEANS,
|
|
613
631
|
// and a host that supplies nothing leaves every control behaving exactly as before.
|
|
@@ -2077,6 +2095,7 @@ function createChartHost(container, config) {
|
|
|
2077
2095
|
p.catch(() => {
|
|
2078
2096
|
});
|
|
2079
2097
|
};
|
|
2098
|
+
let dimVarSet = false;
|
|
2080
2099
|
let current = null;
|
|
2081
2100
|
let activeTickEl = null;
|
|
2082
2101
|
let selectionIsPeriod = false;
|
|
@@ -2153,6 +2172,14 @@ function createChartHost(container, config) {
|
|
|
2153
2172
|
const active = !!sel && sel.length > 0;
|
|
2154
2173
|
const dim = active && !selectionIsPeriod;
|
|
2155
2174
|
container.classList?.[dim ? "add" : "remove"](SELECTION_ACTIVE_CLASS);
|
|
2175
|
+
const want = resolved.dimOpacity;
|
|
2176
|
+
if (typeof want === "number") {
|
|
2177
|
+
container.style?.setProperty(DIM_OPACITY_VAR, String(want));
|
|
2178
|
+
dimVarSet = true;
|
|
2179
|
+
} else if (dimVarSet) {
|
|
2180
|
+
container.style?.removeProperty(DIM_OPACITY_VAR);
|
|
2181
|
+
dimVarSet = false;
|
|
2182
|
+
}
|
|
2156
2183
|
const lit = container.querySelectorAll(`.${ACTIVE_TICK_CLASS}`);
|
|
2157
2184
|
for (const t of Array.from(lit)) t.classList?.remove(ACTIVE_TICK_CLASS);
|
|
2158
2185
|
const tickStillDrawn = !!activeTickEl && (typeof container.contains === "function" ? container.contains(activeTickEl) : activeTickEl.isConnected !== false);
|
|
@@ -2192,12 +2219,209 @@ function createChartHost(container, config) {
|
|
|
2192
2219
|
} catch {
|
|
2193
2220
|
}
|
|
2194
2221
|
};
|
|
2222
|
+
const GLYPH_LAYER_CLASS = "bic-selection-glyphs";
|
|
2223
|
+
let glyphPositionWas = null;
|
|
2224
|
+
let glyphObserver = null;
|
|
2225
|
+
let glyphResize = null;
|
|
2226
|
+
let glyphSize = "";
|
|
2227
|
+
let glyphQueued = false;
|
|
2228
|
+
let glyphQueuedReport = false;
|
|
2229
|
+
let glyphReported = "";
|
|
2230
|
+
const sizeOfContainer = () => `${container.offsetWidth ?? 0}x${container.offsetHeight ?? 0}`;
|
|
2231
|
+
const glyphBlind = `.${GLYPH_LAYER_CLASS}, .${LASSO_OUTLINE_CLASS}`;
|
|
2232
|
+
const movesAMark = (r) => {
|
|
2233
|
+
const t = r.target;
|
|
2234
|
+
if (!t || t.closest?.(glyphBlind)) return false;
|
|
2235
|
+
return !!(t.classList?.contains(MARK_CLASS) || t.querySelector?.(`.${MARK_CLASS}`));
|
|
2236
|
+
};
|
|
2237
|
+
const queueGlyphs = (reportIfChanged) => {
|
|
2238
|
+
if (reportIfChanged) glyphQueuedReport = true;
|
|
2239
|
+
if (glyphQueued) return;
|
|
2240
|
+
glyphQueued = true;
|
|
2241
|
+
const run = () => {
|
|
2242
|
+
const r = glyphQueuedReport;
|
|
2243
|
+
glyphQueued = false;
|
|
2244
|
+
glyphQueuedReport = false;
|
|
2245
|
+
if (glyphObserver || glyphResize) paintGlyphLayer(r ? "if-changed" : false);
|
|
2246
|
+
};
|
|
2247
|
+
if (win?.requestAnimationFrame) win.requestAnimationFrame(run);
|
|
2248
|
+
else setTimeout(run, 16);
|
|
2249
|
+
};
|
|
2250
|
+
const followGlyphs = (on) => {
|
|
2251
|
+
if (!on) {
|
|
2252
|
+
if (glyphObserver) {
|
|
2253
|
+
glyphObserver.disconnect();
|
|
2254
|
+
glyphObserver = null;
|
|
2255
|
+
}
|
|
2256
|
+
if (glyphResize) {
|
|
2257
|
+
glyphResize.disconnect();
|
|
2258
|
+
glyphResize = null;
|
|
2259
|
+
}
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
const MO = win?.MutationObserver;
|
|
2263
|
+
if (!glyphObserver && MO) {
|
|
2264
|
+
glyphObserver = new MO((records) => {
|
|
2265
|
+
if (!glyphQueued && records.some(movesAMark)) queueGlyphs(false);
|
|
2266
|
+
});
|
|
2267
|
+
glyphObserver.observe(container, {
|
|
2268
|
+
subtree: true,
|
|
2269
|
+
attributes: true,
|
|
2270
|
+
attributeFilter: [
|
|
2271
|
+
"transform",
|
|
2272
|
+
"d",
|
|
2273
|
+
"x",
|
|
2274
|
+
"y",
|
|
2275
|
+
"cx",
|
|
2276
|
+
"cy",
|
|
2277
|
+
"points",
|
|
2278
|
+
"width",
|
|
2279
|
+
"height",
|
|
2280
|
+
"visibility",
|
|
2281
|
+
"opacity",
|
|
2282
|
+
"style",
|
|
2283
|
+
"class"
|
|
2284
|
+
]
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
const RO = win?.ResizeObserver;
|
|
2288
|
+
if (!glyphResize && RO) {
|
|
2289
|
+
glyphResize = new RO(() => {
|
|
2290
|
+
if (sizeOfContainer() !== glyphSize) queueGlyphs(true);
|
|
2291
|
+
});
|
|
2292
|
+
glyphResize.observe(container);
|
|
2293
|
+
}
|
|
2294
|
+
};
|
|
2295
|
+
const markShown = (m) => {
|
|
2296
|
+
try {
|
|
2297
|
+
const cv = m.checkVisibility;
|
|
2298
|
+
if (typeof cv === "function") return cv.call(m, { visibilityProperty: true, opacityProperty: true }) !== false;
|
|
2299
|
+
const cs = win?.getComputedStyle;
|
|
2300
|
+
if (typeof cs !== "function") return true;
|
|
2301
|
+
const own = cs.call(win, m);
|
|
2302
|
+
if (own.visibility === "hidden" || own.visibility === "collapse") return false;
|
|
2303
|
+
for (let el = m; el && el !== container; el = el.parentElement) {
|
|
2304
|
+
const s = el === m ? own : cs.call(win, el);
|
|
2305
|
+
if (s.display === "none" || s.opacity !== "" && parseFloat(s.opacity) === 0) return false;
|
|
2306
|
+
}
|
|
2307
|
+
} catch {
|
|
2308
|
+
}
|
|
2309
|
+
return true;
|
|
2310
|
+
};
|
|
2311
|
+
const glyphWindows = () => {
|
|
2312
|
+
const windowOf = /* @__PURE__ */ new Map();
|
|
2313
|
+
const read = (el) => {
|
|
2314
|
+
if (!windowOf.has(el)) {
|
|
2315
|
+
let w = null;
|
|
2316
|
+
try {
|
|
2317
|
+
if ((el.tagName || "").toLowerCase() === "svg") {
|
|
2318
|
+
const r = el.getBoundingClientRect();
|
|
2319
|
+
if (r.width > 0 && r.height > 0) w = r;
|
|
2320
|
+
} else if (el.hasAttribute?.("clip-path")) w = clipWindowOf(el);
|
|
2321
|
+
} catch {
|
|
2322
|
+
w = null;
|
|
2323
|
+
}
|
|
2324
|
+
windowOf.set(el, w);
|
|
2325
|
+
}
|
|
2326
|
+
return windowOf.get(el) ?? null;
|
|
2327
|
+
};
|
|
2328
|
+
const EPS2 = 0.5;
|
|
2329
|
+
return (m, x, y) => {
|
|
2330
|
+
for (let el = m; el && el !== container; el = el.parentElement) {
|
|
2331
|
+
const w = read(el);
|
|
2332
|
+
if (w && (x < w.left - EPS2 || x > w.right + EPS2 || y < w.top - EPS2 || y > w.bottom + EPS2)) return false;
|
|
2333
|
+
}
|
|
2334
|
+
return true;
|
|
2335
|
+
};
|
|
2336
|
+
};
|
|
2337
|
+
const paintGlyphLayer = (report = true) => {
|
|
2338
|
+
if (destroyed) return;
|
|
2339
|
+
let follow = false;
|
|
2340
|
+
try {
|
|
2341
|
+
let layer = container.querySelector(`:scope > .${GLYPH_LAYER_CLASS}`);
|
|
2342
|
+
clearSelectionGlyphs(layer);
|
|
2343
|
+
const mode = resolved.selectionGlyph;
|
|
2344
|
+
if (mode !== "dot" && mode !== "check") {
|
|
2345
|
+
glyphReported = "";
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
const active = !!current && current.length > 0 && !selectionIsPeriod;
|
|
2349
|
+
if (!active) {
|
|
2350
|
+
glyphReported = "";
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
if (resolved.suppressSelectionGlyph) {
|
|
2354
|
+
if (report === true) try {
|
|
2355
|
+
config.onSelectionGlyphs?.({ mode, drawn: 0, total: 0, suppressed: true });
|
|
2356
|
+
} catch {
|
|
2357
|
+
}
|
|
2358
|
+
glyphReported = "";
|
|
2359
|
+
return;
|
|
2360
|
+
}
|
|
2361
|
+
follow = true;
|
|
2362
|
+
if (!layer) {
|
|
2363
|
+
layer = doc.createElement("div");
|
|
2364
|
+
layer.className = GLYPH_LAYER_CLASS;
|
|
2365
|
+
layer.setAttribute("aria-hidden", "true");
|
|
2366
|
+
Object.assign(layer.style, {
|
|
2367
|
+
position: "absolute",
|
|
2368
|
+
left: "0",
|
|
2369
|
+
top: "0",
|
|
2370
|
+
width: "0",
|
|
2371
|
+
height: "0",
|
|
2372
|
+
overflow: "hidden",
|
|
2373
|
+
pointerEvents: "none",
|
|
2374
|
+
zIndex: "1"
|
|
2375
|
+
});
|
|
2376
|
+
try {
|
|
2377
|
+
const pos = win?.getComputedStyle?.(container)?.position || container.style.position;
|
|
2378
|
+
if (!pos || pos === "static") {
|
|
2379
|
+
const was = container.style.position;
|
|
2380
|
+
container.style.position = "relative";
|
|
2381
|
+
if (glyphPositionWas === null) glyphPositionWas = was;
|
|
2382
|
+
}
|
|
2383
|
+
} catch {
|
|
2384
|
+
}
|
|
2385
|
+
container.appendChild(layer);
|
|
2386
|
+
}
|
|
2387
|
+
layer.style.width = "0";
|
|
2388
|
+
layer.style.height = "0";
|
|
2389
|
+
const sw = container.scrollWidth || 0, sh = container.scrollHeight || 0;
|
|
2390
|
+
layer.style.width = `${sw}px`;
|
|
2391
|
+
layer.style.height = `${sh}px`;
|
|
2392
|
+
glyphSize = sizeOfContainer();
|
|
2393
|
+
const centers = [];
|
|
2394
|
+
collectGlyphCentersWhere(container, layer.getBoundingClientRect(), centers, { shown: markShown, at: glyphWindows() });
|
|
2395
|
+
const hc = !!resolved.isHighContrast;
|
|
2396
|
+
const drawn = centers.length ? paintSelectionGlyphs(layer, centers, {
|
|
2397
|
+
symbol: mode === "check" ? "\u2713" : "\u25CF",
|
|
2398
|
+
color: hc ? resolved.themeFg || "#111" : "#111",
|
|
2399
|
+
halo: hc ? resolved.themeBg || "#fff" : "#fff"
|
|
2400
|
+
}) : 0;
|
|
2401
|
+
const said = `${mode}:${drawn}:${centers.length}`;
|
|
2402
|
+
if (report === true || report === "if-changed" && said !== glyphReported) {
|
|
2403
|
+
glyphReported = said;
|
|
2404
|
+
try {
|
|
2405
|
+
config.onSelectionGlyphs?.({ mode, drawn, total: centers.length, suppressed: false });
|
|
2406
|
+
} catch {
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
} catch {
|
|
2410
|
+
} finally {
|
|
2411
|
+
try {
|
|
2412
|
+
followGlyphs(follow);
|
|
2413
|
+
glyphObserver?.takeRecords();
|
|
2414
|
+
} catch {
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
};
|
|
2195
2418
|
const notify = (rowIdxs, source, tick, fromChart = false) => {
|
|
2196
2419
|
current = rowIdxs;
|
|
2197
2420
|
selectionFromChart = rowIdxs.length > 0 && fromChart;
|
|
2198
2421
|
activeTickEl = rowIdxs.length ? tick ?? null : null;
|
|
2199
2422
|
selectionIsPeriod = rowIdxs.length > 0 && periodTickSuppressesFeedback(!!tick, chartOwnsTimeline(container));
|
|
2200
2423
|
paintSelection();
|
|
2424
|
+
paintGlyphLayer();
|
|
2201
2425
|
for (const cb of subs) {
|
|
2202
2426
|
try {
|
|
2203
2427
|
cb(rowIdxs, source);
|
|
@@ -2395,6 +2619,7 @@ function createChartHost(container, config) {
|
|
|
2395
2619
|
drawAnnotations();
|
|
2396
2620
|
} catch {
|
|
2397
2621
|
}
|
|
2622
|
+
paintGlyphLayer();
|
|
2398
2623
|
try {
|
|
2399
2624
|
lasso = installLasso({
|
|
2400
2625
|
container,
|
|
@@ -2421,6 +2646,7 @@ function createChartHost(container, config) {
|
|
|
2421
2646
|
if (destroyed) return;
|
|
2422
2647
|
const seq2 = ++renderSeq;
|
|
2423
2648
|
stopAnim();
|
|
2649
|
+
followGlyphs(false);
|
|
2424
2650
|
disposeLasso();
|
|
2425
2651
|
flushZoom();
|
|
2426
2652
|
container.innerHTML = "";
|
|
@@ -2445,6 +2671,8 @@ function createChartHost(container, config) {
|
|
|
2445
2671
|
if (resolved.geoPoint === void 0 && data.geoPoint) resolved = { ...resolved, geoPoint: data.geoPoint };
|
|
2446
2672
|
if (resolved.geoPointDest === void 0 && data.geoPointDest) resolved = { ...resolved, geoPointDest: data.geoPointDest };
|
|
2447
2673
|
if (resolved.dateCellsAreUtcDays === void 0 && data.dateCellsAreUtcDays) resolved = { ...resolved, dateCellsAreUtcDays: true };
|
|
2674
|
+
if (resolved.suppressSelectionGlyph === void 0 && data.meta?.suppressSelectionGlyph === true)
|
|
2675
|
+
resolved = { ...resolved, suppressSelectionGlyph: true };
|
|
2448
2676
|
let outcome;
|
|
2449
2677
|
zoomCap = null;
|
|
2450
2678
|
if (zoomMemory && config.code && !config.renderFn) {
|
|
@@ -2580,10 +2808,25 @@ function createChartHost(container, config) {
|
|
|
2580
2808
|
clearPress(container);
|
|
2581
2809
|
disposeLasso();
|
|
2582
2810
|
subs.clear();
|
|
2811
|
+
if (dimVarSet) {
|
|
2812
|
+
try {
|
|
2813
|
+
container.style?.removeProperty(DIM_OPACITY_VAR);
|
|
2814
|
+
} catch {
|
|
2815
|
+
}
|
|
2816
|
+
dimVarSet = false;
|
|
2817
|
+
}
|
|
2583
2818
|
annotationLayer.destroy();
|
|
2584
2819
|
unpinScrolledAxis(container);
|
|
2585
2820
|
flushZoom();
|
|
2821
|
+
followGlyphs(false);
|
|
2586
2822
|
container.innerHTML = "";
|
|
2823
|
+
if (glyphPositionWas !== null) {
|
|
2824
|
+
try {
|
|
2825
|
+
if (container.style.position === "relative") container.style.position = glyphPositionWas;
|
|
2826
|
+
} catch {
|
|
2827
|
+
}
|
|
2828
|
+
glyphPositionWas = null;
|
|
2829
|
+
}
|
|
2587
2830
|
}
|
|
2588
2831
|
};
|
|
2589
2832
|
return host;
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SELECTION_RULE_ATTR,
|
|
9
9
|
SELECTION_RULE_CLICKED_MARKS,
|
|
10
10
|
XFILTER_REFRESH_EVENT
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YDHXOIAI.mjs";
|
|
12
12
|
|
|
13
13
|
// src/selection.ts
|
|
14
14
|
function rowIdxsFromMark(el) {
|
|
@@ -304,8 +304,12 @@ function createMarkResolver(env) {
|
|
|
304
304
|
return { isInvisibleStrokePath, distToPathCenterline, refineHitCorridor, findMark, rowIdxsFromMark, penetrateOverlayAt, resolveByGeometry };
|
|
305
305
|
}
|
|
306
306
|
function collectD3GlyphCenters(container, baseRect, out) {
|
|
307
|
+
collectGlyphCentersWhere(container, baseRect, out);
|
|
308
|
+
}
|
|
309
|
+
function collectGlyphCentersWhere(container, baseRect, out, filter) {
|
|
307
310
|
const Point = container.ownerDocument?.defaultView?.DOMPoint ?? globalThis.DOMPoint;
|
|
308
|
-
|
|
311
|
+
let marks = container.querySelectorAll(`.${MARK_CLASS}.${MARK_SELECTED_CLASS}`);
|
|
312
|
+
if (filter?.shown) marks = Array.from(marks).filter((m) => filter.shown(m));
|
|
309
313
|
const rects = [];
|
|
310
314
|
for (let i = 0; i < marks.length; i++) {
|
|
311
315
|
const r = marks[i].getBoundingClientRect();
|
|
@@ -385,6 +389,7 @@ function collectD3GlyphCenters(container, baseRect, out) {
|
|
|
385
389
|
sx = isRect ? r.left + r.width * 0.8 : r.left + r.width / 2;
|
|
386
390
|
sy = isRect ? r.top + r.height * 0.2 : r.top + r.height / 2;
|
|
387
391
|
}
|
|
392
|
+
if (filter?.at && !filter.at(el, sx, sy)) continue;
|
|
388
393
|
out.push({ x: sx - baseRect.left, y: sy - baseRect.top });
|
|
389
394
|
}
|
|
390
395
|
}
|
|
@@ -439,6 +444,7 @@ export {
|
|
|
439
444
|
clickWasDrag,
|
|
440
445
|
createMarkResolver,
|
|
441
446
|
collectD3GlyphCenters,
|
|
447
|
+
collectGlyphCentersWhere,
|
|
442
448
|
SELECTION_GLYPH_CLASS,
|
|
443
449
|
clearSelectionGlyphs,
|
|
444
450
|
paintSelectionGlyphs
|
|
@@ -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-OG6RR2AJ.mjs";
|
|
5
5
|
|
|
6
6
|
// src/filterScope.ts
|
|
7
7
|
function viewToken(view) {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
gestureWasDrag,
|
|
5
5
|
isInsideControl,
|
|
6
6
|
rowIdxsFromMark
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DJ5IJV57.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-YDHXOIAI.mjs";
|
|
16
16
|
|
|
17
17
|
// src/lasso.ts
|
|
18
18
|
var LASSO_ROW_CAP = 5e3;
|
|
@@ -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-YDHXOIAI.mjs";
|
|
5
5
|
|
|
6
6
|
// src/fit.ts
|
|
7
7
|
var SCROLL_SLACK_PX = 8;
|
|
@@ -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-YDHXOIAI.mjs";
|
|
5
5
|
|
|
6
6
|
// src/snapshot.ts
|
|
7
7
|
var DEFAULT_TIMEOUT_MS = 2e3;
|
|
@@ -34,6 +34,7 @@ var MARK_SELECTED_CLASS = "lch-mark-selected";
|
|
|
34
34
|
var ACTIVE_TICK_CLASS = "lch-tick-active";
|
|
35
35
|
var DIM_OPACITY_VAR = "--lch-dim-opacity";
|
|
36
36
|
var DIM_OPACITY_DEFAULT = 0.25;
|
|
37
|
+
var DIM_OPACITY_MIN = 0.01;
|
|
37
38
|
function chartOwnsTimeline(container) {
|
|
38
39
|
return !!container && (!!container[CONTAINER_SLOT_XF_CLEAR] || !!container[CONTAINER_SLOT_ANIM_STOP]);
|
|
39
40
|
}
|
|
@@ -97,6 +98,7 @@ export {
|
|
|
97
98
|
ACTIVE_TICK_CLASS,
|
|
98
99
|
DIM_OPACITY_VAR,
|
|
99
100
|
DIM_OPACITY_DEFAULT,
|
|
101
|
+
DIM_OPACITY_MIN,
|
|
100
102
|
chartOwnsTimeline,
|
|
101
103
|
periodTickSuppressesFeedback,
|
|
102
104
|
ANIM_PLAY_SPEED_DEFAULT,
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
svgNaturalSize,
|
|
16
16
|
svgToDataUrl,
|
|
17
17
|
tableHostOf
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-UBB5LNH4.mjs";
|
|
19
19
|
import {
|
|
20
20
|
ANNOTATION_CLASS,
|
|
21
21
|
ANNOTATION_LAYER_CLASS,
|
|
@@ -97,7 +97,7 @@ import {
|
|
|
97
97
|
toRGBA,
|
|
98
98
|
toSourceRows,
|
|
99
99
|
valuePlacementFlag
|
|
100
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-562LF7XM.mjs";
|
|
101
101
|
import {
|
|
102
102
|
LASSO_AXES_SLOT,
|
|
103
103
|
LASSO_COUNT_CLASS,
|
|
@@ -122,13 +122,13 @@ import {
|
|
|
122
122
|
lassoVerdict,
|
|
123
123
|
pointInShape,
|
|
124
124
|
registerLassoAction
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-OG6RR2AJ.mjs";
|
|
126
126
|
import {
|
|
127
127
|
MIN_HIT_BAND_PX,
|
|
128
128
|
censusHitBands,
|
|
129
129
|
ensureCrossfilterHitTargets,
|
|
130
130
|
hitBandFlag
|
|
131
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-XNS34AMM.mjs";
|
|
132
132
|
import {
|
|
133
133
|
CONTAINER_SLOT_PRESS_AT,
|
|
134
134
|
DRAG_NOT_CLICK_PX,
|
|
@@ -153,7 +153,7 @@ import {
|
|
|
153
153
|
selectionRuleOf,
|
|
154
154
|
trackPress,
|
|
155
155
|
validRowSet
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-DJ5IJV57.mjs";
|
|
157
157
|
import {
|
|
158
158
|
AXIS_PIN_BAND_PAD_PX,
|
|
159
159
|
AXIS_PIN_MAX_BAND_FRACTION,
|
|
@@ -179,7 +179,7 @@ import {
|
|
|
179
179
|
scrollFitFor,
|
|
180
180
|
svgInkReach,
|
|
181
181
|
unpinScrolledAxis
|
|
182
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-QHIPRAZK.mjs";
|
|
183
183
|
import {
|
|
184
184
|
_3,
|
|
185
185
|
l,
|
|
@@ -209,6 +209,7 @@ import {
|
|
|
209
209
|
CONTAINER_SLOT_XF_CLEAR,
|
|
210
210
|
CONTROL_CLASS,
|
|
211
211
|
DIM_OPACITY_DEFAULT,
|
|
212
|
+
DIM_OPACITY_MIN,
|
|
212
213
|
DIM_OPACITY_VAR,
|
|
213
214
|
FLIP_DIRECTION_DEFAULT,
|
|
214
215
|
FLIP_INTERVAL_MAX_MS,
|
|
@@ -236,7 +237,7 @@ import {
|
|
|
236
237
|
chartOwnsTimeline,
|
|
237
238
|
periodTickSuppressesFeedback,
|
|
238
239
|
withoutViewOnlyKeys
|
|
239
|
-
} from "./chunk-
|
|
240
|
+
} from "./chunk-YDHXOIAI.mjs";
|
|
240
241
|
import "./chunk-GHODWOAL.mjs";
|
|
241
242
|
|
|
242
243
|
// src/optionsVocabulary.ts
|
|
@@ -2161,6 +2162,7 @@ export {
|
|
|
2161
2162
|
DEFAULT_FILTER_MATCH_STYLE,
|
|
2162
2163
|
DEFAULT_MODEL_SUFFIX,
|
|
2163
2164
|
DIM_OPACITY_DEFAULT,
|
|
2165
|
+
DIM_OPACITY_MIN,
|
|
2164
2166
|
DIM_OPACITY_VAR,
|
|
2165
2167
|
DRAG_NOT_CLICK_PX,
|
|
2166
2168
|
DUPLICATE_GENERATE_WINDOW_MS,
|
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-UBB5LNH4.mjs";
|
|
6
6
|
import {
|
|
7
7
|
FIT_CONTENT_SELECTOR,
|
|
8
8
|
ctmScaleOf,
|
|
9
9
|
isPhantomBox
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-QHIPRAZK.mjs";
|
|
11
|
+
import "./chunk-YDHXOIAI.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-GOIG756B.mjs";
|
|
18
|
+
import "./chunk-OG6RR2AJ.mjs";
|
|
19
|
+
import "./chunk-DJ5IJV57.mjs";
|
|
20
|
+
import "./chunk-YDHXOIAI.mjs";
|
|
21
21
|
import "./chunk-GHODWOAL.mjs";
|
|
22
22
|
export {
|
|
23
23
|
LINKED_HOVER_CLASS,
|
package/dist/react.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
payloadRowReader,
|
|
14
14
|
viewFromToken,
|
|
15
15
|
viewToken
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GOIG756B.mjs";
|
|
17
17
|
import {
|
|
18
18
|
assembleD3,
|
|
19
19
|
createChartGroup,
|
|
@@ -22,14 +22,14 @@ import {
|
|
|
22
22
|
loadGeo,
|
|
23
23
|
syncMemberSelection,
|
|
24
24
|
toSourceRows
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-562LF7XM.mjs";
|
|
26
|
+
import "./chunk-OG6RR2AJ.mjs";
|
|
27
|
+
import "./chunk-XNS34AMM.mjs";
|
|
28
|
+
import "./chunk-DJ5IJV57.mjs";
|
|
29
|
+
import "./chunk-QHIPRAZK.mjs";
|
|
30
30
|
import "./chunk-KQN5C7SZ.mjs";
|
|
31
31
|
import "./chunk-A2GMXZP7.mjs";
|
|
32
|
-
import "./chunk-
|
|
32
|
+
import "./chunk-YDHXOIAI.mjs";
|
|
33
33
|
import "./chunk-GHODWOAL.mjs";
|
|
34
34
|
|
|
35
35
|
// src/react.tsx
|
|
@@ -70,6 +70,7 @@ function BicChart(props) {
|
|
|
70
70
|
zoomMemory,
|
|
71
71
|
labelContrast,
|
|
72
72
|
onLabelContrast,
|
|
73
|
+
onSelectionGlyphs,
|
|
73
74
|
layoutPass,
|
|
74
75
|
onInvalidSentinel,
|
|
75
76
|
id,
|
|
@@ -116,6 +117,8 @@ function BicChart(props) {
|
|
|
116
117
|
onSelectRef.current = onSelect;
|
|
117
118
|
const onLabelContrastRef = useRef(onLabelContrast);
|
|
118
119
|
onLabelContrastRef.current = onLabelContrast;
|
|
120
|
+
const onSelectionGlyphsRef = useRef(onSelectionGlyphs);
|
|
121
|
+
onSelectionGlyphsRef.current = onSelectionGlyphs;
|
|
119
122
|
const onInvalidSentinelRef = useRef(onInvalidSentinel);
|
|
120
123
|
onInvalidSentinelRef.current = onInvalidSentinel;
|
|
121
124
|
const onAnnotationClickRef = useRef(onAnnotationClick);
|
|
@@ -155,6 +158,7 @@ function BicChart(props) {
|
|
|
155
158
|
labelContrast,
|
|
156
159
|
layoutPass,
|
|
157
160
|
onLabelContrast: (r) => onLabelContrastRef.current?.(r),
|
|
161
|
+
onSelectionGlyphs: (r) => onSelectionGlyphsRef.current?.(r),
|
|
158
162
|
// A GETTER, not a wrapper: the host decides whether to
|
|
159
163
|
// swallow the sentinel throw by whether this is SET, so
|
|
160
164
|
// an always-present wrapper would hide the throw from a
|
package/dist/testing.mjs
CHANGED
package/dist/types/contract.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare const MARK_SELECTED_CLASS = "lch-mark-selected";
|
|
|
72
72
|
export declare const ACTIVE_TICK_CLASS = "lch-tick-active";
|
|
73
73
|
export declare const DIM_OPACITY_VAR = "--lch-dim-opacity";
|
|
74
74
|
export declare const DIM_OPACITY_DEFAULT = 0.25;
|
|
75
|
+
export declare const DIM_OPACITY_MIN = 0.01;
|
|
75
76
|
export declare function chartOwnsTimeline(container: any): boolean;
|
|
76
77
|
export declare function periodTickSuppressesFeedback(isAxisTick: boolean, ownsTimeline: boolean): boolean;
|
|
77
78
|
export declare const ANIM_PLAY_SPEED_DEFAULT = 1000;
|
|
@@ -159,6 +160,13 @@ export interface RenderOptions {
|
|
|
159
160
|
cultureCode?: string;
|
|
160
161
|
allowTooltips?: boolean;
|
|
161
162
|
noDataText?: string;
|
|
163
|
+
/** How far a selection dims the marks outside it, as a share of full opacity (DIM_OPACITY_MIN-1). Absent: the
|
|
164
|
+
* stylesheet decides - DIM_OPACITY_DEFAULT, or whatever the page sets on --lch-dim-opacity. */
|
|
165
|
+
dimOpacity?: number;
|
|
166
|
+
/** A small glyph on each selected mark: "dot" or "check". Absent or "none": no glyph (the default). */
|
|
167
|
+
selectionGlyph?: "none" | "dot" | "check";
|
|
168
|
+
/** A host FACT from the generate answer: this chart's family never takes a selection glyph. */
|
|
169
|
+
suppressSelectionGlyph?: boolean;
|
|
162
170
|
animAutoPlay?: boolean;
|
|
163
171
|
animPlaySpeedMs?: number;
|
|
164
172
|
animLoopDelaySec?: number;
|
package/dist/types/host.d.ts
CHANGED
|
@@ -62,6 +62,9 @@ export interface ChartHostConfig {
|
|
|
62
62
|
meta?: {
|
|
63
63
|
hostContract?: string;
|
|
64
64
|
chart?: string;
|
|
65
|
+
/** The generate answer's fact that this chart's family never takes a selection glyph. Promoted into
|
|
66
|
+
* options.suppressSelectionGlyph, so a host that hands over the whole payload honors it unasked. */
|
|
67
|
+
suppressSelectionGlyph?: boolean;
|
|
65
68
|
};
|
|
66
69
|
};
|
|
67
70
|
/** Generated render() source — compiled exactly like the visual/preview/exec-gate. */
|
|
@@ -199,6 +202,18 @@ export interface ChartHostConfig {
|
|
|
199
202
|
labelContrast?: boolean | LabelContrastOptions;
|
|
200
203
|
/** What the label-contrast pass did after each render - counts, so a host can log them. */
|
|
201
204
|
onLabelContrast?: (report: LabelContrastReport) => void;
|
|
205
|
+
/**
|
|
206
|
+
* What the selection-glyph pass did after each paint of an active selection - counts, so a host can log them.
|
|
207
|
+
* Called only when options.selectionGlyph is "dot" or "check"; `suppressed` is true when the chart's family never
|
|
208
|
+
* takes a glyph (options.suppressSelectionGlyph, or the same fact in data.meta). A repaint that only follows marks
|
|
209
|
+
* moving without a render (a pan, a transition) is not reported again.
|
|
210
|
+
*/
|
|
211
|
+
onSelectionGlyphs?: (report: {
|
|
212
|
+
mode: "dot" | "check";
|
|
213
|
+
drawn: number;
|
|
214
|
+
total: number;
|
|
215
|
+
suppressed: boolean;
|
|
216
|
+
}) => void;
|
|
202
217
|
/**
|
|
203
218
|
* A LAYOUT PASS the host brings, run after every render (both the synchronous and the promise lane, and every
|
|
204
219
|
* setOptions / setData re-render) AFTER the label-contrast pass and BEFORE the hit-target heal, the selection
|
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, 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, VIEW_ONLY_UI_STATE_KEYS, withoutViewOnlyKeys, HOST_CONTAINER_CLASS, SELECTION_ACTIVE_CLASS, MARK_SELECTED_CLASS, ACTIVE_TICK_CLASS, DIM_OPACITY_VAR, DIM_OPACITY_DEFAULT, 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, } 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, 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, 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, } from "./contract";
|
|
2
2
|
export { resolveOptions, type ResolveOptionsInput } from "./defaults";
|
|
3
3
|
export { OPTIONS_VOCABULARY, LIVE_OPTION_KEYS, MAX_MAP_POINTS_MIN, MAX_MAP_POINTS_MAX, LIMIT_COUNT_MAX, wireLimitCount, codeReadsOption, type OptionVocabularyEntry, type OptionTiming, type OptionWire, type OptionKey, } from "./optionsVocabulary";
|
|
4
4
|
export { loadGeo, geoFromCache, registerGeo, registerGeoAsset, geoAssetFor, clearGeoCache, type GeoAssetName, } from "./geoLazy";
|
package/dist/types/react.d.ts
CHANGED
|
@@ -48,6 +48,9 @@ export interface BicChartProps {
|
|
|
48
48
|
labelContrast?: ChartHostConfig["labelContrast"];
|
|
49
49
|
/** What the label-contrast pass did after each render - counts, for a page that logs. */
|
|
50
50
|
onLabelContrast?: ChartHostConfig["onLabelContrast"];
|
|
51
|
+
/** What the selection-glyph pass did after each paint, when `options.selectionGlyph` is set - counts, for a page
|
|
52
|
+
* that logs. The glyph itself, the dim level and the suppression fact ride the `options` prop. */
|
|
53
|
+
onSelectionGlyphs?: ChartHostConfig["onSelectionGlyphs"];
|
|
51
54
|
/**
|
|
52
55
|
* A LAYOUT PASS run after every render, after label contrast and before the fit - e.g.
|
|
53
56
|
* `createLegendFitPass()` from "@bicharts/chart-host/legend-fit", which slides a legend clear of
|
|
@@ -169,6 +169,18 @@ export declare function collectD3GlyphCenters(container: Element, baseRect: {
|
|
|
169
169
|
left: number;
|
|
170
170
|
top: number;
|
|
171
171
|
}, out: GlyphCenter[]): void;
|
|
172
|
+
/** Which selected marks get a glyph, for a host that draws its own layer: `shown` drops a mark before anything is
|
|
173
|
+
* measured against it (a mark the reader can't see), `at` drops one by where its glyph would go, in client
|
|
174
|
+
* coordinates (a mark panned or zoomed out of its plot). Either absent keeps every mark. */
|
|
175
|
+
export interface GlyphCenterFilter {
|
|
176
|
+
shown?(mark: Element): boolean;
|
|
177
|
+
at?(mark: Element, clientX: number, clientY: number): boolean;
|
|
178
|
+
}
|
|
179
|
+
/** collectD3GlyphCenters with a filter. Package-internal: the exported function keeps every mark, as it always has. */
|
|
180
|
+
export declare function collectGlyphCentersWhere(container: Element, baseRect: {
|
|
181
|
+
left: number;
|
|
182
|
+
top: number;
|
|
183
|
+
}, out: GlyphCenter[], filter?: GlyphCenterFilter): void;
|
|
172
184
|
/** The class every painted selection glyph carries. */
|
|
173
185
|
export declare const SELECTION_GLYPH_CLASS = "lch-sel-glyph";
|
|
174
186
|
/** Removes every glyph (every child) from the overlay. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.89",
|
|
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",
|