@visactor/vchart-extension 2.1.0-alpha.23 → 2.1.0-alpha.25

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 (185) hide show
  1. package/build/index.js +229 -379
  2. package/build/index.min.js +2 -2
  3. package/cjs/charts/3d/plugin.js +1 -1
  4. package/cjs/charts/3d/pyramid-3d.js +1 -1
  5. package/cjs/charts/3d/rect-3d.js +1 -1
  6. package/cjs/charts/3d/util.js +1 -1
  7. package/cjs/charts/axis-3d/axis-3d-mixin.js +1 -1
  8. package/cjs/charts/axis-3d/band-axis.js +1 -1
  9. package/cjs/charts/axis-3d/index.js +1 -1
  10. package/cjs/charts/axis-3d/linear-axis.js +2 -1
  11. package/cjs/charts/axis-3d/log-axis.js +1 -1
  12. package/cjs/charts/axis-3d/symlog-axis.js +1 -1
  13. package/cjs/charts/axis-3d/theme.js +1 -1
  14. package/cjs/charts/axis-3d/time-axis.js +1 -1
  15. package/cjs/charts/axis-3d/util.js +1 -1
  16. package/cjs/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  17. package/cjs/charts/combination-candlestick/combination-candlestick.js +1 -1
  18. package/cjs/charts/combination-candlestick/constant.js +1 -1
  19. package/cjs/charts/combination-candlestick/index.js +1 -1
  20. package/cjs/charts/combination-candlestick/interface.js +1 -1
  21. package/cjs/charts/conversion-funnel/arrow-data-transform.js +1 -1
  22. package/cjs/charts/conversion-funnel/constants.js +1 -1
  23. package/cjs/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  24. package/cjs/charts/conversion-funnel/conversion-funnel.js +1 -1
  25. package/cjs/charts/conversion-funnel/index.js +1 -1
  26. package/cjs/charts/conversion-funnel/interface.js +1 -1
  27. package/cjs/charts/conversion-funnel/util.js +1 -1
  28. package/cjs/charts/funnel-3d/chart.js +2 -1
  29. package/cjs/charts/funnel-3d/constant.js +1 -1
  30. package/cjs/charts/funnel-3d/index.js +1 -1
  31. package/cjs/charts/funnel-3d/interface.js +1 -1
  32. package/cjs/charts/funnel-3d/series-spec-transformer.js +1 -1
  33. package/cjs/charts/funnel-3d/series.js +1 -1
  34. package/cjs/charts/funnel-3d/theme.js +1 -1
  35. package/cjs/charts/histogram-3d/chart.js +1 -1
  36. package/cjs/charts/storyline/interface.d.ts +2 -4
  37. package/cjs/charts/storyline/interface.js.map +1 -1
  38. package/cjs/charts/storyline/layout.d.ts +0 -1
  39. package/cjs/charts/storyline/layout.js +4 -27
  40. package/cjs/charts/storyline/layout.js.map +1 -1
  41. package/cjs/charts/storyline/layouts/arc.js +56 -48
  42. package/cjs/charts/storyline/layouts/arc.js.map +1 -1
  43. package/cjs/charts/storyline/layouts/clock.js +3 -4
  44. package/cjs/charts/storyline/layouts/clock.js.map +1 -1
  45. package/cjs/charts/storyline/layouts/common.d.ts +2 -3
  46. package/cjs/charts/storyline/layouts/common.js +17 -12
  47. package/cjs/charts/storyline/layouts/common.js.map +1 -1
  48. package/cjs/charts/storyline/layouts/default.js +3 -3
  49. package/cjs/charts/storyline/layouts/default.js.map +1 -1
  50. package/cjs/charts/storyline/layouts/landscape.js +35 -24
  51. package/cjs/charts/storyline/layouts/landscape.js.map +1 -1
  52. package/cjs/charts/storyline/layouts/portrait.js +3 -3
  53. package/cjs/charts/storyline/layouts/portrait.js.map +1 -1
  54. package/cjs/charts/storyline/layouts/wing.js +53 -11
  55. package/cjs/charts/storyline/layouts/wing.js.map +1 -1
  56. package/cjs/charts/storyline/storyline-transformer.js +6 -22
  57. package/cjs/charts/storyline/storyline-transformer.js.map +1 -1
  58. package/cjs/components/bar-link/bar-link.js +1 -1
  59. package/cjs/components/bar-link/constant.js +1 -1
  60. package/cjs/components/bar-link/index.js +1 -1
  61. package/cjs/components/bar-link/type.js +1 -1
  62. package/cjs/components/bar-link/util.js +1 -1
  63. package/cjs/components/bar-regression-line/index.js +1 -1
  64. package/cjs/components/bar-regression-line/type.js +1 -2
  65. package/cjs/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  66. package/cjs/components/extension-mark-sync-state/index.js +1 -1
  67. package/cjs/components/extension-mark-sync-state/type.js +1 -1
  68. package/cjs/components/histogram-regression-line/index.js +1 -1
  69. package/cjs/components/histogram-regression-line/type.js +1 -1
  70. package/cjs/components/map-label/index.js +1 -1
  71. package/cjs/components/map-label/layout.js +1 -1
  72. package/cjs/components/map-label/map-label-transformer.js +1 -1
  73. package/cjs/components/map-label/map-label.js +1 -1
  74. package/cjs/components/map-label/theme.js +1 -1
  75. package/cjs/components/map-label/type.js +1 -1
  76. package/cjs/components/regression-line/index.js +1 -1
  77. package/cjs/components/regression-line/regression-line.js +1 -1
  78. package/cjs/components/regression-line/type.js +1 -1
  79. package/cjs/components/scatter-regression-line/index.js +1 -1
  80. package/cjs/components/scatter-regression-line/type.js +1 -1
  81. package/cjs/components/series-break/constant.js +1 -1
  82. package/cjs/components/series-break/index.js +1 -1
  83. package/cjs/components/series-break/series-break.js +1 -1
  84. package/cjs/components/series-break/type.js +1 -1
  85. package/cjs/components/series-break/util.js +1 -1
  86. package/cjs/components/series-label/constant.js +1 -1
  87. package/cjs/components/series-label/index.js +1 -2
  88. package/cjs/components/series-label/series-label.js +1 -1
  89. package/cjs/components/series-label/type.js +1 -1
  90. package/cjs/components/series-label/util.js +1 -1
  91. package/esm/charts/3d/plugin.js +1 -1
  92. package/esm/charts/3d/pyramid-3d.js +1 -1
  93. package/esm/charts/3d/rect-3d.js +1 -1
  94. package/esm/charts/3d/util.js +1 -1
  95. package/esm/charts/axis-3d/axis-3d-mixin.js +1 -1
  96. package/esm/charts/axis-3d/band-axis.js +1 -1
  97. package/esm/charts/axis-3d/index.js +1 -1
  98. package/esm/charts/axis-3d/linear-axis.js +2 -1
  99. package/esm/charts/axis-3d/log-axis.js +1 -1
  100. package/esm/charts/axis-3d/symlog-axis.js +1 -1
  101. package/esm/charts/axis-3d/theme.js +1 -1
  102. package/esm/charts/axis-3d/time-axis.js +1 -1
  103. package/esm/charts/axis-3d/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 -1
  115. package/esm/charts/conversion-funnel/util.js +1 -1
  116. package/esm/charts/funnel-3d/chart.js +2 -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 -1
  122. package/esm/charts/funnel-3d/theme.js +1 -1
  123. package/esm/charts/histogram-3d/chart.js +1 -1
  124. package/esm/charts/storyline/interface.d.ts +2 -4
  125. package/esm/charts/storyline/interface.js.map +1 -1
  126. package/esm/charts/storyline/layout.d.ts +0 -1
  127. package/esm/charts/storyline/layout.js +4 -27
  128. package/esm/charts/storyline/layout.js.map +1 -1
  129. package/esm/charts/storyline/layouts/arc.js +54 -46
  130. package/esm/charts/storyline/layouts/arc.js.map +1 -1
  131. package/esm/charts/storyline/layouts/clock.js +4 -5
  132. package/esm/charts/storyline/layouts/clock.js.map +1 -1
  133. package/esm/charts/storyline/layouts/common.d.ts +2 -3
  134. package/esm/charts/storyline/layouts/common.js +11 -9
  135. package/esm/charts/storyline/layouts/common.js.map +1 -1
  136. package/esm/charts/storyline/layouts/default.js +3 -3
  137. package/esm/charts/storyline/layouts/default.js.map +1 -1
  138. package/esm/charts/storyline/layouts/landscape.js +33 -22
  139. package/esm/charts/storyline/layouts/landscape.js.map +1 -1
  140. package/esm/charts/storyline/layouts/portrait.js +3 -3
  141. package/esm/charts/storyline/layouts/portrait.js.map +1 -1
  142. package/esm/charts/storyline/layouts/wing.js +52 -10
  143. package/esm/charts/storyline/layouts/wing.js.map +1 -1
  144. package/esm/charts/storyline/storyline-transformer.js +6 -21
  145. package/esm/charts/storyline/storyline-transformer.js.map +1 -1
  146. package/esm/components/bar-link/bar-link.js +1 -1
  147. package/esm/components/bar-link/constant.js +1 -1
  148. package/esm/components/bar-link/index.js +1 -1
  149. package/esm/components/bar-link/type.js +1 -1
  150. package/esm/components/bar-link/util.js +1 -1
  151. package/esm/components/bar-regression-line/index.js +1 -1
  152. package/esm/components/bar-regression-line/type.js +1 -2
  153. package/esm/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  154. package/esm/components/extension-mark-sync-state/index.js +1 -1
  155. package/esm/components/extension-mark-sync-state/type.js +1 -1
  156. package/esm/components/histogram-regression-line/index.js +1 -1
  157. package/esm/components/histogram-regression-line/type.js +1 -1
  158. package/esm/components/map-label/index.js +1 -1
  159. package/esm/components/map-label/layout.js +1 -1
  160. package/esm/components/map-label/map-label-transformer.js +1 -1
  161. package/esm/components/map-label/map-label.js +1 -1
  162. package/esm/components/map-label/theme.js +1 -1
  163. package/esm/components/map-label/type.js +1 -1
  164. package/esm/components/regression-line/index.js +1 -1
  165. package/esm/components/regression-line/regression-line.js +1 -1
  166. package/esm/components/regression-line/type.js +1 -1
  167. package/esm/components/scatter-regression-line/index.js +1 -1
  168. package/esm/components/scatter-regression-line/type.js +1 -1
  169. package/esm/components/series-break/constant.js +1 -1
  170. package/esm/components/series-break/index.js +1 -1
  171. package/esm/components/series-break/series-break.js +1 -1
  172. package/esm/components/series-break/type.js +1 -1
  173. package/esm/components/series-break/util.js +1 -1
  174. package/esm/components/series-label/constant.js +1 -1
  175. package/esm/components/series-label/index.js +1 -2
  176. package/esm/components/series-label/series-label.js +1 -1
  177. package/esm/components/series-label/type.js +1 -1
  178. package/esm/components/series-label/util.js +1 -1
  179. package/package.json +4 -4
  180. package/cjs/charts/storyline/layouts/ladder.d.ts +0 -5
  181. package/cjs/charts/storyline/layouts/ladder.js +0 -229
  182. package/cjs/charts/storyline/layouts/ladder.js.map +0 -1
  183. package/esm/charts/storyline/layouts/ladder.d.ts +0 -5
  184. package/esm/charts/storyline/layouts/ladder.js +0 -216
  185. package/esm/charts/storyline/layouts/ladder.js.map +0 -1
