@bicharts/chart-host 0.6.61 → 0.6.62
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.
|
@@ -3830,6 +3830,47 @@ function applyLabelContrast(container, opts = {}) {
|
|
|
3830
3830
|
}
|
|
3831
3831
|
}
|
|
3832
3832
|
|
|
3833
|
+
// src/idScope.ts
|
|
3834
|
+
var seq = 0;
|
|
3835
|
+
function newIdScope() {
|
|
3836
|
+
seq += 1;
|
|
3837
|
+
return "h" + seq;
|
|
3838
|
+
}
|
|
3839
|
+
var URL_REF = /url\(\s*(['"]?)#([^'")\s]+)\1\s*\)/g;
|
|
3840
|
+
function scopeChartIds(container, scope) {
|
|
3841
|
+
const report = { renamed: 0, collisions: [] };
|
|
3842
|
+
try {
|
|
3843
|
+
const tag = "--" + scope, doc = container.ownerDocument, map = /* @__PURE__ */ new Map();
|
|
3844
|
+
const refs = [], used = /* @__PURE__ */ new Set();
|
|
3845
|
+
container.querySelectorAll("*").forEach((el) => {
|
|
3846
|
+
for (const a3 of el.getAttributeNames()) {
|
|
3847
|
+
const v = el.getAttribute(a3);
|
|
3848
|
+
const href = (a3 === "href" || a3 === "xlink:href") && v[0] === "#";
|
|
3849
|
+
if (!href && v.indexOf("url(") < 0) continue;
|
|
3850
|
+
refs.push([el, a3, v]);
|
|
3851
|
+
if (href) used.add(v.slice(1));
|
|
3852
|
+
for (const m4 of v.matchAll(URL_REF)) used.add(m4[2]);
|
|
3853
|
+
}
|
|
3854
|
+
});
|
|
3855
|
+
container.querySelectorAll("[id]").forEach((el) => {
|
|
3856
|
+
const id = el.id;
|
|
3857
|
+
if (!used.has(id) || id.endsWith(tag) || id.startsWith("bic-")) return;
|
|
3858
|
+
const q2 = id.replace(/["\\]/g, "\\$&");
|
|
3859
|
+
if (doc && Array.from(doc.querySelectorAll(`[id="${q2}"],[id^="${q2}--h"]`)).some((o4) => !container.contains(o4))) {
|
|
3860
|
+
report.collisions.push(id);
|
|
3861
|
+
}
|
|
3862
|
+
map.set(id, el.id = id + tag);
|
|
3863
|
+
report.renamed++;
|
|
3864
|
+
});
|
|
3865
|
+
for (const [el, a3, v] of refs) {
|
|
3866
|
+
const nv = v[0] === "#" && map.has(v.slice(1)) ? "#" + map.get(v.slice(1)) : v.replace(URL_REF, (m4, q2, id) => map.has(id) ? `url(${q2}#${map.get(id)}${q2})` : m4);
|
|
3867
|
+
if (nv !== v) el.setAttribute(a3, nv);
|
|
3868
|
+
}
|
|
3869
|
+
} catch {
|
|
3870
|
+
}
|
|
3871
|
+
return report;
|
|
3872
|
+
}
|
|
3873
|
+
|
|
3833
3874
|
// src/invalidSentinel.ts
|
|
3834
3875
|
function isInvalidSentinelError(text2) {
|
|
3835
3876
|
if (!text2) return false;
|
|
@@ -4136,6 +4177,8 @@ function createChartHost(container, config) {
|
|
|
4136
4177
|
let destroyed = false;
|
|
4137
4178
|
let warnedGeo = false;
|
|
4138
4179
|
let warnedBlank = false;
|
|
4180
|
+
let warnedIds = false;
|
|
4181
|
+
const idScope = newIdScope();
|
|
4139
4182
|
let renderSeq = 0;
|
|
4140
4183
|
const annotationLayer = createAnnotationLayer(container, (a3) => config.onAnnotationClick?.(a3));
|
|
4141
4184
|
const drawAnnotations = () => annotationLayer.draw(
|
|
@@ -4307,6 +4350,20 @@ function createChartHost(container, config) {
|
|
|
4307
4350
|
}
|
|
4308
4351
|
};
|
|
4309
4352
|
const runPostRenderPasses = () => {
|
|
4353
|
+
try {
|
|
4354
|
+
const r2 = scopeChartIds(container, idScope);
|
|
4355
|
+
if (r2.collisions.length && !warnedIds) {
|
|
4356
|
+
warnedIds = true;
|
|
4357
|
+
try {
|
|
4358
|
+
(win?.console ?? console)?.warn(
|
|
4359
|
+
`[@bicharts/chart-host] this chart named ${r2.collisions.length} id(s) another element on the page already uses (${r2.collisions.slice(0, 5).join(", ")}). They were scoped to this chart, so its clip paths and gradients resolve to its own definitions.`
|
|
4360
|
+
);
|
|
4361
|
+
} catch {
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
config.onIdScope?.(r2);
|
|
4365
|
+
} catch {
|
|
4366
|
+
}
|
|
4310
4367
|
if (labelContrastOpts !== false) {
|
|
4311
4368
|
try {
|
|
4312
4369
|
const lc = labelContrastOpts === true ? {} : { ...labelContrastOpts };
|
|
@@ -4386,7 +4443,7 @@ function createChartHost(container, config) {
|
|
|
4386
4443
|
const host = {
|
|
4387
4444
|
render() {
|
|
4388
4445
|
if (destroyed) return;
|
|
4389
|
-
const
|
|
4446
|
+
const seq2 = ++renderSeq;
|
|
4390
4447
|
stopAnim();
|
|
4391
4448
|
container.innerHTML = "";
|
|
4392
4449
|
if (!renderFn) {
|
|
@@ -4439,7 +4496,7 @@ function createChartHost(container, config) {
|
|
|
4439
4496
|
};
|
|
4440
4497
|
Promise.resolve(outcome).then(
|
|
4441
4498
|
() => done(() => {
|
|
4442
|
-
if (destroyed ||
|
|
4499
|
+
if (destroyed || seq2 !== renderSeq) {
|
|
4443
4500
|
resolve();
|
|
4444
4501
|
return;
|
|
4445
4502
|
}
|
|
@@ -4447,7 +4504,7 @@ function createChartHost(container, config) {
|
|
|
4447
4504
|
resolve();
|
|
4448
4505
|
}),
|
|
4449
4506
|
(err) => done(() => {
|
|
4450
|
-
if (destroyed ||
|
|
4507
|
+
if (destroyed || seq2 !== renderSeq) {
|
|
4451
4508
|
resolve();
|
|
4452
4509
|
return;
|
|
4453
4510
|
}
|
|
@@ -4773,6 +4830,8 @@ export {
|
|
|
4773
4830
|
LABEL_CONTRAST_CAP,
|
|
4774
4831
|
LABEL_PILL_CLASS,
|
|
4775
4832
|
applyLabelContrast,
|
|
4833
|
+
newIdScope,
|
|
4834
|
+
scopeChartIds,
|
|
4776
4835
|
isInvalidSentinelError,
|
|
4777
4836
|
invalidSentinelReason,
|
|
4778
4837
|
ANNOTATION_LAYER_CLASS,
|
package/dist/index.mjs
CHANGED
|
@@ -91,6 +91,7 @@ import {
|
|
|
91
91
|
measureContainerBoxes,
|
|
92
92
|
minContrastOver,
|
|
93
93
|
needsScroll,
|
|
94
|
+
newIdScope,
|
|
94
95
|
nextSelection,
|
|
95
96
|
noopViewStateProvider,
|
|
96
97
|
o,
|
|
@@ -108,6 +109,7 @@ import {
|
|
|
108
109
|
resolveAutoColorScale,
|
|
109
110
|
resolveOptions,
|
|
110
111
|
rowIdxsFromMark,
|
|
112
|
+
scopeChartIds,
|
|
111
113
|
scrollFitFor,
|
|
112
114
|
sessionViewStateProvider,
|
|
113
115
|
straddleSampleGrid,
|
|
@@ -120,7 +122,7 @@ import {
|
|
|
120
122
|
toSourceRows,
|
|
121
123
|
unpinScrolledAxis,
|
|
122
124
|
valuePlacementFlag
|
|
123
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-ZLJM3EIP.mjs";
|
|
124
126
|
import "./chunk-A2GMXZP7.mjs";
|
|
125
127
|
import {
|
|
126
128
|
ACTIVE_TICK_CLASS,
|
|
@@ -3008,6 +3010,7 @@ export {
|
|
|
3008
3010
|
minContrastOver,
|
|
3009
3011
|
mountProductFeedbackBox,
|
|
3010
3012
|
needsScroll,
|
|
3013
|
+
newIdScope,
|
|
3011
3014
|
newQualifyGroupState,
|
|
3012
3015
|
newQualifyRefusalGroupState,
|
|
3013
3016
|
nextSelection,
|
|
@@ -3058,6 +3061,7 @@ export {
|
|
|
3058
3061
|
resolveOptions,
|
|
3059
3062
|
rowIdxsFromMark,
|
|
3060
3063
|
sameMarker,
|
|
3064
|
+
scopeChartIds,
|
|
3061
3065
|
scrollFitFor,
|
|
3062
3066
|
servedCorrelationProves,
|
|
3063
3067
|
sessionViewStateProvider,
|
package/dist/react.mjs
CHANGED
package/dist/types/host.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type ColourSpreadCensus } from "./colourSpread";
|
|
|
6
6
|
import { type ValuePlacementCensus } from "./valuePlacement";
|
|
7
7
|
import { type FitRenderedChartOptions, type FitRenderedChartResult } from "./fitDom";
|
|
8
8
|
import { type LabelContrastOptions, type LabelContrastReport } from "./labelContrastDom";
|
|
9
|
+
import { type IdScopeReport } from "./idScope";
|
|
9
10
|
import { type MarkAnnotation, type AnnotationReport } from "./annotations";
|
|
10
11
|
export type RenderFn = (container: HTMLElement, data: any, options: RenderOptions) => void;
|
|
11
12
|
/**
|
|
@@ -166,6 +167,11 @@ export interface ChartHostConfig {
|
|
|
166
167
|
labelContrast?: boolean | LabelContrastOptions;
|
|
167
168
|
/** What the label-contrast pass did after each render - counts, so a host can log them. */
|
|
168
169
|
onLabelContrast?: (report: LabelContrastReport) => void;
|
|
170
|
+
/**
|
|
171
|
+
* What the id-scoping pass did after each render: how many of the chart's ids got this host's suffix, and which
|
|
172
|
+
* of them also existed elsewhere in the page (a clash it prevented - two same-size charts naming one clip path).
|
|
173
|
+
*/
|
|
174
|
+
onIdScope?: (report: IdScopeReport) => void;
|
|
169
175
|
/**
|
|
170
176
|
* THE CHART SAID THE DATA LACKS SOMETHING IT IS BUILT ON. Generated code has one sanctioned
|
|
171
177
|
* hard stop at runtime: a column the chart needs is gone from `data.columns`, and it throws
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** A fresh suffix for one chart host. Unique within the page for the page's lifetime. */
|
|
2
|
+
export declare function newIdScope(): string;
|
|
3
|
+
export interface IdScopeReport {
|
|
4
|
+
/** How many ids were given the suffix. */
|
|
5
|
+
renamed: number;
|
|
6
|
+
/** Ids that also existed outside this chart when the pass ran - each one a clash this pass prevented. */
|
|
7
|
+
collisions: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function scopeChartIds(container: Element, scope: string): IdScopeReport;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export { formatSourceDate, formatSourceDateFor, isExcelDateFormat, type SourceFo
|
|
|
27
27
|
export { composeSummaryText } from "./summaryText";
|
|
28
28
|
export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
|
|
29
29
|
export { applyLabelContrast, LABEL_CONTRAST_DONE_ATTR, LABEL_CONTRAST_CAP, LABEL_PILL_CLASS, type LabelContrastOptions, type LabelContrastReport, } from "./labelContrastDom";
|
|
30
|
+
export { scopeChartIds, newIdScope, type IdScopeReport } from "./idScope";
|
|
30
31
|
export { decideLabelColor, toRGBA, compositeOver, relativeLuminance, contrastRatio, isPillBackdropAlpha, pillBacksGlyph, backingHoldsGlyph, cellSuppressesNormalize, glyphSampleGrid, DARK_TEXT, LIGHT_TEXT, MIN_CONTRAST, WHITE_TEXT_BG_LUM, PILL_MIN_ALPHA, PILL_OPAQUE_ALPHA, PILL_MIN_COVERAGE, PAGE_MATCH_TOLERANCE, BACKING_MAJORITY, GLYPH_SAMPLE_N, straddles, straddleSampleGrid, minContrastOver, pickColorOver, STRADDLE_COLS, STRADDLE_ROWS, STRADDLE_MIN_SHARE, STRADDLE_TARGET_CONTRAST, STRADDLE_PILL_ALPHA, type LabelDecision, } from "./labelContrast";
|
|
31
32
|
export { censusMarks, isBlankRender, blankRenderFlag, type MarkCensus, type BlankVerdictInput } from "./blankRender";
|
|
32
33
|
export { isInvalidSentinelError, invalidSentinelReason } from "./invalidSentinel";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.62",
|
|
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",
|