graphein 0.8.0 → 0.9.1

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
@@ -1114,6 +1114,13 @@ interface AxisConfig {
1114
1114
  format?: string;
1115
1115
  /** Show tick labels. */
1116
1116
  labels?: boolean;
1117
+ /**
1118
+ * Rotation of x-axis tick labels in degrees: `0` horizontal, `45` diagonal,
1119
+ * `90` vertical. Omit for **auto** — categorical (bar/column) labels rotate to
1120
+ * 45° when there isn't room to show them all horizontally, so every category
1121
+ * stays visible instead of being thinned out. (X axis only.)
1122
+ */
1123
+ labelAngle?: number;
1117
1124
  }
1118
1125
  interface AxesConfig {
1119
1126
  x?: AxisConfig;
@@ -2475,6 +2482,12 @@ interface TextMetricsLite {
2475
2482
  declare function measureText(text: string, font: string): TextMetricsLite;
2476
2483
  /** Build a CSS font shorthand string. */
2477
2484
  declare function fontString(size: number, family: string, weight?: number | string, style?: string): string;
2485
+ /**
2486
+ * Truncate `text` with a trailing ellipsis so it fits within `maxWidth` px when
2487
+ * drawn in the given CSS `font`. Returns the original string if it already fits,
2488
+ * or an empty string if not even the ellipsis fits.
2489
+ */
2490
+ declare function ellipsize(text: string, maxWidth: number, font: string): string;
2478
2491
 
2479
2492
  /**
2480
2493
  * Dashboard spec — the single-JSON, agent-facing layer that composes several
@@ -2877,6 +2890,12 @@ interface AxisInput {
2877
2890
  * false/omitted for them.
2878
2891
  */
2879
2892
  edgeAnchored?: boolean;
2893
+ /**
2894
+ * Explicit tick-label rotation in degrees (0/45/90). When omitted, categorical
2895
+ * (non-edge-anchored) labels auto-rotate to 45° if they wouldn't fit; the
2896
+ * resolved angle is returned on {@link Frame.xLabelAngle}.
2897
+ */
2898
+ labelAngle?: number;
2880
2899
  }
2881
2900
  interface FrameInput {
2882
2901
  width: number;
@@ -2909,6 +2928,8 @@ interface Frame {
2909
2928
  legendRect?: Rect;
2910
2929
  legendItems?: PositionedLegendItem[];
2911
2930
  legendPosition?: LegendPosition;
2931
+ /** Resolved x tick-label rotation in degrees (0 = horizontal). */
2932
+ xLabelAngle: number;
2912
2933
  }
2913
2934
  declare const TICK_SIZE = 6;
2914
2935
  /** Reserve space for every region and return the plot rect + positioned chrome. */
@@ -3782,4 +3803,4 @@ declare function renderDashboard(target: HTMLElement | string, spec: DashboardSp
3782
3803
  */
3783
3804
  declare const VERSION = "0.1.0";
3784
3805
 
3785
- 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 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 KpiSpec, type LegendConfig, 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, 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 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, 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, 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, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, renderToContext, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, 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 };
3806
+ 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 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 KpiSpec, type LegendConfig, 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, 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 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, 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, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, renderToContext, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, 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 };
package/dist/index.js CHANGED
@@ -3268,7 +3268,10 @@ function paintCanvasText(ctx, c) {
3268
3268
  }
3269
3269
  function overlayTextToCanvasCmd(o, font) {
3270
3270
  const t = o.transform ?? "";
3271
- const rotate = t.includes("rotate(-90deg)") ? -Math.PI / 2 : t.includes("rotate(90deg)") ? Math.PI / 2 : void 0;
3271
+ const rotate = t.includes("rotate(-90deg)") ? -Math.PI / 2 : t.includes("rotate(90deg)") ? Math.PI / 2 : (() => {
3272
+ const m = t.match(/rotate\((-?\d+(?:\.\d+)?)deg\)/);
3273
+ return m ? parseFloat(m[1]) * Math.PI / 180 : void 0;
3274
+ })();
3272
3275
  let align = "left";
3273
3276
  let x = o.left;
3274
3277
  const y = o.top;
@@ -3342,6 +3345,21 @@ function measureText(text, font) {
3342
3345
  function fontString(size, family, weight = 400, style = "normal") {
3343
3346
  return `${style} ${weight} ${size}px ${family}`;
3344
3347
  }
3348
+ function ellipsize(text, maxWidth, font) {
3349
+ if (maxWidth <= 0 || text.length === 0) return "";
3350
+ if (measureText(text, font).width <= maxWidth) return text;
3351
+ const ellipsis = "\u2026";
3352
+ const ellipsisW = measureText(ellipsis, font).width;
3353
+ if (ellipsisW > maxWidth) return "";
3354
+ let lo = 0;
3355
+ let hi = text.length;
3356
+ while (lo < hi) {
3357
+ const mid = Math.ceil((lo + hi) / 2);
3358
+ if (measureText(text.slice(0, mid) + ellipsis, font).width <= maxWidth) lo = mid;
3359
+ else hi = mid - 1;
3360
+ }
3361
+ return text.slice(0, lo) + ellipsis;
3362
+ }
3345
3363
 
3346
3364
  // src/theme/tokens.ts
3347
3365
  var PALETTE = [
@@ -5797,6 +5815,15 @@ var LEGEND_ITEM_GAP = 16;
5797
5815
  var LEGEND_ROW_GAP = 6;
5798
5816
  var LEGEND_PAD = 4;
5799
5817
  var lineHeight = (size) => Math.round(size * 1.35);
5818
+ function resolveXLabelAngle(axis, available, font) {
5819
+ if (axis.labelAngle != null) return Math.max(0, Math.min(90, axis.labelAngle));
5820
+ const labels = axis.labels;
5821
+ if (axis.edgeAnchored || labels.length < 2 || available <= 0) return 0;
5822
+ const wfont = fontString(font.size.small, font.family, font.weight.normal);
5823
+ const widest = Math.max(...labels.map((l) => measureText(l, wfont).width));
5824
+ const needed = widest + 10;
5825
+ return available / labels.length >= needed ? 0 : 45;
5826
+ }
5800
5827
  function legendItemWidth(label, font) {
5801
5828
  const w = measureText(label, fontString(font.size.small, font.family, font.weight.normal)).width;
5802
5829
  return LEGEND_SWATCH + LEGEND_SWATCH_GAP + Math.ceil(w);
@@ -5857,7 +5884,8 @@ function computeFrame(input) {
5857
5884
  height,
5858
5885
  originX: ox,
5859
5886
  originY: oy,
5860
- plot: { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) }
5887
+ plot: { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) },
5888
+ xLabelAngle: 0
5861
5889
  };
5862
5890
  if (input.title?.text) {
5863
5891
  const titleH = lineHeight(font.size.title);
@@ -5922,10 +5950,21 @@ function computeFrame(input) {
5922
5950
  }
5923
5951
  }
5924
5952
  if (input.xAxis?.show) {
5925
- let gutter = lineHeight(font.size.small) + TICK_SIZE + AXIS_LABEL_GAP;
5953
+ const angle = resolveXLabelAngle(input.xAxis, right - left, font);
5954
+ frame.xLabelAngle = angle;
5955
+ const labelH = lineHeight(font.size.small);
5956
+ let labelBand = labelH;
5957
+ if (angle > 0 && input.xAxis.labels.length) {
5958
+ const wfont = fontString(font.size.small, font.family, font.weight.normal);
5959
+ const widest = Math.max(...input.xAxis.labels.map((l) => measureText(l, wfont).width));
5960
+ const cappedW = Math.min(widest, (bottom - top) * 0.4);
5961
+ const rad = angle * Math.PI / 180;
5962
+ labelBand = Math.ceil(cappedW * Math.sin(rad) + labelH * Math.cos(rad));
5963
+ }
5964
+ let gutter = labelBand + TICK_SIZE + AXIS_LABEL_GAP;
5926
5965
  if (input.xAxis.title) gutter += lineHeight(font.size.base) + AXIS_TITLE_GAP;
5927
5966
  bottom -= gutter;
5928
- if (input.xAxis.edgeAnchored && input.xAxis.labels.length) {
5967
+ if (input.xAxis.edgeAnchored && angle === 0 && input.xAxis.labels.length) {
5929
5968
  const wfont = fontString(font.size.small, font.family, font.weight.normal);
5930
5969
  const labels = input.xAxis.labels;
5931
5970
  const firstHalf = Math.ceil(measureText(labels[0], wfont).width / 2);
@@ -5980,6 +6019,7 @@ function addText(surface, font, o) {
5980
6019
  el.style.textAlign = o.align ?? "left";
5981
6020
  }
5982
6021
  if (o.transform) el.style.transform = o.transform;
6022
+ if (o.transformOrigin) el.style.transformOrigin = o.transformOrigin;
5983
6023
  el.style.pointerEvents = "none";
5984
6024
  overlay.appendChild(el);
5985
6025
  }
@@ -6115,8 +6155,18 @@ function placeXLabels(ticks2, originX, frameWidth, font) {
6115
6155
  }
6116
6156
  return boxes.filter((_, i) => keep[i]);
6117
6157
  }
6158
+ function placeRotatedXLabels(ticks2, angle) {
6159
+ return ticks2.map((t) => ({
6160
+ text: t.label,
6161
+ pos: t.pos,
6162
+ left: t.pos,
6163
+ transform: `translateX(-100%) rotate(-${angle}deg)`
6164
+ }));
6165
+ }
6118
6166
  function resolveXLabels(model) {
6119
6167
  const f = model.tokens.font;
6168
+ const angle = model.frame.xLabelAngle;
6169
+ if (angle > 0) return placeRotatedXLabels(model.xTicks, angle);
6120
6170
  const smallFont = fontString(f.size.small, f.family, f.weight.normal);
6121
6171
  const thinned = thinXTicks(model, f.size.small * 0.58);
6122
6172
  return placeXLabels(thinned, model.frame.originX, model.frame.width, smallFont);
@@ -6142,6 +6192,7 @@ function drawOverlay(surface, model) {
6142
6192
  }
6143
6193
  if (model.spec.axes?.x?.labels !== false) {
6144
6194
  const top = plot.y + plot.height + TICK_SIZE + 3;
6195
+ const rotated = frame.xLabelAngle > 0;
6145
6196
  for (const p of resolveXLabels(model)) {
6146
6197
  addText(surface, smallFont, {
6147
6198
  left: p.left,
@@ -6149,7 +6200,9 @@ function drawOverlay(surface, model) {
6149
6200
  text: p.text,
6150
6201
  color: tokens.color.textMuted,
6151
6202
  size: f.size.small,
6152
- transform: p.transform
6203
+ align: rotated ? "right" : void 0,
6204
+ transform: p.transform,
6205
+ transformOrigin: rotated ? "100% 0%" : void 0
6153
6206
  });
6154
6207
  }
6155
6208
  }
@@ -6536,7 +6589,7 @@ function buildCartesianModel(spec, tokens, opts) {
6536
6589
  font: tokens.font,
6537
6590
  title: titleInput4,
6538
6591
  legend: legend.show && legendItems.length > 1 ? { items: legendItems, position: legend.position } : void 0,
6539
- xAxis: { show: xShow, labels: xLabels, title: resolveAxisTitle(enc.x, xAxisCfg), edgeAnchored: !categories },
6592
+ xAxis: { show: xShow, labels: xLabels, title: resolveAxisTitle(enc.x, xAxisCfg), edgeAnchored: !categories, labelAngle: xAxisCfg.labelAngle },
6540
6593
  yAxis: { show: yShow, labels: yLabels, title: resolveAxisTitle(enc.y, yAxisCfg) }
6541
6594
  });
6542
6595
  const plot = frame.plot;
@@ -10294,21 +10347,6 @@ function paintRawCellText(opts, x, y, text, font, color, size, align = "left") {
10294
10347
  baseline: "middle"
10295
10348
  });
10296
10349
  }
10297
- function ellipsize(text, maxWidth, font) {
10298
- if (maxWidth <= 0 || text.length === 0) return "";
10299
- if (measureText(text, font).width <= maxWidth) return text;
10300
- const ellipsis = "\u2026";
10301
- const ellipsisW = measureText(ellipsis, font).width;
10302
- if (ellipsisW > maxWidth) return "";
10303
- let lo = 0;
10304
- let hi = text.length;
10305
- while (lo < hi) {
10306
- const mid = Math.ceil((lo + hi) / 2);
10307
- if (measureText(text.slice(0, mid) + ellipsis, font).width <= maxWidth) lo = mid;
10308
- else hi = mid - 1;
10309
- }
10310
- return text.slice(0, lo) + ellipsis;
10311
- }
10312
10350
  function resolveCanvasConditional(opts, column, colIndex, cell, rowBg) {
10313
10351
  const cf = column.conditionalFormat;
10314
10352
  const raw = cell.raw;
@@ -13069,29 +13107,36 @@ function drawRect2(ctx, pen, rect, fill, stroke) {
13069
13107
  function addTileLabels(surface, tokens, tile, valueFormat) {
13070
13108
  if (tile.rect.width < MIN_LABEL_WIDTH || tile.rect.height < MIN_LABEL_HEIGHT) return;
13071
13109
  const pad3 = 5;
13072
- const textColor = readableTextColor(tile.fill);
13073
- const textCss = rgbaToCss(textColor);
13074
- const valueCss = rgbaToCss({ ...textColor, a: 0.72 });
13110
+ const padX = 6;
13111
+ const padY = 2;
13075
13112
  const labelSize = tokens.font.size.small;
13076
13113
  const valueSize = tokens.font.size.tiny;
13077
- const maxWidth = Math.max(0, tile.rect.width - pad3 * 2);
13114
+ const labelFont = fontString(labelSize, tokens.font.family, tokens.font.weight.bold);
13115
+ const valueFont = fontString(valueSize, tokens.font.family);
13116
+ const maxTextWidth = tile.rect.width - pad3 * 2 - padX * 2 - 2;
13117
+ const labelText2 = ellipsize(tile.categoryLabel, maxTextWidth, labelFont);
13118
+ if (labelText2 === "" || labelText2 === "\u2026") return;
13119
+ const pill = { background: tokens.color.surface, border: tokens.color.border, padX, padY };
13078
13120
  addOverlayText(surface, tokens, {
13079
13121
  left: tile.rect.x + pad3,
13080
13122
  top: tile.rect.y + pad3,
13081
- width: maxWidth,
13082
- text: tile.categoryLabel,
13083
- color: textCss,
13123
+ text: labelText2,
13124
+ color: tokens.color.text,
13084
13125
  size: labelSize,
13085
- weight: tokens.font.weight.bold
13126
+ weight: tokens.font.weight.bold,
13127
+ pill
13086
13128
  });
13087
- if (tile.rect.height >= 38) {
13129
+ const labelPillH = labelSize + padY * 2 + 2;
13130
+ const valuePillH = valueSize + padY * 2 + 2;
13131
+ const valueText = formatValue(tile.value, valueFormat);
13132
+ if (tile.rect.height >= pad3 * 2 + labelPillH + 2 + valuePillH && measureText(valueText, valueFont).width <= maxTextWidth) {
13088
13133
  addOverlayText(surface, tokens, {
13089
13134
  left: tile.rect.x + pad3,
13090
- top: tile.rect.y + pad3 + labelSize + 2,
13091
- width: maxWidth,
13092
- text: formatValue(tile.value, valueFormat),
13093
- color: valueCss,
13094
- size: valueSize
13135
+ top: tile.rect.y + pad3 + labelPillH + 2,
13136
+ text: valueText,
13137
+ color: tokens.color.textMuted,
13138
+ size: valueSize,
13139
+ pill
13095
13140
  });
13096
13141
  }
13097
13142
  }
@@ -15702,6 +15747,7 @@ function checkClippedMarks(model, add) {
15702
15747
  function checkAxisLabelOverlap(model, tokens, add) {
15703
15748
  const ticks2 = model.xTicks;
15704
15749
  if (ticks2.length < 2) return;
15750
+ if (model.frame.xLabelAngle > 0) return;
15705
15751
  const font = fontString(tokens.font.size.small, tokens.font.family, tokens.font.weight.normal);
15706
15752
  const GAP3 = 4;
15707
15753
  let collisions = 0;
@@ -17185,6 +17231,6 @@ function renderToContext(target, spec) {
17185
17231
  // src/index.ts
17186
17232
  var VERSION = "0.1.0";
17187
17233
 
17188
- 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, 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, 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, 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, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, renderToContext, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, 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 };
17234
+ 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, 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, 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, quadIn, quadInOut, quadOut, rampFromStops, readableTextColor, relativeLuminance, render, renderDashboard, renderToContext, repairSpec, resolveCurve, resolveDashboardLayout, resolveDashboardSections, resolveEmphasis, resolveEntrance, resolveFilterValues, resolveInsightOptions, resolveSketch, resolveTheme, resolveUpdate, 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 };
17189
17235
  //# sourceMappingURL=index.js.map
17190
17236
  //# sourceMappingURL=index.js.map