package/build/index.js CHANGED
@@ -5855,12 +5855,11 @@
5855
5855
  return layout;
5856
5856
  };
5857
5857
  const computeStorylineLayout = (data, options) => {
5858
- var _a, _b, _c;
5858
+ var _a, _b;
5859
5859
  const layout = normalizeLayout(options.layout);
5860
5860
  const padding = normalizePadding((_a = layout.padding) !== null && _a !== void 0 ? _a : options.padding);
5861
- const gap = (_b = options.gap) !== null && _b !== void 0 ? _b : 40;
5862
- const lineDistance = (_c = options.lineDistance) !== null && _c !== void 0 ? _c : 8;
5863
- const blocks = computeBlockPositions(data, layout, options.viewBox, options.block, padding, gap);
5861
+ const lineDistance = (_b = options.lineDistance) !== null && _b !== void 0 ? _b : 8;
5862
+ const blocks = computeBlockPositions(data, layout, options.viewBox, options.block, padding);
5864
5863
  const circleGuide = layout.type === 'clock' ? computeClockCircleGuide(options.viewBox, options.block, padding, layout) : undefined;
5865
5864
  return {
5866
5865
  blocks,
@@ -5868,7 +5867,7 @@
5868
5867
  circleGuide
5869
5868
  };
5870
5869
  };
5871
- const computeBlockPositions = (data, layout, viewBox, block, padding, gap) => {
5870
+ const computeBlockPositions = (data, layout, viewBox, block, padding) => {
5872
5871
  const count = data.length;
5873
5872
  if (!count) {
5874
5873
  return [];
@@ -5888,34 +5887,6 @@
5888
5887
  case 'portrait':
5889
5888
  centers = lineCenters(count, center.x, inner.y + block.height / 2, center.x, inner.y + inner.height - block.height / 2);
5890
5889
  break;
5891
- case 'ladder': {
5892
- const isDown = layout.direction === 'down';
5893
- const x0 = inner.x + block.width / 2;
5894
- const x1 = inner.x + inner.width - block.width / 2;
5895
- const yTop = inner.y + block.height / 2;
5896
- const yBot = inner.y + inner.height - block.height / 2;
5897
- const y0 = isDown ? yTop : yBot;
5898
- const y1 = isDown ? yBot : yTop;
5899
- const anchors = lineCenters(count, x0, y0, x1, y1);
5900
- const dx = x1 - x0;
5901
- const dy = y1 - y0;
5902
- const len = Math.hypot(dx, dy) || 1;
5903
- const nx = -dy / len;
5904
- const ny = dx / len;
5905
- const headlineFontSize = Math.max(80, Math.min(240, Math.round(inner.height * 0.42)));
5906
- const offset = headlineFontSize * 1.2;
5907
- centers = anchors.map((p, i) => {
5908
- const sign = i % 2 === 0 ? 1 : -1;
5909
- return {
5910
- x: p.x + nx * offset * sign,
5911
- y: p.y + ny * offset * sign
5912
- };
5913
- });
5914
- break;
5915
- }
5916
- case 'spiral':
5917
- centers = alternatingVerticalCenters(count, inner, block, gap);
5918
- break;
5919
5890
  case 'clock':
5920
5891
  centers = circularCenters(count, viewBox, block, padding, layout);
5921
5892
  break;
@@ -5962,15 +5933,6 @@
5962
5933
  };
5963
5934
  });
5964
5935
  };
5965
- const alternatingVerticalCenters = (count, inner, block, gap) => {
5966
- const baseX = inner.x + inner.width / 2;
5967
- const offset = Math.min(Math.max(block.width * 0.65 + gap / 2, 0), Math.max((inner.width - block.width) / 2, 0));
5968
- const points = lineCenters(count, baseX, inner.y + block.height / 2, baseX, inner.y + inner.height - block.height / 2);
5969
- return points.map((point, index) => ({
5970
- x: point.x + (index % 2 === 0 ? -offset : offset),
5971
- y: point.y
5972
- }));
5973
- };
5974
5936
  const circularCenters = (count, viewBox, block, padding, layout) => {
5975
5937
  var _a;
5976
5938
  const guide = computeClockCircleGuide(viewBox, block, padding, layout);
@@ -6073,7 +6035,6 @@
6073
6035
  const DEFAULT_BLOCK_WIDTH = 180;
6074
6036
  const DEFAULT_BLOCK_HEIGHT = 400;
6075
6037
  const DEFAULT_BLOCK_WIDTH_RATIO = 0.24;
6076
- const DEFAULT_BLOCK_GAP = 36;
6077
6038
  const DEFAULT_IMAGE_WIDTH = 48;
6078
6039
  const DEFAULT_IMAGE_HEIGHT = 48;
6079
6040
  const DEFAULT_IMAGE_GAP = 10;
@@ -6089,12 +6050,11 @@
6089
6050
  const isClock = (spec) => normalizeLayout(spec.layout).type === 'clock';
6090
6051
  const isArc = (spec) => normalizeLayout(spec.layout).type === 'arc';
6091
6052
  const isWing = (spec) => normalizeLayout(spec.layout).type === 'wing';
6092
- const isLadder = (spec) => normalizeLayout(spec.layout).type === 'ladder';
6093
6053
  const getThemeColor = (spec) => { var _a; return (_a = spec.themeColor) !== null && _a !== void 0 ? _a : DEFAULT_THEME_COLOR; };
6094
6054
  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)); };
6095
6055
  const TITLE_FONT_SCALE_ID = 'storylineTitleFontSize';
6096
6056
  const MARKER_FONT_SCALE_ID = 'storylineMarkerFontSize';
6097
- const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
6057
+ const clamp$2 = (value, min, max) => Math.max(min, Math.min(max, value));
6098
6058
  const getTextWeight = (text) => {
6099
6059
  if (!text) {
6100
6060
  return 4;
@@ -6143,7 +6103,7 @@
6143
6103
  ? ((options.boxWidth * BLOCK_TITLE_MAX_LINES) / textWeight) * 0.96
6144
6104
  : Number.POSITIVE_INFINITY;
6145
6105
  const boxHeightLimit = options.boxHeight && options.boxHeight > 0 ? options.boxHeight / Math.max(textWeight, 1) : Number.POSITIVE_INFINITY;
6146
- return Math.floor(clamp(Math.min(adaptiveSize, boxWidthLimit, boxHeightLimit), minFontSize, maxFontSize));
6106
+ return Math.floor(clamp$2(Math.min(adaptiveSize, boxWidthLimit, boxHeightLimit), minFontSize, maxFontSize));
6147
6107
  };
6148
6108
  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)); };
6149
6109
  const resolveTitleFontSize = (spec, ctx, title, boxWidth, fallback, range = [16, 34]) => {
@@ -6285,7 +6245,7 @@
6285
6245
  };
6286
6246
  };
6287
6247
  const getLayout = (spec, ctx) => {
6288
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
6248
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
6289
6249
  const { width, height, startX, startY } = getRegionGeometry(ctx, spec);
6290
6250
  let blockWidth = resolveBlockWidth(spec, width);
6291
6251
  let blockHeight = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : (isLandscape(spec) ? 320 : DEFAULT_BLOCK_HEIGHT);
@@ -6317,9 +6277,8 @@
6317
6277
  width: blockWidth,
6318
6278
  height: blockHeight
6319
6279
  },
