@bicharts/chart-host 0.6.113 → 0.6.116
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 +94 -5
- package/dist/adapters.mjs +3 -3
- package/dist/card.mjs +2 -2
- package/dist/category-colours.mjs +275 -0
- package/dist/{chunk-7XT5OJ6M.mjs → chunk-63IUMWY2.mjs} +40 -3
- package/dist/{chunk-AEO5SFEQ.mjs → chunk-EFKGSDFF.mjs} +1 -1
- package/dist/{chunk-TE54AFRN.mjs → chunk-GZSYTDFN.mjs} +531 -393
- package/dist/{chunk-PELRAFYZ.mjs → chunk-IW6BKFF5.mjs} +1 -1
- package/dist/{chunk-OLCUKXKL.mjs → chunk-JMLSNV5Q.mjs} +1 -1
- package/dist/chunk-JTZTTJJK.mjs +244 -0
- package/dist/{chunk-FIG5DIW7.mjs → chunk-K2TH7D5V.mjs} +335 -335
- package/dist/{chunk-KY4FI2HA.mjs → chunk-QG5TENI3.mjs} +5 -1
- package/dist/{chunk-KGVNZR23.mjs → chunk-RLOIA7QK.mjs} +1 -1
- package/dist/{chunk-IL5M7K6Z.mjs → chunk-TUZCM7SX.mjs} +2 -2
- package/dist/{chunk-GTJG3SMD.mjs → chunk-VGJH63LZ.mjs} +1 -1
- package/dist/{chunk-2KLFIGTQ.mjs → chunk-ZZBX5ZJ6.mjs} +145 -18
- package/dist/dax.mjs +23 -1
- package/dist/index.mjs +97 -16
- package/dist/legend-fit.mjs +3 -3
- package/dist/page.mjs +7 -5
- package/dist/provinces.mjs +4 -4
- package/dist/react.mjs +18 -14
- package/dist/testing.mjs +1 -1
- package/dist/types/categoryColours.d.ts +71 -0
- package/dist/types/contract.d.ts +16 -3
- package/dist/types/dax.d.ts +26 -0
- package/dist/types/filterScope.d.ts +52 -4
- package/dist/types/fit.d.ts +6 -1
- package/dist/types/fitDom.d.ts +13 -0
- package/dist/types/host.d.ts +19 -5
- package/dist/types/index.d.ts +7 -4
- package/dist/types/keyboardMarks.d.ts +1 -1
- package/dist/types/markFollower.d.ts +21 -0
- package/dist/types/page.d.ts +1 -1
- package/dist/types/qualifyTable.d.ts +52 -0
- package/dist/types/react.d.ts +11 -3
- package/dist/types/selectionMarker.d.ts +92 -0
- package/dist/zoom-memory.mjs +1 -1
- package/package.json +6 -1
- /package/dist/{chunk-5YSZABCS.mjs → chunk-LXTW6YII.mjs} +0 -0
|
@@ -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.24.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";
|
|
@@ -22,6 +22,7 @@ var CONTAINER_SLOT_XF_CLEAR = "__llmXfClear";
|
|
|
22
22
|
var CONTAINER_SLOT_INITIAL_XF_MARK = "__llmInitialXfMark";
|
|
23
23
|
var CONTAINER_SLOT_UI_STATE = "__lchUiState";
|
|
24
24
|
var CONTAINER_SLOT_SCROLL = "__lchScroll";
|
|
25
|
+
var TABLE_SCROLLER_CLASS = "lch-table-body";
|
|
25
26
|
var CONTAINER_SLOT_CLICKED_MARKS = "__lchClickedMarks";
|
|
26
27
|
var VIEW_ONLY_UI_STATE_KEYS = Object.freeze(["camera", "llmZoom"]);
|
|
27
28
|
function withoutViewOnlyKeys(bag) {
|
|
@@ -39,6 +40,7 @@ var ACTIVE_TICK_CLASS = "lch-tick-active";
|
|
|
39
40
|
var DIM_OPACITY_VAR = "--lch-dim-opacity";
|
|
40
41
|
var DIM_OPACITY_DEFAULT = 0.25;
|
|
41
42
|
var DIM_OPACITY_MIN = 0.01;
|
|
43
|
+
var CATEGORY_DELTA_E_FLOOR = 25;
|
|
42
44
|
function chartOwnsTimeline(container) {
|
|
43
45
|
return !!container && (!!container[CONTAINER_SLOT_XF_CLEAR] || !!container[CONTAINER_SLOT_ANIM_STOP]);
|
|
44
46
|
}
|
|
@@ -96,6 +98,7 @@ export {
|
|
|
96
98
|
CONTAINER_SLOT_INITIAL_XF_MARK,
|
|
97
99
|
CONTAINER_SLOT_UI_STATE,
|
|
98
100
|
CONTAINER_SLOT_SCROLL,
|
|
101
|
+
TABLE_SCROLLER_CLASS,
|
|
99
102
|
CONTAINER_SLOT_CLICKED_MARKS,
|
|
100
103
|
VIEW_ONLY_UI_STATE_KEYS,
|
|
101
104
|
withoutViewOnlyKeys,
|
|
@@ -107,6 +110,7 @@ export {
|
|
|
107
110
|
DIM_OPACITY_VAR,
|
|
108
111
|
DIM_OPACITY_DEFAULT,
|
|
109
112
|
DIM_OPACITY_MIN,
|
|
113
|
+
CATEGORY_DELTA_E_FLOOR,
|
|
110
114
|
chartOwnsTimeline,
|
|
111
115
|
periodTickSuppressesFeedback,
|
|
112
116
|
ANIM_PLAY_SPEED_DEFAULT,
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
gestureWasDrag,
|
|
5
5
|
isInsideControl,
|
|
6
6
|
rowIdxsFromMark
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RLOIA7QK.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-QG5TENI3.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
|
LASSO_KNOB_KEY
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TUZCM7SX.mjs";
|
|
5
5
|
|
|
6
6
|
// src/controls.ts
|
|
7
7
|
var isKnob = (key) => key !== LASSO_KNOB_KEY;
|
|
@@ -43,6 +43,11 @@ function toKeys(input, width) {
|
|
|
43
43
|
return input.length === width ? [input.slice()] : [];
|
|
44
44
|
}
|
|
45
45
|
var nextId = 0;
|
|
46
|
+
var peersOf = /* @__PURE__ */ new WeakMap();
|
|
47
|
+
var pickSubsOf = /* @__PURE__ */ new WeakMap();
|
|
48
|
+
var firePick = (f) => {
|
|
49
|
+
for (const m of Array.from(peersOf.get(f) ?? [f])) for (const cb of Array.from(pickSubsOf.get(m) ?? [])) cb();
|
|
50
|
+
};
|
|
46
51
|
function createFilter(columns, opts = {}) {
|
|
47
52
|
const cols = Array.isArray(columns) ? columns.slice() : [columns];
|
|
48
53
|
if (!cols.length || cols.some((c) => typeof c !== "string" || !c)) {
|
|
@@ -71,7 +76,11 @@ function createFilter(columns, opts = {}) {
|
|
|
71
76
|
rows = nextRows;
|
|
72
77
|
reason = why;
|
|
73
78
|
version++;
|
|
79
|
+
if (nextKeys.length) {
|
|
80
|
+
for (const p of Array.from(peersOf.get(filter) ?? [])) if (p !== filter && p.active) p.clear(why);
|
|
81
|
+
}
|
|
74
82
|
for (const cb of Array.from(subs)) cb(filter, why);
|
|
83
|
+
firePick(filter);
|
|
75
84
|
};
|
|
76
85
|
const dedupe = (ks) => {
|
|
77
86
|
const seen2 = /* @__PURE__ */ new Set();
|
|
@@ -94,6 +103,15 @@ function createFilter(columns, opts = {}) {
|
|
|
94
103
|
const text = parts.filter(shown).map(String).join(" \u2192 ");
|
|
95
104
|
return text || k.filter(shown).map(String).join(" \u2192 ");
|
|
96
105
|
};
|
|
106
|
+
const partsOf = (k, more, names) => {
|
|
107
|
+
const s = keyString(k);
|
|
108
|
+
const pos = cols.map((c, i) => names.includes(c) && !isAnyValue(k[i]) ? i : -1).filter((i) => i >= 0);
|
|
109
|
+
const row = (more ?? []).find((r) => keyString(keyOfRow(r, cols)) === s) ?? seen.get(s);
|
|
110
|
+
const speaksFor = (d, j) => cols.includes(d) ? cols.indexOf(d) : display.length === cols.length ? j : -1;
|
|
111
|
+
const shown = (p) => p != null && p !== "" && !isAnyValue(p);
|
|
112
|
+
const text = row ? display.filter((d, j) => pos.includes(speaksFor(d, j))).map((d) => row[d]).filter(shown).map(String).join(" \u2192 ") : "";
|
|
113
|
+
return text || pos.map((i) => k[i]).filter(shown).map(String).join(" \u2192 ");
|
|
114
|
+
};
|
|
97
115
|
let warnedKeep = false;
|
|
98
116
|
const filter = {
|
|
99
117
|
id: opts.id ?? `f${++nextId}`,
|
|
@@ -137,9 +155,9 @@ function createFilter(columns, opts = {}) {
|
|
|
137
155
|
get text() {
|
|
138
156
|
return keys.map((k) => displayOf(k)).join(", ");
|
|
139
157
|
},
|
|
140
|
-
textOf(key, more) {
|
|
141
|
-
const k = Array.isArray(key) ? key : [key];
|
|
142
|
-
return
|
|
158
|
+
textOf(key, more, parts) {
|
|
159
|
+
const k = (Array.isArray(key) ? key : [key]).slice(0, cols.length);
|
|
160
|
+
return parts && cols.some((c) => !parts.includes(c)) ? partsOf(k, more, parts) : displayOf(k, more);
|
|
143
161
|
},
|
|
144
162
|
get reason() {
|
|
145
163
|
return reason;
|
|
@@ -198,8 +216,23 @@ function createFilter(columns, opts = {}) {
|
|
|
198
216
|
return () => {
|
|
199
217
|
subs.delete(cb);
|
|
200
218
|
};
|
|
219
|
+
},
|
|
220
|
+
group: opts.group || null,
|
|
221
|
+
get pick() {
|
|
222
|
+
const peers = peersOf.get(filter);
|
|
223
|
+
if (!peers) return keys.length ? filter : null;
|
|
224
|
+
for (const p of peers) if (p.active) return p;
|
|
225
|
+
return null;
|
|
226
|
+
},
|
|
227
|
+
onPick(cb) {
|
|
228
|
+
pickSubs.add(cb);
|
|
229
|
+
return () => {
|
|
230
|
+
pickSubs.delete(cb);
|
|
231
|
+
};
|
|
201
232
|
}
|
|
202
233
|
};
|
|
234
|
+
const pickSubs = /* @__PURE__ */ new Set();
|
|
235
|
+
pickSubsOf.set(filter, pickSubs);
|
|
203
236
|
return filter;
|
|
204
237
|
}
|
|
205
238
|
function createFilterScope() {
|
|
@@ -211,6 +244,43 @@ function createFilterScope() {
|
|
|
211
244
|
const notify = () => {
|
|
212
245
|
for (const cb of Array.from(subs)) cb(scope);
|
|
213
246
|
};
|
|
247
|
+
const groups = /* @__PURE__ */ new Map();
|
|
248
|
+
const names = /* @__PURE__ */ new Map();
|
|
249
|
+
const nameFor = (f) => {
|
|
250
|
+
const taken = new Set(names.values());
|
|
251
|
+
let k = f.key, n = 1;
|
|
252
|
+
while (taken.has(k)) k = `${f.key}-${++n}`;
|
|
253
|
+
names.set(f, k);
|
|
254
|
+
};
|
|
255
|
+
const nameOf = (f) => names.get(f) ?? f.key;
|
|
256
|
+
const join = (f) => {
|
|
257
|
+
const name = f.group;
|
|
258
|
+
if (!name) return;
|
|
259
|
+
const members = groups.get(name) ?? /* @__PURE__ */ new Set();
|
|
260
|
+
const first = members.values().next().value;
|
|
261
|
+
if (first && first.columns.join("") !== f.columns.join("")) {
|
|
262
|
+
try {
|
|
263
|
+
console.warn(`[chart-host] filter "${f.label}" is keyed by ${f.columns.join(", ")} but its group "${name}" by ${first.columns.join(", ")}, so it stays out of the group: give one pick's filters the same key columns.`);
|
|
264
|
+
} catch {
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (f.active && [...members].some((m) => m.active)) f.clear("page");
|
|
269
|
+
members.add(f);
|
|
270
|
+
groups.set(name, members);
|
|
271
|
+
peersOf.set(f, members);
|
|
272
|
+
firePick(f);
|
|
273
|
+
};
|
|
274
|
+
const leave = (f) => {
|
|
275
|
+
const members = f.group ? groups.get(f.group) : void 0;
|
|
276
|
+
if (!members?.has(f)) return;
|
|
277
|
+
members.delete(f);
|
|
278
|
+
peersOf.delete(f);
|
|
279
|
+
if (!members.size) groups.delete(f.group);
|
|
280
|
+
firePick(f);
|
|
281
|
+
const rest = members.values().next().value;
|
|
282
|
+
if (rest) firePick(rest);
|
|
283
|
+
};
|
|
214
284
|
const scope = {
|
|
215
285
|
get filters() {
|
|
216
286
|
return list.slice();
|
|
@@ -226,7 +296,9 @@ function createFilterScope() {
|
|
|
226
296
|
add(f) {
|
|
227
297
|
if (!offs.has(f)) {
|
|
228
298
|
list.push(f);
|
|
299
|
+
nameFor(f);
|
|
229
300
|
offs.set(f, f.onChange(() => notify()));
|
|
301
|
+
join(f);
|
|
230
302
|
notify();
|
|
231
303
|
}
|
|
232
304
|
return () => {
|
|
@@ -236,6 +308,8 @@ function createFilterScope() {
|
|
|
236
308
|
offs.delete(f);
|
|
237
309
|
const i = list.indexOf(f);
|
|
238
310
|
if (i >= 0) list.splice(i, 1);
|
|
311
|
+
names.delete(f);
|
|
312
|
+
leave(f);
|
|
239
313
|
notify();
|
|
240
314
|
};
|
|
241
315
|
},
|
|
@@ -248,6 +322,9 @@ function createFilterScope() {
|
|
|
248
322
|
subs.delete(cb);
|
|
249
323
|
};
|
|
250
324
|
},
|
|
325
|
+
keyOf(f) {
|
|
326
|
+
return offs.has(f) ? nameOf(f) : null;
|
|
327
|
+
},
|
|
251
328
|
get controls() {
|
|
252
329
|
return ctl;
|
|
253
330
|
},
|
|
@@ -269,7 +346,7 @@ function createFilterScope() {
|
|
|
269
346
|
},
|
|
270
347
|
save() {
|
|
271
348
|
const view = { v: 1 };
|
|
272
|
-
for (const f of list) if (f.active) (view.filters ??= {})[f
|
|
349
|
+
for (const f of list) if (f.active) (view.filters ??= {})[nameOf(f)] = f.keys.map((k) => k.slice());
|
|
273
350
|
for (const [k, c] of ctl) {
|
|
274
351
|
const values = c.values;
|
|
275
352
|
if (Object.keys(values).length) (view.controls ??= {})[k] = { ...values };
|
|
@@ -278,10 +355,15 @@ function createFilterScope() {
|
|
|
278
355
|
},
|
|
279
356
|
restore(view) {
|
|
280
357
|
if (!view || view.v !== 1) return;
|
|
358
|
+
const restored = /* @__PURE__ */ new Set();
|
|
281
359
|
for (const f of list) {
|
|
282
|
-
const keys = view.filters?.[f
|
|
283
|
-
|
|
284
|
-
|
|
360
|
+
const keys = view.filters?.[nameOf(f)];
|
|
361
|
+
const g = f.group && peersOf.get(f) ? f.group : null;
|
|
362
|
+
if (g && restored.has(g)) continue;
|
|
363
|
+
if (keys && keys.length) {
|
|
364
|
+
f.set(keys, "page");
|
|
365
|
+
if (g) restored.add(g);
|
|
366
|
+
} else f.clear("page");
|
|
285
367
|
}
|
|
286
368
|
for (const [k, c] of ctl) {
|
|
287
369
|
const values = view.controls?.[k];
|
|
@@ -291,19 +373,47 @@ function createFilterScope() {
|
|
|
291
373
|
};
|
|
292
374
|
return scope;
|
|
293
375
|
}
|
|
376
|
+
function scopeFilterOf(src) {
|
|
377
|
+
if (!src || typeof src !== "object") return null;
|
|
378
|
+
if (Array.isArray(src.keys)) return src;
|
|
379
|
+
const f = src.filter;
|
|
380
|
+
return f && typeof f === "object" ? f : null;
|
|
381
|
+
}
|
|
382
|
+
var warnedTakes = /* @__PURE__ */ new Set();
|
|
294
383
|
function filterScopeOf(filters) {
|
|
295
384
|
const list = Array.isArray(filters) ? filters : filters ? [filters] : [];
|
|
296
|
-
const active = list.filter((f) => f && f.active);
|
|
297
385
|
const values = [];
|
|
298
|
-
|
|
386
|
+
const fields = [];
|
|
387
|
+
for (const src of list) {
|
|
388
|
+
const f = scopeFilterOf(src);
|
|
389
|
+
if (!f || !f.active) continue;
|
|
390
|
+
const entry = src === f ? null : src;
|
|
391
|
+
const takes = entry?.takes;
|
|
392
|
+
for (const c of takes ?? []) {
|
|
393
|
+
if (f.columns.includes(c) || warnedTakes.has(`${f.id}${c}`)) continue;
|
|
394
|
+
warnedTakes.add(`${f.id}${c}`);
|
|
395
|
+
try {
|
|
396
|
+
console.warn(`[chart-host] scopedBy: filter "${f.label}" isn't keyed by ${c} (its key: ${f.columns.join(", ")}), so its scope line can't take it - name the filter's own key columns in takes.`);
|
|
397
|
+
} catch {
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const part = takes ? f.columns.filter((c) => takes.includes(c)) : f.columns;
|
|
401
|
+
const whole = part.length === f.columns.length;
|
|
402
|
+
if (!whole) {
|
|
403
|
+
const at = part.map((c) => f.columns.indexOf(c));
|
|
404
|
+
if (!at.length || f.keys.some((k) => at.every((i) => isAnyValue(k[i])))) continue;
|
|
405
|
+
}
|
|
406
|
+
let said = false;
|
|
299
407
|
for (const k of f.keys) {
|
|
300
|
-
const t = f.textOf(k).trim();
|
|
408
|
+
const t = (whole ? f.textOf(k) : f.textOf(k, void 0, part)).trim();
|
|
409
|
+
if (t) said = true;
|
|
301
410
|
if (t && !values.includes(t)) values.push(t);
|
|
302
411
|
}
|
|
412
|
+
if (!whole && !said) continue;
|
|
413
|
+
const label = entry?.label || (whole || f.label !== f.columns.join(" / ") ? f.label : part.join(" / "));
|
|
414
|
+
if (label && !fields.includes(label)) fields.push(label);
|
|
303
415
|
}
|
|
304
416
|
if (!values.length) return void 0;
|
|
305
|
-
const fields = [];
|
|
306
|
-
for (const f of active) if (f.label && !fields.includes(f.label)) fields.push(f.label);
|
|
307
417
|
return { field: fields.join(", "), values };
|
|
308
418
|
}
|
|
309
419
|
var LINKED_HOVER_CLASS = "bic-linked-hover";
|
|
@@ -339,18 +449,21 @@ var sortedEq = (a, b) => {
|
|
|
339
449
|
return x.every((v, i) => v === y[i]);
|
|
340
450
|
};
|
|
341
451
|
function bindFilter(host, filter, opts) {
|
|
452
|
+
const pickOf = () => filter.pick ?? filter;
|
|
342
453
|
const wanted = () => {
|
|
343
|
-
|
|
454
|
+
const src = pickOf();
|
|
455
|
+
if (!src.active) return [];
|
|
344
456
|
const out = [];
|
|
345
457
|
const n = opts.rowCount();
|
|
346
458
|
for (let i = 0; i < n; i++) {
|
|
347
459
|
const r = opts.rowAt(i);
|
|
348
|
-
if (r &&
|
|
460
|
+
if (r && src.has(r)) out.push(i);
|
|
349
461
|
}
|
|
350
462
|
return out;
|
|
351
463
|
};
|
|
352
464
|
const hiddenKeys = () => {
|
|
353
|
-
|
|
465
|
+
const src = pickOf();
|
|
466
|
+
if (!src.active) return [];
|
|
354
467
|
const carried = /* @__PURE__ */ new Set();
|
|
355
468
|
const n = opts.rowCount();
|
|
356
469
|
for (let i = 0; i < n; i++) {
|
|
@@ -364,7 +477,7 @@ function bindFilter(host, filter, opts) {
|
|
|
364
477
|
}
|
|
365
478
|
return false;
|
|
366
479
|
};
|
|
367
|
-
return
|
|
480
|
+
return src.keys.filter((k) => k.some(isAnyValue) ? !anyRowMatches(k) : !carried.has(keyString(k)));
|
|
368
481
|
};
|
|
369
482
|
const paint = () => {
|
|
370
483
|
const want = wanted();
|
|
@@ -379,7 +492,8 @@ function bindFilter(host, filter, opts) {
|
|
|
379
492
|
if (source === "host") return;
|
|
380
493
|
const keep = meta?.keepHidden ? hiddenKeys() : [];
|
|
381
494
|
if (!idxs.length && !keep.length) {
|
|
382
|
-
|
|
495
|
+
const src = pickOf();
|
|
496
|
+
if (src.active) src.clear("clear");
|
|
383
497
|
return;
|
|
384
498
|
}
|
|
385
499
|
const rows = idxs.map((i) => opts.rowAt(i)).filter((r) => !!r);
|
|
@@ -389,8 +503,20 @@ function bindFilter(host, filter, opts) {
|
|
|
389
503
|
filter.set([label], "click");
|
|
390
504
|
return;
|
|
391
505
|
}
|
|
506
|
+
const group = meta?.fromMark && !keep.length ? sharedKey(rows) : null;
|
|
507
|
+
if (group) {
|
|
508
|
+
filter.set([group], "click");
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
392
511
|
filter.selectRows(rows, "click", keep);
|
|
393
512
|
});
|
|
513
|
+
const sharedKey = (rows) => {
|
|
514
|
+
const key = filter.columns.map((c) => {
|
|
515
|
+
const v = rows[0][c];
|
|
516
|
+
return rows.every((r) => keyString([r[c]]) === keyString([v])) ? v : ANY_VALUE;
|
|
517
|
+
});
|
|
518
|
+
return key.some(isAnyValue) && !key.every(isAnyValue) ? key : null;
|
|
519
|
+
};
|
|
394
520
|
const labelKey = (rows) => {
|
|
395
521
|
const n = opts.rowCount();
|
|
396
522
|
const key = filter.columns.map((c) => {
|
|
@@ -404,7 +530,7 @@ function bindFilter(host, filter, opts) {
|
|
|
404
530
|
});
|
|
405
531
|
return key.some(isAnyValue) && !key.every(isAnyValue) ? key : null;
|
|
406
532
|
};
|
|
407
|
-
const offFilter = filter.onChange(() => paint());
|
|
533
|
+
const offFilter = filter.onPick ? filter.onPick(() => paint()) : filter.onChange(() => paint());
|
|
408
534
|
const el = opts.container ?? null;
|
|
409
535
|
let offHoverDom = () => {
|
|
410
536
|
};
|
|
@@ -486,6 +612,7 @@ export {
|
|
|
486
612
|
isAnyValue,
|
|
487
613
|
createFilter,
|
|
488
614
|
createFilterScope,
|
|
615
|
+
scopeFilterOf,
|
|
489
616
|
filterScopeOf,
|
|
490
617
|
LINKED_HOVER_CLASS,
|
|
491
618
|
payloadRowReader,
|
package/dist/dax.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
|
isAnyValue
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZZBX5ZJ6.mjs";
|
|
5
5
|
import "./chunk-GHODWOAL.mjs";
|
|
6
6
|
|
|
7
7
|
// src/dax.ts
|
|
@@ -64,9 +64,31 @@ ${tail}`.replace(/\n$/, "");
|
|
|
64
64
|
function isFilter(x) {
|
|
65
65
|
return !!x && typeof x === "object" && Array.isArray(x.keys) && typeof x.has === "function";
|
|
66
66
|
}
|
|
67
|
+
var HEADER = /^(?:'(?:[^']|'')*'|[^[\]']*)\[((?:[^\]]|\]\])+)\]$/;
|
|
68
|
+
function columnName(header) {
|
|
69
|
+
const m = HEADER.exec(String(header ?? "").trim());
|
|
70
|
+
return m ? m[1].replace(/\]\]/g, "]") : String(header ?? "");
|
|
71
|
+
}
|
|
72
|
+
function queryRows(result) {
|
|
73
|
+
const table = result && "columns" in result ? result : result && "table" in result ? result.table : void 0;
|
|
74
|
+
if (!table || !Array.isArray(table.columns) || !Array.isArray(table.rows)) return [];
|
|
75
|
+
const bare = table.columns.map((c) => columnName(c?.name ?? ""));
|
|
76
|
+
const count = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const b of bare) count.set(b, (count.get(b) ?? 0) + 1);
|
|
78
|
+
const names = bare.map((b, i) => (count.get(b) ?? 0) > 1 ? String(table.columns[i]?.name ?? b) : b);
|
|
79
|
+
return table.rows.map((r) => {
|
|
80
|
+
const o = {};
|
|
81
|
+
names.forEach((n, k) => {
|
|
82
|
+
o[n] = r?.[k];
|
|
83
|
+
});
|
|
84
|
+
return o;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
67
87
|
export {
|
|
68
88
|
calculateTable,
|
|
89
|
+
columnName,
|
|
69
90
|
daxLiteral,
|
|
70
91
|
filterQuery,
|
|
92
|
+
queryRows,
|
|
71
93
|
treatAs
|
|
72
94
|
};
|