@bicharts/chart-host 0.5.60 → 0.5.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.
- package/dist/index.mjs +59 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/qualifyFilter.d.ts +94 -5
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -688,8 +688,12 @@ function filterQualifyRows(rows, term, read) {
|
|
|
688
688
|
if (byDesc.length > 0) return { rows: byDesc, tier: "desc", term: t };
|
|
689
689
|
return { rows: [], tier: "none", term: t };
|
|
690
690
|
}
|
|
691
|
-
|
|
692
|
-
|
|
691
|
+
function readQualifyChartRow(r) {
|
|
692
|
+
return { name: r.name, description: r.description };
|
|
693
|
+
}
|
|
694
|
+
function readQualifyRefusalRow(r) {
|
|
695
|
+
return { name: r.name, description: r.reason };
|
|
696
|
+
}
|
|
693
697
|
var FILTER_ROW_PX = 32;
|
|
694
698
|
var FILTER_MIN_WIDTH_PX = 420;
|
|
695
699
|
var FILTER_MIN_HEIGHT_PX = 300;
|
|
@@ -705,6 +709,57 @@ function qualifyFilterGate(i) {
|
|
|
705
709
|
if (!listNeedsFilter(i.scrollHeight, i.clientHeight)) return { show: false, why: "no-overflow" };
|
|
706
710
|
return { show: true, why: "shown" };
|
|
707
711
|
}
|
|
712
|
+
function computeQualifyFilterView(groups, term) {
|
|
713
|
+
const g = Array.isArray(groups) ? groups : [];
|
|
714
|
+
const read = (r) => ({ name: r.name, description: r.description });
|
|
715
|
+
const collect = (section) => {
|
|
716
|
+
const out = [];
|
|
717
|
+
for (const grp of g) if (grp.section === section) for (const r of grp.rows) out.push(r);
|
|
718
|
+
return out;
|
|
719
|
+
};
|
|
720
|
+
const fitRows = collect("fits");
|
|
721
|
+
const fit = filterQualifyRows(fitRows, term, read);
|
|
722
|
+
const ref = filterQualifyRows(collect("refused"), term, read);
|
|
723
|
+
const visible = /* @__PURE__ */ new Set();
|
|
724
|
+
for (const r of fit.rows) visible.add(r.el);
|
|
725
|
+
for (const r of ref.rows) visible.add(r.el);
|
|
726
|
+
const show = [], hide = [], showHeadings = [], hideHeadings = [];
|
|
727
|
+
for (const grp of g) {
|
|
728
|
+
let any = false;
|
|
729
|
+
for (const r of grp.rows) {
|
|
730
|
+
if (visible.has(r.el)) {
|
|
731
|
+
show.push(r.el);
|
|
732
|
+
any = true;
|
|
733
|
+
} else {
|
|
734
|
+
hide.push(r.el);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (grp.heading !== null) (any ? showHeadings : hideHeadings).push(grp.heading);
|
|
738
|
+
}
|
|
739
|
+
const filtering = fit.tier !== "all";
|
|
740
|
+
const openRefusals = filtering && fit.rows.length === 0 && ref.rows.length > 0;
|
|
741
|
+
let note = "none";
|
|
742
|
+
if (filtering) {
|
|
743
|
+
if (fit.tier === "desc") note = "descFallback";
|
|
744
|
+
else if (fit.tier === "none") note = openRefusals ? "onlyRefusals" : "noMatch";
|
|
745
|
+
}
|
|
746
|
+
return {
|
|
747
|
+
show,
|
|
748
|
+
hide,
|
|
749
|
+
showHeadings,
|
|
750
|
+
hideHeadings,
|
|
751
|
+
tier: fit.tier,
|
|
752
|
+
matched: fit.rows.length,
|
|
753
|
+
total: fitRows.length,
|
|
754
|
+
refusalMatched: ref.rows.length,
|
|
755
|
+
openRefusals,
|
|
756
|
+
note,
|
|
757
|
+
term: fit.term
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
function qualifyFilterCountText(view) {
|
|
761
|
+
return view.tier === "all" ? String(view.total) : `${view.matched} of ${view.total}`;
|
|
762
|
+
}
|
|
708
763
|
function inlineFilterGate(rowCount) {
|
|
709
764
|
return rowCount >= INLINE_FILTER_MIN_ROWS ? { show: true, why: "shown" } : { show: false, why: "no-overflow" };
|
|
710
765
|
}
|
|
@@ -985,6 +1040,7 @@ export {
|
|
|
985
1040
|
clearGeoCache,
|
|
986
1041
|
compileRenderFn,
|
|
987
1042
|
compileTrivialSource,
|
|
1043
|
+
computeQualifyFilterView,
|
|
988
1044
|
computeSelectionCard,
|
|
989
1045
|
confirmLaunch,
|
|
990
1046
|
createChartHost,
|
|
@@ -1014,6 +1070,7 @@ export {
|
|
|
1014
1070
|
qualifyAuto,
|
|
1015
1071
|
qualifyCancel,
|
|
1016
1072
|
qualifyFailureFallsOpen,
|
|
1073
|
+
qualifyFilterCountText,
|
|
1017
1074
|
qualifyFilterGate,
|
|
1018
1075
|
qualifyGroupHeadingFor,
|
|
1019
1076
|
qualifyPick,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { shouldReview, buildReviewWire, bareBase64, actionFor, type ReviewGate,
|
|
|
13
13
|
export { askApplyImprovements, type ReviewDialogOptions, type ReviewDialogText } from "./reviewDialog";
|
|
14
14
|
export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, type QualifyGroupState, type QualifyGroupHeading, orderRefusalsForDisplay, refusalIsSelectable, hasRefusalsToShow, qualifyRefusalHeadingFor, newQualifyRefusalGroupState, type QualifyRefusalRow, type QualifyRefusalGroupState, type QualifyRefusalHeading, } from "./qualifyGroups";
|
|
15
15
|
export { qualifyPick, qualifyAuto, qualifyCancel, launchGenerates, launchFavorStyle, chooserFitsViewport, shouldOpenChooserOnGenerate, shouldOpenInlineChooserOnGenerate, canConfirmLaunch, confirmLaunch, qualifyFailureFallsOpen, CHOOSER_MIN_WIDTH_PX, CHOOSER_MIN_HEIGHT_PX, type QualifyLaunchOutcome, type ChooserGateInput, } from "./qualifyLaunch";
|
|
16
|
-
export { normalizeFilterTerm, filterQualifyRows, readQualifyChartRow, readQualifyRefusalRow, filterFitsChooser, listNeedsFilter, qualifyFilterGate, inlineFilterGate, FILTER_MIN_TERM_CHARS, FILTER_ROW_PX, FILTER_MIN_WIDTH_PX, FILTER_MIN_HEIGHT_PX, INLINE_FILTER_MIN_ROWS, type QualifyFilterTier, type QualifyFilterResult, type QualifyFilterRead, type QualifyFilterGateReason, type QualifyFilterGateInput, } from "./qualifyFilter";
|
|
16
|
+
export { normalizeFilterTerm, filterQualifyRows, readQualifyChartRow, readQualifyRefusalRow, filterFitsChooser, listNeedsFilter, qualifyFilterGate, inlineFilterGate, FILTER_MIN_TERM_CHARS, FILTER_ROW_PX, FILTER_MIN_WIDTH_PX, FILTER_MIN_HEIGHT_PX, INLINE_FILTER_MIN_ROWS, computeQualifyFilterView, qualifyFilterCountText, type QualifyFilterTier, type QualifyFilterResult, type QualifyFilterRead, type QualifyFilterGateReason, type QualifyFilterGateInput, type QualifyFilterRow, type QualifyFilterGroup, type QualifyFilterView, type QualifyFilterNoteKind, } from "./qualifyFilter";
|
|
17
17
|
export { computeSelectionCard, normaliseAggregation, type SelectionCardModel, type SelectionCardLine, type SelectionCardOptions, } from "./selectionCard";
|
|
18
18
|
export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
|
|
19
19
|
export { censusMarks, isBlankRender, blankRenderFlag, type MarkCensus, type BlankVerdictInput } from "./blankRender";
|
|
@@ -67,21 +67,33 @@ export type QualifyFilterRead<T> = (row: T) => {
|
|
|
67
67
|
* and the hosts already drop it at render time.
|
|
68
68
|
*/
|
|
69
69
|
export declare function filterQualifyRows<T>(rows: readonly T[] | null | undefined, term: string | null | undefined, read: QualifyFilterRead<T>): QualifyFilterResult<T>;
|
|
70
|
-
/** Reads a fitting row (`charts[]`): `name` / `description`.
|
|
71
|
-
|
|
70
|
+
/** Reads a fitting row (`charts[]`): `name` / `description`.
|
|
71
|
+
*
|
|
72
|
+
* GENERIC, and it has to be. Written as a `const` with an explicit `QualifyFilterRead<{...}>`
|
|
73
|
+
* annotation it PINS the row type, and `filterQualifyRows` then infers T from the reader instead
|
|
74
|
+
* of from the rows - so a caller passing its own richer row type gets back an array typed as the
|
|
75
|
+
* reader's minimal shape and fails to assign it home. Caught by the MCP tool, which passes
|
|
76
|
+
* `EligibleChart[]` and got `{name?, description?}[]` back. */
|
|
77
|
+
export declare function readQualifyChartRow<T extends {
|
|
78
|
+
name?: string | null;
|
|
79
|
+
description?: string | null;
|
|
80
|
+
}>(r: T): {
|
|
72
81
|
name?: string | null;
|
|
73
82
|
description?: string | null;
|
|
74
|
-
}
|
|
83
|
+
};
|
|
75
84
|
/**
|
|
76
85
|
* Reads a REFUSED row (`refused[]`). Its second field is the gate's SENTENCE rather than a
|
|
77
86
|
* description, and searching it is right for the same reason the tier exists: the sentence names
|
|
78
87
|
* the reader's own columns, so "region" finding every type refused over Region is a useful
|
|
79
88
|
* answer to "why isn't my chart here" - which is the only question that section is open to ask.
|
|
80
89
|
*/
|
|
81
|
-
export declare
|
|
90
|
+
export declare function readQualifyRefusalRow<T extends {
|
|
82
91
|
name?: string | null;
|
|
83
92
|
reason?: string | null;
|
|
84
|
-
}
|
|
93
|
+
}>(r: T): {
|
|
94
|
+
name?: string | null;
|
|
95
|
+
description?: string | null;
|
|
96
|
+
};
|
|
85
97
|
/**
|
|
86
98
|
* THE HEIGHT THE FILTER ROW COSTS THE LIST - the row plus its 6px bottom margin.
|
|
87
99
|
*
|
|
@@ -165,6 +177,83 @@ export declare function qualifyFilterGate(i: QualifyFilterGateInput): {
|
|
|
165
177
|
show: boolean;
|
|
166
178
|
why: QualifyFilterGateReason;
|
|
167
179
|
};
|
|
180
|
+
/** One row, as the hosts record it while BUILDING the list - the element handle plus the text it
|
|
181
|
+
* is matched on, carried beside the element rather than scraped back out of it later. */
|
|
182
|
+
export interface QualifyFilterRow<E> {
|
|
183
|
+
el: E;
|
|
184
|
+
name: string;
|
|
185
|
+
description: string;
|
|
186
|
+
}
|
|
187
|
+
/** A heading and the rows it introduces, in render order. `section` separates the fitting list
|
|
188
|
+
* from the refusal block behind "Show all chart types" - two independently visible surfaces
|
|
189
|
+
* answering two different questions, and only one of them can be auto-opened. */
|
|
190
|
+
export interface QualifyFilterGroup<E> {
|
|
191
|
+
heading: E | null;
|
|
192
|
+
section: "fits" | "refused";
|
|
193
|
+
rows: QualifyFilterRow<E>[];
|
|
194
|
+
}
|
|
195
|
+
/** WHICH SENTENCE THE HOST HAS TO SHOW. The host owns the words (it localizes); this owns the
|
|
196
|
+
* decision, which is the half that can differ between two hosts without anyone noticing.
|
|
197
|
+
*
|
|
198
|
+
* "none" - a name tier answered, or nothing is being filtered. Say nothing: the reader's
|
|
199
|
+
* own word was found where they expected it and needs no explanation.
|
|
200
|
+
* "descFallback" - no name matched; these matched on description. MUST be said - a silent
|
|
201
|
+
* fall-through is indistinguishable from bad matching.
|
|
202
|
+
* "onlyRefusals" - nothing that FITS matches, but something in the refusal block does. Say where
|
|
203
|
+
* it went; that block is now open.
|
|
204
|
+
* "noMatch" - nothing anywhere. NEVER phrase this like "nothing fits your data": one is a
|
|
205
|
+
* statement about a typed string and is fixed with backspace, the other is a
|
|
206
|
+
* statement about the data and is not.
|
|
207
|
+
*/
|
|
208
|
+
export type QualifyFilterNoteKind = "none" | "descFallback" | "onlyRefusals" | "noMatch";
|
|
209
|
+
export interface QualifyFilterView<E> {
|
|
210
|
+
/** Rows to show, and rows to hide. Two lists rather than one predicate so a host can write
|
|
211
|
+
* them in one pass without asking a Set per element. */
|
|
212
|
+
show: E[];
|
|
213
|
+
hide: E[];
|
|
214
|
+
/** Headings to show, and headings that now introduce nothing. A heading with nothing under it
|
|
215
|
+
* is a label for an empty category, and the rule it draws reads as a divider between two
|
|
216
|
+
* things that are not there. */
|
|
217
|
+
showHeadings: E[];
|
|
218
|
+
hideHeadings: E[];
|
|
219
|
+
tier: QualifyFilterTier;
|
|
220
|
+
/** Matches and totals for the FITTING list - what the "12 of 137" counter is made of. */
|
|
221
|
+
matched: number;
|
|
222
|
+
total: number;
|
|
223
|
+
refusalMatched: number;
|
|
224
|
+
/**
|
|
225
|
+
* Does the refusal block need to be OPEN for this term?
|
|
226
|
+
*
|
|
227
|
+
* True only when the term matches nothing that fits and something that does not. "Why isn't
|
|
228
|
+
* my chart here" is the only question that section is open to ask, and the reader has just
|
|
229
|
+
* asked it by name - the server's own sentence about why it cannot be drawn is already
|
|
230
|
+
* rendered, one collapsed checkbox away.
|
|
231
|
+
*
|
|
232
|
+
* THE HOST MUST TREAT THIS AS AN OVERRIDE, NOT A SETTING: remember what the reader's own
|
|
233
|
+
* checkbox said before the first override, and put it back the moment this goes false. An
|
|
234
|
+
* auto-expansion that sticks leaves the reader with a section they never opened.
|
|
235
|
+
*/
|
|
236
|
+
openRefusals: boolean;
|
|
237
|
+
note: QualifyFilterNoteKind;
|
|
238
|
+
/** The normalized term, for the host to interpolate into whichever sentence it shows. */
|
|
239
|
+
term: string;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* The filtered view of a whole dialog: fitting rows, refusal rows, headings and the note.
|
|
243
|
+
*
|
|
244
|
+
* ORDER IS UNTOUCHED, as everywhere else here - `show` and `hide` come out in the order the
|
|
245
|
+
* groups were built, so a host writing them in sequence cannot reorder anything by accident.
|
|
246
|
+
*/
|
|
247
|
+
export declare function computeQualifyFilterView<E>(groups: readonly QualifyFilterGroup<E>[], term: string | null | undefined): QualifyFilterView<E>;
|
|
248
|
+
/** The counter beside the box: "12 of 137" while filtering, the plain total otherwise.
|
|
249
|
+
*
|
|
250
|
+
* Digits only, assembled here so both hosts show the same shape of number - the words around it
|
|
251
|
+
* (there are none today) would be the host's business, the arithmetic is not. */
|
|
252
|
+
export declare function qualifyFilterCountText(view: {
|
|
253
|
+
tier: QualifyFilterTier;
|
|
254
|
+
matched: number;
|
|
255
|
+
total: number;
|
|
256
|
+
}): string;
|
|
168
257
|
/**
|
|
169
258
|
* The same question for a host whose chooser is an INLINE, SCROLLING PANEL - and it has no size
|
|
170
259
|
* clause, for the reason `shouldOpenInlineChooserOnGenerate` already sets out at length.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.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",
|