@visactor/vchart-extension 2.1.0-alpha.22 → 2.1.0-alpha.24

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.
Files changed (177) hide show
  1. package/build/index.js +258 -159
  2. package/build/index.min.js +2 -2
  3. package/cjs/charts/axis-3d/index.js +2 -1
  4. package/cjs/charts/bar-3d/chart-spec-transformer.js +1 -1
  5. package/cjs/charts/bar-3d/chart.js +1 -1
  6. package/cjs/charts/bar-3d/constant.js +1 -2
  7. package/cjs/charts/bar-3d/index.js +1 -1
  8. package/cjs/charts/bar-3d/interface.js +1 -1
  9. package/cjs/charts/bar-3d/series-spec-transformer.js +1 -1
  10. package/cjs/charts/bar-3d/series.js +1 -1
  11. package/cjs/charts/bar-3d/theme.js +1 -1
  12. package/cjs/charts/candlestick/candlestick-transformer.js +1 -1
  13. package/cjs/charts/candlestick/candlestick.js +1 -1
  14. package/cjs/charts/candlestick/index.js +1 -1
  15. package/cjs/charts/candlestick/interface.js +1 -1
  16. package/cjs/charts/candlestick/util.js +1 -1
  17. package/cjs/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  18. package/cjs/charts/combination-candlestick/combination-candlestick.js +1 -1
  19. package/cjs/charts/combination-candlestick/constant.js +1 -1
  20. package/cjs/charts/combination-candlestick/index.js +1 -1
  21. package/cjs/charts/combination-candlestick/interface.js +1 -1
  22. package/cjs/charts/conversion-funnel/arrow-data-transform.js +1 -1
  23. package/cjs/charts/conversion-funnel/constants.js +1 -1
  24. package/cjs/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  25. package/cjs/charts/conversion-funnel/conversion-funnel.js +1 -1
  26. package/cjs/charts/conversion-funnel/index.js +1 -1
  27. package/cjs/charts/conversion-funnel/interface.js +1 -2
  28. package/cjs/charts/conversion-funnel/util.js +1 -1
  29. package/cjs/charts/funnel-3d/chart.js +1 -1
  30. package/cjs/charts/funnel-3d/constant.js +1 -1
  31. package/cjs/charts/funnel-3d/index.js +1 -1
  32. package/cjs/charts/funnel-3d/interface.js +1 -1
  33. package/cjs/charts/funnel-3d/series-spec-transformer.js +1 -1
  34. package/cjs/charts/funnel-3d/series.js +1 -2
  35. package/cjs/charts/funnel-3d/theme.js +1 -1
  36. package/cjs/charts/pictogram/element-highlight-by-graphic-name.js +1 -1
  37. package/cjs/charts/storyline/layouts/arc.js +104 -51
  38. package/cjs/charts/storyline/layouts/arc.js.map +1 -1
  39. package/cjs/charts/storyline/layouts/clock.js +17 -9
  40. package/cjs/charts/storyline/layouts/clock.js.map +1 -1
  41. package/cjs/charts/storyline/layouts/common.d.ts +4 -15
  42. package/cjs/charts/storyline/layouts/common.js +18 -20
  43. package/cjs/charts/storyline/layouts/common.js.map +1 -1
  44. package/cjs/charts/storyline/layouts/default.js +15 -8
  45. package/cjs/charts/storyline/layouts/default.js.map +1 -1
  46. package/cjs/charts/storyline/layouts/ladder.js +16 -9
  47. package/cjs/charts/storyline/layouts/ladder.js.map +1 -1
  48. package/cjs/charts/storyline/layouts/landscape.js +47 -29
  49. package/cjs/charts/storyline/layouts/landscape.js.map +1 -1
  50. package/cjs/charts/storyline/layouts/portrait.d.ts +1 -1
  51. package/cjs/charts/storyline/layouts/portrait.js +22 -16
  52. package/cjs/charts/storyline/layouts/portrait.js.map +1 -1
  53. package/cjs/charts/storyline/layouts/wing.js +16 -8
  54. package/cjs/charts/storyline/layouts/wing.js.map +1 -1
  55. package/cjs/charts/storyline/storyline-transformer.js +1 -1
  56. package/cjs/charts/storyline/storyline-transformer.js.map +1 -1
  57. package/cjs/components/bar-link/bar-link.js +1 -1
  58. package/cjs/components/bar-link/constant.js +1 -1
  59. package/cjs/components/bar-link/index.js +1 -1
  60. package/cjs/components/bar-link/type.js +1 -1
  61. package/cjs/components/bar-link/util.js +1 -1
  62. package/cjs/components/bar-regression-line/index.js +1 -1
  63. package/cjs/components/bar-regression-line/type.js +1 -1
  64. package/cjs/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  65. package/cjs/components/extension-mark-sync-state/index.js +1 -1
  66. package/cjs/components/extension-mark-sync-state/type.js +1 -1
  67. package/cjs/components/histogram-regression-line/index.js +1 -1
  68. package/cjs/components/histogram-regression-line/type.js +2 -1
  69. package/cjs/components/map-label/index.js +1 -1
  70. package/cjs/components/map-label/layout.js +1 -1
  71. package/cjs/components/map-label/map-label-transformer.js +1 -1
  72. package/cjs/components/map-label/map-label.js +1 -1
  73. package/cjs/components/map-label/theme.js +1 -1
  74. package/cjs/components/map-label/type.js +1 -1
  75. package/cjs/components/regression-line/index.js +1 -1
  76. package/cjs/components/regression-line/regression-line.js +1 -1
  77. package/cjs/components/regression-line/type.js +1 -1
  78. package/cjs/components/scatter-regression-line/index.js +1 -1
  79. package/cjs/components/scatter-regression-line/type.js +1 -1
  80. package/cjs/components/series-break/constant.js +1 -1
  81. package/cjs/components/series-break/index.js +1 -1
  82. package/cjs/components/series-break/series-break.js +1 -1
  83. package/cjs/components/series-break/type.js +1 -1
  84. package/cjs/components/series-break/util.js +2 -1
  85. package/cjs/components/series-label/constant.js +1 -1
  86. package/cjs/components/series-label/index.js +1 -1
  87. package/cjs/components/series-label/series-label.js +1 -1
  88. package/cjs/components/series-label/type.js +1 -1
  89. package/cjs/components/series-label/util.js +1 -1
  90. package/esm/charts/axis-3d/index.js +2 -1
  91. package/esm/charts/bar-3d/chart-spec-transformer.js +1 -1
  92. package/esm/charts/bar-3d/chart.js +1 -1
  93. package/esm/charts/bar-3d/constant.js +1 -2
  94. package/esm/charts/bar-3d/index.js +1 -1
  95. package/esm/charts/bar-3d/interface.js +1 -1
  96. package/esm/charts/bar-3d/series-spec-transformer.js +1 -1
  97. package/esm/charts/bar-3d/series.js +1 -1
  98. package/esm/charts/bar-3d/theme.js +1 -1
  99. package/esm/charts/candlestick/candlestick-transformer.js +1 -1
  100. package/esm/charts/candlestick/candlestick.js +1 -1
  101. package/esm/charts/candlestick/index.js +1 -1
  102. package/esm/charts/candlestick/interface.js +1 -1
  103. package/esm/charts/candlestick/util.js +1 -1
  104. package/esm/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  105. package/esm/charts/combination-candlestick/combination-candlestick.js +1 -1
  106. package/esm/charts/combination-candlestick/constant.js +1 -1
  107. package/esm/charts/combination-candlestick/index.js +1 -1
  108. package/esm/charts/combination-candlestick/interface.js +1 -1
  109. package/esm/charts/conversion-funnel/arrow-data-transform.js +1 -1
  110. package/esm/charts/conversion-funnel/constants.js +1 -1
  111. package/esm/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  112. package/esm/charts/conversion-funnel/conversion-funnel.js +1 -1
  113. package/esm/charts/conversion-funnel/index.js +1 -1
  114. package/esm/charts/conversion-funnel/interface.js +1 -2
  115. package/esm/charts/conversion-funnel/util.js +1 -1
  116. package/esm/charts/funnel-3d/chart.js +1 -1
  117. package/esm/charts/funnel-3d/constant.js +1 -1
  118. package/esm/charts/funnel-3d/index.js +1 -1
  119. package/esm/charts/funnel-3d/interface.js +1 -1
  120. package/esm/charts/funnel-3d/series-spec-transformer.js +1 -1
  121. package/esm/charts/funnel-3d/series.js +1 -2
  122. package/esm/charts/funnel-3d/theme.js +1 -1
  123. package/esm/charts/pictogram/element-highlight-by-graphic-name.js +1 -1
  124. package/esm/charts/storyline/layouts/arc.js +101 -50
  125. package/esm/charts/storyline/layouts/arc.js.map +1 -1
  126. package/esm/charts/storyline/layouts/clock.js +18 -10
  127. package/esm/charts/storyline/layouts/clock.js.map +1 -1
  128. package/esm/charts/storyline/layouts/common.d.ts +4 -15
  129. package/esm/charts/storyline/layouts/common.js +12 -17
  130. package/esm/charts/storyline/layouts/common.js.map +1 -1
  131. package/esm/charts/storyline/layouts/default.js +15 -9
  132. package/esm/charts/storyline/layouts/default.js.map +1 -1
  133. package/esm/charts/storyline/layouts/ladder.js +16 -10
  134. package/esm/charts/storyline/layouts/ladder.js.map +1 -1
  135. package/esm/charts/storyline/layouts/landscape.js +46 -30
  136. package/esm/charts/storyline/layouts/landscape.js.map +1 -1
  137. package/esm/charts/storyline/layouts/portrait.d.ts +1 -1
  138. package/esm/charts/storyline/layouts/portrait.js +21 -16
  139. package/esm/charts/storyline/layouts/portrait.js.map +1 -1
  140. package/esm/charts/storyline/layouts/wing.js +16 -9
  141. package/esm/charts/storyline/layouts/wing.js.map +1 -1
  142. package/esm/charts/storyline/storyline-transformer.js +1 -1
  143. package/esm/charts/storyline/storyline-transformer.js.map +1 -1
  144. package/esm/components/bar-link/bar-link.js +1 -1
  145. package/esm/components/bar-link/constant.js +1 -1
  146. package/esm/components/bar-link/index.js +1 -1
  147. package/esm/components/bar-link/type.js +1 -1
  148. package/esm/components/bar-link/util.js +1 -1
  149. package/esm/components/bar-regression-line/index.js +1 -1
  150. package/esm/components/bar-regression-line/type.js +1 -1
  151. package/esm/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  152. package/esm/components/extension-mark-sync-state/index.js +1 -1
  153. package/esm/components/extension-mark-sync-state/type.js +1 -1
  154. package/esm/components/histogram-regression-line/index.js +1 -1
  155. package/esm/components/histogram-regression-line/type.js +2 -1
  156. package/esm/components/map-label/index.js +1 -1
  157. package/esm/components/map-label/layout.js +1 -1
  158. package/esm/components/map-label/map-label-transformer.js +1 -1
  159. package/esm/components/map-label/map-label.js +1 -1
  160. package/esm/components/map-label/theme.js +1 -1
  161. package/esm/components/map-label/type.js +1 -1
  162. package/esm/components/regression-line/index.js +1 -1
  163. package/esm/components/regression-line/regression-line.js +1 -1
  164. package/esm/components/regression-line/type.js +1 -1
  165. package/esm/components/scatter-regression-line/index.js +1 -1
  166. package/esm/components/scatter-regression-line/type.js +1 -1
  167. package/esm/components/series-break/constant.js +1 -1
  168. package/esm/components/series-break/index.js +1 -1
  169. package/esm/components/series-break/series-break.js +1 -1
  170. package/esm/components/series-break/type.js +1 -1
  171. package/esm/components/series-break/util.js +2 -1
  172. package/esm/components/series-label/constant.js +1 -1
  173. package/esm/components/series-label/index.js +1 -1
  174. package/esm/components/series-label/series-label.js +1 -1
  175. package/esm/components/series-label/type.js +1 -1
  176. package/esm/components/series-label/util.js +1 -1
  177. package/package.json +2 -2
