@bicharts/chart-host 0.5.87 → 0.5.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/dist/index.mjs +897 -267
- package/dist/types/index.d.ts +1 -0
- package/dist/types/palette.d.ts +78 -0
- package/package.json +2 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -25,3 +25,4 @@ export { SCROLL_SLACK_PX, MAX_FRAME_GROW_FACTOR, PHANTOM_FRACTION, FIT_CONTENT_S
|
|
|
25
25
|
export { fitRenderedChart, fitReadingFor, measureContainerBoxes, svgInkReach, ctmScaleOf, type FitReading, type InkReach, type FitRenderedChartOptions, type FitRenderedChartResult, } from "./fitDom";
|
|
26
26
|
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";
|
|
27
27
|
export { pinScrolledAxis, unpinScrolledAxis, type AxisPinReport } from "./fitDom";
|
|
28
|
+
export { MIN_DELTA_E, pickDistinctColorFromSeed, buildPalette, buildPaletteFromSeed, type PaletteResult, type SeedForSlot, } from "./palette";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimum perceptual distance (CIE2000 deltaE) that any returned color must
|
|
3
|
+
* achieve from every previously-issued color. Picked for chart-readable
|
|
4
|
+
* swatches; JND (just-noticeable-difference) at this scale is ≈5.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MIN_DELTA_E = 10;
|
|
7
|
+
/**
|
|
8
|
+
* Pick a hex color for a palette slot.
|
|
9
|
+
*
|
|
10
|
+
* Strategy (ordered from "closest to theme" to "furthest from theme"):
|
|
11
|
+
* 1. The seed itself if it's already distant enough.
|
|
12
|
+
* 2. Saturation walk around the seed (same hue family, in-theme).
|
|
13
|
+
* 3. Lightness walk around the seed (same hue family, in-theme).
|
|
14
|
+
* 4. Hue rotation around the seed (drifts off-theme but still tied).
|
|
15
|
+
* 5. Give up — return the seed. Never random: a slightly-colliding theme
|
|
16
|
+
* color reads better than a stranger color.
|
|
17
|
+
*
|
|
18
|
+
* The set of `existing` colors is treated as readonly — the caller is
|
|
19
|
+
* responsible for adding the returned color (and possibly the best-effort
|
|
20
|
+
* fallback) to their own set when this function returns. We return BOTH the
|
|
21
|
+
* chosen color AND the colorSet-entry to register, because the give-up case
|
|
22
|
+
* registers a DIFFERENT value (the best-so-far candidate) than what it
|
|
23
|
+
* returns (the seed): registering the seed would make a later call think
|
|
24
|
+
* its slot is empty, but returning the best-so-far would lose theme
|
|
25
|
+
* fidelity.
|
|
26
|
+
*/
|
|
27
|
+
export interface PaletteResult {
|
|
28
|
+
/** Hex color to use for this slot. */
|
|
29
|
+
readonly hex: string;
|
|
30
|
+
/** Hex color to register in the palette-issued set (may differ from `hex` on the give-up fallback). */
|
|
31
|
+
readonly registerHex: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function pickDistinctColorFromSeed(seedHex: string, existing: ReadonlySet<string>, minDistance?: number): PaletteResult;
|
|
34
|
+
/**
|
|
35
|
+
* A whole categorical palette from ONE seed colour.
|
|
36
|
+
*
|
|
37
|
+
* THE DIFFERENCE BETWEEN THE TWO HOSTS, and the reason this wrapper exists rather than each
|
|
38
|
+
* host looping for itself. Power BI hands the visual a DIFFERENT theme colour per slot
|
|
39
|
+
* (`getColor("1")`, `getColor("2")`, ...), so its loop varies the seed and the walk mostly
|
|
40
|
+
* settles at step 1. Excel has no such API: a workbook offers ONE resolvable accent - the fill
|
|
41
|
+
* a themed table style actually painted - so every slot is seeded from the SAME colour and the
|
|
42
|
+
* walk does the spreading, saturation first, then lightness, then hue.
|
|
43
|
+
*
|
|
44
|
+
* That ordering is why one accent is enough to be worth doing. The early slots stay in the
|
|
45
|
+
* seed's own hue family, so a two- or three-series chart reads as the workbook's colour rather
|
|
46
|
+
* than as a stranger's; only once those are exhausted does it rotate away. A host with one
|
|
47
|
+
* brand colour gets a palette that still looks like the brand.
|
|
48
|
+
*
|
|
49
|
+
* Deterministic: same seed and count in, same array out, which is what lets a host PERSIST the
|
|
50
|
+
* result and re-derive it later without the colours shifting under a saved chart.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildPaletteFromSeed(seedHex: string, count: number, minDistance?: number): string[];
|
|
53
|
+
/**
|
|
54
|
+
* WHERE EACH SLOT'S BASE COLOUR COMES FROM. Called with the slot index, 0-based.
|
|
55
|
+
*
|
|
56
|
+
* Returning a blank or nothing means "no base colour for this slot" - the builder then falls
|
|
57
|
+
* back to the last one that WAS supplied, so a host whose colour source runs dry degrades into
|
|
58
|
+
* spreading rather than into a gap.
|
|
59
|
+
*/
|
|
60
|
+
export type SeedForSlot = (slot: number) => string | null | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The general form: a palette whose BASE COLOURS the host decides, slot by slot.
|
|
63
|
+
*
|
|
64
|
+
* THIS IS THE RICH FORM AND `buildPaletteFromSeed` IS THE DEGENERATE ONE. Read that sentence
|
|
65
|
+
* before "simplifying" a host onto the single-seed call, because the difference is a real loss
|
|
66
|
+
* and it is invisible in the output - both return a plausible list of distinct colours.
|
|
67
|
+
*
|
|
68
|
+
* Power BI hands a visual a DIFFERENT theme colour per slot (`colorPalette.getColor("1")`,
|
|
69
|
+
* `getColor("2")`, ...). Every one of those is a deliberate choice by whoever built the report
|
|
70
|
+
* theme, and feeding them in per slot means the walk usually settles at step 1 and RETURNS THEM
|
|
71
|
+
* UNCHANGED - the chart is coloured by the theme, not by our arithmetic. Collapse that host onto
|
|
72
|
+
* one seed and twenty authored colours become one authored colour plus nineteen derived ones:
|
|
73
|
+
* still distinct, still pretty, and no longer the report's.
|
|
74
|
+
*
|
|
75
|
+
* A host with no such API - an Excel workbook offers exactly one resolvable accent - passes a
|
|
76
|
+
* constant provider and the walk does the spreading. That is a fallback, not the design.
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildPalette(seedFor: SeedForSlot, count: number, minDistance?: number): string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.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",
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"// devDependencies": "@bicharts/shape-core is deliberately NOT declared. It is a workspace sibling that npm links regardless, and its code is BUNDLED into dist, so a consumer never installs it. Declaring it made this package a registry DEPENDENT of shape-core, which blocks lifecycle operations on that package in exchange for nothing. Do not add it back; if the build stops resolving it, fix the workspace, not the manifest.",
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/react": "^19.2.17",
|
|
71
|
+
"colorsea": "^1.2.2",
|
|
71
72
|
"esbuild": "^0.28.1",
|
|
72
73
|
"react": "^19.2.8",
|
|
73
74
|
"react-dom": "^19.2.8",
|