6320
- gap: (_p = (_o = spec.block) === null || _o === void 0 ? void 0 : _o.gap) !== null && _p !== void 0 ? _p : DEFAULT_BLOCK_GAP,
6321
- padding: (_q = spec.block) === null || _q === void 0 ? void 0 : _q.padding,
6322
- lineDistance: (_r = spec.line) === null || _r === void 0 ? void 0 : _r.distance
6280
+ padding: (_o = spec.block) === null || _o === void 0 ? void 0 : _o.padding,
6281
+ lineDistance: (_p = spec.line) === null || _p === void 0 ? void 0 : _p.distance
6323
6282
  });
6324
6283
  if (!startX && !startY) {
6325
6284
  return result;
@@ -6330,7 +6289,17 @@
6330
6289
  } }))), 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 })) }))) });
6331
6290
  };
6332
6291
  const buildPlainContent = (contentText) => contentText.join('\n');
6333
- const getBlockTitleHeight = (lineHeight, title) => title ? lineHeight * BLOCK_TITLE_MAX_LINES : 0;
6292
+ const getBlockTitleLineCount = (title, boxWidth, fontSize) => {
6293
+ if (!title) {
6294
+ return 0;
6295
+ }
6296
+ if (!boxWidth || boxWidth <= 0 || !fontSize || fontSize <= 0) {
6297
+ return 1;
6298
+ }
6299
+ const estimatedWidth = getTextWeight(title) * fontSize;
6300
+ return Math.max(1, Math.min(BLOCK_TITLE_MAX_LINES, Math.ceil(estimatedWidth / Math.max(boxWidth * 0.96, 1))));
6301
+ };
6302
+ const getBlockTitleHeight = (lineHeight, title, boxWidth, fontSize) => lineHeight * getBlockTitleLineCount(title, boxWidth, fontSize);
6334
6303
  const omitImageLayoutSpec = (imageSpec) => {
6335
6304
  if (!imageSpec) {
6336
6305
  return {};
@@ -6524,6 +6493,7 @@
6524
6493
  const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
6525
6494
  const getTitleFontSize = (ctx) => resolveTitleFontSize(spec, ctx, block.title, getClockTextRect(spec, ctx, index).width, CLOCK_TITLE_FONT_SIZE, [8, 30]);
6526
6495
  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); };
6496
+ const getTitleHeight = (ctx) => getBlockTitleHeight(getTitleLineHeight(ctx), block.title, getClockTextRect(spec, ctx, index).width, getTitleFontSize(ctx));
6527
6497
  const leadPath = (_d, ctx) => {
6528
6498
  const { start, end } = getClockLeadLine(spec, ctx, index);
6529
6499
  return `M ${start.x.toFixed(2)} ${start.y.toFixed(2)} L ${end.x.toFixed(2)} ${end.y.toFixed(2)}`;
@@ -6573,7 +6543,7 @@
6573
6543
  }
6574
6544
  },
6575
6545
  block.title
6576
- ? 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) * BLOCK_TITLE_MAX_LINES, text: block.title, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, height: (_d, ctx) => getTitleLineHeight(ctx) * BLOCK_TITLE_MAX_LINES, 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) })
6546
+ ? 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, 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) })
6577
6547
  : null,
6578
6548
  contentText.length
6579
6549
  ? 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) })
@@ -6625,7 +6595,7 @@
6625
6595
  const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
6626
6596
  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]);
6627
6597
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_u = spec.title) === null || _u === void 0 ? void 0 : _u.style, Math.round(18 * 1.35));
6628
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_w = (_v = spec.data) === null || _v === void 0 ? void 0 : _v[index]) === null || _w === void 0 ? void 0 : _w.title);
6598
+ 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);
6629
6599
  const contentGap = ((_y = (_x = spec.data) === null || _x === void 0 ? void 0 : _x[index]) === null || _y === void 0 ? void 0 : _y.title) ? 8 : 0;
6630
6600
  return {
6631
6601
  block: {
@@ -6634,6 +6604,7 @@
6634
6604
  },
6635
6605
  titleFontSize,
6636
6606
  titleLineHeight,
6607
+ titleHeight,
6637
6608
  imageBox,
6638
6609
  textBox,
6639
6610
  contentBox: {
@@ -6678,7 +6649,7 @@
6678
6649
  ? 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) })
6679
6650
  : null,
6680
6651
  block.title
6681
- ? 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).titleLineHeight * BLOCK_TITLE_MAX_LINES, 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) })
6652
+ ? 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, 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) })
6682
6653
  : null,
6683
6654
  contentText.length
6684
6655
  ? 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) })
@@ -6727,25 +6698,26 @@
6727
6698
  };
6728
6699
 
6729
6700
  const LANDSCAPE_IMAGE_HEIGHT_RATIO = 0.42;
6730
- const LANDSCAPE_DETACHED_GAP = 64;
6731
- const LANDSCAPE_CONNECTOR_ARROW_SIZE = 9;
6701
+ const LANDSCAPE_CONNECTOR_GAP = 8;
6732
6702
  const LANDSCAPE_CONNECTOR_X_RATIO = 0.2;
6733
6703
  const LANDSCAPE_TEXT_GAP_FROM_CONNECTOR = 12;
6734
- const LANDSCAPE_CONTENT_LINES = 10;
6735
6704
  const LANDSCAPE_TITLE_LINE_HEIGHT = 34;
6736
6705
  const LANDSCAPE_CONTENT_LINE_HEIGHT = 23;
6737
6706
  const LANDSCAPE_CONTENT_FONT_SIZE = 16;
6738
6707
  const LANDSCAPE_TITLE_TO_CONTENT_GAP = 4;
6708
+ const LANDSCAPE_BODY_MARGIN = 8;
6709
+ const LANDSCAPE_IMAGE_BAND_RATIO = 0.28;
6710
+ const LANDSCAPE_IMAGE_BAND_MAX_RATIO = 0.42;
6739
6711
  const getLandscapeImageCenter = (spec, ctx, index) => {
6740
- var _a, _b, _c, _e;
6741
6712
  const lb = getLayout(spec, ctx).blocks[index];
6742
6713
  if (!lb) {
6743
6714
  return null;
6744
6715
  }
6745
- const cx = (_b = (_a = lb.center) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : lb.x + lb.width / 2;
6746
- const cy = (_e = (_c = lb.center) === null || _c === void 0 ? void 0 : _c.y) !== null && _e !== void 0 ? _e : lb.y + lb.height / 2;
6747
- const stagger = (index % 2 === 0 ? -1 : 1) * lb.height * 0.1;
6748
- return { x: cx, y: cy + stagger };
6716
+ const m = getLandscapeMetrics(spec, lb.width, lb.height, index, ctx);
6717
+ return {
6718
+ x: lb.x + m.imageBox.x + m.imageBox.width / 2,
6719
+ y: m.bodyOriginY + m.imageBox.y + m.imageBox.height / 2
6720
+ };
6749
6721
  };
6750
6722
  const buildLandscapeConnectingCurve = (spec) => {
6751
6723
  var _a, _b, _c, _e, _f, _g, _h;
@@ -6806,16 +6778,19 @@
6806
6778
  const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
6807
6779
  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]);
6808
6780
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style, LANDSCAPE_TITLE_LINE_HEIGHT);
6809
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_h = (_g = spec.data) === null || _g === void 0 ? void 0 : _g[index]) === null || _h === void 0 ? void 0 : _h.title);
6810
- const contentFontSize = Number((_l = (_k = (_j = spec.content) === null || _j === void 0 ? void 0 : _j.style) === null || _k === void 0 ? void 0 : _k.fontSize) !== null && _l !== void 0 ? _l : LANDSCAPE_CONTENT_FONT_SIZE);
6811
- const contentLineHeight = Number((_p = (_o = (_m = spec.content) === null || _m === void 0 ? void 0 : _m.style) === null || _o === void 0 ? void 0 : _o.lineHeight) !== null && _p !== void 0 ? _p : LANDSCAPE_CONTENT_LINE_HEIGHT);
6812
- const imageHeight = Math.max((_r = (_q = spec.image) === null || _q === void 0 ? void 0 : _q.height) !== null && _r !== void 0 ? _r : Math.round(blockHeight * LANDSCAPE_IMAGE_HEIGHT_RATIO), titleLineHeight + padding.top + padding.bottom);
6813
- const connectorGap = LANDSCAPE_DETACHED_GAP;
6814
- const canvasHeight = spec.height;
6815
- const contentHeight = canvasHeight
6816
- ? Math.max(contentLineHeight * 2, Math.round(canvasHeight / 4))
6817
- : LANDSCAPE_CONTENT_LINES * contentLineHeight;
6781
+ 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);
6782
+ 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);
6783
+ const { width: regionWidth } = getRegionGeometry(ctx, spec);
6784
+ const blockCount = Math.max((_p = (_o = spec.data) === null || _o === void 0 ? void 0 : _o.length) !== null && _p !== void 0 ? _p : 1, 1);
6785
+ const textWidth = Math.max(regionWidth / blockCount, 1);
6786
+ 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);
6787
+ 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);
6818
6788
  const titleToContentGap = LANDSCAPE_TITLE_TO_CONTENT_GAP;
6789
+ const minTextBandHeight = titleHeight + titleToContentGap + contentLineHeight * 2;
6790
+ const body = getLandscapeBodyGeometry(ctx, spec, rawImageHeight, blockHeight, minTextBandHeight);
6791
+ const imageHeight = body.imageHeight;
6792
+ const textBandHeight = body.textBandHeight;
6793
+ const contentHeight = Math.max(0, textBandHeight - titleHeight - titleToContentGap);
6819
6794
  const textHeight = titleHeight + titleToContentGap + contentHeight;
6820
6795
  const textOnTop = index % 2 === 0;
6821
6796
  let textBox;
