@bicharts/chart-host 0.5.86 → 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.
package/dist/react.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  createChartHost,
5
5
  geoFromCache,
6
6
  loadGeo
7
- } from "./chunk-R4STRHXO.mjs";
7
+ } from "./chunk-NWMMNXH2.mjs";
8
8
  import "./chunk-A2GMXZP7.mjs";
9
9
  import "./chunk-GHODWOAL.mjs";
10
10
 
@@ -15,6 +15,7 @@ export { qualifyGroupHeadingFor, newQualifyGroupState, type QualifyGroupRow, typ
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
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
+ export { formatSourceDate, formatSourceDateFor, type SourceFormats, type SourceFormatDialect, type SourceDateOptions, } from "./sourceDateFormat";
18
19
  export { ensureCrossfilterHitTargets, type HitTargetReport } from "./hitTargets";
19
20
  export { applyLabelContrast, LABEL_CONTRAST_DONE_ATTR, LABEL_CONTRAST_CAP, type LabelContrastOptions, type LabelContrastReport, } from "./labelContrastDom";
20
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";
@@ -24,3 +25,4 @@ export { SCROLL_SLACK_PX, MAX_FRAME_GROW_FACTOR, PHANTOM_FRACTION, FIT_CONTENT_S
24
25
  export { fitRenderedChart, fitReadingFor, measureContainerBoxes, svgInkReach, ctmScaleOf, type FitReading, type InkReach, type FitRenderedChartOptions, type FitRenderedChartResult, } from "./fitDom";
25
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";
26
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[];
@@ -1,4 +1,5 @@
1
1
  import type { RenderPayload } from "./payload";
2
+ import { type SourceFormats } from "./sourceDateFormat";
2
3
  export interface SelectionCardOptions {
3
4
  /** The chart's own aggregation, so the card AGREES with the picture it sits on. A card
4
5
  * reading "Sum" beside a chart drawn from averages is two answers to one question.
@@ -24,6 +25,16 @@ export interface SelectionCardOptions {
24
25
  * cap already had (on the sample table the two coordinate columns took two of the four
25
26
  * measure slots and pushed the real measures under "+2 more"). Default 2. */
26
27
  maxDimensions?: number;
28
+ /** THE SOURCE'S OWN DATE FORMATS, keyed by column name, plus the dialect they are written in
29
+ * — Excel's `range.numberFormat` for the add-in, a `.NET` format string for the visual.
30
+ *
31
+ * Optional, and the fallback is deliberately good rather than minimal: a host that supplies
32
+ * nothing still gets a locale date instead of the ISO instant this replaced, so the MCP and
33
+ * React hosts (a CSV has no cell formatting to read) and every chart cached before today
34
+ * improve without anyone plumbing anything. What the map buys is AGREEMENT with the cells
35
+ * the card is floating over — a sheet that shows `31-Aug-25` gets a card that says
36
+ * `31-Aug-25`. */
37
+ sourceFormats?: SourceFormats | null;
27
38
  }
28
39
  export interface SelectionCardLine {
29
40
  column: string;
@@ -0,0 +1,30 @@
1
+ /** Which vocabulary a source format string is written in. See the header note - this is stated
2
+ * by the host that owns the format, never inferred from the string. */
3
+ export type SourceFormatDialect = "excel" | "dotnet";
4
+ /** A host's per-column source formats. The dialect is carried WITH the map rather than passed
5
+ * beside it, so a caller cannot supply one without the other. */
6
+ export interface SourceFormats {
7
+ dialect: SourceFormatDialect;
8
+ /** Keyed by column name, which is the key the payload's columns already carry. Absent or
9
+ * blank for a column with no source format - a computed column, a CSV, a text date whose
10
+ * own text IS its formatting. */
11
+ byColumn: Record<string, string>;
12
+ }
13
+ export interface SourceDateOptions {
14
+ /** The source's own format string for this column, if it has one. */
15
+ format?: string | null;
16
+ /** Which vocabulary `format` is written in. Ignored when `format` is absent. */
17
+ dialect?: SourceFormatDialect;
18
+ /** BCP-47 tag, for month and weekday names and for the locale fallback. */
19
+ culture?: string;
20
+ }
21
+ /**
22
+ * Render a temporal payload value for a reader, or NULL when the value is not a date at all.
23
+ *
24
+ * Null rather than a best-effort string, so a caller can fall through to whatever it did before
25
+ * without this file having an opinion about non-dates. Accepts a `Date` (what a host holds before
26
+ * the payload is built) and an ISO string (what the payload carries after it).
27
+ */
28
+ export declare function formatSourceDate(raw: any, opts?: SourceDateOptions): string | null;
29
+ /** Convenience for a caller holding a `SourceFormats` map and a column name. */
30
+ export declare function formatSourceDateFor(raw: any, columnName: string, formats: SourceFormats | null | undefined, culture?: string): string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bicharts/chart-host",
3
- "version": "0.5.86",
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",