graphein 0.14.0 → 0.16.0

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.d.ts CHANGED
@@ -2969,6 +2969,14 @@ declare function prettyDate(value: Date | number): string;
2969
2969
  * `"2024-05-02"` renders `May 2, 2024` rather than the raw string.
2970
2970
  */
2971
2971
  declare function formatValue(value: unknown, hint?: string): string;
2972
+ /**
2973
+ * Format one frame of a count-up / value tween so it never shows finer precision
2974
+ * than the final value. With an explicit format the decimals are already pinned,
2975
+ * so this defers to {@link formatValue}. With the smart default it mirrors the
2976
+ * final value's own precision (a whole-number target stays whole) — otherwise a
2977
+ * tween between integers would flash up to 6 decimals mid-animation.
2978
+ */
2979
+ declare function formatCountUp(displayValue: number, finalValue: number, hint?: string): string;
2972
2980
 
2973
2981
  /**
2974
2982
  * Layout engine.
@@ -3873,6 +3881,14 @@ interface RenderOptions {
3873
3881
  * flat so the chrome isn't doubled. Optional; defaults to false.
3874
3882
  */
3875
3883
  frame?: boolean;
3884
+ /**
3885
+ * Publish the chart's effective config (spec minus `data`) to a
3886
+ * `data-graphein-spec` DOM attribute on the root and re-render when an external
3887
+ * tool edits it (merging the edit with the chart's in-memory data). Lets browser
3888
+ * tools identify and live-edit the chart from the DOM. Optional; defaults to true.
3889
+ * Set `false` to opt out (no attribute, no observer).
3890
+ */
3891
+ inspect?: boolean;
3876
3892
  }
3877
3893
  interface ChartInstance {
3878
3894
  /** Re-render with a new spec (data or config changes). */
@@ -3912,6 +3928,62 @@ declare global {
3912
3928
  }
3913
3929
  declare function render(target: HTMLElement | string, spec: ChartSpec, options?: RenderOptions): ChartInstance;
3914
3930
 
3931
+ /**
3932
+ * DOM spec publishing — makes a rendered chart identifiable and editable by
3933
+ * external tools (agents, devtools extensions, page scripts) straight from the
3934
+ * DOM, with no JS handle required.
3935
+ *
3936
+ * Each chart/dashboard root carries:
3937
+ * - `data-graphein-spec`: the effective spec **minus its `data` array** (config
3938
+ * only), JSON-serialized. Compact, and no row-level data leaks into the DOM.
3939
+ * - `data-graphein-type`: the chart/dashboard `type`, so a tool can find and
3940
+ * filter Graphein visuals cheaply (`querySelectorAll('[data-graphein-spec]')`)
3941
+ * without parsing JSON.
3942
+ *
3943
+ * Editing `data-graphein-spec` is **two-way**: a {@link MutationObserver} reports
3944
+ * the change and the runtime re-renders, merging the edited config with the
3945
+ * chart's existing in-memory data (see the runtime's `onExternalEdit`). Malformed
3946
+ * edits are ignored so a tool can't break a live chart mid-keystroke.
3947
+ */
3948
+ /** Attribute holding the JSON-serialized config (spec without `data`). */
3949
+ declare const SPEC_ATTR = "data-graphein-spec";
3950
+ /** Attribute holding the chart/dashboard type, for cheap querying. */
3951
+ declare const TYPE_ATTR = "data-graphein-type";
3952
+ interface SpecLike {
3953
+ type?: unknown;
3954
+ data?: unknown;
3955
+ }
3956
+ /** A shallow copy of a spec without its top-level `data` array (config only). */
3957
+ declare function stripData<T extends SpecLike>(spec: T): Omit<T, 'data'>;
3958
+ /** Serialize a spec's config (its `data` excluded) to a JSON string. */
3959
+ declare function serializeSpec(spec: SpecLike): string;
3960
+ interface Inspector {
3961
+ /**
3962
+ * Publish `spec`'s config to the root. Writes `data-graphein-spec` only when the
3963
+ * serialized config actually changed (so resize/animation frames don't churn the
3964
+ * DOM), and refreshes `data-graphein-type`.
3965
+ */
3966
+ write(spec: SpecLike): void;
3967
+ /** Stop observing. Leaves the published attributes in place. */
3968
+ destroy(): void;
3969
+ }
3970
+ interface InspectorOptions {
3971
+ /**
3972
+ * Invoked when an external agent edits `data-graphein-spec` to a value the
3973
+ * inspector didn't write, with the parsed config object. JSON parse failures and
3974
+ * non-object payloads are swallowed (the last good render is kept).
3975
+ */
3976
+ onExternalEdit(config: Record<string, unknown>): void;
3977
+ }
3978
+ /**
3979
+ * Wire spec-publishing + two-way editing onto a chart/dashboard root element.
3980
+ *
3981
+ * The {@link MutationObserver} is created only when the API exists, so this is a
3982
+ * no-op observer in SSR/Node/headless environments (attributes are still set,
3983
+ * which is harmless).
3984
+ */
3985
+ declare function createInspector(root: HTMLElement, options: InspectorOptions): Inspector;
3986
+
3915
3987
  /**
3916
3988
  * Dashboard auto-wiring — pure spec rewriting that turns a set of views into
3917
3989
  * cross-interacting ones by injecting `params` (sources), `highlight`, and
@@ -3955,6 +4027,13 @@ declare function wireViews(views: DashboardView[], interactions: 'auto' | 'none'
3955
4027
  interface RenderDashboardOptions {
3956
4028
  /** Share a bus with charts/dashboards outside this one. */
3957
4029
  store?: SelectionStore;
4030
+ /**
4031
+ * Publish each view's config (and the dashboard's) to `data-graphein-spec` DOM
4032
+ * attributes and re-render on external edits, so browser tools can identify and
4033
+ * live-edit the page from the DOM. Optional; defaults to true. Set `false` to opt
4034
+ * out for the whole dashboard (propagates to every view).
4035
+ */
4036
+ inspect?: boolean;
3958
4037
  }