@@ -6827,13 +6802,11 @@
6827
6802
  const imageX = 0;
6828
6803
  const connectorX = imageX + blockWidth * LANDSCAPE_CONNECTOR_X_RATIO;
6829
6804
  const textX = connectorX + LANDSCAPE_TEXT_GAP_FROM_CONNECTOR;
6830
- const { width: regionWidth } = getRegionGeometry(ctx, spec);
6831
- const blockCount = Math.max((_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s.length) !== null && _t !== void 0 ? _t : 1, 1);
6832
- const textWidth = Math.max(regionWidth / blockCount, 1);
6805
+ const waveOffset = (textOnTop ? -1 : 1) * body.waveAmplitude;
6806
+ const imageY = body.imageBandTop + body.imageBandHeight / 2 + waveOffset - imageHeight / 2;
6833
6807
  if (textOnTop) {
6834
- const imageY = 0;
6835
- const textY = imageY - connectorGap - textHeight;
6836
- const connectorY1 = imageY;
6808
+ const textY = body.upperTextTop;
6809
+ const connectorY1 = Math.max(imageY - LANDSCAPE_CONNECTOR_GAP, body.upperTextTop);
6837
6810
  const connectorY2 = textY + Math.max(titleHeight, titleLineHeight) / 2;
6838
6811
  imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6839
6812
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
@@ -6844,13 +6817,12 @@
6844
6817
  height: contentHeight
6845
6818
  };
6846
6819
  connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6847
- groupTop = textY;
6848
- groupHeight = imageHeight - groupTop;
6820
+ groupTop = 0;
6821
+ groupHeight = body.height;
6849
6822
  }
6850
6823
  else {
6851
- const imageY = 0;
6852
- const textY = imageY + imageHeight + connectorGap;
6853
- const connectorY1 = imageY + imageHeight;
6824
+ const textY = body.lowerTextTop;
6825
+ const connectorY1 = Math.min(imageY + imageHeight + LANDSCAPE_CONNECTOR_GAP, body.height);
6854
6826
  const connectorY2 = textY + textHeight;
6855
6827
  imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6856
6828
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
@@ -6861,16 +6833,19 @@
6861
6833
  height: contentHeight
6862
6834
  };
6863
6835
  connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6864
- groupTop = imageY;
6865
- groupHeight = textY + textHeight - imageY;
6836
+ groupTop = 0;
6837
+ groupHeight = body.height;
6866
6838
  }
6867
6839
  return {
6868
6840
  padding,
6869
6841
  titleFontSize,
6870
6842
  titleLineHeight,
6843
+ titleHeight,
6871
6844
  contentFontSize,
6872
6845
  contentLineHeight,
6873
6846
  contentHeight,
6847
+ minTextBandHeight,
6848
+ bodyOriginY: body.originY,
6874
6849
  blockWidth: Math.max(blockWidth, textX + textWidth),
6875
6850
  imageBox,
6876
6851
  textBox,
@@ -6881,6 +6856,28 @@
6881
6856
  groupHeight
6882
6857
  };
6883
6858
  };
6859
+ const getLandscapeBodyGeometry = (ctx, spec, rawImageHeight, blockHeight, minTextBandHeight) => {
6860
+ const region = getRegionGeometry(ctx, spec);
6861
+ const margin = Math.min(LANDSCAPE_BODY_MARGIN, Math.max(region.height * 0.04, 0));
6862
+ const height = Math.max(region.height - margin * 2, 1);
6863
+ const textBandReserve = Math.min(minTextBandHeight, Math.max((height - 48) / 2, 0));
6864
+ const maxImageBandHeight = Math.max(height - textBandReserve * 2, height * 0.18);
6865
+ 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)));
6866
+ const imageHeight = Math.min(rawImageHeight, Math.max(imageBandHeight - 16, 1));
6867
+ const textBandHeight = Math.max((height - imageBandHeight) / 2, 1);
6868
+ const imageBandTop = textBandHeight;
6869
+ return {
6870
+ originY: region.startY + margin,
6871
+ height,
6872
+ textBandHeight,
6873
+ imageBandTop,
6874
+ imageBandHeight,
6875
+ imageHeight,
6876
+ upperTextTop: 0,
6877
+ lowerTextTop: imageBandTop + imageBandHeight,
6878
+ waveAmplitude: Math.min(imageBandHeight * 0.18, blockHeight * 0.1)
6879
+ };
6880
+ };
6884
6881
  const buildLandscapeBlockMark = (spec, block, index) => {
6885
6882
  var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m;
6886
6883
  const hasImage = !!block.image;
@@ -6910,13 +6907,8 @@
6910
6907
  return (_a = lb === null || lb === void 0 ? void 0 : lb.x) !== null && _a !== void 0 ? _a : 0;
6911
6908
  },
6912
6909
  y: (_d, ctx) => {
6913
- var _a, _b, _c, _e, _f, _g, _h;
6914
- const lb = getLayout(spec, ctx).blocks[index];
6915
6910
  const m = getMetrics(ctx);
6916
- 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;
6917
- 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;
6918
- const stagger = m.textOnTop ? blockH * 0.1 : -blockH * 0.1;
6919
- return cy - m.imageBox.height / 2 + stagger;
6911
+ return m.bodyOriginY;
6920
6912
  },
6921
6913
  width: (_d, ctx) => getMetrics(ctx).blockWidth,
6922
6914
  height: (_d, ctx) => getMetrics(ctx).groupHeight
@@ -6941,23 +6933,18 @@
6941
6933
  stroke: connectorStroke,
6942
6934
  lineWidth: connectorLineWidth,
6943
6935
  lineDash: connectorDash,
6944
- fill: connectorStroke,
6936
+ fill: false,
6945
6937
  path: (_d, ctx) => {
6946
6938
  const m = getMetrics(ctx);
6947
- const tipSize = LANDSCAPE_CONNECTOR_ARROW_SIZE;
6948
6939
  const x = m.connector.x1;
6949
6940
  const y0 = m.connector.y1;
6950
6941
  const y1 = m.connector.y2;
6951
- const tipDir = y1 < y0 ? -1 : 1;
6952
- const baseY = y1 - tipDir * tipSize;
6953
- const dashLine = `M ${x} ${y0} L ${x} ${baseY}`;
6954
- const triangle = `M ${x - tipSize / 2} ${baseY} L ${x + tipSize / 2} ${baseY} L ${x} ${y1} Z`;
6955
- return `${dashLine} ${triangle}`;
6942
+ return `M ${x} ${y0} L ${x} ${y1}`;
6956
6943
  }
6957
6944
  }
6958
6945
  },
6959
6946
  block.title
6960
- ? 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).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: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_l = spec.title) === null || _l === void 0 ? void 0 : _l.style) })
6947
+ ? 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, 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) })
6961
6948
  : null,
6962
6949
  contentText.length
6963
6950
  ? 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) })
@@ -7072,7 +7059,7 @@
7072
7059
  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);
7073
7060
  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]);
7074
7061
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_p = spec.title) === null || _p === void 0 ? void 0 : _p.style, PORTRAIT_TITLE_LINE_HEIGHT);
7075
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_r = (_q = spec.data) === null || _q === void 0 ? void 0 : _q[index]) === null || _r === void 0 ? void 0 : _r.title);
7062
+ 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);
7076
7063
  const minContentHeight = PORTRAIT_CONTENT_LINES * contentLineHeight;
7077
7064
  const contentHeight = Math.max(minContentHeight, Math.round(blockHeight * PORTRAIT_CONTENT_HEIGHT_RATIO));
7078
7065
  const textHeight = titleHeight + titleToContentGap + contentHeight;
@@ -7107,6 +7094,7 @@
7107
7094
  onLeft,
7108
7095
  titleFontSize,
7109
7096
  titleLineHeight,
7097
+ titleHeight,
7110
7098
  contentFontSize,
7111
7099
  contentLineHeight,
7112
7100
  blockWidth,
@@ -7199,7 +7187,7 @@
7199
7187
  ? 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) })
7200
7188
  : null,
7201
7189
  block.title
7202
- ? 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).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: 'left', textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_f = spec.title) === null || _f === void 0 ? void 0 : _f.style) })
7190
+ ? 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, 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) })
7203
7191
  : null,
7204
7192
  contentText.length
7205
7193
  ? 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) })
@@ -7219,12 +7207,15 @@
7219
7207
  const ARC_TEXT_BOX_HEIGHT = 240;
7220
7208
  const ARC_TITLE_TO_CONTENT_GAP = 4;
7221
7209
  const ARC_TEXT_PADDING = 20;
7222
- const ARC_TEXT_BOX_MIN_WIDTH = 240;
7210
+ const ARC_TEXT_BOX_MIN_WIDTH = 96;
7211
+ const ARC_TEXT_BOX_ABSOLUTE_MIN_WIDTH = 64;
7212
+ const ARC_TEXT_BOX_MAX_WIDTH = 260;
7223
7213
  const ARC_TITLE_IMAGE_WIDTH_RATIO = 0.68;
7224
7214
  const ARC_TITLE_IMAGE_MAX_WIDTH = 900;
7225
7215
  const ARC_TITLE_IMAGE_HEIGHT_RATIO = 0.34;
7226
7216
  const ARC_GAP_FROM_TITLE_IMAGE = 200;
7227
7217
  const ARC_FIT_MARGIN = 8;
7218
+ const clamp$1 = (value, min, max) => Math.max(min, Math.min(max, value));
7228
7219
  const isDownArc = (spec) => normalizeLayout(spec.layout).direction === 'down';