package/build/index.js CHANGED
@@ -6078,6 +6078,7 @@
6078
6078
  const DEFAULT_IMAGE_HEIGHT = 48;
6079
6079
  const DEFAULT_IMAGE_GAP = 10;
6080
6080
  const DEFAULT_THEME_COLOR = '#e8543d';
6081
+ const BLOCK_TITLE_MAX_LINES = 2;
6081
6082
  const DEFAULT_TITLE_IMAGE_WIDTH_RATIO = 0.52;
6082
6083
  const DEFAULT_TITLE_IMAGE_MAX_WIDTH = 720;
6083
6084
  const DEFAULT_TITLE_IMAGE_HEIGHT_RATIO = 0.36;
@@ -6093,7 +6094,7 @@
6093
6094
  const shouldShowImageBackground = (spec) => { var _a, _b; return (_b = (_a = spec.image) === null || _a === void 0 ? void 0 : _a.showBackground) !== null && _b !== void 0 ? _b : !(isPortrait(spec) || isLandscape(spec)); };
6094
6095
  const TITLE_FONT_SCALE_ID = 'storylineTitleFontSize';
6095
6096
  const MARKER_FONT_SCALE_ID = 'storylineMarkerFontSize';
6096
- const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
6097
+ const clamp$1 = (value, min, max) => Math.max(min, Math.min(max, value));
6097
6098
  const getTextWeight = (text) => {
6098
6099
  if (!text) {
6099
6100
  return 4;
@@ -6138,9 +6139,11 @@
6138
6139
  const canvasSize = Math.sqrt(width * height) * options.canvasRatio;
6139
6140
  const lengthFactor = Math.sqrt(8 / Math.max(textWeight, 4));
6140
6141
  const adaptiveSize = width <= 1 && height <= 1 ? options.fallback : canvasSize * lengthFactor;
6141
- const boxWidthLimit = options.boxWidth && options.boxWidth > 0 ? (options.boxWidth / textWeight) * 0.96 : Number.POSITIVE_INFINITY;
6142
+ const boxWidthLimit = options.boxWidth && options.boxWidth > 0
6143
+ ? ((options.boxWidth * BLOCK_TITLE_MAX_LINES) / textWeight) * 0.96
6144
+ : Number.POSITIVE_INFINITY;
6142
6145
  const boxHeightLimit = options.boxHeight && options.boxHeight > 0 ? options.boxHeight / Math.max(textWeight, 1) : Number.POSITIVE_INFINITY;
6143
- return Math.floor(clamp(Math.min(adaptiveSize, boxWidthLimit, boxHeightLimit), minFontSize, maxFontSize));
6146
+ return Math.floor(clamp$1(Math.min(adaptiveSize, boxWidthLimit, boxHeightLimit), minFontSize, maxFontSize));
6144
6147
  };
6145
6148
  const resolveAdaptiveLineHeight = (fontSize, style, fallback, ratio = 1.35) => { var _a; return Number((_a = style === null || style === void 0 ? void 0 : style.lineHeight) !== null && _a !== void 0 ? _a : Math.round((Number.isFinite(fontSize) ? fontSize : fallback) * ratio)); };
6146
6149
  const resolveTitleFontSize = (spec, ctx, title, boxWidth, fallback, range = [16, 34]) => {
@@ -6326,27 +6329,18 @@
6326
6329
  y: block.center.y + startY
6327
6330
  } }))), links: result.links.map(link => (Object.assign(Object.assign({}, link), { start: { x: link.start.x + startX, y: link.start.y + startY }, end: { x: link.end.x + startX, y: link.end.y + startY }, points: link.points.map(point => ({ x: point.x + startX, y: point.y + startY })) }))) });
6328
6331
  };
