@bicharts/chart-host 0.5.89 → 0.5.90
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/{chunk-NWMMNXH2.mjs → chunk-GUCTCDEO.mjs} +1797 -1146
- package/dist/index.mjs +300 -810
- package/dist/react.mjs +1 -1
- package/dist/types/colourSpread.d.ts +75 -0
- package/dist/types/host.d.ts +16 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CIE2000 distance at which two fills stop being separable at a glance, side by side on a chart.
|
|
3
|
+
*
|
|
4
|
+
* Not a tuned parameter — a perceptual constant. 1.0 is the textbook just-noticeable difference
|
|
5
|
+
* under laboratory conditions with the two patches touching; 5 is the conventional "clearly
|
|
6
|
+
* different to an ordinary observer in ordinary conditions", which is what a reader scanning a
|
|
7
|
+
* choropleth is. Erring high is the safe direction: it makes the census UNDERstate crowding.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SAME_SHADE_DELTA_E = 5;
|
|
10
|
+
/**
|
|
11
|
+
* Fewer distinct fills than this and there is nothing to characterise.
|
|
12
|
+
*
|
|
13
|
+
* Four is the floor for the collinearity test below, not a judgement: the two extremes anchor the
|
|
14
|
+
* line, so a fourth fill is the second interior point and the first one that can disagree.
|
|
15
|
+
*/
|
|
16
|
+
export declare const MIN_RAMP_FILLS = 4;
|
|
17
|
+
/**
|
|
18
|
+
* How far off a straight line a set of fills may sit and still be a RAMP.
|
|
19
|
+
*
|
|
20
|
+
* THIS IS WHAT SEPARATES A VALUE-ENCODED COLOUR CHANNEL FROM A CATEGORICAL ONE, and counting
|
|
21
|
+
* fills cannot do it. The obvious "at least six distinct colours" rule fails at exactly the
|
|
22
|
+
* wrong moment: a five-bin quantile scale — the recommended REMEDY for the washout this census
|
|
23
|
+
* exists to find — has five fills, so a count floor would have excluded the charts that did the
|
|
24
|
+
* right thing and biased the prevalence it was built to measure.
|
|
25
|
+
*
|
|
26
|
+
* A sequential ramp is, by construction, a path between two colours: every fill lies close to the
|
|
27
|
+
* segment joining its extremes, so `d(lo,x) + d(x,hi)` barely exceeds `d(lo,hi)`. A categorical
|
|
28
|
+
* scheme is chosen for mutual separation and its members sit well off that line. Measured in
|
|
29
|
+
* CIE2000 over the standard schemes, the two populations do not overlap:
|
|
30
|
+
*
|
|
31
|
+
* ```text
|
|
32
|
+
* interpolateBlues (5, 8 and 40 stops) mean slack -0.05 SEQUENTIAL
|
|
33
|
+
* interpolateReds (8) mean slack +0.06 SEQUENTIAL
|
|
34
|
+
* viridis (8) mean slack +0.02 SEQUENTIAL
|
|
35
|
+
* schemeTableau10 (5 and 8) mean slack +0.24 categorical
|
|
36
|
+
* RdBu diverging (7) mean slack +0.35 two arms, not one line
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* 0.15 sits in the four-fold gap. A DIVERGING ramp landing outside is correct rather than a miss:
|
|
40
|
+
* it is genuinely two paths from a neutral middle, and measuring it as one would report the arm
|
|
41
|
+
* that happened to be longer. It is excluded and said so, not mismeasured.
|
|
42
|
+
*/
|
|
43
|
+
export declare const RAMP_SLACK_MAX = 0.15;
|
|
44
|
+
export interface ColourSpreadCensus {
|
|
45
|
+
/** Marks carrying a resolvable, non-transparent fill. */
|
|
46
|
+
marks: number;
|
|
47
|
+
/** Distinct fills among them, before quantisation. */
|
|
48
|
+
distinctFills: number;
|
|
49
|
+
/** Share (0-100) of marks whose fill is within SAME_SHADE_DELTA_E of the most crowded fill. */
|
|
50
|
+
crowdShare: number;
|
|
51
|
+
/** Largest CIE2000 distance between any two sampled fills — the ramp's perceptual reach. */
|
|
52
|
+
spanDeltaE: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* How much of this chart is one shade?
|
|
56
|
+
*
|
|
57
|
+
* Never throws. Telemetry must not be the reason a delivered render fails, and an environment
|
|
58
|
+
* that cannot report a fill reports nothing rather than a number that describes the environment.
|
|
59
|
+
*
|
|
60
|
+
* KNOWN LIMIT, stated rather than hidden: a DIVERGING ramp is measured the same way as any
|
|
61
|
+
* other, so a chart whose two arms are each well spread but which crowds around its neutral
|
|
62
|
+
* midpoint reports honestly, while one that crowds at BOTH ends reports the larger arm only. That
|
|
63
|
+
* understates rather than overstates, which is the direction an audit should err.
|
|
64
|
+
*/
|
|
65
|
+
export declare function censusColourSpread(container: any, doc?: any): ColourSpreadCensus;
|
|
66
|
+
/**
|
|
67
|
+
* The always-on behaviour tag, or "" when the census had nothing to say.
|
|
68
|
+
*
|
|
69
|
+
* A BUCKETED MEASUREMENT, NOT A VERDICT. `ramp:d3:crowd60` says three in five marks are one
|
|
70
|
+
* shade; it does not say that is wrong. Twenty-point buckets are coarse enough to read as a
|
|
71
|
+
* distribution off a few hundred renders and fine enough to separate "a bit clustered" from the
|
|
72
|
+
* failure this exists for, and the whole family is one `LIKE 'ramp:d3:crowd%'` away — which is
|
|
73
|
+
* the denominator any rate needs. When the distribution is in, a cut can be argued from it.
|
|
74
|
+
*/
|
|
75
|
+
export declare function colourSpreadFlag(c: ColourSpreadCensus): string;
|
package/dist/types/host.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type RenderOptions, type ViewStateProvider } from "./contract";
|
|
|
2
2
|
import { type ResolveOptionsInput } from "./defaults";
|
|
3
3
|
import { type MarkCensus } from "./blankRender";
|
|
4
4
|
import { type HitBandCensus } from "./hitBands";
|
|
5
|
+
import { type ColourSpreadCensus } from "./colourSpread";
|
|
5
6
|
import { type FitRenderedChartOptions, type FitRenderedChartResult } from "./fitDom";
|
|
6
7
|
import { type LabelContrastOptions, type LabelContrastReport } from "./labelContrastDom";
|
|
7
8
|
export type RenderFn = (container: HTMLElement, data: any, options: RenderOptions) => void;
|
|
@@ -92,6 +93,21 @@ export interface ChartHostConfig {
|
|
|
92
93
|
* number only the browser knows, and this reads the COMPUTED width off the rendered element.
|
|
93
94
|
*/
|
|
94
95
|
onHitBandCensus?: (census: HitBandCensus) => void;
|
|
96
|
+
/**
|
|
97
|
+
* HOW MUCH OF THIS CHART IS ONE SHADE (2026-09-09)? Runs after every render, counts only.
|
|
98
|
+
*
|
|
99
|
+
* The sibling question to the hit-band census, on the colour channel: a right-skewed measure
|
|
100
|
+
* on a linear ramp is accurate and unreadable, because the outliers eat the ramp and the
|
|
101
|
+
* dense bulk lands in one indistinguishable tint. It measures the OUTCOME, never the scale,
|
|
102
|
+
* so a well-spread scale of any kind reports well and a curved or hand-rolled ramp needs no
|
|
103
|
+
* special case; it declines outright on a categorical palette or a diverging ramp, which are
|
|
104
|
+
* a different question wearing the same numbers.
|
|
105
|
+
*
|
|
106
|
+
* The other half a server-side check cannot do. A code rule reads `scaleLinear()` and a
|
|
107
|
+
* domain built from `d3.max`; whether THAT washes out depends on the data, and the shape's
|
|
108
|
+
* own skew is measured on the raw column while the ramp encodes an aggregate.
|
|
109
|
+
*/
|
|
110
|
+
onColourSpreadCensus?: (census: ColourSpreadCensus) => void;
|
|
95
111
|
/** This chart declares time keyframes: frame one is allowed to be empty, so no blank verdict
|
|
96
112
|
* is issued for it. */
|
|
97
113
|
animated?: boolean;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { applyLabelContrast, LABEL_CONTRAST_DONE_ATTR, LABEL_CONTRAST_CAP, type
|
|
|
21
21
|
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, type LabelDecision, } from "./labelContrast";
|
|
22
22
|
export { censusMarks, isBlankRender, blankRenderFlag, type MarkCensus, type BlankVerdictInput } from "./blankRender";
|
|
23
23
|
export { censusHitBands, hitBandFlag, MIN_HIT_BAND_PX, type HitBandCensus } from "./hitBands";
|
|
24
|
+
export { censusColourSpread, colourSpreadFlag, SAME_SHADE_DELTA_E, MIN_RAMP_FILLS, type ColourSpreadCensus } from "./colourSpread";
|
|
24
25
|
export { SCROLL_SLACK_PX, MAX_FRAME_GROW_FACTOR, PHANTOM_FRACTION, FIT_CONTENT_SELECTOR, needsScroll, contentExtentOf, scrollFitFor, planFrameGrow, isPhantomBox, type MeasuredBox, type ContentExtent, type ScrollFit, type FrameGrowPlan, } from "./fit";
|
|
25
26
|
export { fitRenderedChart, fitReadingFor, measureContainerBoxes, svgInkReach, ctmScaleOf, type FitReading, type InkReach, type FitRenderedChartOptions, type FitRenderedChartResult, } from "./fitDom";
|
|
26
27
|
export { AXIS_PIN_MIN_LABELS, AXIS_PIN_BAND_PAD_PX, AXIS_PIN_MAX_BAND_FRACTION, AXIS_PIN_TRACK_REACH_PX, isHorizontalLabelRow, labelBand, planAxisPin, axisPinPlacement, type LabelRowBox, type AxisBand, type AxisPinCandidate, type AxisPinPlan, type AxisPinEdge, } from "./fit";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.90",
|
|
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",
|