@opendata-ai/openchart-core 6.23.1 → 6.24.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendata-ai/openchart-core",
3
- "version": "6.23.1",
3
+ "version": "6.24.0",
4
4
  "description": "Types, theme, colors, accessibility, and utilities for openchart",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Riley Hilliard",
package/src/index.ts CHANGED
@@ -56,6 +56,7 @@ export {
56
56
  BRAND_FONT_SIZE,
57
57
  BRAND_MIN_WIDTH,
58
58
  BRAND_RESERVE_WIDTH,
59
+ COMPACT_WIDTH,
59
60
  computeChrome,
60
61
  estimateTextWidth,
61
62
  wrapText,
@@ -26,6 +26,7 @@ import {
26
26
  BRAND_FONT_SIZE,
27
27
  BRAND_MIN_WIDTH,
28
28
  BRAND_RESERVE_WIDTH,
29
+ COMPACT_WIDTH,
29
30
  estimateCharWidth,
30
31
  estimateTextHeight,
31
32
  } from './text-measure';
@@ -236,9 +237,12 @@ export function computeChrome(
236
237
  topY += estimateTextHeight(style.fontSize, lineCount, style.lineHeight) + chromeGap;
237
238
  }
238
239
 
239
- // Add chromeToChart gap if there are any top elements
240
+ // Add chromeToChart gap if there are any top elements. Tighten on narrow
241
+ // viewports so the subtitle doesn't float far above a legend or chart area.
240
242
  const hasTopChrome = titleNorm || subtitleNorm;
241
- const topHeight = hasTopChrome ? topY - pad + theme.spacing.chromeToChart - chromeGap : 0;
243
+ const chromeToChart =
244
+ width < COMPACT_WIDTH ? Math.min(theme.spacing.chromeToChart, 2) : theme.spacing.chromeToChart;
245
+ const topHeight = hasTopChrome ? topY - pad + chromeToChart - chromeGap : 0;
242
246
 
243
247
  // Bottom chrome text hidden in compact mode, but brand watermark still
244
248
  // renders for wide-enough charts. Reserve space so it doesn't overflow.
@@ -7,6 +7,7 @@ export {
7
7
  BRAND_FONT_SIZE,
8
8
  BRAND_MIN_WIDTH,
9
9
  BRAND_RESERVE_WIDTH,
10
+ COMPACT_WIDTH,
10
11
  estimateCharWidth,
11
12
  estimateTextHeight,
12
13
  estimateTextWidth,
@@ -73,6 +73,16 @@ export const BRAND_FONT_SIZE = 12;
73
73
  /** Minimum chart width to render the brand watermark (px). */
74
74
  export const BRAND_MIN_WIDTH = 120;
75
75
 
76
+ // ---------------------------------------------------------------------------
77
+ // Responsive breakpoints
78
+ // ---------------------------------------------------------------------------
79
+
80
+ /**
81
+ * Width threshold below which layout tightens spacing (legend gaps, chrome
82
+ * padding, label gaps) to maximize data area on small screens.
83
+ */
84
+ export const COMPACT_WIDTH = 420;
85
+
76
86
  /**
77
87
  * Estimate the rendered height of a text block.
78
88
  *
@@ -6,8 +6,8 @@
6
6
  * accurate wrapping. Otherwise falls back to a character-width
7
7
  * heuristic driven by `estimateCharWidth` from text-measure.ts.
8
8
  *
9
- * Callers that want heuristic-only behavior (e.g. sankey) should omit
10
- * the measureText argument. Do not change the signature without
9
+ * Non-browser callers (SSR, tests) omit the measureText argument to
10
+ * use the heuristic fallback. Do not change the signature without
11
11
  * re-verifying visual baselines for every caller.
12
12
  */
13
13
 
@@ -1030,6 +1030,8 @@ export interface SankeyLayout {
1030
1030
  animation?: ResolvedAnimation;
1031
1031
  /** Whether the tryOpenData.ai watermark is enabled. */
1032
1032
  watermark: boolean;
1033
+ /** Real text measurement function from the adapter (for accurate SVG text wrapping). */
1034
+ measureText?: MeasureTextFn;
1033
1035
  }
1034
1036
 
1035
1037
  // ---------------------------------------------------------------------------