@bicharts/chart-host 0.5.87 → 0.5.88

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.
@@ -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, buildPaletteFromSeed, type PaletteResult } from "./palette";
@@ -0,0 +1,52 @@
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[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.87",
3
+ "version": "0.5.88",
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",