@opendata-ai/openchart-core 6.13.0 → 6.15.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
@@ -2191,6 +2191,8 @@ interface ChartLayout {
2191
2191
  animation?: ResolvedAnimation;
2192
2192
  /** Whether the tryOpenData.ai watermark is enabled. */
2193
2193
  watermark: boolean;
2194
+ /** Real text measurement function from the adapter (for accurate SVG text wrapping). */
2195
+ measureText?: MeasureTextFn;
2194
2196
  }
2195
2197
  /** A resolved column definition with computed properties. */
2196
2198
  interface ResolvedColumn {
package/dist/index.js CHANGED
@@ -1048,7 +1048,15 @@ function estimateCharWidth(fontSize, fontWeight = 400) {
1048
1048
  return fontSize * AVG_CHAR_WIDTH_RATIO * weightFactor;
1049
1049
  }
1050
1050
  function estimateTextWidth(text, fontSize, fontWeight = 400) {
1051
- return text.length * estimateCharWidth(fontSize, fontWeight);
1051
+ const charWidth = estimateCharWidth(fontSize, fontWeight);
1052
+ if (text.includes("\n")) {
1053
+ let maxLen = 0;
1054
+ for (const line of text.split("\n")) {
1055
+ if (line.length > maxLen) maxLen = line.length;
1056
+ }
1057
+ return maxLen * charWidth;
1058
+ }
1059
+ return text.length * charWidth;
1052
1060
  }
1053
1061
  var BRAND_RESERVE_WIDTH = 110;
1054
1062
  var BRAND_FONT_SIZE = 12;
@@ -1083,14 +1091,32 @@ function buildTextStyle(defaults, fontFamily, textColor, width, overrides) {
1083
1091
  dominantBaseline: "hanging"
1084
1092
  };
1085
1093
  }
1086
- function estimateLineCount(text, style, maxWidth, _measureText) {
1094
+ function estimateLineCount(text, style, maxWidth, measureText) {
1087
1095
  if (maxWidth <= 0) return 1;
1088
1096
  const segments = text.split("\n");
1089
1097
  if (segments.length > 1) {
1090
1098
  return segments.reduce((total, segment) => {
1091
- return total + (segment.length === 0 ? 1 : estimateLineCount(segment, style, maxWidth, _measureText));
1099
+ return total + (segment.length === 0 ? 1 : estimateLineCount(segment, style, maxWidth, measureText));
1092
1100
  }, 0);
1093
1101
  }
1102
+ if (measureText) {
1103
+ const textWidth = measureText(text, style.fontSize, style.fontWeight).width;
1104
+ if (textWidth <= maxWidth) return 1;
1105
+ const words2 = text.split(" ");
1106
+ let lines2 = 1;
1107
+ let current2 = "";
1108
+ for (const word of words2) {
1109
+ const candidate = current2 ? `${current2} ${word}` : word;
1110
+ const candidateWidth = measureText(candidate, style.fontSize, style.fontWeight).width;
1111
+ if (candidateWidth > maxWidth && current2) {
1112
+ lines2++;
1113
+ current2 = word;
1114
+ } else {
1115
+ current2 = candidate;
1116
+ }
1117
+ }
1118
+ return lines2;
1119
+ }
1094
1120
  const charWidth = estimateCharWidth(style.fontSize, style.fontWeight);
1095
1121
  const maxChars = Math.floor(maxWidth / charWidth);
1096
1122
  if (text.length <= maxChars) return 1;