7229
7220
  const getArcTitleImageRect = (spec, ctx) => {
7230
7221
  var _a, _b, _c, _e;
@@ -7277,8 +7268,8 @@
7277
7268
  centerBottom
7278
7269
  };
7279
7270
  };
7280
- const getArcBlockCenterByGeometry = (spec, arc, index) => {
7281
- var _a, _b, _c, _e;
7271
+ const getArcBlockCenterByGeometry = (spec, arc, index, ctx) => {
7272
+ var _a, _b;
7282
7273
  const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7283
7274
  if (count <= 0) {
7284
7275
  return { x: arc.cx, y: arc.cy };
@@ -7292,13 +7283,13 @@
7292
7283
  const nLen = Math.hypot(nxRaw, nyRaw) || 1;
7293
7284
  const nx = nxRaw / nLen;
7294
7285
  const ny = nyRaw / nLen;
7295
- const imageHeight = (_e = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.height) !== null && _e !== void 0 ? _e : ARC_BLOCK_IMAGE_SIZE;
7286
+ const imageHeight = getArcBlockMetrics(spec, index, ctx).imageBox.height;
7296
7287
  const offset = imageHeight / 2;
7297
7288
  return { x: px + nx * offset, y: py + ny * offset };
7298
7289
  };
7299
- const getArcBlockBounds = (spec, arc, index) => {
7300
- const center = getArcBlockCenterByGeometry(spec, arc, index);
7301
- const metrics = getArcBlockMetrics(spec, index);
7290
+ const getArcBlockBounds = (spec, arc, index, ctx) => {
7291
+ const center = getArcBlockCenterByGeometry(spec, arc, index, ctx);
7292
+ const metrics = getArcBlockMetrics(spec, index, ctx);
7302
7293
  const halo = shouldShowImageBackground(spec) ? ARC_BLOCK_IMAGE_HALO_PADDING + ARC_BLOCK_IMAGE_BORDER : 0;
7303
7294
  const minX = Math.min(metrics.imageBox.x - halo, metrics.textBox.x, metrics.contentBox.x);
7304
7295
  const maxX = Math.max(metrics.imageBox.x + metrics.imageBox.width + halo, metrics.textBox.x + metrics.textBox.width, metrics.contentBox.x + metrics.contentBox.width);
@@ -7311,13 +7302,13 @@
7311
7302
  bottom: center.y + maxY
7312
7303
  };
7313
7304
  };
7314
- const getArcBlocksBounds = (spec, arc) => {
7305
+ const getArcBlocksBounds = (spec, arc, ctx) => {
7315
7306
  var _a, _b;
7316
7307
  const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7317
7308
  if (!count) {
7318
7309
  return { left: arc.cx, right: arc.cx, top: arc.cy, bottom: arc.cy };
7319
7310
  }
7320
- return Array.from({ length: count }, (_, index) => getArcBlockBounds(spec, arc, index)).reduce((bounds, blockBounds) => ({
7311
+ return Array.from({ length: count }, (_, index) => getArcBlockBounds(spec, arc, index, ctx)).reduce((bounds, blockBounds) => ({
7321
7312
  left: Math.min(bounds.left, blockBounds.left),
7322
7313
  right: Math.max(bounds.right, blockBounds.right),
7323
7314
  top: Math.min(bounds.top, blockBounds.top),
@@ -7332,7 +7323,7 @@
7332
7323
  const getArcGeometry = (spec, ctx) => {
7333
7324
  const arc = getBaseArcGeometry(spec, ctx);
7334
7325
  const region = getRegionGeometry(ctx);
7335
- const bounds = getArcBlocksBounds(spec, arc);
7326
+ const bounds = getArcBlocksBounds(spec, arc, ctx);
7336
7327
  const fit = {
7337
7328
  left: region.startX + ARC_FIT_MARGIN,
7338
7329
  right: region.startX + region.width - ARC_FIT_MARGIN,
@@ -7365,7 +7356,7 @@
7365
7356
  }
7366
7357
  return shiftX || shiftY ? Object.assign(Object.assign({}, arc), { cx: arc.cx + shiftX, cy: arc.cy + shiftY }) : arc;
7367
7358
  };
7368
- const getArcBlockCenter = (spec, ctx, index) => getArcBlockCenterByGeometry(spec, getArcGeometry(spec, ctx), index);
7359
+ const getArcBlockCenter = (spec, ctx, index) => getArcBlockCenterByGeometry(spec, getArcGeometry(spec, ctx), index, ctx);
7369
7360
  const buildArcMark = (spec) => {
7370
7361
  var _a;
7371
7362
  if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) !== true) {
@@ -7428,23 +7419,32 @@
7428
7419
  ]
7429
7420
  };
7430
7421
  };
7431
- const getArcBlockMetrics = (spec, index = 0) => {
7422
+ const getArcBlockMetrics = (spec, index = 0, ctx) => {
7432
7423
  var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
7433
- 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);
7434
- 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);
7424
+ const region = ctx ? getRegionGeometry(ctx, spec) : undefined;
7425
+ const count = Math.max((_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0, 1);
7426
+ 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);
7427
+ 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);
7428
+ const slotWidth = regionWidth / (count + 1);
7429
+ const imageScale = clamp$1(Math.min(regionWidth / Math.max(count * ARC_BLOCK_IMAGE_SIZE * 0.92, 1), regionHeight / 620), 0.42, 1);
7430
+ const textScale = clamp$1(Math.min(slotWidth / 180, imageScale), 0.48, 1);
7431
+ const styleContent = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style;
7432
+ 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));
7433
+ 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)));
7435
7434
  const titleToContentGap = ARC_TITLE_TO_CONTENT_GAP;
7436
- 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);
7435
+ 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);
7436
+ const imageDiameter = Math.round(clamp$1(configuredImageDiameter * imageScale, 64, configuredImageDiameter));
7437
7437
  const imageWidth = imageDiameter;
7438
7438
  const imageHeight = imageDiameter;
7439
7439
  const isDown = isDownArc(spec);
7440
- const count = Math.max((_o = (_m = spec.data) === null || _m === void 0 ? void 0 : _m.length) !== null && _o !== void 0 ? _o : 0, 1);
7441
- const canvasWidth = Number((_p = spec.width) !== null && _p !== void 0 ? _p : imageWidth * count);
7442
- const defaultTextWidth = Math.round(canvasWidth / (count + 1));
7443
- 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);
7444
- 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]);
7440
+ 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);
7441
+ const defaultTextWidth = Math.round(slotWidth * 0.96);
7442
+ const minTextWidth = Math.min(ARC_TEXT_BOX_MIN_WIDTH, Math.max(Math.round(slotWidth * 0.72), ARC_TEXT_BOX_ABSOLUTE_MIN_WIDTH));
7443
+ const textBoxWidth = Math.round(clamp$1(Math.min(configuredTextWidth, defaultTextWidth), minTextWidth, ARC_TEXT_BOX_MAX_WIDTH));
7444
+ 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]);
7445
7445
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_u = spec.title) === null || _u === void 0 ? void 0 : _u.style, ARC_TITLE_LINE_HEIGHT);
7446
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_w = (_v = spec.data) === null || _v === void 0 ? void 0 : _v[index]) === null || _w === void 0 ? void 0 : _w.title);
7447
- const textHeight = ARC_TEXT_BOX_HEIGHT;
7446
+ 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);
7447
+ const textHeight = Math.round(clamp$1(ARC_TEXT_BOX_HEIGHT * textScale, 88, ARC_TEXT_BOX_HEIGHT));
7448
7448
  const contentHeight = Math.max(textHeight - titleHeight - titleToContentGap, contentLineHeight);
7449
7449
  const isLeftSide = index < count / 2;
7450
7450
  const textAlign = isLeftSide ? 'right' : 'left';
@@ -7454,7 +7454,9 @@
7454
7454
  width: imageWidth,
7455
7455
  height: imageHeight
7456
7456
  };
7457
- const textBoxX = isLeftSide ? -ARC_TEXT_PADDING : ARC_TEXT_PADDING;
7457
+ const textPadding = Math.round(ARC_TEXT_PADDING * textScale);
7458
+ const textBoxX = isLeftSide ? -textPadding - textBoxWidth : textPadding;
7459
+ const textAnchorX = isLeftSide ? -textPadding : textPadding;
7458
7460
  const textBox = {
7459
7461
  x: textBoxX,
7460
7462
  y: isDown ? imageBox.y + imageHeight + ARC_TEXT_GAP_FROM_IMAGE : imageBox.y - ARC_TEXT_GAP_FROM_IMAGE - textHeight,
@@ -7476,7 +7478,8 @@
7476
7478
  textBox,
7477
7479
  contentBox,
7478
7480
  isDown,
7479
- textAlign
7481
+ textAlign,
7482
+ textAnchorX
7480
7483
  };
7481
7484
  };