3959
4038
  interface DashboardInstance {
3960
4039
  /** Re-render with a new dashboard spec (keeps the shared store/selection). */
@@ -4017,4 +4096,4 @@ declare function renderDashboard(target: HTMLElement | string, spec: DashboardSp
4017
4096
  */
4018
4097
  declare const VERSION = "0.1.0";
4019
4098
 
4020
- export { type AggOp, type AggregateOp, type AggregateTransform, type AnimateOptions, type AnimationConfig, type AnimationHandle, type Annotation, type AnySpec, type ArcOptions, type AreaOptions, type AreaPoint, type AreaSpec, type AxesConfig, type AxisConfig, type AxisInput, type BackingSize, type BandScale, type BandScaleOptions, type BarSpec, type BaseSlicerSpec, type BaseSpec, type BinLayout, type BinTransform, type BoxSpec, type BuildOptions, type BulletSpec, CARTESIAN_TYPES, CHART_TYPES, type CalculateTransform, type CalendarHeatmapSpec, CanvasLayer, type CanvasPillStyle, type CanvasTextCmd, type CartesianChartSpec, type CartesianInteractionBuilder, type CartesianModel, type CartesianRenderer, type CategoryInsights, type ChartInsights, type ChartInstance, type ChartSpec, type ChartSummary, type ChartType, type ChoroplethSpec, type ColorScale, type ColumnProfile, type ComboAxisModel, type ComboLayer, type ComboLayerModel, type ComboMark, type ComboModel, type ComboSide, type ComboSpec, type Comparable, type ConditionalFormat, type ContinuousScale, type ControllerSelect, type Curve, type CurveType, type CustomRenderer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, type DashboardCell, type DashboardInstance, type DashboardLayout, type DashboardResponsiveSpan, type DashboardSection, type DashboardSpec, type DashboardView, type DateRangeSlicerSpec, type Datum, type DecimateOptions, type Dimensions, type DropdownSlicerSpec, type DumbbellSpec, type EasingFunction, type Emphasis, type Encoding, type EntranceContext, ExpressionError, type Extent, FACETABLE_TYPES, FUNCTION_NAMES, type FacetConfig, type FacetLayout, type FacetPanel, type FieldDef, type FieldType, type FieldValue, type FillStyle, type FilterClause, type FilterPredicate, type FilterTransform, type FoldTransform, type Frame, type FrameInput, type FunnelSpec, type GaugeSpec, type GeoFeature, type GeoFeatureCollection, type GeoGeometry, type GeoMultiPolygon, type GeoPolygon, type GeoPosition, type GroupedMap, type HachureSegment, type HeadlessTarget, type HeatmapSpec, type HighlightConfig, type HistogramBin, type HistogramBinDatum, type HistogramModel, type HistogramSpec, type Hover, type IconRule, type Insets, type InsightFamily, type InsightOptions, InteractionController, type InteractionLink, type InteractionModel, type Interpolator, type JsonPatchOp, type KpiComparison, type KpiSpec, type LegendConfig, type LegendHitRegion, type LegendItem, type LegendPosition, type LegendSymbol, type LineOptions, type LineSpec, type LinearScaleOptions, type LintFinding, type ListSlicerSpec, type LiteralPredicate, type LogScaleOptions, type MapProjection, type MarkOptions, type MatrixSpec, type MatrixValueDef, NO_PADDING, type NumberFormatSpec, type OKLCH, type OKLab, type OverlayTextOpts, type PathSink, type PieLabels, type PieSpec, type PivotCell, type PivotFlatRow, type PivotHeaderNode, type PivotOptions, type PivotResult, type PivotValueDef, type Point, type PointRef, type PointScale, type PointScaleOptions, type PointSelection, type PositionedLegendItem, type RGBA, type RangeSelection, type RangeSlicerSpec, type RecommendOptions, type RecommendedChart, type Rect, type RegressionFit, type RenderContext, type RenderDashboardOptions, type RenderDiagnostic, type RenderOptions, type RenderReport, type RepairResult, type ReportInput, type ReportSeverity, type ResolvedEntrance, type ResolvedSeries, type ResolvedSketch, type Rng, type RoughContext, RoughPen, type RoughStyle, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SR_ONLY_STYLE, type SankeySpec, type ScaleConfig, type ScaleType, type ScatterInsights, type ScatterSpec, type SearchSlicerSpec, type SelectConfig, type SelectionChangeListener, type SelectionDef, type SelectionListener, type SelectionParam, type SelectionStore, type SelectionValue, type SeriesInsights, type SetSelection, type SharedScales, type Size, type SketchConfig, type SlicerSpec, type SlicerType, type SlopeSpec, Surface, TICK_SIZE, TIME_UNITS, TRANSFORM_KINDS, type TableColumn, type TableSpec, type TextMetricsLite, type TextSelection, type ThemeColors, type ThemeFont, type ThemeInput, type ThemeTokens, type Tick, type TimeScaleOptions, type TimeUnit, type TimeUnitTransform, type TitleConfig, type TitleInput, Tooltip, type TooltipConfig, type TooltipContent, type TooltipRow, type Transform, type TreemapSpec, type TrendlineConfig, type UpdateContext, VERSION, type ValidationError, type ValidationResult, type ValueInsights, type ValueRef, type ValueRule, type WaterfallSpec, type WiredView, type XKind, type XModel, type YModel, aggregateValues, analyzeChart, animate, applyA11y, applyAggregate, applyBin, applyCalculate, applyFilter, applyFold, applyPatch, applyPick, applyTimeUnit, applyTransform, applyTransforms, arc, area, assertValidSpec, autoInsightAnnotations, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildComboModel, buildDataTableFallback, buildFacetModels, buildHistogramModel, buildRenderReport, cartesianInteractionBuilders, cartesianRenderers, categorical, categoricalSchemes, chartTitleText, chartTypeLabel, checkExpression, clamp01, clamp255, compileExpression, compilePredicate, computeBackingSize, computeBins, computeFrame, computeSeriesInsights, contrastRatio, createDiv, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, defaultSpan, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAnnotationLabels, drawAnnotations, drawAxesUnderlay, drawFacet, drawLegend, drawOverlay, drawTitle, drawTrendlineLabels, drawTrendlines, easings, elasticOut, ellipsize, ensureSketchFont, expoInOut, expoOut, facetReport, fillParentStyle, filterRows, fontString, formatDate, formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, inheritInto, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isFaceted, isParamClause, isSlicerType, keyFields, legendSwatchWidth, lightTheme, line, linear, linearRegression, linearScale, linearToSrgb, lintSpec, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, overlayTextToCanvasCmd, paintCanvasText, paintLegendSwatch, parseColor, parseNumberFormat, pivot, placeViews, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, profileColumns, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, recommendChart, relativeLuminance, render, renderDashboard, renderToContext, repairReport, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, resolveValueRef, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, setMeasureContext, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, summarize, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, toPointer, tooltipEnabled, truncateTo, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
4099
+ export { type AggOp, type AggregateOp, type AggregateTransform, type AnimateOptions, type AnimationConfig, type AnimationHandle, type Annotation, type AnySpec, type ArcOptions, type AreaOptions, type AreaPoint, type AreaSpec, type AxesConfig, type AxisConfig, type AxisInput, type BackingSize, type BandScale, type BandScaleOptions, type BarSpec, type BaseSlicerSpec, type BaseSpec, type BinLayout, type BinTransform, type BoxSpec, type BuildOptions, type BulletSpec, CARTESIAN_TYPES, CHART_TYPES, type CalculateTransform, type CalendarHeatmapSpec, CanvasLayer, type CanvasPillStyle, type CanvasTextCmd, type CartesianChartSpec, type CartesianInteractionBuilder, type CartesianModel, type CartesianRenderer, type CategoryInsights, type ChartInsights, type ChartInstance, type ChartSpec, type ChartSummary, type ChartType, type ChoroplethSpec, type ColorScale, type ColumnProfile, type ComboAxisModel, type ComboLayer, type ComboLayerModel, type ComboMark, type ComboModel, type ComboSide, type ComboSpec, type Comparable, type ConditionalFormat, type ContinuousScale, type ControllerSelect, type Curve, type CurveType, type CustomRenderer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, type DashboardCell, type DashboardInstance, type DashboardLayout, type DashboardResponsiveSpan, type DashboardSection, type DashboardSpec, type DashboardView, type DateRangeSlicerSpec, type Datum, type DecimateOptions, type Dimensions, type DropdownSlicerSpec, type DumbbellSpec, type EasingFunction, type Emphasis, type Encoding, type EntranceContext, ExpressionError, type Extent, FACETABLE_TYPES, FUNCTION_NAMES, type FacetConfig, type FacetLayout, type FacetPanel, type FieldDef, type FieldType, type FieldValue, type FillStyle, type FilterClause, type FilterPredicate, type FilterTransform, type FoldTransform, type Frame, type FrameInput, type FunnelSpec, type GaugeSpec, type GeoFeature, type GeoFeatureCollection, type GeoGeometry, type GeoMultiPolygon, type GeoPolygon, type GeoPosition, type GroupedMap, type HachureSegment, type HeadlessTarget, type HeatmapSpec, type HighlightConfig, type HistogramBin, type HistogramBinDatum, type HistogramModel, type HistogramSpec, type Hover, type IconRule, type Insets, type InsightFamily, type InsightOptions, type Inspector, type InspectorOptions, InteractionController, type InteractionLink, type InteractionModel, type Interpolator, type JsonPatchOp, type KpiComparison, type KpiSpec, type LegendConfig, type LegendHitRegion, type LegendItem, type LegendPosition, type LegendSymbol, type LineOptions, type LineSpec, type LinearScaleOptions, type LintFinding, type ListSlicerSpec, type LiteralPredicate, type LogScaleOptions, type MapProjection, type MarkOptions, type MatrixSpec, type MatrixValueDef, NO_PADDING, type NumberFormatSpec, type OKLCH, type OKLab, type OverlayTextOpts, type PathSink, type PieLabels, type PieSpec, type PivotCell, type PivotFlatRow, type PivotHeaderNode, type PivotOptions, type PivotResult, type PivotValueDef, type Point, type PointRef, type PointScale, type PointScaleOptions, type PointSelection, type PositionedLegendItem, type RGBA, type RangeSelection, type RangeSlicerSpec, type RecommendOptions, type RecommendedChart, type Rect, type RegressionFit, type RenderContext, type RenderDashboardOptions, type RenderDiagnostic, type RenderOptions, type RenderReport, type RepairResult, type ReportInput, type ReportSeverity, type ResolvedEntrance, type ResolvedSeries, type ResolvedSketch, type Rng, type RoughContext, RoughPen, type RoughStyle, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SPEC_ATTR, SR_ONLY_STYLE, type SankeySpec, type ScaleConfig, type ScaleType, type ScatterInsights, type ScatterSpec, type SearchSlicerSpec, type SelectConfig, type SelectionChangeListener, type SelectionDef, type SelectionListener, type SelectionParam, type SelectionStore, type SelectionValue, type SeriesInsights, type SetSelection, type SharedScales, type Size, type SketchConfig, type SlicerSpec, type SlicerType, type SlopeSpec, Surface, TICK_SIZE, TIME_UNITS, TRANSFORM_KINDS, TYPE_ATTR, type TableColumn, type TableSpec, type TextMetricsLite, type TextSelection, type ThemeColors, type ThemeFont, type ThemeInput, type ThemeTokens, type Tick, type TimeScaleOptions, type TimeUnit, type TimeUnitTransform, type TitleConfig, type TitleInput, Tooltip, type TooltipConfig, type TooltipContent, type TooltipRow, type Transform, type TreemapSpec, type TrendlineConfig, type UpdateContext, VERSION, type ValidationError, type ValidationResult, type ValueInsights, type ValueRef, type ValueRule, type WaterfallSpec, type WiredView, type XKind, type XModel, type YModel, aggregateValues, analyzeChart, animate, applyA11y, applyAggregate, applyBin, applyCalculate, applyFilter, applyFold, applyPatch, applyPick, applyTimeUnit, applyTransform, applyTransforms, arc, area, assertValidSpec, autoInsightAnnotations, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildComboModel, buildDataTableFallback, buildFacetModels, buildHistogramModel, buildRenderReport, cartesianInteractionBuilders, cartesianRenderers, categorical, categoricalSchemes, chartTitleText, chartTypeLabel, checkExpression, clamp01, clamp255, compileExpression, compilePredicate, computeBackingSize, computeBins, computeFrame, computeSeriesInsights, contrastRatio, createDiv, createInspector, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, defaultSpan, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAnnotationLabels, drawAnnotations, drawAxesUnderlay, drawFacet, drawLegend, drawOverlay, drawTitle, drawTrendlineLabels, drawTrendlines, easings, elasticOut, ellipsize, ensureSketchFont, expoInOut, expoOut, facetReport, fillParentStyle, filterRows, fontString, formatCountUp, formatDate, formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, inheritInto, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isFaceted, isParamClause, isSlicerType, keyFields, legendSwatchWidth, lightTheme, line, linear, linearRegression, linearScale, linearToSrgb, lintSpec, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, overlayTextToCanvasCmd, paintCanvasText, paintLegendSwatch, parseColor, parseNumberFormat, pivot, placeViews, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, profileColumns, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, recommendChart, relativeLuminance, render, renderDashboard, renderToContext, repairReport, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, resolveValueRef, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, serializeSpec, setMeasureContext, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, stripData, summarize, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, toPointer, tooltipEnabled, truncateTo, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
package/dist/index.js CHANGED
@@ -2300,6 +2300,19 @@ function formatValue(value, hint) {
2300
2300
  }
2301
2301
  return String(value);
2302
2302
  }
2303
+ function decimalPlaces2(n) {
2304
+ if (!Number.isFinite(n) || Number.isInteger(n)) return 0;
2305
+ const s = Math.abs(n).toString();
2306
+ if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return 6;
2307
+ const dot = s.indexOf(".");
2308
+ return dot === -1 ? 0 : s.length - dot - 1;
2309
+ }
2310
+ function formatCountUp(displayValue, finalValue, hint) {
2311
+ if (hint) return formatValue(displayValue, hint);
2312
+ const dp = decimalPlaces2(finalValue);
2313
+ const q = dp === 0 ? Math.round(displayValue) : Number(displayValue.toFixed(dp));
2314
+ return formatValue(q, hint);
2315
+ }
2303
2316
 
2304
2317
  // src/pivot/pivot.ts
2305
2318
  var GRAND_TOTAL_LABEL = "Grand Total";
@@ -9611,7 +9624,7 @@ function drawKpi(surface, spec, tokens, size, context) {
9611
9624
  const displayValue = value != null && progress != null && progress < 1 ? from + (value - from) * progress : value;
9612
9625
  const displaySparkValues = morphSparkline(sparkValues, context?.sparklineFrom, progress);
9613
9626
  const valueText = value == null ? "\u2014" : formatValue(value, kpi.format);
9614
- const displayText = displayValue == null ? "\u2014" : formatValue(displayValue, kpi.format);
9627
+ const displayText = displayValue == null ? "\u2014" : formatCountUp(displayValue, value, kpi.format);
9615
9628
  const fromText = context?.valueFrom != null && value != null ? formatValue(context.valueFrom, kpi.format) : valueText;
9616
9629
  const sizingText = fromText.length > valueText.length ? fromText : valueText;
9617
9630
  const pad3 = framed ? 0 : tokens.spacing.lg;
@@ -14627,7 +14640,7 @@ function drawGauge(surface, spec, tokens, size, context) {
14627
14640
  const sweepT = context?.sweepProgress ?? 1;
14628
14641
  const from = context?.valueFrom ?? min;
14629
14642
  const displayValue = from + (value - from) * sweepT;
14630
- const shownText = formatValue(displayValue, gauge.format);
14643
+ const shownText = formatCountUp(displayValue, value, gauge.format);
14631
14644
  const valueAngle = toAngle(displayValue);
14632
14645
  strokePoints(ctx, pen, arcPoints(cx, cy, radius, Math.PI, 0), track, trackWidth);
14633
14646
  if (valueAngle < Math.PI) {
@@ -17450,6 +17463,54 @@ function onFontsReady(cb) {
17450
17463
  });
17451
17464
  }
17452
17465
 
17466
+ // src/runtime/inspect.ts
17467
+ var SPEC_ATTR = "data-graphein-spec";
17468
+ var TYPE_ATTR = "data-graphein-type";
17469
+ function stripData(spec) {
17470
+ const { data: _data, ...config } = spec;
17471
+ return config;
17472
+ }
17473
+ function serializeSpec(spec) {
17474
+ return JSON.stringify(stripData(spec));
17475
+ }
17476
+ function createInspector(root, options) {
17477
+ let lastWritten = null;
17478
+ let disposed = false;
17479
+ const write = (spec) => {
17480
+ const type = typeof spec.type === "string" ? spec.type : "";
17481
+ if (type) root.setAttribute(TYPE_ATTR, type);
17482
+ const json = serializeSpec(spec);
17483
+ if (json === lastWritten) return;
17484
+ lastWritten = json;
17485
+ root.setAttribute(SPEC_ATTR, json);
17486
+ };
17487
+ let observer;
17488
+ if (typeof MutationObserver !== "undefined") {
17489
+ observer = new MutationObserver(() => {
17490
+ if (disposed) return;
17491
+ const current = root.getAttribute(SPEC_ATTR);
17492
+ if (current == null || current === lastWritten) return;
17493
+ let parsed;
17494
+ try {
17495
+ parsed = JSON.parse(current);
17496
+ } catch {
17497
+ return;
17498
+ }
17499
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return;
17500
+ lastWritten = current;
17501
+ options.onExternalEdit(parsed);
17502
+ });
17503
+ observer.observe(root, { attributes: true, attributeFilter: [SPEC_ATTR] });
17504
+ }
17505
+ return {
17506
+ write,
17507
+ destroy() {
17508
+ disposed = true;
17509
+ observer?.disconnect();
17510
+ }
17511
+ };
17512
+ }
17513
+
17453
17514
  // src/runtime/render.ts
17454
17515
  var CANVAS_MARK_TYPES = /* @__PURE__ */ new Set([
17455
17516
  "line",
@@ -17460,7 +17521,16 @@ var CANVAS_MARK_TYPES = /* @__PURE__ */ new Set([
17460
17521
  "pie",
17461
17522
  "heatmap",
17462
17523
  "sankey",
17463
- "choropleth"
17524
+ "choropleth",
17525
+ "combo",
17526
+ "histogram",
17527
+ "funnel",
17528
+ "treemap",
17529
+ "waterfall",
17530
+ "calendarHeatmap",
17531
+ "slope",
17532
+ "dumbbell",
17533
+ "bullet"
17464
17534
  ]);
17465
17535
  var COUNT_UP_TYPES = /* @__PURE__ */ new Set(["kpi"]);
17466
17536
  var SWEEP_TYPES = /* @__PURE__ */ new Set(["pie", "gauge"]);
@@ -17727,6 +17797,7 @@ function render(target, spec, options) {
17727
17797
  interaction.setSelect(null);
17728
17798
  }
17729
17799
  applyA11y(surface, currentSpec);
17800
+ inspector?.write(currentSpec);
17730
17801
  lastReport = facetRpt ?? buildRenderReport({
17731
17802
  type,
17732
17803
  spec: currentSpec,
@@ -17776,6 +17847,46 @@ function render(target, spec, options) {
17776
17847
  });
17777
17848
  observer.observe(container);
17778
17849
  }
17850
+ const update = (next) => {
17851
+ updateTransition?.cancel();
17852
+ updateTransition = void 0;
17853
+ for (const param of next.params ?? []) {
17854
+ if (param.value !== void 0 && store.get(param.name) == null) {
17855
+ store.set(param.name, param.value ?? null);
17856
+ }
17857
+ }
17858
+ const prevType = currentSpec.type;
17859
+ const prevW = surface.width;
17860
+ const prevH = surface.height;
17861
+ const anim = resolveUpdate(next.animation, {
17862
+ reducedMotion: prefersReducedMotion(),
17863
+ disabled: globalThis.__GRAPHEIN_DISABLE_ANIM === true
17864
+ });
17865
+ const wantFade = anim.enabled && CANVAS_MARK_TYPES.has(prevType) && CANVAS_MARK_TYPES.has(next.type);
17866
+ const before = wantFade ? snapshotLayer(surface.marks) : void 0;
17867
+ const prevValue = lastValue;
17868
+ const prevCompare = lastCompare;
17869
+ const prevSparkline = lastSparkline;
17870
+ const wantValueTween = prevType === next.type && (COUNT_UP_TYPES.has(next.type) || SWEEP_TYPES.has(next.type)) && prevValue != null;
17871
+ const wantSparklineTween = prevType === next.type && next.type === "kpi" && prevSparkline != null && prevSparkline.length > 0;
17872
+ currentSpec = next;
17873
+ draw(
17874
+ false,
17875
+ wantValueTween ? prevValue ?? void 0 : void 0,
17876
+ wantValueTween ? prevCompare ?? void 0 : void 0,
17877
+ wantValueTween || wantSparklineTween ? prevSparkline ?? void 0 : void 0
17878
+ );
17879
+ if (before && surface.width === prevW && surface.height === prevH && surface.marks.canvas.width === before.width && surface.marks.canvas.height === before.height) {
17880
+ updateTransition = runUpdateCrossfade(surface, before, anim);
17881
+ }
17882
+ };
17883
+ const onExternalEdit = (config) => {
17884
+ if (destroyed) return;
17885
+ const merged = { ...config, data: currentSpec.data };
17886
+ if (validateSpec(merged).errors.length > 0) return;
17887
+ update(merged);
17888
+ };
17889
+ const inspector = options?.inspect === false ? void 0 : createInspector(surface.root, { onExternalEdit });
17779
17890
  const unsubscribe = store.subscribe((name, value) => {
17780
17891
  for (const listener of [...hostListeners]) listener(name, value);
17781
17892
  if (destroyed) return;
@@ -17818,37 +17929,7 @@ function render(target, spec, options) {
17818
17929
  hostListeners.delete(listener);
17819
17930
  },
17820
17931
  update(next) {
17821
- updateTransition?.cancel();
17822
- updateTransition = void 0;
17823
- for (const param of next.params ?? []) {
17824
- if (param.value !== void 0 && store.get(param.name) == null) {
17825
- store.set(param.name, param.value ?? null);
17826
- }
17827
- }
17828
- const prevType = currentSpec.type;
17829
- const prevW = surface.width;
17830
- const prevH = surface.height;
17831
- const anim = resolveUpdate(next.animation, {
17832
- reducedMotion: prefersReducedMotion(),
17833
- disabled: globalThis.__GRAPHEIN_DISABLE_ANIM === true
17834
- });
17835
- const wantFade = anim.enabled && CANVAS_MARK_TYPES.has(prevType) && CANVAS_MARK_TYPES.has(next.type);
17836
- const before = wantFade ? snapshotLayer(surface.marks) : void 0;
17837
- const prevValue = lastValue;
17838
- const prevCompare = lastCompare;
17839
- const prevSparkline = lastSparkline;
17840
- const wantValueTween = prevType === next.type && (COUNT_UP_TYPES.has(next.type) || SWEEP_TYPES.has(next.type)) && prevValue != null;
17841
- const wantSparklineTween = prevType === next.type && next.type === "kpi" && prevSparkline != null && prevSparkline.length > 0;
17842
- currentSpec = next;
17843
- draw(
17844
- false,
17845
- wantValueTween ? prevValue ?? void 0 : void 0,
17846
- wantValueTween ? prevCompare ?? void 0 : void 0,
17847
- wantValueTween || wantSparklineTween ? prevSparkline ?? void 0 : void 0
17848
- );
17849
- if (before && surface.width === prevW && surface.height === prevH && surface.marks.canvas.width === before.width && surface.marks.canvas.height === before.height) {
17850
- updateTransition = runUpdateCrossfade(surface, before, anim);
17851
- }
17932
+ update(next);
17852
17933
  },
17853
17934
  resize() {
17854
17935
  draw(false);
@@ -17860,6 +17941,7 @@ function render(target, spec, options) {
17860
17941
  entrance?.cancel();
17861
17942
  updateTransition?.cancel();
17862
17943
  observer?.disconnect();
17944
+ inspector?.destroy();
17863
17945
  interaction?.destroy();
17864
17946
  surface.destroy();
17865
17947
  }
@@ -18343,6 +18425,7 @@ function renderDashboard(target, spec, options) {
18343
18425
  const hostListeners = /* @__PURE__ */ new Set();
18344
18426
  let root;
18345
18427
  let resizeObs;
18428
+ let dashboardInspector;
18346
18429
  let destroyed = false;
18347
18430
  let sourceCells = /* @__PURE__ */ new Map();
18348
18431
  const syncSourceCell = (name, value) => {
@@ -18434,7 +18517,7 @@ function renderDashboard(target, spec, options) {
18434
18517
  const mount = (host, view) => {
18435
18518
  const finalSpec = inheritInto(view.spec, currentSpec, tokens, !!(view.title || view.subtitle));
18436
18519
  try {
18437
- instances.push(render(host, finalSpec, { store, frame: view.frame ?? true }));
18520
+ instances.push(render(host, finalSpec, { store, frame: view.frame ?? true, inspect: options?.inspect }));
18438
18521
  } catch (err) {
18439
18522
  host.textContent = String(err);
18440
18523
  }
@@ -18717,12 +18800,28 @@ function renderDashboard(target, spec, options) {
18717
18800
  });
18718
18801
  resizeObs.observe(root);
18719
18802
  }
18803
+ if (options?.inspect !== false && root) {
18804
+ dashboardInspector = createInspector(root, { onExternalEdit: applyExternalEdit });
18805
+ dashboardInspector.write(currentSpec);
18806
+ }
18807
+ };
18808
+ const applyExternalEdit = (config) => {
18809
+ if (destroyed) return;
18810
+ const merged = { ...config, data: currentSpec.data };
18811
+ if (validateSpec(merged).errors.length > 0) return;
18812
+ teardown();
18813
+ currentSpec = merged;
18814
+ build();
18720
18815
  };
18721
18816
  const teardown = () => {
18722
18817
  if (resizeObs) {
18723
18818
  resizeObs.disconnect();
18724
18819
  resizeObs = void 0;
18725
18820
  }
18821
+ if (dashboardInspector) {
18822
+ dashboardInspector.destroy();
18823
+ dashboardInspector = void 0;
18824
+ }
18726
18825
  for (const inst of instances) inst.destroy();
18727
18826
  instances.length = 0;
18728
18827
  if (root && root.parentNode) root.parentNode.removeChild(root);
@@ -18948,6 +19047,6 @@ function renderToContext(target, spec) {
18948
19047
  // src/index.ts
18949
19048
  var VERSION = "0.1.0";
18950
19049
 
18951
- export { CARTESIAN_TYPES, CHART_TYPES, CanvasLayer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, ExpressionError, FACETABLE_TYPES2 as FACETABLE_TYPES, FUNCTION_NAMES, InteractionController, NO_PADDING, RoughPen, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SR_ONLY_STYLE, Surface, TICK_SIZE, TIME_UNITS, TRANSFORM_KINDS, Tooltip, VERSION, aggregateValues, analyzeChart, animate, applyA11y, applyAggregate, applyBin, applyCalculate, applyFilter, applyFold, applyPatch, applyPick, applyTimeUnit, applyTransform, applyTransforms, arc, area, assertValidSpec, autoInsightAnnotations, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildComboModel, buildDataTableFallback, buildFacetModels, buildHistogramModel, buildRenderReport, cartesianInteractionBuilders, cartesianRenderers, categorical, categoricalSchemes, chartTitleText, chartTypeLabel, checkExpression, clamp012 as clamp01, clamp255, compileExpression, compilePredicate, computeBackingSize, computeBins, computeFrame, computeSeriesInsights, contrastRatio, createDiv, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, defaultSpan, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAnnotationLabels, drawAnnotations, drawAxesUnderlay, drawFacet, drawLegend, drawOverlay, drawTitle, drawTrendlineLabels, drawTrendlines, easings, elasticOut, ellipsize, ensureSketchFont, expoInOut, expoOut, facetReport, fillParentStyle, filterRows, fontString, formatDate, formatNumber2 as formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, inheritInto, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isFaceted, isParamClause, isSlicerType, keyFields, legendSwatchWidth, lightTheme, line, linear, linearRegression, linearScale, linearToSrgb, lintSpec, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, overlayTextToCanvasCmd, paintCanvasText, paintLegendSwatch, parseColor, parseNumberFormat, pivot, placeViews, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, profileColumns, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, recommendChart, relativeLuminance, render, renderDashboard, renderToContext, repairReport, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, resolveValueRef, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, setMeasureContext, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, summarize, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, toPointer, tooltipEnabled, truncateTo, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
19050
+ export { CARTESIAN_TYPES, CHART_TYPES, CanvasLayer, DEFAULT_ENTRANCE_DURATION, DEFAULT_ROUGH_STYLE, DEFAULT_UPDATE_DURATION, DIM_ALPHA, ExpressionError, FACETABLE_TYPES2 as FACETABLE_TYPES, FUNCTION_NAMES, InteractionController, NO_PADDING, RoughPen, SKETCH_FONT_FAMILY, SKETCH_FONT_NAME, SLICER_TYPES, SPEC_ATTR, SR_ONLY_STYLE, Surface, TICK_SIZE, TIME_UNITS, TRANSFORM_KINDS, TYPE_ATTR, Tooltip, VERSION, aggregateValues, analyzeChart, animate, applyA11y, applyAggregate, applyBin, applyCalculate, applyFilter, applyFold, applyPatch, applyPick, applyTimeUnit, applyTransform, applyTransforms, arc, area, assertValidSpec, autoInsightAnnotations, backOut, bandScale, bounceOut, buildCartesianInteraction, buildCartesianModel, buildComboModel, buildDataTableFallback, buildFacetModels, buildHistogramModel, buildRenderReport, cartesianInteractionBuilders, cartesianRenderers, categorical, categoricalSchemes, chartTitleText, chartTypeLabel, checkExpression, clamp012 as clamp01, clamp255, compileExpression, compilePredicate, computeBackingSize, computeBins, computeFrame, computeSeriesInsights, contrastRatio, createDiv, createInspector, createRoughPen, createSelectionStore, cubicIn, cubicInOut, cubicOut, curveCatmullRom, curveLinear, curveMonotoneX, curveStep, curveStepAfter, curveStepBefore, customRenderers, darkTheme, decimate, defaultSpan, dependentParams, diverging, divergingColorScale, divergingSchemes, drawAnnotationLabels, drawAnnotations, drawAxesUnderlay, drawFacet, drawLegend, drawOverlay, drawTitle, drawTrendlineLabels, drawTrendlines, easings, elasticOut, ellipsize, ensureSketchFont, expoInOut, expoOut, facetReport, fillParentStyle, filterRows, fontString, formatCountUp, formatDate, formatNumber2 as formatNumber, formatValue, getDevicePixelRatio, groupBy, hashString, inferFieldType, inferFieldTypes, inferValueType, inheritInto, interpolateArray, interpolateNumber, interpolateNumberArray, interpolateObject, interpolateOklab, interpolateRgb, isBrowser, isEmptyValue, isFaceted, isParamClause, isSlicerType, keyFields, legendSwatchWidth, lightTheme, line, linear, linearRegression, linearScale, linearToSrgb, lintSpec, literalToValue, logScale, lttbRun, makeMatcher, matchesValue, measureText, monotoneXTangents, mulberry32, niceDomain, oklabToOklch, oklabToRgb, oklchToOklab, ordinalColorScale, overlayTextToCanvasCmd, paintCanvasText, paintLegendSwatch, parseColor, parseNumberFormat, pivot, placeViews, pointScale, polygonHachureLines, prefersReducedMotion, prettyDate, profileColumns, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, recommendChart, relativeLuminance, render, renderDashboard, renderToContext, repairReport, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, resolveValueRef, rgbToOklab, rgbaToCss, rotatePoint, roundedRect, sampleArc, sequential, sequentialColorScale, sequentialSchemes, serializeSpec, setMeasureContext, setStyle, sinInOut, slicerParamName, smartDate, specFields, srgbToLinear, stripData, summarize, summarizeChart, themes, tickIncrement, tickStep, ticks, timeScale, timeTickFormat, timeTicks, toHex, toPointer, tooltipEnabled, truncateTo, validateDashboard, validateSpec, wireViews, withAlpha, withSketchFont };
18952
19051
  //# sourceMappingURL=index.js.map
18953
19052
  //# sourceMappingURL=index.js.map