@opendata-ai/openchart-core 8.0.0-rc.11 → 8.0.0-rc.12

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
@@ -1037,6 +1037,14 @@ interface ChromeTextStyle {
1037
1037
  fontFamily?: string;
1038
1038
  /** Text color (CSS color string). */
1039
1039
  color?: string;
1040
+ /**
1041
+ * Maximum number of lines this chrome text may wrap to. Additional lines are
1042
+ * dropped and the last kept line is truncated with an ellipsis. Bounds the
1043
+ * chrome's contribution to layout height at any container width. Applies
1044
+ * whether the font size comes from the theme default or an explicit override.
1045
+ * Caps height only, not horizontal overflow of a single unbreakable word.
1046
+ */
1047
+ maxLines?: number;
1040
1048
  }
1041
1049
  /** A chrome text element with optional style overrides. */
1042
1050
  interface ChromeText {
@@ -1890,6 +1898,20 @@ interface BaseChartSpec<TData extends DataRow = DataRow> {
1890
1898
  transform?: Transform[];
1891
1899
  /** Editorial chrome (title, subtitle, source, etc.). */
1892
1900
  chrome?: Chrome;
1901
+ /**
1902
+ * How chrome height interacts with the container height budget.
1903
+ *
1904
+ * - `'subtract'` (default): the container height is fixed and chrome text
1905
+ * (title/subtitle/source) is subtracted from it, shrinking the plot. This
1906
+ * is the historical behavior.
1907
+ * - `'grow'`: the container height is treated as the *plot* budget, and the
1908
+ * rendered SVG grows taller by the measured chrome height. The plot keeps
1909
+ * its full budget (minus axis/padding overhead) regardless of how many
1910
+ * lines the title wraps to.
1911
+ *
1912
+ * `'grow'` is a no-op for faceted specs in this version.
1913
+ */
1914
+ chromeLayout?: 'subtract' | 'grow';
1893
1915
  /**
1894
1916
  * Top-level title sugar (Vega-Lite aligned). Expanded into `chrome.title`
1895
1917
  * (and `chrome.subtitle` for the object form). `chrome.title` wins when
@@ -3215,6 +3237,12 @@ interface ResolvedChromeElement {
3215
3237
  y: number;
3216
3238
  /** Maximum width for line wrapping. */
3217
3239
  maxWidth: number;
3240
+ /**
3241
+ * Maximum wrapped lines. When set, the renderer caps the wrapped output to
3242
+ * this many lines and truncates the last kept line with an ellipsis. The
3243
+ * layout height reserved for this element already reflects the cap.
3244
+ */
3245
+ maxLines?: number;
3218
3246
  /** Computed text style. */
3219
3247
  style: TextStyle;
3220
3248
  }
@@ -4969,6 +4997,14 @@ interface CompileOptions {
4969
4997
  width: number;
4970
4998
  /** Total available height in pixels. */
4971
4999
  height: number;
5000
+ /**
5001
+ * How chrome height interacts with the height budget. Mirrors the spec-level
5002
+ * `chromeLayout`; the engine reads whichever is set (spec wins).
5003
+ *
5004
+ * - `'subtract'` (default): `height` is the fixed total; chrome shrinks the plot.
5005
+ * - `'grow'`: `height` is the plot budget; the SVG grows by the chrome height.
5006
+ */
5007
+ chromeLayout?: 'subtract' | 'grow';
4972
5008
  /** Theme overrides. */
4973
5009
  theme?: ThemeConfig;
4974
5010
  /**
@@ -5547,12 +5583,20 @@ declare function computeXAxisExtentFromLabels(input: XAxisExtentInput): number;
5547
5583
  */
5548
5584
  declare function maxRotatedLabelWidth(tickAngle: number, tickFontSize: number): number;
5549
5585
  /**
5550
- * Truncate a rotated tick label with an ellipsis so it fits inside the capped
5551
- * reservation. Returns the label unchanged when it already fits.
5586
+ * Truncate a label with an ellipsis so it fits inside an explicit pixel budget.
5587
+ * Returns the label unchanged when it already fits.
5552
5588
  *
5553
5589
  * Binary-search on character count against the real measure function, so it
5554
5590
  * respects proportional fonts rather than assuming a fixed character width.
5555
5591
  */
5592
+ declare function truncateToWidth(label: string, budget: number, fontSize: number, fontWeight: number, measure?: (text: string, fontSize: number, fontWeight?: number) => number): string;
5593
+ /**
5594
+ * Truncate a rotated tick label with an ellipsis so it fits inside the capped
5595
+ * reservation. Returns the label unchanged when it already fits.
5596
+ *
5597
+ * Delegates to `truncateToWidth` with the budget derived from the rotation
5598
+ * geometry, so the binary-search stays in one place.
5599
+ */
5556
5600
  declare function truncateRotatedLabel(label: string, tickAngle: number, tickFontSize: number, tickFontWeight: number, measure?: (text: string, fontSize: number, fontWeight?: number) => number): string;
5557
5601
 
5558
5602
  /**
@@ -5987,4 +6031,4 @@ declare const CSS_TOKEN_ROOT_SELECTORS: readonly string[];
5987
6031
  declare const CSS_TOKENS: readonly CssTokenDef[];
5988
6032
  declare function cssTokenDefault(name: string, mode: 'light' | 'dark'): string;
5989
6033
 
5990
- export { type A11yConfig, type A11yMetadata, ACHROMATIC_RAMP, AXIS_TITLE_GAP, AXIS_TITLE_OFFSET_COMPACT, AXIS_TITLE_OFFSET_DEFAULT, AXIS_TITLE_TRAILING_PAD, type AggregateOp, type AggregateTransform, type AnimationConfig, type AnimationEase, type AnimationPhaseConfig, type AnimationSpec, type AnimationStagger, type Annotation, type AnnotationAnchor, type AnnotationFootnote, type AnnotationOffset, type AnnotationPosition, type ArcEncoding, type ArcMark, type AreaEncoding, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, BREAKPOINT_COMPACT_MAX, BREAKPOINT_MEDIUM_MAX, type BarColumnConfig, type BarEncoding, type BarListEncoding, type BarListLayout, type BarListRowMark, type BarListSpec, type BarListSpecWithoutData, type BarTableCell, type BaseLegendLayout, type BeeswarmEncoding, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, COMPACT_WIDTH, CSS_TOKENS, CSS_TOKEN_ROOT_SELECTORS, type CalculateExpression, type CalculateTransform, type CalendarEncoding, type CategoricalLegendLayout, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ChromeThemeOverride, type CircleEncoding, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type CompileWarning, type Condition, type ConditionalValueDef, type ConnectorConfig, type ConnectorType, type ContinuousLegendBin, type ContinuousLegendLayout, type ContinuousLegendTick, type CssTokenDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type Display, type DivergingPalette, EXTENDED_OFFSET_STRATEGIES, type ElementEdit, type ElementRef, type Encoding, type EncodingChannel, type EncodingRule, type EndpointLabelContent, type EndpointLabelEntry, type EndpointLabelsConfig, type EndpointLabelsLayout, FOOTNOTE_LINE_HEIGHT, type FacetChannel, type FacetLayout, type FacetPanelLayout, type FieldFormatContext, type FieldPredicate, type FieldRef, type FieldType, type FillPatternType, type FilterPredicate, type FilterTransform, type FlagTableCell, type FoldTransform, GRAPH_ENCODING_RULES, type GradientColorStop, type GradientDef, type GradientLegendLayout, type GradientStop, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, HEIGHT_CRAMPED_MAX, HEIGHT_SHORT_MAX, HPAD_COMPACT_FRACTION, HPAD_COMPACT_MIN, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, LABEL_GAP_COMPACT, LABEL_GAP_DEFAULT, LABEL_GAP_NARROW_MAX, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LabelSpec, type LayerSpec, type LayoutStrategy, type LegendChannel, type LegendConfig, type LegendEntry, type LegendEntryPosition, type LegendLayout, type LegendPosition, type LineEncoding, type LineMark, type LinearGradient, type LogicalAnd, type LogicalNot, type LogicalOr, type LollipopEncoding, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, MAX_LEFT_LABEL_FRACTION_COMPACT, MAX_LEFT_LABEL_FRACTION_DEFAULT, MAX_LEFT_LABEL_FRACTION_MEDIUM, MAX_LEFT_LABEL_FRACTION_MEDIUM_MAX, type MapBorders, type MapEncoding, type MapFeatureMark, type MapFocus, type MapFocusLayout, type MapGeo, type MapLayout, type MapPointMark, type MapPointsLayer, type MapProjection, type MapSpec, type MapSpecWithoutData, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type Metric, NARROW_VIEWPORT_MAX, type NodeOverride, type NumberFormatter, OFFSET_STRATEGIES, type OffsetStrategy, type PaginationState, type ParliamentEncoding, type Point, type PointEncoding, type PointMark, type RadialGradient, type RangeAnnotation, type RangeEncoding, type Rect, type RectEncoding, type RectMark, type RefLineAnnotation, type RelativeTimeRef, type ResolveConfig, type ResolveMode, type ResolvedAnimation, type ResolvedAnimationPhase, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedFillPattern, type ResolvedLabel, type ResolvedMetricBar, type ResolvedMetricCell, type ResolvedSeriesSearch, type ResolvedTheme, type ResolvedYouDrawIt, type ResponsiveConfig, type RuleMarkLayout, SEQUENTIAL_PALETTES, SUPPORTED_SCHEME_NAMES, type SankeyEncoding, type SankeyLayout, type SankeyLinkColor, type SankeyLinkMark, type SankeyNodeAlign, type SankeyNodeMark, type SankeySpec, type SankeySpecWithoutData, type ScaleConfig, type ScaleInvert, type ScaleType, type SequentialPalette, type SeriesSearchConfig, type SeriesStrategy, type SeriesStyle, type SizeLegendCircle, type SizeLegendLayout, type SortByField, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, TICK_LABEL_OFFSET, TICK_LINE_HEIGHT_FACTOR, TOP_PAD_EXTRA_NARROW, TOP_PAD_NARROW_MAX, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextEncoding, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickEncoding, type TickMarkLayout, type TileMapBuilderOptions, type TileMapEncoding, type TileMapLayout, type TileMapPalette, type TileMapSpec, type TileMapSpecWithoutData, type TileMapTileMark, type TimeUnit, type TimeUnitTransform, type TokenValue, type TooltipContent, type TooltipField, type Transform, type ValueDef, type VizSpec, type WaffleEncoding, type WindowFieldDef, type WindowOp, type WindowSortField, type WindowTransform, type XAxisExtentInput, X_AXIS_BAND_HEIGHT, X_AXIS_ROTATED_EXTENT_CAP, X_AXIS_TITLE_BAND, X_AXIS_TITLE_BAND_ROTATED, type YouDrawItConfig, type YouDrawItSample, type YouDrawItYInvert, abbreviateNumber, adaptColorForDarkMode, adaptForLightLineStroke, adaptTheme, areaChart, axisTitleOffset, barChart, buildCompactStepFormatter, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeFieldFormatContext, computeLabelBounds, computeXAxisExtentFromLabels, contrastRatio, cssTokenDefault, dataTable, deepMergeSpec, defaultNumberFormatter, detectCollision, donutChart, dotChart, editorial, elementRef, essay, estimateTextWidth, findAccessibleColor, footnoteBandHeight, formatCurrency, formatDate, formatNumber, formatOrdinal, formatPercent, generateAltText, generateAriaLabels, generateDataTable, getAxisTitleOffset, getBreakpoint, getHeightClass, getLayoutStrategy, getRepresentativeColor, heuristicMeasure, inferFieldType, isAxislessMark, isBarListSpec, isChartSpec, isConditionalDef, isEncodingChannel, isGradientDef, isGraphSpec, isLayerSpec, isMapSpec, isOpaqueColor, isRangeAnnotation, isRefLineAnnotation, isSankeySpec, isTableSpec, isTextAnnotation, isTileMapSpec, isValueDef, isYearContext, lineChart, maxRotatedLabelWidth, meetsAA, overlapArea, pickLabelColor, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveMeasurer, resolveNumberFormatter, resolveSchemeName, resolveTheme, scatterChart, simulateColorBlindness, textAscent, tileMap, truncateRotatedLabel, wire, wrapText };
6034
+ export { type A11yConfig, type A11yMetadata, ACHROMATIC_RAMP, AXIS_TITLE_GAP, AXIS_TITLE_OFFSET_COMPACT, AXIS_TITLE_OFFSET_DEFAULT, AXIS_TITLE_TRAILING_PAD, type AggregateOp, type AggregateTransform, type AnimationConfig, type AnimationEase, type AnimationPhaseConfig, type AnimationSpec, type AnimationStagger, type Annotation, type AnnotationAnchor, type AnnotationFootnote, type AnnotationOffset, type AnnotationPosition, type ArcEncoding, type ArcMark, type AreaEncoding, type AreaMark, type AxisConfig, type AxisLabelDensity, type AxisLayout, type AxisTick, BRAND_FONT_SIZE, BRAND_MIN_WIDTH, BRAND_RESERVE_WIDTH, BREAKPOINT_COMPACT_MAX, BREAKPOINT_MEDIUM_MAX, type BarColumnConfig, type BarEncoding, type BarListEncoding, type BarListLayout, type BarListRowMark, type BarListSpec, type BarListSpecWithoutData, type BarTableCell, type BaseLegendLayout, type BeeswarmEncoding, type BinParams, type BinTransform, type Breakpoint, CATEGORICAL_PALETTE, COMPACT_WIDTH, CSS_TOKENS, CSS_TOKEN_ROOT_SELECTORS, type CalculateExpression, type CalculateTransform, type CalendarEncoding, type CategoricalLegendLayout, type CategoricalPalette, type CategoryColorsConfig, type CategoryTableCell, type CellStyle, type ChannelRule, type ChartBuilderOptions, type ChartEventHandlers, type ChartLayout, type ChartSpec, type ChartSpecOverride, type ChartSpecWithoutData, type Chrome, type ChromeDefaults, type ChromeKey, type ChromeMode, type ChromeText, type ChromeTextStyle, type ChromeThemeOverride, type CircleEncoding, type ColorBlindnessType, type ColumnConfig, type CompileOptions, type CompileTableOptions, type CompileWarning, type Condition, type ConditionalValueDef, type ConnectorConfig, type ConnectorType, type ContinuousLegendBin, type ContinuousLegendLayout, type ContinuousLegendTick, type CssTokenDef, DEFAULT_THEME, DIVERGING_PALETTES, type DarkMode, type DataRow, type DateGranularity, type Display, type DivergingPalette, EXTENDED_OFFSET_STRATEGIES, type ElementEdit, type ElementRef, type Encoding, type EncodingChannel, type EncodingRule, type EndpointLabelContent, type EndpointLabelEntry, type EndpointLabelsConfig, type EndpointLabelsLayout, FOOTNOTE_LINE_HEIGHT, type FacetChannel, type FacetLayout, type FacetPanelLayout, type FieldFormatContext, type FieldPredicate, type FieldRef, type FieldType, type FillPatternType, type FilterPredicate, type FilterTransform, type FlagTableCell, type FoldTransform, GRAPH_ENCODING_RULES, type GradientColorStop, type GradientDef, type GradientLegendLayout, type GradientStop, type GraphChannelRule, type GraphEdge, type GraphEdgeLayout, type GraphEncoding, type GraphEncodingChannel, type GraphLayout, type GraphLayoutConfig, type GraphNode, type GraphNodeLayout, type GraphSpec, type GraphSpecWithoutData, type Gridline, HEIGHT_CRAMPED_MAX, HEIGHT_SHORT_MAX, HPAD_COMPACT_FRACTION, HPAD_COMPACT_MIN, type HeatmapColumnConfig, type HeatmapTableCell, type HeightClass, type ImageColumnConfig, type ImageTableCell, LABEL_GAP_COMPACT, LABEL_GAP_DEFAULT, LABEL_GAP_NARROW_MAX, type LabelCandidate, type LabelConfig, type LabelDensity, type LabelMode, type LabelPriority, type LabelSpec, type LayerSpec, type LayoutStrategy, type LegendChannel, type LegendConfig, type LegendEntry, type LegendEntryPosition, type LegendLayout, type LegendPosition, type LineEncoding, type LineMark, type LinearGradient, type LogicalAnd, type LogicalNot, type LogicalOr, type LollipopEncoding, MARK_DISPLAY_NAMES, MARK_ENCODING_RULES, MARK_TYPES, MAX_LEFT_LABEL_FRACTION_COMPACT, MAX_LEFT_LABEL_FRACTION_DEFAULT, MAX_LEFT_LABEL_FRACTION_MEDIUM, MAX_LEFT_LABEL_FRACTION_MEDIUM_MAX, type MapBorders, type MapEncoding, type MapFeatureMark, type MapFocus, type MapFocusLayout, type MapGeo, type MapLayout, type MapPointMark, type MapPointsLayer, type MapProjection, type MapSpec, type MapSpecWithoutData, type Margins, type Mark, type MarkAria, type MarkDef, type MarkEvent, type MarkType, type MeasureTextFn, type Metric, NARROW_VIEWPORT_MAX, type NodeOverride, type NumberFormatter, OFFSET_STRATEGIES, type OffsetStrategy, type PaginationState, type ParliamentEncoding, type Point, type PointEncoding, type PointMark, type RadialGradient, type RangeAnnotation, type RangeEncoding, type Rect, type RectEncoding, type RectMark, type RefLineAnnotation, type RelativeTimeRef, type ResolveConfig, type ResolveMode, type ResolvedAnimation, type ResolvedAnimationPhase, type ResolvedAnnotation, type ResolvedChrome, type ResolvedChromeElement, type ResolvedColumn, type ResolvedFillPattern, type ResolvedLabel, type ResolvedMetricBar, type ResolvedMetricCell, type ResolvedSeriesSearch, type ResolvedTheme, type ResolvedYouDrawIt, type ResponsiveConfig, type RuleMarkLayout, SEQUENTIAL_PALETTES, SUPPORTED_SCHEME_NAMES, type SankeyEncoding, type SankeyLayout, type SankeyLinkColor, type SankeyLinkMark, type SankeyNodeAlign, type SankeyNodeMark, type SankeySpec, type SankeySpecWithoutData, type ScaleConfig, type ScaleInvert, type ScaleType, type SequentialPalette, type SeriesSearchConfig, type SeriesStrategy, type SeriesStyle, type SizeLegendCircle, type SizeLegendLayout, type SortByField, type SortState, type SparklineColumnConfig, type SparklineData, type SparklineTableCell, type StoredVizSpec, TICK_LABEL_OFFSET, TICK_LINE_HEIGHT_FACTOR, TOP_PAD_EXTRA_NARROW, TOP_PAD_NARROW_MAX, type TableBuilderOptions, type TableCell, type TableCellBase, type TableLayout, type TableRow, type TableSpec, type TableSpecWithoutData, type TextAnnotation, type TextEncoding, type TextMarkLayout, type TextStyle, type TextTableCell, type Theme, type ThemeChromeDefaults, type ThemeColors, type ThemeConfig, type ThemeFontSizes, type ThemeFontWeights, type ThemeFonts, type ThemeSpacing, type TickEncoding, type TickMarkLayout, type TileMapBuilderOptions, type TileMapEncoding, type TileMapLayout, type TileMapPalette, type TileMapSpec, type TileMapSpecWithoutData, type TileMapTileMark, type TimeUnit, type TimeUnitTransform, type TokenValue, type TooltipContent, type TooltipField, type Transform, type ValueDef, type VizSpec, type WaffleEncoding, type WindowFieldDef, type WindowOp, type WindowSortField, type WindowTransform, type XAxisExtentInput, X_AXIS_BAND_HEIGHT, X_AXIS_ROTATED_EXTENT_CAP, X_AXIS_TITLE_BAND, X_AXIS_TITLE_BAND_ROTATED, type YouDrawItConfig, type YouDrawItSample, type YouDrawItYInvert, abbreviateNumber, adaptColorForDarkMode, adaptForLightLineStroke, adaptTheme, areaChart, axisTitleOffset, barChart, buildCompactStepFormatter, buildD3Formatter, buildTemporalFormatter, checkPaletteDistinguishability, columnChart, computeChrome, computeFieldFormatContext, computeLabelBounds, computeXAxisExtentFromLabels, contrastRatio, cssTokenDefault, dataTable, deepMergeSpec, defaultNumberFormatter, detectCollision, donutChart, dotChart, editorial, elementRef, essay, estimateTextWidth, findAccessibleColor, footnoteBandHeight, formatCurrency, formatDate, formatNumber, formatOrdinal, formatPercent, generateAltText, generateAriaLabels, generateDataTable, getAxisTitleOffset, getBreakpoint, getHeightClass, getLayoutStrategy, getRepresentativeColor, heuristicMeasure, inferFieldType, isAxislessMark, isBarListSpec, isChartSpec, isConditionalDef, isEncodingChannel, isGradientDef, isGraphSpec, isLayerSpec, isMapSpec, isOpaqueColor, isRangeAnnotation, isRefLineAnnotation, isSankeySpec, isTableSpec, isTextAnnotation, isTileMapSpec, isValueDef, isYearContext, lineChart, maxRotatedLabelWidth, meetsAA, overlapArea, pickLabelColor, pieChart, resolveCollisions, resolveMarkDef, resolveMarkType, resolveMeasurer, resolveNumberFormatter, resolveSchemeName, resolveTheme, scatterChart, simulateColorBlindness, textAscent, tileMap, truncateRotatedLabel, truncateToWidth, wire, wrapText };
package/dist/index.js CHANGED
@@ -1371,17 +1371,16 @@ function maxRotatedLabelWidth(tickAngle, tickFontSize) {
1371
1371
  const usable = X_AXIS_ROTATED_EXTENT_CAP - lineHeight * Math.cos(angleRad) - AXIS_TO_LABEL_GAP;
1372
1372
  return Math.max(0, usable / sin);
1373
1373
  }
1374
- function truncateRotatedLabel(label, tickAngle, tickFontSize, tickFontWeight, measure = estimateTextWidth) {
1375
- const budget = maxRotatedLabelWidth(tickAngle, tickFontSize);
1374
+ function truncateToWidth(label, budget, fontSize, fontWeight, measure = estimateTextWidth) {
1376
1375
  if (!Number.isFinite(budget)) return label;
1377
- if (measure(label, tickFontSize, tickFontWeight) <= budget) return label;
1376
+ if (measure(label, fontSize, fontWeight) <= budget) return label;
1378
1377
  const ELLIPSIS = "\u2026";
1379
1378
  let lo = 0;
1380
1379
  let hi = label.length;
1381
1380
  while (lo < hi) {
1382
1381
  const mid = Math.ceil((lo + hi) / 2);
1383
1382
  const candidate = label.slice(0, mid) + ELLIPSIS;
1384
- if (measure(candidate, tickFontSize, tickFontWeight) <= budget) {
1383
+ if (measure(candidate, fontSize, fontWeight) <= budget) {
1385
1384
  lo = mid;
1386
1385
  } else {
1387
1386
  hi = mid - 1;
@@ -1389,6 +1388,10 @@ function truncateRotatedLabel(label, tickAngle, tickFontSize, tickFontWeight, me
1389
1388
  }
1390
1389
  return lo > 0 ? label.slice(0, lo).trimEnd() + ELLIPSIS : ELLIPSIS;
1391
1390
  }
1391
+ function truncateRotatedLabel(label, tickAngle, tickFontSize, tickFontWeight, measure = estimateTextWidth) {
1392
+ const budget = maxRotatedLabelWidth(tickAngle, tickFontSize);
1393
+ return truncateToWidth(label, budget, tickFontSize, tickFontWeight, measure);
1394
+ }
1392
1395
 
1393
1396
  // src/theme/defaults.ts
1394
1397
  var DEFAULT_THEME = {
@@ -1884,13 +1887,14 @@ function buildTextStyle(defaults, fontFamily, textColor, width, overrides) {
1884
1887
  textAnchor: "start"
1885
1888
  };
1886
1889
  }
1887
- function estimateLineCount(text, style, maxWidth, measureText) {
1890
+ function estimateLineCount(text, style, maxWidth, measureText, maxLines) {
1888
1891
  if (maxWidth <= 0) return 1;
1889
1892
  const segments = text.split("\n");
1890
1893
  if (segments.length > 1) {
1891
- return segments.reduce((total, segment) => {
1894
+ const count = segments.reduce((total, segment) => {
1892
1895
  return total + (segment.length === 0 ? 1 : estimateLineCount(segment, style, maxWidth, measureText));
1893
1896
  }, 0);
1897
+ return maxLines != null ? Math.min(count, maxLines) : count;
1894
1898
  }
1895
1899
  if (measureText) {
1896
1900
  const textWidth = measureText(text, style.fontSize, style.fontWeight).width;
@@ -1908,7 +1912,7 @@ function estimateLineCount(text, style, maxWidth, measureText) {
1908
1912
  current2 = candidate;
1909
1913
  }
1910
1914
  }
1911
- return lines2;
1915
+ return maxLines != null ? Math.min(lines2, maxLines) : lines2;
1912
1916
  }
1913
1917
  const charWidth = estimateCharWidth(style.fontSize, style.fontWeight);
1914
1918
  const maxChars = Math.floor(maxWidth / charWidth);
@@ -1925,7 +1929,7 @@ function estimateLineCount(text, style, maxWidth, measureText) {
1925
1929
  current = candidate;
1926
1930
  }
1927
1931
  }
1928
- return lines;
1932
+ return maxLines != null ? Math.min(lines, maxLines) : lines;
1929
1933
  }
1930
1934
  var FOOTNOTE_LINE_HEIGHT = 1.3;
1931
1935
  var FOOTNOTE_BAND_GAP = 4;
@@ -1953,12 +1957,14 @@ function computeChrome(chrome, theme, width, measureText, chromeMode = "full", p
1953
1957
  width,
1954
1958
  eyebrowNorm.style
1955
1959
  );
1956
- const lineCount = estimateLineCount(eyebrowNorm.text, style, maxWidth, measureText);
1960
+ const maxLines = eyebrowNorm.style?.maxLines;
1961
+ const lineCount = estimateLineCount(eyebrowNorm.text, style, maxWidth, measureText, maxLines);
1957
1962
  const element = {
1958
1963
  text: eyebrowNorm.text,
1959
1964
  x: pad2 + (eyebrowNorm.offset?.dx ?? 0),
1960
1965
  y: topY + (eyebrowNorm.offset?.dy ?? 0),
1961
1966
  maxWidth,
1967
+ ...maxLines != null ? { maxLines } : {},
1962
1968
  style
1963
1969
  };
1964
1970
  topElements.eyebrow = element;
@@ -1973,12 +1979,14 @@ function computeChrome(chrome, theme, width, measureText, chromeMode = "full", p
1973
1979
  width,
1974
1980
  titleNorm.style
1975
1981
  );
1976
- const lineCount = estimateLineCount(titleNorm.text, style, maxWidth, measureText);
1982
+ const maxLines = titleNorm.style?.maxLines;
1983
+ const lineCount = estimateLineCount(titleNorm.text, style, maxWidth, measureText, maxLines);
1977
1984
  const element = {
1978
1985
  text: titleNorm.text,
1979
1986
  x: pad2 + (titleNorm.offset?.dx ?? 0),
1980
1987
  y: topY + (titleNorm.offset?.dy ?? 0),
1981
1988
  maxWidth,
1989
+ ...maxLines != null ? { maxLines } : {},
1982
1990
  style
1983
1991
  };
1984
1992
  topElements.title = element;
@@ -1993,12 +2001,14 @@ function computeChrome(chrome, theme, width, measureText, chromeMode = "full", p
1993
2001
  width,
1994
2002
  subtitleNorm.style
1995
2003
  );
1996
- const lineCount = estimateLineCount(subtitleNorm.text, style, maxWidth, measureText);
2004
+ const maxLines = subtitleNorm.style?.maxLines;
2005
+ const lineCount = estimateLineCount(subtitleNorm.text, style, maxWidth, measureText, maxLines);
1997
2006
  const element = {
1998
2007
  text: subtitleNorm.text,
1999
2008
  x: pad2 + (subtitleNorm.offset?.dx ?? 0),
2000
2009
  y: topY + (subtitleNorm.offset?.dy ?? 0),
2001
2010
  maxWidth,
2011
+ ...maxLines != null ? { maxLines } : {},
2002
2012
  style
2003
2013
  };
2004
2014
  topElements.subtitle = element;
@@ -2063,7 +2073,14 @@ function computeChrome(chrome, theme, width, measureText, chromeMode = "full", p
2063
2073
  width,
2064
2074
  item.norm.style
2065
2075
  );
2066
- const lineCount = estimateLineCount(item.norm.text, style, bottomMaxWidth, measureText);
2076
+ const maxLines = item.norm.style?.maxLines;
2077
+ const lineCount = estimateLineCount(
2078
+ item.norm.text,
2079
+ style,
2080
+ bottomMaxWidth,
2081
+ measureText,
2082
+ maxLines
2083
+ );
2067
2084
  const height = estimateTextHeight(style.fontSize, lineCount, style.lineHeight);
2068
2085
  bottomElements[item.key] = {
2069
2086
  text: item.norm.text,
@@ -2071,6 +2088,7 @@ function computeChrome(chrome, theme, width, measureText, chromeMode = "full", p
2071
2088
  y: bottomHeight + (item.norm.offset?.dy ?? 0),
2072
2089
  // offset from where bottom chrome starts
2073
2090
  maxWidth: bottomMaxWidth,
2091
+ ...maxLines != null ? { maxLines } : {},
2074
2092
  style
2075
2093
  };
2076
2094
  bottomHeight += height + chromeGap;
@@ -4129,6 +4147,7 @@ export {
4129
4147
  textAscent,
4130
4148
  tileMap,
4131
4149
  truncateRotatedLabel,
4150
+ truncateToWidth,
4132
4151
  wire,
4133
4152
  wrapText
4134
4153
  };