7482
7485
  const buildArcBlockMark = (spec, block, index) => {
@@ -7484,12 +7487,18 @@
7484
7487
  const hasImage = !!block.image;
7485
7488
  const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7486
7489
  const themeColor = getThemeColor(spec);
7487
- const metrics = getArcBlockMetrics(spec, index);
7488
- const connectorY = metrics.isDown ? metrics.imageBox.y + metrics.imageBox.height : metrics.textBox.y;
7489
- const connectorHeight = metrics.isDown
7490
- ? Math.max(metrics.textBox.y + metrics.textBox.height - (metrics.imageBox.y + metrics.imageBox.height), 0)
7491
- : Math.max(metrics.imageBox.y - metrics.textBox.y, 0);
7492
- const connectorX = -1;
7490
+ const getMetrics = (ctx) => getArcBlockMetrics(spec, index, ctx);
7491
+ const getConnectorBox = (ctx) => {
7492
+ const metrics = getMetrics(ctx);
7493
+ return {
7494
+ x: -1,
7495
+ y: metrics.isDown ? metrics.imageBox.y + metrics.imageBox.height : metrics.textBox.y,
7496
+ width: 2,
7497
+ height: metrics.isDown
7498
+ ? Math.max(metrics.textBox.y + metrics.textBox.height - (metrics.imageBox.y + metrics.imageBox.height), 0)
7499
+ : Math.max(metrics.imageBox.y - metrics.textBox.y, 0)
7500
+ };
7501
+ };
7493
7502
  return {
7494
7503
  type: 'group',
7495
7504
  id: `storyline-block-${(_a = block.id) !== null && _a !== void 0 ? _a : index}`,
@@ -7506,22 +7515,22 @@
7506
7515
  interactive: false,
7507
7516
  zIndex: vchart.LayoutZIndex.Mark + 2,
7508
7517
  style: {
7509
- x: connectorX,
7510
- y: connectorY,
7511
- width: 2,
7512
- height: connectorHeight,
7518
+ x: (_d, ctx) => getConnectorBox(ctx).x,
7519
+ y: (_d, ctx) => getConnectorBox(ctx).y,
7520
+ width: (_d, ctx) => getConnectorBox(ctx).width,
7521
+ height: (_d, ctx) => getConnectorBox(ctx).height,
7513
7522
  fill: themeColor,
7514
7523
  fillOpacity: 0.6
7515
7524
  }
7516
7525
  },
7517
7526
  hasImage
7518
- ? 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) })
7527
+ ? 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) })
7519
7528
  : {
7520
7529
  type: 'symbol',
7521
7530
  name: `storyline-block-image-bg-${index}`,
7522
7531
  interactive: false,
7523
7532
  zIndex: vchart.LayoutZIndex.Mark + 3,
7524
- style: Object.assign({ x: 0, y: 0, size: Math.min(metrics.imageBox.width, metrics.imageBox.height), symbolType: 'circle' }, getImageBackgroundStyle(spec))
7533
+ style: Object.assign({ x: 0, y: 0, size: (_d, ctx) => Math.min(getMetrics(ctx).imageBox.width, getMetrics(ctx).imageBox.height), symbolType: 'circle' }, getImageBackgroundStyle(spec))
7525
7534
  },
7526
7535
  shouldShowImageBackground(spec)
7527
7536
  ? {
@@ -7532,7 +7541,8 @@
7532
7541
  style: {
7533
7542
  x: 0,
7534
7543
  y: 0,
7535
- size: Math.min(metrics.imageBox.width, metrics.imageBox.height) + ARC_BLOCK_IMAGE_HALO_PADDING * 2,
7544
+ size: (_d, ctx) => Math.min(getMetrics(ctx).imageBox.width, getMetrics(ctx).imageBox.height) +
7545
+ ARC_BLOCK_IMAGE_HALO_PADDING * 2,
7536
7546
  symbolType: 'circle',
7537
7547
  fill: 'transparent',
7538
7548
  stroke: withAlpha(themeColor, 0.82),
@@ -7541,10 +7551,10 @@
7541
7551
  }
7542
7552
  : null,
7543
7553
  block.title
7544
- ? 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, height: metrics.titleLineHeight * BLOCK_TITLE_MAX_LINES, heightLimit: metrics.titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: metrics.titleFontSize, lineHeight: metrics.titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: metrics.textAlign, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7554
+ ? 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, 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) })
7545
7555
  : null,
7546
7556
  contentText.length
7547
- ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 4 }, spec.content), { 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: buildPlainContent(contentText), fontSize: metrics.contentFontSize, lineHeight: metrics.contentLineHeight, textAlign: metrics.textAlign, textBaseline: 'top', whiteSpace: 'normal', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7557
+ ? 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) })
7548
7558
  : null
7549
7559
  ].filter(Boolean)
7550
7560
  };
@@ -7560,9 +7570,35 @@
7560
7570
  const WING_TITLE_TO_CONTENT_GAP = 4;
7561
7571
  const WING_TITLE_IMAGE_WIDTH_RATIO = 0.6;
7562
7572
  const WING_TITLE_IMAGE_MAX_WIDTH = 820;
7573
+ const WING_DEFAULT_PATH_END_WIDTH = 350;
7574
+ const WING_IMAGE_MIN_SCALE = 0.52;
7575
+ const WING_IMAGE_MAX_SCALE = 1.2;
7576
+ const WING_BOTTOM_TEXT_IMAGE_GAP_RATIO = 1.35;
7577
+ const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
7563
7578
  const getWingDirection = (spec) => {
7564
7579
  return normalizeLayout(spec.layout).direction === 'right' ? 'right' : 'left';
7565
7580
  };
7581
+ const getWingPathWidthRange = (spec) => {
7582
+ var _a, _b, _c, _e, _f;
7583
+ const lineStyle = ((_b = (_a = spec.line) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {});
7584
+ const startWidth = Math.max(Number((_c = lineStyle.startWidth) !== null && _c !== void 0 ? _c : 50), 0.5);
7585
+ const endWidth = Math.max(Number((_f = (_e = lineStyle.endWidth) !== null && _e !== void 0 ? _e : lineStyle.lineWidth) !== null && _f !== void 0 ? _f : WING_DEFAULT_PATH_END_WIDTH), startWidth);
7586
+ return { startWidth, endWidth };
7587
+ };
7588
+ const getWingBlockPathRatio = (spec, index) => {
7589
+ var _a, _b;
7590
+ const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7591
+ if (count <= 1) {
7592
+ return 0.5;
7593
+ }
7594
+ return index / (count - 1);
7595
+ };
7596
+ const getWingBlockImageScale = (spec, index) => {
7597
+ const { startWidth, endWidth } = getWingPathWidthRange(spec);
7598
+ const startScale = clamp(startWidth / WING_DEFAULT_PATH_END_WIDTH, WING_IMAGE_MIN_SCALE, WING_IMAGE_MAX_SCALE);
7599
+ const endScale = clamp(endWidth / WING_DEFAULT_PATH_END_WIDTH, WING_IMAGE_MIN_SCALE, WING_IMAGE_MAX_SCALE);
7600
+ return startScale + (endScale - startScale) * getWingBlockPathRatio(spec, index);
7601
+ };
7566
7602
  const getWingArcGeometry = (spec, ctx) => {
7567
7603
  var _a, _b, _c;
7568
7604
  const { width, height, startX, startY } = getRegionGeometry(ctx);
@@ -7595,15 +7631,31 @@
7595
7631
  y: arc.cy + Math.sin(angle) * arc.ry
7596
7632
  };
7597
7633
  };
7634
+ const isWingBottomBlock = (spec, ctx, index) => {
7635
+ var _a, _b;
7636
+ const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7637
+ if (count <= 0) {
7638
+ return false;
7639
+ }
7640
+ let bottomIndex = 0;
7641
+ let bottomY = Number.NEGATIVE_INFINITY;
7642
+ for (let i = 0; i < count; i++) {
7643
+ const center = getWingBlockCenter(spec, ctx, i);
7644
+ if (center.y > bottomY) {
7645
+ bottomY = center.y;
7646
+ bottomIndex = i;
7647
+ }
7648
+ }
7649
+ return index === bottomIndex;
7650
+ };
7598
7651
  const buildWingArcMark = (spec) => {
7599
- var _a, _b, _c, _e, _f, _g, _h, _j;
7652
+ var _a, _b, _c, _e, _f;
7600
7653
  if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) === false) {
7601
7654
  return null;
7602
7655
  }
7603
7656
  const themeColor = getThemeColor(spec);
7604
7657
  const lineStyle = ((_c = (_b = spec.line) === null || _b === void 0 ? void 0 : _b.style) !== null && _c !== void 0 ? _c : {});
7605
- const startWidth = Math.max(Number((_e = lineStyle.startWidth) !== null && _e !== void 0 ? _e : 50), 0.5);
7606
- const endWidth = Math.max(Number((_g = (_f = lineStyle.endWidth) !== null && _f !== void 0 ? _f : lineStyle.lineWidth) !== null && _g !== void 0 ? _g : 350), startWidth);
7658
+ const { startWidth, endWidth } = getWingPathWidthRange(spec);
7607
7659
  return {
7608
7660
  type: 'group',
7609
7661
  name: 'storyline-wing-arc',
@@ -7616,7 +7668,7 @@
7616
7668
  style: {
7617
7669
  stroke: false,
7618
7670
  lineWidth: 0,
7619
- fill: (_j = (_h = lineStyle.fill) !== null && _h !== void 0 ? _h : lineStyle.stroke) !== null && _j !== void 0 ? _j : themeColor,
7671
+ fill: (_f = (_e = lineStyle.fill) !== null && _e !== void 0 ? _e : lineStyle.stroke) !== null && _f !== void 0 ? _f : themeColor,
7620
7672
  opacity: 0.95,
7621
7673
  path: (_d, ctx) => {
7622
7674
  const arc = getWingArcGeometry(spec, ctx);
@@ -7700,14 +7752,15 @@
7700
7752
  var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
7701
7753
  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]);
7702
7754
  const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style, WING_TITLE_LINE_HEIGHT, 1.3);
7703
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_f = (_e = spec.data) === null || _e === void 0 ? void 0 : _e[index]) === null || _f === void 0 ? void 0 : _f.title);
7755
+ 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);
7704
7756
  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);
7705
7757
  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);
7706
7758
  const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;