6329
- const buildRichContent = (contentText, spec, overrides) => {
6330
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
6331
- const fontSize = Number((_e = (_a = overrides === null || overrides === void 0 ? void 0 : overrides.fontSize) !== null && _a !== void 0 ? _a : (_c = (_b = spec.content) === null || _b === void 0 ? void 0 : _b.style) === null || _c === void 0 ? void 0 : _c.fontSize) !== null && _e !== void 0 ? _e : 18);
6332
- const lineHeight = Number((_j = (_f = overrides === null || overrides === void 0 ? void 0 : overrides.lineHeight) !== null && _f !== void 0 ? _f : (_h = (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.lineHeight) !== null && _j !== void 0 ? _j : 26);
6333
- const fill = (_o = (_k = overrides === null || overrides === void 0 ? void 0 : overrides.fill) !== null && _k !== void 0 ? _k : (_m = (_l = spec.content) === null || _l === void 0 ? void 0 : _l.style) === null || _m === void 0 ? void 0 : _m.fill) !== null && _o !== void 0 ? _o : '#596173';
6334
- const align = (_p = overrides === null || overrides === void 0 ? void 0 : overrides.align) !== null && _p !== void 0 ? _p : 'left';
6335
- return {
6336
- type: 'rich',
6337
- text: contentText.reduce((result, paragraph, index) => {
6338
- const suffix = index === contentText.length - 1 ? '' : '\n';
6339
- result.push({
6340
- text: `${paragraph}${suffix}`,
6341
- fontSize,
6342
- lineHeight,
6343
- fill,
6344
- align
6345
- });
6346
- return result;
6347
- }, [])
6348
- };
6332
+ const buildPlainContent = (contentText) => contentText.join('\n');
6333
+ const getBlockTitleLineCount = (title, boxWidth, fontSize) => {
6334
+ if (!title) {
6335
+ return 0;
6336
+ }
6337
+ if (!boxWidth || boxWidth <= 0 || !fontSize || fontSize <= 0) {
6338
+ return 1;
6339
+ }
6340
+ const estimatedWidth = getTextWeight(title) * fontSize;
6341
+ return Math.max(1, Math.min(BLOCK_TITLE_MAX_LINES, Math.ceil(estimatedWidth / Math.max(boxWidth * 0.96, 1))));
6349
6342
  };
6343
+ const getBlockTitleHeight = (lineHeight, title, boxWidth, fontSize) => lineHeight * getBlockTitleLineCount(title, boxWidth, fontSize);
6350
6344
  const omitImageLayoutSpec = (imageSpec) => {
6351
6345
  if (!imageSpec) {
6352
6346
  return {};
@@ -6444,8 +6438,9 @@
6444
6438
  const CLOCK_ORBIT_DASH = [4, 4];
6445
6439
  const CLOCK_TITLE_FONT_SIZE = 22;
6446
6440
  const CLOCK_TITLE_LINE_HEIGHT = 28;
6447
- const CLOCK_CONTENT_FONT_SIZE = 16;
6448
- const CLOCK_CONTENT_LINE_HEIGHT = 22;
6441
+ const CLOCK_CONTENT_FONT_SIZE = 14;
6442
+ const CLOCK_CONTENT_LINE_HEIGHT = 20;
6443
+ const CLOCK_CONTENT_LINES = 4;
6449
6444
  const getClockGeometry = (spec, ctx) => {
6450
6445
  var _a, _b, _c;
6451
6446
  const { width, height, startX, startY } = getRegionGeometry(ctx);
@@ -6455,7 +6450,7 @@
6455
6450
  const cx = startX + padding.left + innerWidth / 2;
6456
6451
  const cy = startY + padding.top + innerHeight / 2;
6457
6452
  const textReserveX = CLOCK_TEXT_MAX_WIDTH;
6458
- const textReserveY = 4 + CLOCK_CONTENT_LINE_HEIGHT * 4;
6453
+ const textReserveY = 4 + CLOCK_CONTENT_LINE_HEIGHT * CLOCK_CONTENT_LINES;
6459
6454
  const rMaxX = (innerWidth / 2 - textReserveX) / CLOCK_TEXT_INNER_RATIO;
6460
6455
  const rMaxY = (innerHeight / 2 - textReserveY) / CLOCK_TEXT_INNER_RATIO;
6461
6456
  const R = Math.max(Math.min(rMaxX, rMaxY), 1);
@@ -6539,6 +6534,7 @@
6539
6534
  const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
6540
6535
  const getTitleFontSize = (ctx) => resolveTitleFontSize(spec, ctx, block.title, getClockTextRect(spec, ctx, index).width, CLOCK_TITLE_FONT_SIZE, [8, 30]);
6541
6536
  const getTitleLineHeight = (ctx) => { var _a; return resolveAdaptiveLineHeight(getTitleFontSize(ctx), (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style, CLOCK_TITLE_LINE_HEIGHT, 1.28); };
6537
+ const getTitleHeight = (ctx) => getBlockTitleHeight(getTitleLineHeight(ctx), block.title, getClockTextRect(spec, ctx, index).width, getTitleFontSize(ctx));
6542
6538
  const leadPath = (_d, ctx) => {
6543
6539
  const { start, end } = getClockLeadLine(spec, ctx, index);
6544
6540
  return `M ${start.x.toFixed(2)} ${start.y.toFixed(2)} L ${end.x.toFixed(2)} ${end.y.toFixed(2)}`;
@@ -6588,10 +6584,10 @@
6588
6584
  }
6589
6585
  },
6590
6586
  block.title
6591
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-clock-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getClockTextRect(spec, ctx, index).x, y: (_d, ctx) => getClockTextRect(spec, ctx, index).anchorY - getTitleLineHeight(ctx), text: block.title, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, fontSize: (_d, ctx) => getTitleFontSize(ctx), lineHeight: (_d, ctx) => getTitleLineHeight(ctx), fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top' }, (_b = spec.title) === null || _b === void 0 ? void 0 : _b.style) })
6587
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-clock-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getClockTextRect(spec, ctx, index).x, y: (_d, ctx) => getClockTextRect(spec, ctx, index).anchorY - getTitleHeight(ctx), text: block.title, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, height: (_d, ctx) => getTitleHeight(ctx), heightLimit: (_d, ctx) => getTitleLineHeight(ctx) * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getTitleFontSize(ctx), lineHeight: (_d, ctx) => getTitleLineHeight(ctx), fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_b = spec.title) === null || _b === void 0 ? void 0 : _b.style) })
6592
6588
  : null,
6593
6589
  contentText.length
6594
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-clock-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getClockTextRect(spec, ctx, index).x, y: (_d, ctx) => getClockTextRect(spec, ctx, index).anchorY + 4, width: (_d, ctx) => getClockTextRect(spec, ctx, index).width, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, text: buildRichContent(contentText, spec), fontSize: CLOCK_CONTENT_FONT_SIZE, lineHeight: CLOCK_CONTENT_LINE_HEIGHT, fill: '#3a3f4d', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top', wordBreak: 'break-word' }, (_c = spec.content) === null || _c === void 0 ? void 0 : _c.style) })
6590
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-clock-content-${index}`, interactive: false }, spec.content), { style: Object.assign({ x: (_d, ctx) => getClockTextRect(spec, ctx, index).x, y: (_d, ctx) => getClockTextRect(spec, ctx, index).anchorY + 4, width: (_d, ctx) => getClockTextRect(spec, ctx, index).width, height: CLOCK_CONTENT_LINE_HEIGHT * CLOCK_CONTENT_LINES, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, heightLimit: CLOCK_CONTENT_LINE_HEIGHT * CLOCK_CONTENT_LINES, text: buildPlainContent(contentText), fontSize: CLOCK_CONTENT_FONT_SIZE, lineHeight: CLOCK_CONTENT_LINE_HEIGHT, fill: '#3a3f4d', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word' }, (_c = spec.content) === null || _c === void 0 ? void 0 : _c.style) })
6595
6591
  : null
6596
6592
  ];
6597
6593
  return {
@@ -6640,7 +6636,7 @@
6640
6636
  const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
6641
6637
  const titleFontSize = resolveTitleFontSize(spec, ctx, (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s[index]) === null || _t === void 0 ? void 0 : _t.title, textBox.width, 18, [8, 28]);
6642
6638
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_u = spec.title) === null || _u === void 0 ? void 0 : _u.style, Math.round(18 * 1.35));
6643
- const titleHeight = ((_w = (_v = spec.data) === null || _v === void 0 ? void 0 : _v[index]) === null || _w === void 0 ? void 0 : _w.title) ? titleLineHeight : 0;
6639
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_w = (_v = spec.data) === null || _v === void 0 ? void 0 : _v[index]) === null || _w === void 0 ? void 0 : _w.title, textBox.width, titleFontSize);
6644
6640
  const contentGap = ((_y = (_x = spec.data) === null || _x === void 0 ? void 0 : _x[index]) === null || _y === void 0 ? void 0 : _y.title) ? 8 : 0;
6645
6641
  return {
6646
6642
  block: {
@@ -6649,6 +6645,7 @@
6649
6645
  },
6650
6646
  titleFontSize,
6651
6647
  titleLineHeight,
6648
+ titleHeight,
6652
6649
  imageBox,
6653
6650
  textBox,
6654
6651
  contentBox: {
@@ -6693,14 +6690,10 @@
6693
6690
  ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).imageBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).imageBox.y, width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).imageBox.width, height: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).imageBox.height, image: block.image }, (_e = spec.image) === null || _e === void 0 ? void 0 : _e.style) })
6694
6691
  : null,
6695
6692
  block.title
6696
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, fontSize: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style) })
6693
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, height: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleHeight, heightLimit: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style) })
6697
6694
  : null,
6698
6695
  contentText.length
6699
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.y, width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, text: buildRichContent(contentText, spec, {
6700
- fontSize: 18,
6701
- lineHeight: 26,
6702
- fill: '#596173'
6703
- }), maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, heightLimit: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.height, textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) })
6696
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.y, width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, height: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.height, text: buildPlainContent(contentText), maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, heightLimit: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.height, fontSize: 16, lineHeight: 23, textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) })
6704
6697
  : null
6705
6698
  ].filter(Boolean)
6706
6699
  };
@@ -6746,25 +6739,27 @@
6746
6739
  };
6747
6740
 
6748
6741
  const LANDSCAPE_IMAGE_HEIGHT_RATIO = 0.42;
6749
- const LANDSCAPE_DETACHED_GAP = 64;
6742
+ const LANDSCAPE_CONNECTOR_GAP = 8;
6750
6743
  const LANDSCAPE_CONNECTOR_ARROW_SIZE = 9;
6751
6744
  const LANDSCAPE_CONNECTOR_X_RATIO = 0.2;
6752
6745
  const LANDSCAPE_TEXT_GAP_FROM_CONNECTOR = 12;
6753
- const LANDSCAPE_CONTENT_LINES = 10;
6754
6746
  const LANDSCAPE_TITLE_LINE_HEIGHT = 34;
6755
- const LANDSCAPE_CONTENT_LINE_HEIGHT = 26;
6756
- const LANDSCAPE_CONTENT_FONT_SIZE = 18;
6747
+ const LANDSCAPE_CONTENT_LINE_HEIGHT = 23;
6748
+ const LANDSCAPE_CONTENT_FONT_SIZE = 16;
6757
6749
  const LANDSCAPE_TITLE_TO_CONTENT_GAP = 4;
6750
+ const LANDSCAPE_BODY_MARGIN = 8;
6751
+ const LANDSCAPE_IMAGE_BAND_RATIO = 0.28;
6752
+ const LANDSCAPE_IMAGE_BAND_MAX_RATIO = 0.42;
6758
6753
  const getLandscapeImageCenter = (spec, ctx, index) => {
6759
- var _a, _b, _c, _e;
6760
6754
  const lb = getLayout(spec, ctx).blocks[index];
6761
6755
  if (!lb) {
6762
6756
  return null;
6763
6757
  }
6764
- const cx = (_b = (_a = lb.center) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : lb.x + lb.width / 2;
6765
- const cy = (_e = (_c = lb.center) === null || _c === void 0 ? void 0 : _c.y) !== null && _e !== void 0 ? _e : lb.y + lb.height / 2;
6766
- const stagger = (index % 2 === 0 ? -1 : 1) * lb.height * 0.1;
6767
- return { x: cx, y: cy + stagger };
6758
+ const m = getLandscapeMetrics(spec, lb.width, lb.height, index, ctx);
6759
+ return {
6760
+ x: lb.x + m.imageBox.x + m.imageBox.width / 2,
6761
+ y: m.bodyOriginY + m.imageBox.y + m.imageBox.height / 2
6762
+ };
6768
6763
  };
6769
6764
  const buildLandscapeConnectingCurve = (spec) => {
6770
6765
  var _a, _b, _c, _e, _f, _g, _h;
@@ -6821,20 +6816,24 @@
6821
6816
  };
6822
6817
  };
6823
6818
  const getLandscapeMetrics = (spec, blockWidth, blockHeight, index, ctx) => {
6824
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
6819
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6825
6820
  const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
6826
6821
  const titleFontSize = resolveTitleFontSize(spec, ctx, (_e = (_c = spec.data) === null || _c === void 0 ? void 0 : _c[index]) === null || _e === void 0 ? void 0 : _e.title, blockWidth, 26, [8, 34]);
6827
6822
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style, LANDSCAPE_TITLE_LINE_HEIGHT);
6828
6823
  const contentFontSize = Number((_j = (_h = (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.fontSize) !== null && _j !== void 0 ? _j : LANDSCAPE_CONTENT_FONT_SIZE);
6829
6824
  const contentLineHeight = Number((_m = (_l = (_k = spec.content) === null || _k === void 0 ? void 0 : _k.style) === null || _l === void 0 ? void 0 : _l.lineHeight) !== null && _m !== void 0 ? _m : LANDSCAPE_CONTENT_LINE_HEIGHT);
6830
- const imageHeight = Math.max((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.height) !== null && _p !== void 0 ? _p : Math.round(blockHeight * LANDSCAPE_IMAGE_HEIGHT_RATIO), titleLineHeight + padding.top + padding.bottom);
6831
- const connectorGap = LANDSCAPE_DETACHED_GAP;
6832
- const canvasHeight = spec.height;
6833
- const contentHeight = canvasHeight
6834
- ? Math.max(contentLineHeight * 2, Math.round(canvasHeight / 4))
6835
- : LANDSCAPE_CONTENT_LINES * contentLineHeight;
6825
+ const { width: regionWidth } = getRegionGeometry(ctx, spec);
6826
+ const blockCount = Math.max((_p = (_o = spec.data) === null || _o === void 0 ? void 0 : _o.length) !== null && _p !== void 0 ? _p : 1, 1);
6827
+ const textWidth = Math.max(regionWidth / blockCount, 1);
6828
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_r = (_q = spec.data) === null || _q === void 0 ? void 0 : _q[index]) === null || _r === void 0 ? void 0 : _r.title, textWidth, titleFontSize);
6829
+ const rawImageHeight = Math.max((_t = (_s = spec.image) === null || _s === void 0 ? void 0 : _s.height) !== null && _t !== void 0 ? _t : Math.round(blockHeight * LANDSCAPE_IMAGE_HEIGHT_RATIO), titleLineHeight + padding.top + padding.bottom);
6836
6830
  const titleToContentGap = LANDSCAPE_TITLE_TO_CONTENT_GAP;
6837
- const textHeight = titleLineHeight + titleToContentGap + contentHeight;
6831
+ const minTextBandHeight = titleHeight + titleToContentGap + contentLineHeight * 2;
6832
+ const body = getLandscapeBodyGeometry(ctx, spec, rawImageHeight, blockHeight, minTextBandHeight);
6833
+ const imageHeight = body.imageHeight;
6834
+ const textBandHeight = body.textBandHeight;
6835
+ const contentHeight = Math.max(0, textBandHeight - titleHeight - titleToContentGap);
6836
+ const textHeight = titleHeight + titleToContentGap + contentHeight;
6838
6837
  const textOnTop = index % 2 === 0;
6839
6838
  let textBox;
6840
6839
  let contentBox;
@@ -6845,49 +6844,51 @@
6845
6844
  const imageX = 0;
6846
6845
  const connectorX = imageX + blockWidth * LANDSCAPE_CONNECTOR_X_RATIO;
6847
6846
  const textX = connectorX + LANDSCAPE_TEXT_GAP_FROM_CONNECTOR;
6848
- const textWidth = Math.max(blockWidth - (textX - imageX), 0);
6847
+ const waveOffset = (textOnTop ? -1 : 1) * body.waveAmplitude;
6848
+ const imageY = body.imageBandTop + body.imageBandHeight / 2 + waveOffset - imageHeight / 2;
6849
6849
  if (textOnTop) {
6850
- const imageY = 0;
6851
- const textY = imageY - connectorGap - textHeight;
6852
- const connectorY1 = imageY;
6853
- const connectorY2 = textY + titleLineHeight / 2;
6850
+ const textY = body.upperTextTop;
6851
+ const connectorY1 = Math.max(imageY - LANDSCAPE_CONNECTOR_GAP, body.upperTextTop);
6852
+ const connectorY2 = textY + Math.max(titleHeight, titleLineHeight) / 2;
6854
6853
  imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6855
6854
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
6856
6855
  contentBox = {
6857
6856
  x: textX,
6858
- y: textY + titleLineHeight + titleToContentGap,
6857
+ y: textY + titleHeight + titleToContentGap,
6859
6858
  width: textWidth,
6860
6859
  height: contentHeight
6861
6860
  };
6862
6861
  connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6863
- groupTop = textY;
6864
- groupHeight = imageHeight - groupTop;
6862
+ groupTop = 0;
6863
+ groupHeight = body.height;
6865
6864
  }
6866
6865
  else {
6867
- const imageY = 0;
6868
- const textY = imageY + imageHeight + connectorGap;
6869
- const connectorY1 = imageY + imageHeight;
6866
+ const textY = body.lowerTextTop;
6867
+ const connectorY1 = Math.min(imageY + imageHeight + LANDSCAPE_CONNECTOR_GAP, body.height);
6870
6868
  const connectorY2 = textY + textHeight;
6871
6869
  imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6872
6870
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
6873
6871
  contentBox = {
6874
6872
  x: textX,
6875
- y: textY + titleLineHeight + titleToContentGap,
6873
+ y: textY + titleHeight + titleToContentGap,
6876
6874
  width: textWidth,
6877
6875
  height: contentHeight
6878
6876
  };
6879
6877
  connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6880
- groupTop = imageY;
6881
- groupHeight = textY + textHeight - imageY;
6878
+ groupTop = 0;
6879
+ groupHeight = body.height;
6882
6880
  }
6883
6881
  return {
6884
6882
  padding,
6885
6883
  titleFontSize,
6886
6884
  titleLineHeight,
6885
+ titleHeight,
6887
6886
  contentFontSize,
6888
6887
  contentLineHeight,
6889
6888
  contentHeight,
6890
- blockWidth,
6889
+ minTextBandHeight,
6890
+ bodyOriginY: body.originY,
6891
+ blockWidth: Math.max(blockWidth, textX + textWidth),
6891
6892
  imageBox,
6892
6893
  textBox,
6893
6894
  contentBox,
@@ -6897,6 +6898,28 @@
6897
6898
  groupHeight
6898
6899
  };
6899
6900
  };
6901
+ const getLandscapeBodyGeometry = (ctx, spec, rawImageHeight, blockHeight, minTextBandHeight) => {
6902
+ const region = getRegionGeometry(ctx, spec);
6903
+ const margin = Math.min(LANDSCAPE_BODY_MARGIN, Math.max(region.height * 0.04, 0));
6904
+ const height = Math.max(region.height - margin * 2, 1);
6905
+ const textBandReserve = Math.min(minTextBandHeight, Math.max((height - 48) / 2, 0));
6906
+ const maxImageBandHeight = Math.max(height - textBandReserve * 2, height * 0.18);
6907
+ const imageBandHeight = Math.min(Math.max(rawImageHeight + 24, height * LANDSCAPE_IMAGE_BAND_RATIO), Math.max(1, Math.min(maxImageBandHeight, height * LANDSCAPE_IMAGE_BAND_MAX_RATIO)));
6908
+ const imageHeight = Math.min(rawImageHeight, Math.max(imageBandHeight - 16, 1));
6909
+ const textBandHeight = Math.max((height - imageBandHeight) / 2, 1);
6910
+ const imageBandTop = textBandHeight;
6911
+ return {
6912
+ originY: region.startY + margin,
6913
+ height,
6914
+ textBandHeight,
6915
+ imageBandTop,
6916
+ imageBandHeight,
6917
+ imageHeight,
6918
+ upperTextTop: 0,
6919
+ lowerTextTop: imageBandTop + imageBandHeight,
6920
+ waveAmplitude: Math.min(imageBandHeight * 0.18, blockHeight * 0.1)
6921
+ };
6922
+ };
6900
6923
  const buildLandscapeBlockMark = (spec, block, index) => {
6901
6924
  var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m;
6902
6925
  const hasImage = !!block.image;
@@ -6926,13 +6949,8 @@
6926
6949
  return (_a = lb === null || lb === void 0 ? void 0 : lb.x) !== null && _a !== void 0 ? _a : 0;
6927
6950
  },
6928
6951
  y: (_d, ctx) => {
6929
- var _a, _b, _c, _e, _f, _g, _h;
6930
- const lb = getLayout(spec, ctx).blocks[index];
6931
6952
  const m = getMetrics(ctx);
6932
- const cy = (_b = (_a = lb === null || lb === void 0 ? void 0 : lb.center) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : ((_c = lb === null || lb === void 0 ? void 0 : lb.y) !== null && _c !== void 0 ? _c : 0) + ((_e = lb === null || lb === void 0 ? void 0 : lb.height) !== null && _e !== void 0 ? _e : 0) / 2;
6933
- const blockH = (_h = (_f = lb === null || lb === void 0 ? void 0 : lb.height) !== null && _f !== void 0 ? _f : (_g = spec.block) === null || _g === void 0 ? void 0 : _g.height) !== null && _h !== void 0 ? _h : DEFAULT_BLOCK_HEIGHT;
6934
- const stagger = m.textOnTop ? blockH * 0.1 : -blockH * 0.1;
6935
- return cy - m.imageBox.height / 2 + stagger;
6953
+ return m.bodyOriginY;
6936
6954
  },
6937
6955
  width: (_d, ctx) => getMetrics(ctx).blockWidth,
6938
6956
  height: (_d, ctx) => getMetrics(ctx).groupHeight
@@ -6973,14 +6991,10 @@
6973
6991
  }
6974
6992
  },
6975
6993
  block.title
6976
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, fontSize: (_d, ctx) => getMetrics(ctx).titleFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_l = spec.title) === null || _l === void 0 ? void 0 : _l.style) })
6994
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, height: (_d, ctx) => getMetrics(ctx).titleHeight, heightLimit: (_d, ctx) => getMetrics(ctx).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getMetrics(ctx).titleFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_l = spec.title) === null || _l === void 0 ? void 0 : _l.style) })
6977
6995
  : null,
6978
6996
  contentText.length
6979
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildRichContent(contentText, spec, {
6980
- fontSize: LANDSCAPE_CONTENT_FONT_SIZE,
6981
- lineHeight: LANDSCAPE_CONTENT_LINE_HEIGHT,
6982
- fill: '#596173'
6983
- }), textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_m = spec.content) === null || _m === void 0 ? void 0 : _m.style) })
6997
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildPlainContent(contentText), fontSize: (_d, ctx) => getMetrics(ctx).contentFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).contentLineHeight, textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_m = spec.content) === null || _m === void 0 ? void 0 : _m.style) })
6984
6998
  : null
6985
6999
  ].filter(Boolean)
6986
7000
  };
@@ -6988,8 +7002,8 @@
6988
7002
 
6989
7003
  const PORTRAIT_AXIS_WIDTH = 96;
6990
7004
  const PORTRAIT_AXIS_PADDING = 120;
6991
- const PORTRAIT_MARKER_FONT_SIZE = 40;
6992
- const PORTRAIT_MARKER_LINE_HEIGHT = 28;
7005
+ const PORTRAIT_MARKER_FONT_SIZE = 34;
7006
+ const PORTRAIT_MARKER_LINE_HEIGHT = 24;
6993
7007
  const PORTRAIT_MARKER_AXIS_PADDING = 6;
6994
7008
  const PORTRAIT_IMAGE_HEIGHT_RATIO = 0.6;
6995
7009
  const PORTRAIT_CONTENT_HEIGHT_RATIO = 1.25;
@@ -7000,8 +7014,8 @@
7000
7014
  const PORTRAIT_TEXT_GAP_FROM_IMAGE = 8;
7001
7015
  const PORTRAIT_CONTENT_LINES = 3;
7002
7016
  const PORTRAIT_TITLE_LINE_HEIGHT = 34;
7003
- const PORTRAIT_CONTENT_LINE_HEIGHT = 26;
7004
- const PORTRAIT_CONTENT_FONT_SIZE = 18;
7017
+ const PORTRAIT_CONTENT_LINE_HEIGHT = 23;
7018
+ const PORTRAIT_CONTENT_FONT_SIZE = 16;
7005
7019
  const PORTRAIT_TITLE_TO_CONTENT_GAP = 4;
7006
7020
  const buildPortraitAxisMark = (spec) => {
7007
7021
  var _a, _b, _c, _e, _f, _g, _h, _j, _k;
@@ -7043,7 +7057,7 @@
7043
7057
  }, text: (_d, ctx) => {
7044
7058
  var _a, _b, _c;
7045
7059
  const axis = getPortraitAxisRect(spec, ctx);
7046
- const markerFontSize = resolveMarkerFontSize(spec, ctx, block.marker, axis.height / Math.max((_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 1, 1), PORTRAIT_MARKER_FONT_SIZE);
7060
+ const markerFontSize = resolveMarkerFontSize(spec, ctx, block.marker, axis.height / Math.max((_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 1, 1), PORTRAIT_MARKER_FONT_SIZE, [16, 38]);
7047
7061
  const markerLineHeight = resolveAdaptiveLineHeight(markerFontSize, (_c = spec.marker) === null || _c === void 0 ? void 0 : _c.style, PORTRAIT_MARKER_LINE_HEIGHT, 0.9);
7048
7062
  return {
7049
7063
  type: 'rich',
@@ -7084,7 +7098,7 @@
7084
7098
  };
7085
7099
  };
7086
7100
  const getPortraitMetrics = (spec, blockWidth, blockHeight, index, ctx) => {
7087
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
7101
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
7088
7102
  const contentFontSize = Number((_c = (_b = (_a = spec.content) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : PORTRAIT_CONTENT_FONT_SIZE);
7089
7103
  const contentLineHeight = Number((_g = (_f = (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : PORTRAIT_CONTENT_LINE_HEIGHT);
7090
7104
  const titleToContentGap = PORTRAIT_TITLE_TO_CONTENT_GAP;
@@ -7092,9 +7106,10 @@
7092
7106
  const imageHeight = (_l = (_k = spec.image) === null || _k === void 0 ? void 0 : _k.height) !== null && _l !== void 0 ? _l : Math.round(blockHeight * PORTRAIT_IMAGE_HEIGHT_RATIO);
7093
7107
  const titleFontSize = resolveTitleFontSize(spec, ctx, (_o = (_m = spec.data) === null || _m === void 0 ? void 0 : _m[index]) === null || _o === void 0 ? void 0 : _o.title, imageWidth, 26, [8, 34]);
7094
7108
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_p = spec.title) === null || _p === void 0 ? void 0 : _p.style, PORTRAIT_TITLE_LINE_HEIGHT);
7109
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_r = (_q = spec.data) === null || _q === void 0 ? void 0 : _q[index]) === null || _r === void 0 ? void 0 : _r.title, imageWidth, titleFontSize);
7095
7110
  const minContentHeight = PORTRAIT_CONTENT_LINES * contentLineHeight;
7096
7111
  const contentHeight = Math.max(minContentHeight, Math.round(blockHeight * PORTRAIT_CONTENT_HEIGHT_RATIO));
7097
- const textHeight = titleLineHeight + titleToContentGap + contentHeight;
7112
+ const textHeight = titleHeight + titleToContentGap + contentHeight;
7098
7113
  const onLeft = index % 2 === 0;
7099
7114
  const axisHalf = PORTRAIT_AXIS_WIDTH / 2;
7100
7115
  const imageX = onLeft
@@ -7106,7 +7121,7 @@
7106
7121
  const textWidth = imageWidth;
7107
7122
  const contentBox = {
7108
7123
  x: textX,
7109
- y: textY + titleLineHeight + titleToContentGap,
7124
+ y: textY + titleHeight + titleToContentGap,
7110
7125
  width: textWidth,
7111
7126
  height: contentHeight
7112
7127
  };
@@ -7126,6 +7141,7 @@
7126
7141
  onLeft,
7127
7142
  titleFontSize,
7128
7143
  titleLineHeight,
7144
+ titleHeight,
7129
7145
  contentFontSize,
7130
7146
  contentLineHeight,
7131
7147
  blockWidth,
@@ -7218,14 +7234,10 @@
7218
7234
  ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).imageBox.x, y: (_d, ctx) => getMetrics(ctx).imageBox.y, width: (_d, ctx) => getMetrics(ctx).imageBox.width, height: (_d, ctx) => getMetrics(ctx).imageBox.height, image: block.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'contain', imagePosition: 'center' }, (_e = spec.image) === null || _e === void 0 ? void 0 : _e.style) })
7219
7235
  : null,
7220
7236
  block.title
7221
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, fontSize: (_d, ctx) => getMetrics(ctx).titleFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style) })
7237
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, height: (_d, ctx) => getMetrics(ctx).titleHeight, heightLimit: (_d, ctx) => getMetrics(ctx).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getMetrics(ctx).titleFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style) })
7222
7238
  : null,
7223
7239
  contentText.length
7224
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildRichContent(contentText, spec, {
7225
- fontSize: PORTRAIT_CONTENT_FONT_SIZE,
7226
- lineHeight: PORTRAIT_CONTENT_LINE_HEIGHT,
7227
- fill: '#596173'
7228
- }), textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) })
7240
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildPlainContent(contentText), fontSize: PORTRAIT_CONTENT_FONT_SIZE, lineHeight: PORTRAIT_CONTENT_LINE_HEIGHT, textAlign: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) })
7229
7241
  : null
7230
7242
  ].filter(Boolean)
7231
7243
  };
@@ -7237,16 +7249,20 @@
7237
7249
  const ARC_TEXT_GAP_FROM_IMAGE = 10;
7238
7250
  const ARC_TITLE_FONT_SIZE = 32;
7239
7251
  const ARC_TITLE_LINE_HEIGHT = 34;
7240
- const ARC_CONTENT_LINE_HEIGHT = 26;
7241
- const ARC_CONTENT_FONT_SIZE = 20;
7252
+ const ARC_CONTENT_LINE_HEIGHT = 24;
7253
+ const ARC_CONTENT_FONT_SIZE = 18;
7242
7254
  const ARC_TEXT_BOX_HEIGHT = 240;
7243
7255
  const ARC_TITLE_TO_CONTENT_GAP = 4;
7244
7256
  const ARC_TEXT_PADDING = 20;
7245
- const ARC_TEXT_BOX_MIN_WIDTH = 240;
7257
+ const ARC_TEXT_BOX_MIN_WIDTH = 96;
7258
+ const ARC_TEXT_BOX_ABSOLUTE_MIN_WIDTH = 64;
7259
+ const ARC_TEXT_BOX_MAX_WIDTH = 260;
7246
7260
  const ARC_TITLE_IMAGE_WIDTH_RATIO = 0.68;
7247
7261
  const ARC_TITLE_IMAGE_MAX_WIDTH = 900;
7248
7262
  const ARC_TITLE_IMAGE_HEIGHT_RATIO = 0.34;
7249
7263
  const ARC_GAP_FROM_TITLE_IMAGE = 200;
7264
+ const ARC_FIT_MARGIN = 8;
7265
+ const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
7250
7266
  const isDownArc = (spec) => normalizeLayout(spec.layout).direction === 'down';
7251
7267
  const getArcTitleImageRect = (spec, ctx) => {
7252
7268
  var _a, _b, _c, _e;
@@ -7261,7 +7277,7 @@
7261
7277
  const top = isDown ? startY : startY + innerHeight - h;
7262
7278
  return { x: cx - w / 2, y: top, width: w, height: h };
7263
7279
  };
7264
- const getArcGeometry = (spec, ctx) => {
7280
+ const getBaseArcGeometry = (spec, ctx) => {
7265
7281
  var _a, _b, _c;
7266
7282
  const { width, startX } = getRegionGeometry(ctx);
7267
7283
  const innerWidth = Math.max(width, 1);
@@ -7299,9 +7315,8 @@
7299
7315
  centerBottom
7300
7316
  };
7301
7317
  };
7302
- const getArcBlockCenter = (spec, ctx, index) => {
7303
- var _a, _b, _c, _e;
7304
- const arc = getArcGeometry(spec, ctx);
7318
+ const getArcBlockCenterByGeometry = (spec, arc, index, ctx) => {
7319
+ var _a, _b;
7305
7320
  const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7306
7321
  if (count <= 0) {
7307
7322
  return { x: arc.cx, y: arc.cy };
@@ -7315,10 +7330,80 @@
7315
7330
  const nLen = Math.hypot(nxRaw, nyRaw) || 1;
7316
7331
  const nx = nxRaw / nLen;
7317
7332
  const ny = nyRaw / nLen;
7318
- const imageHeight = (_e = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.height) !== null && _e !== void 0 ? _e : ARC_BLOCK_IMAGE_SIZE;
7333
+ const imageHeight = getArcBlockMetrics(spec, index, ctx).imageBox.height;
7319
7334
  const offset = imageHeight / 2;
7320
7335
  return { x: px + nx * offset, y: py + ny * offset };
7321
7336
  };
7337
+ const getArcBlockBounds = (spec, arc, index, ctx) => {
7338
+ const center = getArcBlockCenterByGeometry(spec, arc, index, ctx);
7339
+ const metrics = getArcBlockMetrics(spec, index, ctx);
7340
+ const halo = shouldShowImageBackground(spec) ? ARC_BLOCK_IMAGE_HALO_PADDING + ARC_BLOCK_IMAGE_BORDER : 0;
7341
+ const minX = Math.min(metrics.imageBox.x - halo, metrics.textBox.x, metrics.contentBox.x);
7342
+ const maxX = Math.max(metrics.imageBox.x + metrics.imageBox.width + halo, metrics.textBox.x + metrics.textBox.width, metrics.contentBox.x + metrics.contentBox.width);
7343
+ const minY = Math.min(metrics.imageBox.y - halo, metrics.textBox.y, metrics.contentBox.y);
7344
+ const maxY = Math.max(metrics.imageBox.y + metrics.imageBox.height + halo, metrics.textBox.y + metrics.textBox.height, metrics.contentBox.y + metrics.contentBox.height);
7345
+ return {
7346
+ left: center.x + minX,
7347
+ right: center.x + maxX,
7348
+ top: center.y + minY,
7349
+ bottom: center.y + maxY
7350
+ };
7351
+ };
7352
+ const getArcBlocksBounds = (spec, arc, ctx) => {
7353
+ var _a, _b;
7354
+ const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7355
+ if (!count) {
7356
+ return { left: arc.cx, right: arc.cx, top: arc.cy, bottom: arc.cy };
7357
+ }
7358
+ return Array.from({ length: count }, (_, index) => getArcBlockBounds(spec, arc, index, ctx)).reduce((bounds, blockBounds) => ({
7359
+ left: Math.min(bounds.left, blockBounds.left),
7360
+ right: Math.max(bounds.right, blockBounds.right),
7361
+ top: Math.min(bounds.top, blockBounds.top),
7362
+ bottom: Math.max(bounds.bottom, blockBounds.bottom)
7363
+ }), {
7364
+ left: Number.POSITIVE_INFINITY,
7365
+ right: Number.NEGATIVE_INFINITY,
7366
+ top: Number.POSITIVE_INFINITY,
7367
+ bottom: Number.NEGATIVE_INFINITY
7368
+ });
7369
+ };
7370
+ const getArcGeometry = (spec, ctx) => {
7371
+ const arc = getBaseArcGeometry(spec, ctx);
7372
+ const region = getRegionGeometry(ctx);
7373
+ const bounds = getArcBlocksBounds(spec, arc, ctx);
7374
+ const fit = {
7375
+ left: region.startX + ARC_FIT_MARGIN,
7376
+ right: region.startX + region.width - ARC_FIT_MARGIN,
7377
+ top: region.startY + ARC_FIT_MARGIN,
7378
+ bottom: region.startY + region.height - ARC_FIT_MARGIN
7379
+ };
7380
+ let shiftX = 0;
7381
+ let shiftY = 0;
7382
+ const boundsWidth = bounds.right - bounds.left;
7383
+ const boundsHeight = bounds.bottom - bounds.top;
7384
+ const fitWidth = fit.right - fit.left;
7385
+ const fitHeight = fit.bottom - fit.top;
7386
+ if (boundsWidth > fitWidth) {
7387
+ shiftX = (fit.left + fit.right - bounds.left - bounds.right) / 2;
7388
+ }
7389
+ else if (bounds.left < fit.left) {
7390
+ shiftX = fit.left - bounds.left;
7391
+ }
7392
+ else if (bounds.right > fit.right) {
7393
+ shiftX = fit.right - bounds.right;
7394
+ }
7395
+ if (boundsHeight > fitHeight) {
7396
+ shiftY = (fit.top + fit.bottom - bounds.top - bounds.bottom) / 2;
7397
+ }
7398
+ else if (bounds.top < fit.top) {
7399
+ shiftY = fit.top - bounds.top;
7400
+ }
7401
+ else if (bounds.bottom > fit.bottom) {
7402
+ shiftY = fit.bottom - bounds.bottom;
7403
+ }
7404
+ return shiftX || shiftY ? Object.assign(Object.assign({}, arc), { cx: arc.cx + shiftX, cy: arc.cy + shiftY }) : arc;
7405
+ };
7406
+ const getArcBlockCenter = (spec, ctx, index) => getArcBlockCenterByGeometry(spec, getArcGeometry(spec, ctx), index, ctx);
7322
7407
  const buildArcMark = (spec) => {
7323
7408
  var _a;
7324
7409
  if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) !== true) {
@@ -7381,23 +7466,33 @@
7381
7466
  ]
7382
7467
  };
7383
7468
  };
7384
- const getArcBlockMetrics = (spec, index = 0) => {
7385
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
7386
- const contentFontSize = Number((_c = (_b = (_a = spec.content) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : ARC_CONTENT_FONT_SIZE);
7387
- const contentLineHeight = Number((_g = (_f = (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : ARC_CONTENT_LINE_HEIGHT);
7469
+ const getArcBlockMetrics = (spec, index = 0, ctx) => {
7470
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
7471
+ const region = ctx ? getRegionGeometry(ctx, spec) : undefined;
7472
+ const count = Math.max((_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0, 1);
7473
+ const regionWidth = Math.max((_c = region === null || region === void 0 ? void 0 : region.width) !== null && _c !== void 0 ? _c : Number((_e = spec.width) !== null && _e !== void 0 ? _e : ARC_BLOCK_IMAGE_SIZE * count), 1);
7474
+ const regionHeight = Math.max((_f = region === null || region === void 0 ? void 0 : region.height) !== null && _f !== void 0 ? _f : Number((_g = spec.height) !== null && _g !== void 0 ? _g : ARC_TEXT_BOX_HEIGHT), 1);
7475
+ const slotWidth = regionWidth / (count + 1);
7476
+ const imageScale = clamp(Math.min(regionWidth / Math.max(count * ARC_BLOCK_IMAGE_SIZE * 0.92, 1), regionHeight / 620), 0.42, 1);
7477
+ const textScale = clamp(Math.min(slotWidth / 180, imageScale), 0.48, 1);
7478
+ const styleContent = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style;
7479
+ const contentFontSize = Number((_j = styleContent === null || styleContent === void 0 ? void 0 : styleContent.fontSize) !== null && _j !== void 0 ? _j : Math.round(ARC_CONTENT_FONT_SIZE * textScale));
7480
+ const contentLineHeight = Number((_k = styleContent === null || styleContent === void 0 ? void 0 : styleContent.lineHeight) !== null && _k !== void 0 ? _k : Math.round(Math.max(contentFontSize * 1.35, ARC_CONTENT_LINE_HEIGHT * textScale)));
7388
7481
  const titleToContentGap = ARC_TITLE_TO_CONTENT_GAP;
7389
- const imageDiameter = Math.max((_j = (_h = spec.image) === null || _h === void 0 ? void 0 : _h.width) !== null && _j !== void 0 ? _j : ARC_BLOCK_IMAGE_SIZE, (_l = (_k = spec.image) === null || _k === void 0 ? void 0 : _k.height) !== null && _l !== void 0 ? _l : ARC_BLOCK_IMAGE_SIZE);
7482
+ const configuredImageDiameter = Math.max((_m = (_l = spec.image) === null || _l === void 0 ? void 0 : _l.width) !== null && _m !== void 0 ? _m : ARC_BLOCK_IMAGE_SIZE, (_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.height) !== null && _p !== void 0 ? _p : ARC_BLOCK_IMAGE_SIZE);
7483
+ const imageDiameter = Math.round(clamp(configuredImageDiameter * imageScale, 64, configuredImageDiameter));
7390
7484
  const imageWidth = imageDiameter;
7391
7485
  const imageHeight = imageDiameter;
7392
7486
  const isDown = isDownArc(spec);
7393
- const count = Math.max((_o = (_m = spec.data) === null || _m === void 0 ? void 0 : _m.length) !== null && _o !== void 0 ? _o : 0, 1);
7394
- const canvasWidth = Number((_p = spec.width) !== null && _p !== void 0 ? _p : imageWidth * count);
7395
- const defaultTextWidth = Math.round(canvasWidth / (count + 1));
7396
- const textBoxWidth = Math.max(Number((_r = (_q = spec.block) === null || _q === void 0 ? void 0 : _q.width) !== null && _r !== void 0 ? _r : defaultTextWidth), ARC_TEXT_BOX_MIN_WIDTH);
7397
- const titleFontSize = resolveTitleFontSize(spec, undefined, (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s[index]) === null || _t === void 0 ? void 0 : _t.title, textBoxWidth, ARC_TITLE_FONT_SIZE, [8, 40]);
7487
+ const configuredTextWidth = Number((_r = (_q = spec.block) === null || _q === void 0 ? void 0 : _q.width) !== null && _r !== void 0 ? _r : ARC_TEXT_BOX_MAX_WIDTH);
7488
+ const defaultTextWidth = Math.round(slotWidth * 0.96);
7489
+ const minTextWidth = Math.min(ARC_TEXT_BOX_MIN_WIDTH, Math.max(Math.round(slotWidth * 0.72), ARC_TEXT_BOX_ABSOLUTE_MIN_WIDTH));
7490
+ const textBoxWidth = Math.round(clamp(Math.min(configuredTextWidth, defaultTextWidth), minTextWidth, ARC_TEXT_BOX_MAX_WIDTH));
7491
+ const titleFontSize = resolveTitleFontSize(spec, ctx, (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s[index]) === null || _t === void 0 ? void 0 : _t.title, textBoxWidth, Math.round(ARC_TITLE_FONT_SIZE * textScale), [10, 40]);
7398
7492
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_u = spec.title) === null || _u === void 0 ? void 0 : _u.style, ARC_TITLE_LINE_HEIGHT);
7399
- const textHeight = ARC_TEXT_BOX_HEIGHT;
7400
- const contentHeight = Math.max(textHeight - titleLineHeight - titleToContentGap, contentLineHeight);
7493
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_w = (_v = spec.data) === null || _v === void 0 ? void 0 : _v[index]) === null || _w === void 0 ? void 0 : _w.title, textBoxWidth, titleFontSize);
7494
+ const textHeight = Math.round(clamp(ARC_TEXT_BOX_HEIGHT * textScale, 88, ARC_TEXT_BOX_HEIGHT));
7495
+ const contentHeight = Math.max(textHeight - titleHeight - titleToContentGap, contentLineHeight);
7401
7496
  const isLeftSide = index < count / 2;
7402
7497
  const textAlign = isLeftSide ? 'right' : 'left';
7403
7498
  const imageBox = {
@@ -7406,7 +7501,9 @@
7406
7501
  width: imageWidth,
7407
7502
  height: imageHeight
7408
7503
  };
7409
- const textBoxX = isLeftSide ? -ARC_TEXT_PADDING : ARC_TEXT_PADDING;
7504
+ const textPadding = Math.round(ARC_TEXT_PADDING * textScale);
7505
+ const textBoxX = isLeftSide ? -textPadding - textBoxWidth : textPadding;
7506
+ const textAnchorX = isLeftSide ? -textPadding : textPadding;
7410
7507
  const textBox = {
7411
7508
  x: textBoxX,
7412
7509
  y: isDown ? imageBox.y + imageHeight + ARC_TEXT_GAP_FROM_IMAGE : imageBox.y - ARC_TEXT_GAP_FROM_IMAGE - textHeight,
@@ -7415,7 +7512,7 @@
7415
7512
  };
7416
7513
  const contentBox = {
7417
7514
  x: textBox.x,
7418
- y: textBox.y + titleLineHeight + titleToContentGap,
7515
+ y: textBox.y + titleHeight + titleToContentGap,
7419
7516
  width: textBox.width,
7420
7517
  height: contentHeight
7421
7518
  };
@@ -7428,7 +7525,8 @@
7428
7525
  textBox,
7429
7526
  contentBox,
7430
7527
  isDown,
7431
- textAlign
7528
+ textAlign,
7529
+ textAnchorX
7432
7530
  };
7433
7531
  };
7434
7532
  const buildArcBlockMark = (spec, block, index) => {
@@ -7436,12 +7534,18 @@
7436
7534
  const hasImage = !!block.image;
7437
7535
  const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7438
7536
  const themeColor = getThemeColor(spec);
7439
- const metrics = getArcBlockMetrics(spec, index);
7440
- const connectorY = metrics.isDown ? metrics.imageBox.y + metrics.imageBox.height : metrics.textBox.y;
7441
- const connectorHeight = metrics.isDown
7442
- ? Math.max(metrics.textBox.y + metrics.textBox.height - (metrics.imageBox.y + metrics.imageBox.height), 0)
7443
- : Math.max(metrics.imageBox.y - metrics.textBox.y, 0);
7444
- const connectorX = -1;
7537
+ const getMetrics = (ctx) => getArcBlockMetrics(spec, index, ctx);
7538
+ const getConnectorBox = (ctx) => {
7539
+ const metrics = getMetrics(ctx);
7540
+ return {
7541
+ x: -1,
7542
+ y: metrics.isDown ? metrics.imageBox.y + metrics.imageBox.height : metrics.textBox.y,
7543
+ width: 2,
7544
+ height: metrics.isDown
7545
+ ? Math.max(metrics.textBox.y + metrics.textBox.height - (metrics.imageBox.y + metrics.imageBox.height), 0)
7546
+ : Math.max(metrics.imageBox.y - metrics.textBox.y, 0)
7547
+ };
7548
+ };
7445
7549
  return {
7446
7550
  type: 'group',
7447
7551
  id: `storyline-block-${(_a = block.id) !== null && _a !== void 0 ? _a : index}`,
@@ -7458,22 +7562,22 @@
7458
7562
  interactive: false,
7459
7563
  zIndex: vchart.LayoutZIndex.Mark + 2,
7460
7564
  style: {
7461
- x: connectorX,
7462
- y: connectorY,
7463
- width: 2,
7464
- height: connectorHeight,
7565
+ x: (_d, ctx) => getConnectorBox(ctx).x,
7566
+ y: (_d, ctx) => getConnectorBox(ctx).y,
7567
+ width: (_d, ctx) => getConnectorBox(ctx).width,
7568
+ height: (_d, ctx) => getConnectorBox(ctx).height,
7465
7569
  fill: themeColor,
7466
7570
  fillOpacity: 0.6
7467
7571
  }
7468
7572
  },
7469
7573
  hasImage
7470
- ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 3 }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: metrics.imageBox.x, y: metrics.imageBox.y, width: metrics.imageBox.width, height: metrics.imageBox.height, cornerRadius: Math.min(metrics.imageBox.width, metrics.imageBox.height) / 2, image: block.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'contain', imagePosition: 'center' }, (_b = spec.image) === null || _b === void 0 ? void 0 : _b.style) })
7574
+ ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 3 }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).imageBox.x, y: (_d, ctx) => getMetrics(ctx).imageBox.y, width: (_d, ctx) => getMetrics(ctx).imageBox.width, height: (_d, ctx) => getMetrics(ctx).imageBox.height, cornerRadius: (_d, ctx) => Math.min(getMetrics(ctx).imageBox.width, getMetrics(ctx).imageBox.height) / 2, image: block.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'contain', imagePosition: 'center' }, (_b = spec.image) === null || _b === void 0 ? void 0 : _b.style) })
7471
7575
  : {
7472
7576
  type: 'symbol',
7473
7577
  name: `storyline-block-image-bg-${index}`,
7474
7578
  interactive: false,
7475
7579
  zIndex: vchart.LayoutZIndex.Mark + 3,
7476
- style: Object.assign({ x: 0, y: 0, size: Math.min(metrics.imageBox.width, metrics.imageBox.height), symbolType: 'circle' }, getImageBackgroundStyle(spec))
7580
+ style: Object.assign({ x: 0, y: 0, size: (_d, ctx) => Math.min(getMetrics(ctx).imageBox.width, getMetrics(ctx).imageBox.height), symbolType: 'circle' }, getImageBackgroundStyle(spec))
7477
7581
  },
7478
7582
  shouldShowImageBackground(spec)
7479
7583
  ? {
@@ -7484,7 +7588,8 @@
7484
7588
  style: {
7485
7589
  x: 0,
7486
7590
  y: 0,
7487
- size: Math.min(metrics.imageBox.width, metrics.imageBox.height) + ARC_BLOCK_IMAGE_HALO_PADDING * 2,
7591
+ size: (_d, ctx) => Math.min(getMetrics(ctx).imageBox.width, getMetrics(ctx).imageBox.height) +
7592
+ ARC_BLOCK_IMAGE_HALO_PADDING * 2,
7488
7593
  symbolType: 'circle',
7489
7594
  fill: 'transparent',
7490
7595
  stroke: withAlpha(themeColor, 0.82),
@@ -7493,15 +7598,10 @@
7493
7598
  }
7494
7599
  : null,
7495
7600
  block.title
7496
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 5 }, spec.title), { style: Object.assign({ x: metrics.textBox.x, y: metrics.textBox.y, text: block.title, maxLineWidth: metrics.textBox.width, fontSize: metrics.titleFontSize, lineHeight: metrics.titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: metrics.textAlign, textBaseline: 'top' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7601
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 5 }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textAnchorX, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, height: (_d, ctx) => getMetrics(ctx).titleLineHeight * BLOCK_TITLE_MAX_LINES, heightLimit: (_d, ctx) => getMetrics(ctx).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getMetrics(ctx).titleFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => getMetrics(ctx).textAlign, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7497
7602
  : null,
7498
7603
  contentText.length
7499
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 4 }, spec.content), { textType: 'rich', style: Object.assign({ x: metrics.contentBox.x, y: metrics.contentBox.y, width: metrics.contentBox.width, height: metrics.contentBox.height, maxLineWidth: metrics.contentBox.width, heightLimit: metrics.contentBox.height, text: buildRichContent(contentText, spec, {
7500
- fontSize: metrics.contentFontSize,
7501
- lineHeight: metrics.contentLineHeight,
7502
- fill: '#596173',
7503
- align: metrics.textAlign
7504
- }), textAlign: metrics.textAlign, textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7604
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 4 }, spec.content), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textAnchorX, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildPlainContent(contentText), fontSize: (_d, ctx) => getMetrics(ctx).contentFontSize, lineHeight: (_d, ctx) => getMetrics(ctx).contentLineHeight, textAlign: (_d, ctx) => getMetrics(ctx).textAlign, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7505
7605
  : null
7506
7606
  ].filter(Boolean)
7507
7607
  };
@@ -7654,16 +7754,17 @@
7654
7754
  };
7655
7755
  const WING_TEXT_IMAGE_GAP = 120;
7656
7756
  const getWingBlockMetrics = (spec, ctx, index) => {
7657
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
7757
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
7658
7758
  const titleFontSize = resolveTitleFontSize(spec, ctx, (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a[index]) === null || _b === void 0 ? void 0 : _b.title, WING_TEXT_BOX_WIDTH, WING_TITLE_FONT_SIZE, [8, 30]);
7659
7759
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style, WING_TITLE_LINE_HEIGHT, 1.3);
7660
- const contentFontSize = Number((_g = (_f = (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.fontSize) !== null && _g !== void 0 ? _g : WING_CONTENT_FONT_SIZE);
7661
- const contentLineHeight = Number((_k = (_j = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style) === null || _j === void 0 ? void 0 : _j.lineHeight) !== null && _k !== void 0 ? _k : WING_CONTENT_LINE_HEIGHT);
7760
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_f = (_e = spec.data) === null || _e === void 0 ? void 0 : _e[index]) === null || _f === void 0 ? void 0 : _f.title, WING_TEXT_BOX_WIDTH, titleFontSize);
7761
+ const contentFontSize = Number((_j = (_h = (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.fontSize) !== null && _j !== void 0 ? _j : WING_CONTENT_FONT_SIZE);
7762
+ const contentLineHeight = Number((_m = (_l = (_k = spec.content) === null || _k === void 0 ? void 0 : _k.style) === null || _l === void 0 ? void 0 : _l.lineHeight) !== null && _m !== void 0 ? _m : WING_CONTENT_LINE_HEIGHT);
7662
7763
  const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;
7663
7764
  const textHeight = WING_TEXT_BOX_HEIGHT;
7664
7765
  const contentHeight = 100000;
7665
- const imageWidth = Number((_m = (_l = spec.image) === null || _l === void 0 ? void 0 : _l.width) !== null && _m !== void 0 ? _m : WING_BLOCK_IMAGE_SIZE);
7666
- const imageHeight = Number((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.height) !== null && _p !== void 0 ? _p : WING_BLOCK_IMAGE_SIZE);
7766
+ const imageWidth = Number((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.width) !== null && _p !== void 0 ? _p : WING_BLOCK_IMAGE_SIZE);
7767
+ const imageHeight = Number((_r = (_q = spec.image) === null || _q === void 0 ? void 0 : _q.height) !== null && _r !== void 0 ? _r : WING_BLOCK_IMAGE_SIZE);
7667
7768
  const imageBox = {
7668
7769
  x: -imageWidth / 2,
7669
7770
  y: -imageHeight / 2,
@@ -7671,7 +7772,7 @@
7671
7772
  height: imageHeight
7672
7773
  };
7673
7774
  const direction = getWingDirection(spec);
7674
- const count = (_r = (_q = spec.data) === null || _q === void 0 ? void 0 : _q.length) !== null && _r !== void 0 ? _r : 0;
7775
+ const count = (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s.length) !== null && _t !== void 0 ? _t : 0;
7675
7776
  const isSpecialBelow = (direction === 'right' && count > 0 && index === count - 1) || (direction === 'left' && index === 0);
7676
7777
  const isVerticalLayout = isSpecialBelow;
7677
7778
  const textWidth = WING_TEXT_BOX_WIDTH;
@@ -7686,7 +7787,7 @@
7686
7787
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
7687
7788
  contentBox = {
7688
7789
  x: textX,
7689
- y: textY + titleLineHeight + titleToContentGap,
7790
+ y: textY + titleHeight + titleToContentGap,
7690
7791
  width: textWidth,
7691
7792
  height: contentHeight
7692
7793
  };
@@ -7706,7 +7807,7 @@
7706
7807
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
7707
7808
  contentBox = {
7708
7809
  x: textX,
7709
- y: textY + titleLineHeight + titleToContentGap,
7810
+ y: textY + titleHeight + titleToContentGap,
7710
7811
  width: textWidth,
7711
7812
  height: contentHeight
7712
7813
  };
@@ -7726,6 +7827,7 @@
7726
7827
  verticalAlign,
7727
7828
  titleFontSize,
7728
7829
  titleLineHeight,
7830
+ titleHeight,
7729
7831
  contentFontSize,
7730
7832
  contentLineHeight,
7731
7833
  imageBox,
@@ -7787,28 +7889,28 @@
7787
7889
  return m.textBox.x + m.textBox.width / 2;
7788
7890
  }
7789
7891
  return m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;
7790
- }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.width, fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => {
7892
+ }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.width, height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleHeight, heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => {
7791
7893
  const m = getWingBlockMetrics(spec, ctx, index);
7792
7894
  if (m.verticalAlign) {
7793
7895
  return 'center';
7794
7896
  }
7795
7897
  return m.onLeft ? 'right' : 'left';
7796
- }, textBaseline: 'top' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7898
+ }, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7797
7899
  : null,
7798
7900
  contentText.length
7799
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 10 }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => {
7901
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 10 }, spec.content), { style: Object.assign({ x: (_d, ctx) => {
7800
7902
  const m = getWingBlockMetrics(spec, ctx, index);
7801
7903
  if (m.verticalAlign) {
7802
7904
  return m.contentBox.x + m.contentBox.width / 2;
7803
7905
  }
7804
7906
  return m.onLeft ? m.contentBox.x + m.contentBox.width : m.contentBox.x;
7805
- }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.y, width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width, height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height, maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width, heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height, text: buildRichContent(contentText, spec), fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentLineHeight, textAlign: (_d, ctx) => {
7907
+ }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.y, width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width, height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height, maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width, heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height, text: buildPlainContent(contentText), fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentLineHeight, textAlign: (_d, ctx) => {
7806
7908
  const m = getWingBlockMetrics(spec, ctx, index);
7807
7909
  if (m.verticalAlign) {
7808
7910
  return 'center';
7809
7911
  }
7810
7912
  return m.onLeft ? 'right' : 'left';
7811
- }, textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#1f2430' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7913
+ }, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#1f2430' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7812
7914
  : null
7813
7915
  ].filter(Boolean)
7814
7916
  };
@@ -7822,8 +7924,8 @@
7822
7924
  const LADDER_BLOCK_IMAGE_SIZE = 100;
7823
7925
  const LADDER_TITLE_FONT_SIZE = 28;
7824
7926
  const LADDER_TITLE_LINE_HEIGHT = 26;
7825
- const LADDER_CONTENT_FONT_SIZE = 18;
7826
- const LADDER_CONTENT_LINE_HEIGHT = 26;
7927
+ const LADDER_CONTENT_FONT_SIZE = 16;
7928
+ const LADDER_CONTENT_LINE_HEIGHT = 23;
7827
7929
  const isDownLadder = (spec) => normalizeLayout(spec.layout).direction === 'down';
7828
7930
  const getLadderDiagonalGeometry = (spec, ctx) => {
7829
7931
  var _a;
@@ -7934,12 +8036,13 @@
7934
8036
  const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
7935
8037
  const titleFontSize = resolveTitleFontSize(spec, ctx, (_s = (_r = spec.data) === null || _r === void 0 ? void 0 : _r[index]) === null || _s === void 0 ? void 0 : _s.title, textBox.width, LADDER_TITLE_FONT_SIZE, [8, 34]);
7936
8038
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_t = spec.title) === null || _t === void 0 ? void 0 : _t.style, LADDER_TITLE_LINE_HEIGHT, LADDER_TITLE_LINE_HEIGHT / LADDER_TITLE_FONT_SIZE);
7937
- const titleHeight = ((_v = (_u = spec.data) === null || _u === void 0 ? void 0 : _u[index]) === null || _v === void 0 ? void 0 : _v.title) ? titleLineHeight : 0;
8039
+ const titleHeight = getBlockTitleHeight(titleLineHeight, (_v = (_u = spec.data) === null || _u === void 0 ? void 0 : _u[index]) === null || _v === void 0 ? void 0 : _v.title, textBox.width, titleFontSize);
7938
8040
  const contentGap = ((_x = (_w = spec.data) === null || _w === void 0 ? void 0 : _w[index]) === null || _x === void 0 ? void 0 : _x.title) ? 8 : 0;
7939
8041
  return {
7940
8042
  block: { width: blockWidth, height: blockHeight },
7941
8043
  titleFontSize,
7942
8044
  titleLineHeight,
8045
+ titleHeight,
7943
8046
  imageBox,
7944
8047
  textBox,
7945
8048
  contentBox: {
@@ -7992,14 +8095,10 @@
7992
8095
  ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).imageBox.x, y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).imageBox.y, width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).imageBox.width, height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).imageBox.height, image: block.image }, (_f = spec.image) === null || _f === void 0 ? void 0 : _f.style) })
7993
8096
  : null,
7994
8097
  block.title
7995
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, fontSize: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textBaseline: 'top' }, (_g = spec.title) === null || _g === void 0 ? void 0 : _g.style), { textAlign: align }) })
8098
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleHeight, heightLimit: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_g = spec.title) === null || _g === void 0 ? void 0 : _g.style), { textAlign: align }) })
7996
8099
  : null,
7997
8100
  contentText.length
7998
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.y, width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, text: buildRichContent(contentText, spec, {
7999
- fontSize: LADDER_CONTENT_FONT_SIZE,
8000
- lineHeight: LADDER_CONTENT_LINE_HEIGHT,
8001
- align: align
8002
- }), maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, heightLimit: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.height, textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style), { textAlign: align }) })
8101
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.y, width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.height, text: buildPlainContent(contentText), maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, heightLimit: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.height, fontSize: LADDER_CONTENT_FONT_SIZE, lineHeight: LADDER_CONTENT_LINE_HEIGHT, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style), { textAlign: align }) })
8003
8102
  : null
8004
8103
  ].filter(Boolean)
8005
8104
  };
@@ -8096,7 +8195,7 @@
8096
8195
  : wing
8097
8196
  ? 300
8098
8197
  : arcUp
8099
- ? 0
8198
+ ? 100
8100
8199
  : arcDown
8101
8200
  ? TEXT_RESERVE
8102
8201
  : LARGE;