7707
7759
  const textHeight = WING_TEXT_BOX_HEIGHT;
7708
7760
  const contentHeight = 100000;
7709
- const imageWidth = Number((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.width) !== null && _p !== void 0 ? _p : WING_BLOCK_IMAGE_SIZE);
7710
- const imageHeight = Number((_r = (_q = spec.image) === null || _q === void 0 ? void 0 : _q.height) !== null && _r !== void 0 ? _r : WING_BLOCK_IMAGE_SIZE);
7761
+ const imageScale = getWingBlockImageScale(spec, index);
7762
+ const imageWidth = Math.round(Number((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.width) !== null && _p !== void 0 ? _p : WING_BLOCK_IMAGE_SIZE) * imageScale);
7763
+ const imageHeight = Math.round(Number((_r = (_q = spec.image) === null || _q === void 0 ? void 0 : _q.height) !== null && _r !== void 0 ? _r : WING_BLOCK_IMAGE_SIZE) * imageScale);
7711
7764
  const imageBox = {
7712
7765
  x: -imageWidth / 2,
7713
7766
  y: -imageHeight / 2,
@@ -7717,14 +7770,35 @@
7717
7770
  const direction = getWingDirection(spec);
7718
7771
  const count = (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s.length) !== null && _t !== void 0 ? _t : 0;
7719
7772
  const isSpecialBelow = (direction === 'right' && count > 0 && index === count - 1) || (direction === 'left' && index === 0);
7720
- const isVerticalLayout = isSpecialBelow;
7773
+ const isBottomAbove = isWingBottomBlock(spec, ctx, index);
7774
+ const isVerticalLayout = isBottomAbove || isSpecialBelow;
7721
7775
  const textWidth = WING_TEXT_BOX_WIDTH;
7722
7776
  let textBox;
7723
7777
  let contentBox;
7724
7778
  let connectorBox;
7725
7779
  let onLeft;
7726
7780
  let verticalAlign;
7727
- if (isVerticalLayout) {
7781
+ if (isBottomAbove) {
7782
+ const bottomTextImageGap = Math.round(WING_TEXT_IMAGE_GAP * WING_BOTTOM_TEXT_IMAGE_GAP_RATIO);
7783
+ const textX = -textWidth / 2;
7784
+ const textY = -imageHeight / 2 - bottomTextImageGap - textHeight;
7785
+ textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
7786
+ contentBox = {
7787
+ x: textX,
7788
+ y: textY + titleHeight + titleToContentGap,
7789
+ width: textWidth,
7790
+ height: contentHeight
7791
+ };
7792
+ connectorBox = {
7793
+ x: -1,
7794
+ y: textY + textHeight,
7795
+ width: 2,
7796
+ height: bottomTextImageGap
7797
+ };
7798
+ onLeft = false;
7799
+ verticalAlign = 'above';
7800
+ }
7801
+ else if (isVerticalLayout) {
7728
7802
  const textX = -textWidth / 2;
7729
7803
  const textY = imageHeight / 2 + WING_TEXT_IMAGE_GAP;
7730
7804
  textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
@@ -7770,6 +7844,7 @@
7770
7844
  verticalAlign,
7771
7845
  titleFontSize,
7772
7846
  titleLineHeight,
7847
+ titleHeight,
7773
7848
  contentFontSize,
7774
7849
  contentLineHeight,
7775
7850
  imageBox,
@@ -7831,7 +7906,7 @@
7831
7906
  return m.textBox.x + m.textBox.width / 2;
7832
7907
  }
7833
7908
  return m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;
7834
- }, 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).titleLineHeight * BLOCK_TITLE_MAX_LINES, 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) => {
7909
+ }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y, text: block.title, 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) => {
7835
7910
  const m = getWingBlockMetrics(spec, ctx, index);
7836
7911
  if (m.verticalAlign) {
7837
7912
  return 'center';
@@ -7858,193 +7933,6 @@
7858
7933
  };
7859
7934
  };
7860
7935
 
7861
- const LADDER_HEADLINE_FONT_RATIO = 0.42;
7862
- const LADDER_HEADLINE_FONT_MIN = 80;
7863
- const LADDER_HEADLINE_FONT_MAX = 240;
7864
- const LADDER_DIAGONAL_LINE_WIDTH = 2;
7865
- const LADDER_DIAGONAL_DASH = [12, 8];
7866
- const LADDER_BLOCK_IMAGE_SIZE = 100;
7867
- const LADDER_TITLE_FONT_SIZE = 28;
7868
- const LADDER_TITLE_LINE_HEIGHT = 26;
7869
- const LADDER_CONTENT_FONT_SIZE = 16;
7870
- const LADDER_CONTENT_LINE_HEIGHT = 23;
7871
- const isDownLadder = (spec) => normalizeLayout(spec.layout).direction === 'down';
7872
- const getLadderDiagonalGeometry = (spec, ctx) => {
7873
- var _a;
7874
- const { width, height, startX, startY } = getRegionGeometry(ctx);
7875
- const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
7876
- const innerX = startX + padding.left;
7877
- const innerY = startY + padding.top;
7878
- const innerW = Math.max(width - padding.left - padding.right, 1);
7879
- const innerH = Math.max(height - padding.top - padding.bottom, 1);
7880
- const isDown = isDownLadder(spec);
7881
- const x0 = innerX;
7882
- const x1 = innerX + innerW;
7883
- const y0 = isDown ? innerY : innerY + innerH;
7884
- const y1 = isDown ? innerY + innerH : innerY;
7885
- const cx = (x0 + x1) / 2;
7886
- const cy = (y0 + y1) / 2;
7887
- const dx = x1 - x0;
7888
- const dy = y1 - y0;
7889
- const angleRad = (Math.atan2(dy, dx) / Math.PI) * 180;
7890
- const fontSize = Math.max(LADDER_HEADLINE_FONT_MIN, Math.min(LADDER_HEADLINE_FONT_MAX, Math.round(innerH * LADDER_HEADLINE_FONT_RATIO)));
7891
- return { x0, y0, x1, y1, cx, cy, angleRad, fontSize };
7892
- };
7893
- const getLadderHeadlineText = (spec) => {
7894
- var _a, _b;
7895
- const layoutOpt = normalizeLayout(spec.layout);
7896
- if (typeof layoutOpt.headline === 'string' && layoutOpt.headline.length > 0) {
7897
- return layoutOpt.headline;
7898
- }
7899
- const title = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.text;
7900
- if (typeof title === 'string' && title.length > 0) {
7901
- return title;
7902
- }
7903
- return 'storyline';
7904
- };
7905
- const buildLadderDiagonalMark = (spec) => {
7906
- const themeColor = getThemeColor(spec);
7907
- return {
7908
- type: 'group',
7909
- name: 'storyline-ladder-diagonal',
7910
- zIndex: vchart.LayoutZIndex.Mark - 1,
7911
- children: [
7912
- {
7913
- type: 'path',
7914
- name: 'storyline-ladder-diagonal-line',
7915
- interactive: false,
7916
- style: {
7917
- path: (_d, ctx) => {
7918
- const g = getLadderDiagonalGeometry(spec, ctx);
7919
- return `M ${g.x0} ${g.y0} L ${g.x1} ${g.y1}`;
7920
- },
7921
- stroke: withAlpha(themeColor, 0.85),
7922
- lineWidth: LADDER_DIAGONAL_LINE_WIDTH,
7923
- lineDash: LADDER_DIAGONAL_DASH,
7924
- fill: 'transparent'
7925
- }
7926
- }
7927
- ]
7928
- };
7929
- };
7930
- const buildLadderHeadlineMark = (spec) => {
7931
- const text = getLadderHeadlineText(spec);
7932
- if (!text) {
7933
- return null;
7934
- }
7935
- const themeColor = getThemeColor(spec);
7936
- return {
7937
- type: 'group',
7938
- name: 'storyline-ladder-headline',
7939
- zIndex: vchart.LayoutZIndex.Mark,
7940
- style: {
7941
- x: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).cx,
7942
- y: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).cy,
7943
- angle: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).angleRad
7944
- },
7945
- children: [
7946
- {
7947
- type: 'text',
7948
- name: 'storyline-ladder-headline-text',
7949
- interactive: false,
7950
- style: {
7951
- x: 0,
7952
- y: 0,
7953
- text,
7954
- fontSize: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).fontSize,
7955
- fontWeight: 900,
7956
- fontFamily: 'Impact, "Arial Black", sans-serif',
7957
- fill: withAlpha(themeColor, 0.92),
7958
- textAlign: 'center',
7959
- textBaseline: 'middle'
7960
- }
7961
- }
7962
- ]
7963
- };
7964
- };
7965
- const isOnLeft = (index) => index % 2 === 1;
7966
- const getLadderBlockMetrics = (spec, ctx, index) => {
7967
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
7968
- const block = getLayout(spec, ctx).blocks[index];
7969
- const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
7970
- const imagePosition = isOnLeft(index) ? 'right' : 'left';
7971
- const imageWidth = (_e = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.width) !== null && _e !== void 0 ? _e : LADDER_BLOCK_IMAGE_SIZE;
7972
- const imageHeight = (_g = (_f = spec.image) === null || _f === void 0 ? void 0 : _f.height) !== null && _g !== void 0 ? _g : LADDER_BLOCK_IMAGE_SIZE;
7973
- const imageGap = (_j = (_h = spec.image) === null || _h === void 0 ? void 0 : _h.gap) !== null && _j !== void 0 ? _j : DEFAULT_IMAGE_GAP;
7974
- const hasImage = !!((_l = (_k = spec.data) === null || _k === void 0 ? void 0 : _k[index]) === null || _l === void 0 ? void 0 : _l.image);
7975
- const blockWidth = (_m = block === null || block === void 0 ? void 0 : block.width) !== null && _m !== void 0 ? _m : resolveBlockWidth(spec, 0);
7976
- const blockHeight = (_q = (_o = block === null || block === void 0 ? void 0 : block.height) !== null && _o !== void 0 ? _o : (_p = spec.block) === null || _p === void 0 ? void 0 : _p.height) !== null && _q !== void 0 ? _q : DEFAULT_BLOCK_HEIGHT;
7977
- const imageBox = getImageBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
7978
- const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
7979
- 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]);
7980
- 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);
7981
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_v = (_u = spec.data) === null || _u === void 0 ? void 0 : _u[index]) === null || _v === void 0 ? void 0 : _v.title);
7982
- const contentGap = ((_x = (_w = spec.data) === null || _w === void 0 ? void 0 : _w[index]) === null || _x === void 0 ? void 0 : _x.title) ? 8 : 0;
7983
- return {
7984
- block: { width: blockWidth, height: blockHeight },
7985
- titleFontSize,
7986
- titleLineHeight,
7987
- imageBox,
7988
- textBox,
7989
- contentBox: {
7990
- y: textBox.y + titleHeight + contentGap,
7991
- height: Math.max(0, textBox.height - titleHeight - contentGap)
7992
- }
7993
- };
7994
- };
7995
- const buildLadderBlockMark = (spec, block, index) => {
7996
- var _a, _b, _c, _e, _f, _g, _h;
7997
- const hasImage = !!block.image;
7998
- const onLeft = isOnLeft(index);
7999
- const align = onLeft ? 'right' : 'left';
8000
- const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
8001
- const showBackground = ((_a = spec.block) === null || _a === void 0 ? void 0 : _a.showBackground) === true;
8002
- const showImageBackground = shouldShowImageBackground(spec);
8003
- const getTitleX = (ctx) => {
8004
- const m = getLadderBlockMetrics(spec, ctx, index);
8005
- return align === 'right' ? m.textBox.x + m.textBox.width : m.textBox.x;
8006
- };
8007
- return {
8008
- type: 'group',
8009
- id: `storyline-block-${(_b = block.id) !== null && _b !== void 0 ? _b : index}`,
8010
- name: `storyline-block-${index}`,
8011
- zIndex: vchart.LayoutZIndex.Mark + 1,
8012
- style: {
8013
- x: (_d, ctx) => { var _a, _b; return (_b = (_a = getLayout(spec, ctx).blocks[index]) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0; },
8014
- y: (_d, ctx) => { var _a, _b; return (_b = (_a = getLayout(spec, ctx).blocks[index]) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : 0; },
8015
- width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.width,
8016
- height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.height
8017
- },
8018
- children: [
8019
- showBackground
8020
- ? {
8021
- type: 'rect',
8022
- name: `storyline-block-bg-${index}`,
8023
- interactive: false,
8024
- style: Object.assign({ x: 0, y: 0, width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.width, height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.height, cornerRadius: 8, fill: '#ffffff', stroke: '#d7dce5', lineWidth: 1, shadowBlur: 6, shadowColor: 'rgba(0, 0, 0, 0.08)' }, (_c = spec.block) === null || _c === void 0 ? void 0 : _c.style)
8025
- }
8026
- : null,
8027
- showImageBackground
8028
- ? {
8029
- type: 'rect',
8030
- name: `storyline-block-image-bg-${index}`,
8031
- interactive: false,
8032
- style: Object.assign(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, cornerRadius: 8 }, getImageBackgroundStyle(spec)), (_e = spec.block) === null || _e === void 0 ? void 0 : _e.style)
8033
- }
8034
- : null,
8035
- hasImage
8036
- ? 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) })
8037
- : null,
8038
- block.title
8039
- ? 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).titleLineHeight * BLOCK_TITLE_MAX_LINES, 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 }) })
8040
- : null,
8041
- contentText.length
8042
- ? 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 }) })
8043
- : null
8044
- ].filter(Boolean)
8045
- };
8046
- };
8047
-
8048
7936
  class StorylineChartSpecTransformer extends vchart.CommonChartSpecTransformer {
8049
7937
  transformSpec(spec) {
8050
7938
  var _a;
@@ -8069,15 +7957,11 @@
8069
7957
  const arcDown = arc && normalizeLayout(spec.layout).direction === 'down';
8070
7958
  const arcUp = arc && !arcDown;
8071
7959
  const portrait = isPortrait(spec);
8072
- const ladder = isLadder(spec);
8073
7960
  const wing = isWing(spec);
8074
7961
  const clock = isClock(spec);
8075
7962
  const topTitleImageReserve = (() => {
8076
7963
  var _a, _b, _c, _d;
8077
- if (arc ||
8078
- ladder ||
8079
- !((_a = spec.titleImage) === null || _a === void 0 ? void 0 : _a.image) ||
8080
- ((_b = spec.titleImage) === null || _b === void 0 ? void 0 : _b.visible) === false) {
7964
+ if (arc || !((_a = spec.titleImage) === null || _a === void 0 ? void 0 : _a.image) || ((_b = spec.titleImage) === null || _b === void 0 ? void 0 : _b.visible) === false) {
8081
7965
  return 0;
8082
7966
  }
8083
7967
  return getTitleImageReservedHeight(spec, Number((_c = spec.width) !== null && _c !== void 0 ? _c : 1000), Number((_d = spec.height) !== null && _d !== void 0 ? _d : 600));
@@ -8102,33 +7986,7 @@
8102
7986
  const breath = 16;
8103
7987
  return Math.max(LARGE, Math.round(imageHeight / 2 + textGap + titleLineHeight + titleToContentGap + contentHeight + breath));
8104
7988
  })();
8105
- const ladderHorizontalPadding = (() => {
8106
- var _a, _b, _c, _d, _e, _f;
8107
- if (!ladder) {
8108
- return 0;
8109
- }
8110
- const blockWidth = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.minWidth) !== null && _b !== void 0 ? _b : resolveBlockWidth(spec, 0);
8111
- const imageWidth = (_d = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 96;
8112
- const imageGap = (_f = (_e = spec.image) === null || _e === void 0 ? void 0 : _e.gap) !== null && _f !== void 0 ? _f : DEFAULT_IMAGE_GAP;
8113
- const innerPadding = 12 * 2;
8114
- const contentWidth = Math.max(blockWidth - imageWidth - imageGap - innerPadding, DEFAULT_BLOCK_WIDTH * 0.5);
8115
- const ideal = Math.round(contentWidth * 2);
8116
- const canvasWidth = spec.width;
8117
- const cap = canvasWidth ? Math.floor(canvasWidth * 0.3) : ideal;
8118
- return Math.min(ideal, cap);
8119
- })();
8120
- const ladderVerticalPadding = (() => {
8121
- var _a, _b;
8122
- if (!ladder) {
8123
- return 0;
8124
- }
8125
- const blockHeight = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : 132;
8126
- const ideal = Math.round(blockHeight * 3);
8127
- const canvasHeight = spec.height;
8128
- const cap = canvasHeight ? Math.floor(canvasHeight * 0.3) : ideal;
8129
- return Math.min(ideal, cap);
8130
- })();
8131
- const defaultTop = Math.max(topTitleImageReserve, clock ? 40 : ladder ? ladderVerticalPadding : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL);
7989
+ const defaultTop = Math.max(topTitleImageReserve, clock ? 40 : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL);
8132
7990
  const defaultBottom = clock
8133
7991
  ? 60
8134
7992
  : portrait
@@ -8136,7 +7994,7 @@
8136
7994
  : wing
8137
7995
  ? 300
8138
7996
  : arcUp
8139
- ? 0
7997
+ ? 100
8140
7998
  : arcDown
8141
7999
  ? TEXT_RESERVE
8142
8000
  : LARGE;
@@ -8152,8 +8010,8 @@
8152
8010
  }
8153
8011
  return Math.round(canvasWidth / (count + 1));
8154
8012
  })();
8155
- const defaultLeft = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;
8156
- const defaultRight = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;
8013
+ const defaultLeft = clock ? 40 : arcHorizontalPadding;
8014
+ const defaultRight = clock ? 40 : arcHorizontalPadding;
8157
8015
  const p = spec.padding;
8158
8016
  if (p == null) {
8159
8017
  spec.padding = [defaultTop, defaultRight, defaultBottom, defaultLeft];
@@ -8202,11 +8060,6 @@
8202
8060
  const wingTitleImageMark = buildWingTitleImageMark(spec);
8203
8061
  return [arcMark, wingTitleImageMark, ...blockMarks].filter(Boolean);
8204
8062
  }
8205
- if (isLadder(spec)) {
8206
- const diagonalMark = buildLadderDiagonalMark(spec);
8207
- const headlineMark = buildLadderHeadlineMark(spec);
8208
- return [diagonalMark, headlineMark, ...blockMarks].filter(Boolean);
8209
- }
8210
8063
  return [titleImageMark, lineMark, ...blockMarks].filter(Boolean);
8211
8064
  };
8212
8065
  const buildLineMark = (spec) => {
@@ -8238,9 +8091,6 @@
8238
8091
  if (isWing(spec)) {
8239
8092
  return buildWingBlockMark(spec, block, index);
8240
8093
  }
8241
- if (isLadder(spec)) {
8242
- return buildLadderBlockMark(spec, block, index);
8243
- }
8244
8094
  return buildDefaultBlockMark(spec, block, index);
8245
8095
  };
8246
8096