@visactor/vchart-extension 2.1.0-alpha.18 → 2.1.0-alpha.19

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 (227) hide show
  1. package/build/index.js +2151 -0
  2. package/build/index.min.js +2 -2
  3. package/cjs/charts/axis-3d/index.js +2 -1
  4. package/cjs/charts/axis-3d/linear-axis.js +1 -2
  5. package/cjs/charts/bar-3d/chart-spec-transformer.js +1 -1
  6. package/cjs/charts/bar-3d/chart.js +1 -1
  7. package/cjs/charts/bar-3d/constant.js +1 -1
  8. package/cjs/charts/bar-3d/index.js +1 -1
  9. package/cjs/charts/bar-3d/interface.js +1 -1
  10. package/cjs/charts/bar-3d/series-spec-transformer.js +1 -1
  11. package/cjs/charts/bar-3d/series.js +1 -1
  12. package/cjs/charts/bar-3d/theme.js +1 -1
  13. package/cjs/charts/candlestick/candlestick-transformer.js +1 -1
  14. package/cjs/charts/candlestick/candlestick.js +1 -2
  15. package/cjs/charts/candlestick/index.js +1 -1
  16. package/cjs/charts/candlestick/interface.js +1 -1
  17. package/cjs/charts/candlestick/util.js +1 -1
  18. package/cjs/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  19. package/cjs/charts/combination-candlestick/combination-candlestick.js +1 -1
  20. package/cjs/charts/combination-candlestick/constant.js +1 -1
  21. package/cjs/charts/combination-candlestick/index.js +1 -1
  22. package/cjs/charts/combination-candlestick/interface.js +1 -1
  23. package/cjs/charts/conversion-funnel/arrow-data-transform.js +1 -1
  24. package/cjs/charts/conversion-funnel/constants.js +1 -1
  25. package/cjs/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  26. package/cjs/charts/conversion-funnel/conversion-funnel.js +1 -1
  27. package/cjs/charts/conversion-funnel/index.js +1 -1
  28. package/cjs/charts/conversion-funnel/interface.js +1 -1
  29. package/cjs/charts/conversion-funnel/util.js +1 -1
  30. package/cjs/charts/funnel-3d/chart.js +1 -2
  31. package/cjs/charts/funnel-3d/constant.js +1 -1
  32. package/cjs/charts/funnel-3d/index.js +1 -1
  33. package/cjs/charts/funnel-3d/interface.js +1 -1
  34. package/cjs/charts/funnel-3d/series-spec-transformer.js +1 -1
  35. package/cjs/charts/funnel-3d/series.js +1 -1
  36. package/cjs/charts/funnel-3d/theme.js +1 -1
  37. package/cjs/charts/histogram-3d/chart.js +1 -1
  38. package/cjs/charts/image-cloud/series/image-cloud.d.ts +1 -1
  39. package/cjs/charts/storyline/index.d.ts +4 -0
  40. package/cjs/charts/storyline/index.js +22 -0
  41. package/cjs/charts/storyline/index.js.map +1 -0
  42. package/cjs/charts/storyline/interface.d.ts +67 -0
  43. package/cjs/charts/storyline/interface.js +6 -0
  44. package/cjs/charts/storyline/interface.js.map +1 -0
  45. package/cjs/charts/storyline/layout.d.ts +53 -0
  46. package/cjs/charts/storyline/layout.js +208 -0
  47. package/cjs/charts/storyline/layout.js.map +1 -0
  48. package/cjs/charts/storyline/layouts/arc.d.ts +5 -0
  49. package/cjs/charts/storyline/layouts/arc.js +295 -0
  50. package/cjs/charts/storyline/layouts/arc.js.map +1 -0
  51. package/cjs/charts/storyline/layouts/clock.d.ts +5 -0
  52. package/cjs/charts/storyline/layouts/clock.js +246 -0
  53. package/cjs/charts/storyline/layouts/clock.js.map +1 -0
  54. package/cjs/charts/storyline/layouts/common.d.ts +89 -0
  55. package/cjs/charts/storyline/layouts/common.js +291 -0
  56. package/cjs/charts/storyline/layouts/common.js.map +1 -0
  57. package/cjs/charts/storyline/layouts/default.d.ts +4 -0
  58. package/cjs/charts/storyline/layouts/default.js +181 -0
  59. package/cjs/charts/storyline/layouts/default.js.map +1 -0
  60. package/cjs/charts/storyline/layouts/ladder.d.ts +5 -0
  61. package/cjs/charts/storyline/layouts/ladder.js +205 -0
  62. package/cjs/charts/storyline/layouts/ladder.js.map +1 -0
  63. package/cjs/charts/storyline/layouts/landscape.d.ts +4 -0
  64. package/cjs/charts/storyline/layouts/landscape.js +256 -0
  65. package/cjs/charts/storyline/layouts/landscape.js.map +1 -0
  66. package/cjs/charts/storyline/layouts/portrait.d.ts +4 -0
  67. package/cjs/charts/storyline/layouts/portrait.js +214 -0
  68. package/cjs/charts/storyline/layouts/portrait.js.map +1 -0
  69. package/cjs/charts/storyline/layouts/wing.d.ts +4 -0
  70. package/cjs/charts/storyline/layouts/wing.js +215 -0
  71. package/cjs/charts/storyline/layouts/wing.js.map +1 -0
  72. package/cjs/charts/storyline/storyline-transformer.d.ts +4 -0
  73. package/cjs/charts/storyline/storyline-transformer.js +78 -0
  74. package/cjs/charts/storyline/storyline-transformer.js.map +1 -0
  75. package/cjs/charts/storyline/storyline.d.ts +16 -0
  76. package/cjs/charts/storyline/storyline.js +36 -0
  77. package/cjs/charts/storyline/storyline.js.map +1 -0
  78. package/cjs/components/bar-link/bar-link.js +1 -1
  79. package/cjs/components/bar-link/constant.js +1 -1
  80. package/cjs/components/bar-link/index.js +1 -1
  81. package/cjs/components/bar-link/type.js +1 -1
  82. package/cjs/components/bar-link/util.js +1 -1
  83. package/cjs/components/bar-regression-line/index.js +1 -1
  84. package/cjs/components/bar-regression-line/type.js +1 -1
  85. package/cjs/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  86. package/cjs/components/extension-mark-sync-state/index.js +1 -1
  87. package/cjs/components/extension-mark-sync-state/type.js +1 -1
  88. package/cjs/components/histogram-regression-line/index.js +1 -1
  89. package/cjs/components/histogram-regression-line/type.js +1 -1
  90. package/cjs/components/map-label/index.js +1 -1
  91. package/cjs/components/map-label/layout.js +1 -1
  92. package/cjs/components/map-label/map-label-transformer.js +2 -1
  93. package/cjs/components/map-label/map-label.d.ts +1 -1
  94. package/cjs/components/map-label/map-label.js +1 -1
  95. package/cjs/components/map-label/theme.js +1 -1
  96. package/cjs/components/map-label/type.js +1 -1
  97. package/cjs/components/regression-line/index.js +1 -1
  98. package/cjs/components/regression-line/regression-line.js +1 -1
  99. package/cjs/components/regression-line/type.js +1 -1
  100. package/cjs/components/scatter-regression-line/index.js +1 -1
  101. package/cjs/components/scatter-regression-line/type.js +1 -1
  102. package/cjs/components/series-break/constant.js +1 -1
  103. package/cjs/components/series-break/index.js +1 -1
  104. package/cjs/components/series-break/series-break.js +1 -1
  105. package/cjs/components/series-break/type.js +1 -1
  106. package/cjs/components/series-break/util.js +2 -1
  107. package/cjs/components/series-label/constant.js +1 -1
  108. package/cjs/components/series-label/index.js +1 -1
  109. package/cjs/components/series-label/series-label.js +1 -1
  110. package/cjs/components/series-label/type.js +1 -1
  111. package/cjs/components/series-label/util.js +1 -1
  112. package/cjs/index.d.ts +1 -0
  113. package/cjs/index.js +5 -5
  114. package/cjs/index.js.map +1 -1
  115. package/esm/charts/axis-3d/index.js +2 -1
  116. package/esm/charts/axis-3d/linear-axis.js +1 -2
  117. package/esm/charts/bar-3d/chart-spec-transformer.js +1 -1
  118. package/esm/charts/bar-3d/chart.js +1 -1
  119. package/esm/charts/bar-3d/constant.js +1 -1
  120. package/esm/charts/bar-3d/index.js +1 -1
  121. package/esm/charts/bar-3d/interface.js +1 -1
  122. package/esm/charts/bar-3d/series-spec-transformer.js +1 -1
  123. package/esm/charts/bar-3d/series.js +1 -1
  124. package/esm/charts/bar-3d/theme.js +1 -1
  125. package/esm/charts/candlestick/candlestick-transformer.js +1 -1
  126. package/esm/charts/candlestick/candlestick.js +1 -2
  127. package/esm/charts/candlestick/index.js +1 -1
  128. package/esm/charts/candlestick/interface.js +1 -1
  129. package/esm/charts/candlestick/util.js +1 -1
  130. package/esm/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  131. package/esm/charts/combination-candlestick/combination-candlestick.js +1 -1
  132. package/esm/charts/combination-candlestick/constant.js +1 -1
  133. package/esm/charts/combination-candlestick/index.js +1 -1
  134. package/esm/charts/combination-candlestick/interface.js +1 -1
  135. package/esm/charts/conversion-funnel/arrow-data-transform.js +1 -1
  136. package/esm/charts/conversion-funnel/constants.js +1 -1
  137. package/esm/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  138. package/esm/charts/conversion-funnel/conversion-funnel.js +1 -1
  139. package/esm/charts/conversion-funnel/index.js +1 -1
  140. package/esm/charts/conversion-funnel/interface.js +1 -1
  141. package/esm/charts/conversion-funnel/util.js +1 -1
  142. package/esm/charts/funnel-3d/chart.js +1 -2
  143. package/esm/charts/funnel-3d/constant.js +1 -1
  144. package/esm/charts/funnel-3d/index.js +1 -1
  145. package/esm/charts/funnel-3d/interface.js +1 -1
  146. package/esm/charts/funnel-3d/series-spec-transformer.js +1 -1
  147. package/esm/charts/funnel-3d/series.js +1 -1
  148. package/esm/charts/funnel-3d/theme.js +1 -1
  149. package/esm/charts/histogram-3d/chart.js +1 -1
  150. package/esm/charts/image-cloud/series/image-cloud.d.ts +1 -1
  151. package/esm/charts/storyline/index.d.ts +4 -0
  152. package/esm/charts/storyline/index.js +8 -0
  153. package/esm/charts/storyline/index.js.map +1 -0
  154. package/esm/charts/storyline/interface.d.ts +67 -0
  155. package/esm/charts/storyline/interface.js +2 -0
  156. package/esm/charts/storyline/interface.js.map +1 -0
  157. package/esm/charts/storyline/layout.d.ts +53 -0
  158. package/esm/charts/storyline/layout.js +198 -0
  159. package/esm/charts/storyline/layout.js.map +1 -0
  160. package/esm/charts/storyline/layouts/arc.d.ts +5 -0
  161. package/esm/charts/storyline/layouts/arc.js +286 -0
  162. package/esm/charts/storyline/layouts/arc.js.map +1 -0
  163. package/esm/charts/storyline/layouts/clock.d.ts +5 -0
  164. package/esm/charts/storyline/layouts/clock.js +240 -0
  165. package/esm/charts/storyline/layouts/clock.js.map +1 -0
  166. package/esm/charts/storyline/layouts/common.d.ts +89 -0
  167. package/esm/charts/storyline/layouts/common.js +257 -0
  168. package/esm/charts/storyline/layouts/common.js.map +1 -0
  169. package/esm/charts/storyline/layouts/default.d.ts +4 -0
  170. package/esm/charts/storyline/layouts/default.js +174 -0
  171. package/esm/charts/storyline/layouts/default.js.map +1 -0
  172. package/esm/charts/storyline/layouts/ladder.d.ts +5 -0
  173. package/esm/charts/storyline/layouts/ladder.js +196 -0
  174. package/esm/charts/storyline/layouts/ladder.js.map +1 -0
  175. package/esm/charts/storyline/layouts/landscape.d.ts +4 -0
  176. package/esm/charts/storyline/layouts/landscape.js +252 -0
  177. package/esm/charts/storyline/layouts/landscape.js.map +1 -0
  178. package/esm/charts/storyline/layouts/portrait.d.ts +4 -0
  179. package/esm/charts/storyline/layouts/portrait.js +211 -0
  180. package/esm/charts/storyline/layouts/portrait.js.map +1 -0
  181. package/esm/charts/storyline/layouts/wing.d.ts +4 -0
  182. package/esm/charts/storyline/layouts/wing.js +210 -0
  183. package/esm/charts/storyline/layouts/wing.js.map +1 -0
  184. package/esm/charts/storyline/storyline-transformer.d.ts +4 -0
  185. package/esm/charts/storyline/storyline-transformer.js +76 -0
  186. package/esm/charts/storyline/storyline-transformer.js.map +1 -0
  187. package/esm/charts/storyline/storyline.d.ts +16 -0
  188. package/esm/charts/storyline/storyline.js +29 -0
  189. package/esm/charts/storyline/storyline.js.map +1 -0
  190. package/esm/components/bar-link/bar-link.js +1 -1
  191. package/esm/components/bar-link/constant.js +1 -1
  192. package/esm/components/bar-link/index.js +1 -1
  193. package/esm/components/bar-link/type.js +1 -1
  194. package/esm/components/bar-link/util.js +1 -1
  195. package/esm/components/bar-regression-line/index.js +1 -1
  196. package/esm/components/bar-regression-line/type.js +1 -1
  197. package/esm/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  198. package/esm/components/extension-mark-sync-state/index.js +1 -1
  199. package/esm/components/extension-mark-sync-state/type.js +1 -1
  200. package/esm/components/histogram-regression-line/index.js +1 -1
  201. package/esm/components/histogram-regression-line/type.js +1 -1
  202. package/esm/components/map-label/index.js +1 -1
  203. package/esm/components/map-label/layout.js +1 -1
  204. package/esm/components/map-label/map-label-transformer.js +2 -1
  205. package/esm/components/map-label/map-label.d.ts +1 -1
  206. package/esm/components/map-label/map-label.js +1 -1
  207. package/esm/components/map-label/theme.js +1 -1
  208. package/esm/components/map-label/type.js +1 -1
  209. package/esm/components/regression-line/index.js +1 -1
  210. package/esm/components/regression-line/regression-line.js +1 -1
  211. package/esm/components/regression-line/type.js +1 -1
  212. package/esm/components/scatter-regression-line/index.js +1 -1
  213. package/esm/components/scatter-regression-line/type.js +1 -1
  214. package/esm/components/series-break/constant.js +1 -1
  215. package/esm/components/series-break/index.js +1 -1
  216. package/esm/components/series-break/series-break.js +1 -1
  217. package/esm/components/series-break/type.js +1 -1
  218. package/esm/components/series-break/util.js +2 -1
  219. package/esm/components/series-label/constant.js +1 -1
  220. package/esm/components/series-label/index.js +1 -1
  221. package/esm/components/series-label/series-label.js +1 -1
  222. package/esm/components/series-label/type.js +1 -1
  223. package/esm/components/series-label/util.js +1 -1
  224. package/esm/index.d.ts +1 -0
  225. package/esm/index.js +2 -0
  226. package/esm/index.js.map +1 -1
  227. package/package.json +8 -8
package/build/index.js CHANGED
@@ -5822,6 +5822,2151 @@
5822
5822
  vchart.Factory.registerChart(TimelineChart.type, TimelineChart);
5823
5823
  };
5824
5824
 
5825
+ const DEFAULT_LAYOUT = 'landscape';
5826
+ const DEFAULT_PADDING = 24;
5827
+ const normalizePadding = (padding) => {
5828
+ var _a, _b, _c, _d;
5829
+ if (Array.isArray(padding)) {
5830
+ return {
5831
+ top: (_a = padding[0]) !== null && _a !== void 0 ? _a : 0,
5832
+ right: (_b = padding[1]) !== null && _b !== void 0 ? _b : 0,
5833
+ bottom: (_c = padding[2]) !== null && _c !== void 0 ? _c : 0,
5834
+ left: (_d = padding[3]) !== null && _d !== void 0 ? _d : 0
5835
+ };
5836
+ }
5837
+ const value = padding !== null && padding !== void 0 ? padding : DEFAULT_PADDING;
5838
+ return { top: value, right: value, bottom: value, left: value };
5839
+ };
5840
+ const normalizeLayout = (layout) => {
5841
+ if (!layout) {
5842
+ return { type: DEFAULT_LAYOUT };
5843
+ }
5844
+ if (typeof layout === 'string') {
5845
+ return { type: layout };
5846
+ }
5847
+ return layout;
5848
+ };
5849
+ const computeStorylineLayout = (data, options) => {
5850
+ var _a, _b, _c;
5851
+ const layout = normalizeLayout(options.layout);
5852
+ const padding = normalizePadding((_a = layout.padding) !== null && _a !== void 0 ? _a : options.padding);
5853
+ const gap = (_b = options.gap) !== null && _b !== void 0 ? _b : 40;
5854
+ const lineDistance = (_c = options.lineDistance) !== null && _c !== void 0 ? _c : 8;
5855
+ const blocks = computeBlockPositions(data, layout, options.viewBox, options.block, padding, gap);
5856
+ const circleGuide = layout.type === 'clock' ? computeClockCircleGuide(options.viewBox, options.block, padding, layout) : undefined;
5857
+ return {
5858
+ blocks,
5859
+ links: computeLinks(blocks, lineDistance),
5860
+ circleGuide
5861
+ };
5862
+ };
5863
+ const computeBlockPositions = (data, layout, viewBox, block, padding, gap) => {
5864
+ const count = data.length;
5865
+ if (!count) {
5866
+ return [];
5867
+ }
5868
+ const inner = {
5869
+ x: padding.left,
5870
+ y: padding.top,
5871
+ width: Math.max(viewBox.width - padding.left - padding.right, block.width),
5872
+ height: Math.max(viewBox.height - padding.top - padding.bottom, block.height)
5873
+ };
5874
+ const center = {
5875
+ x: inner.x + inner.width / 2,
5876
+ y: inner.y + inner.height / 2
5877
+ };
5878
+ let centers;
5879
+ switch (layout.type) {
5880
+ case 'portrait':
5881
+ centers = lineCenters(count, center.x, inner.y + block.height / 2, center.x, inner.y + inner.height - block.height / 2);
5882
+ break;
5883
+ case 'ladder': {
5884
+ const isDown = layout.direction === 'down';
5885
+ const x0 = inner.x + block.width / 2;
5886
+ const x1 = inner.x + inner.width - block.width / 2;
5887
+ const yTop = inner.y + block.height / 2;
5888
+ const yBot = inner.y + inner.height - block.height / 2;
5889
+ const y0 = isDown ? yTop : yBot;
5890
+ const y1 = isDown ? yBot : yTop;
5891
+ const anchors = lineCenters(count, x0, y0, x1, y1);
5892
+ const dx = x1 - x0;
5893
+ const dy = y1 - y0;
5894
+ const len = Math.hypot(dx, dy) || 1;
5895
+ const nx = -dy / len;
5896
+ const ny = dx / len;
5897
+ const headlineFontSize = Math.max(80, Math.min(240, Math.round(inner.height * 0.42)));
5898
+ const offset = headlineFontSize * 1.2;
5899
+ centers = anchors.map((p, i) => {
5900
+ const sign = i % 2 === 0 ? 1 : -1;
5901
+ return {
5902
+ x: p.x + nx * offset * sign,
5903
+ y: p.y + ny * offset * sign
5904
+ };
5905
+ });
5906
+ break;
5907
+ }
5908
+ case 'spiral':
5909
+ centers = alternatingVerticalCenters(count, inner, block, gap);
5910
+ break;
5911
+ case 'clock':
5912
+ centers = circularCenters(count, viewBox, block, padding, layout);
5913
+ break;
5914
+ case 'arc': {
5915
+ const isDown = layout.direction === 'down';
5916
+ const [s, e] = isDown ? [20, 160] : [200, 340];
5917
+ centers = arcCenters(count, inner, block, layout, s, e);
5918
+ break;
5919
+ }
5920
+ case 'wing': {
5921
+ const direction = layout.direction === 'right' ? 'right' : 'left';
5922
+ const [s, e] = direction === 'right' ? [110, 250] : [-70, 70];
5923
+ centers = arcCenters(count, inner, block, layout, s, e);
5924
+ break;
5925
+ }
5926
+ case 'landscape':
5927
+ default:
5928
+ centers = lineCenters(count, inner.x + block.width / 2, center.y, inner.x + inner.width - block.width / 2, center.y);
5929
+ break;
5930
+ }
5931
+ return centers.map((point, index) => {
5932
+ var _a, _b;
5933
+ return ({
5934
+ id: (_b = (_a = data[index]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : index,
5935
+ index,
5936
+ datum: data[index],
5937
+ width: block.width,
5938
+ height: block.height,
5939
+ x: point.x - block.width / 2,
5940
+ y: point.y - block.height / 2,
5941
+ center: point
5942
+ });
5943
+ });
5944
+ };
5945
+ const lineCenters = (count, x0, y0, x1, y1) => {
5946
+ if (count === 1) {
5947
+ return [{ x: (x0 + x1) / 2, y: (y0 + y1) / 2 }];
5948
+ }
5949
+ return Array.from({ length: count }, (_, index) => {
5950
+ const t = index / (count - 1);
5951
+ return {
5952
+ x: x0 + (x1 - x0) * t,
5953
+ y: y0 + (y1 - y0) * t
5954
+ };
5955
+ });
5956
+ };
5957
+ const alternatingVerticalCenters = (count, inner, block, gap) => {
5958
+ const baseX = inner.x + inner.width / 2;
5959
+ const offset = Math.min(Math.max(block.width * 0.65 + gap / 2, 0), Math.max((inner.width - block.width) / 2, 0));
5960
+ const points = lineCenters(count, baseX, inner.y + block.height / 2, baseX, inner.y + inner.height - block.height / 2);
5961
+ return points.map((point, index) => ({
5962
+ x: point.x + (index % 2 === 0 ? -offset : offset),
5963
+ y: point.y
5964
+ }));
5965
+ };
5966
+ const circularCenters = (count, viewBox, block, padding, layout) => {
5967
+ var _a;
5968
+ const guide = computeClockCircleGuide(viewBox, block, padding, layout);
5969
+ const startAngle = (_a = layout.startAngle) !== null && _a !== void 0 ? _a : -90;
5970
+ const delta = 360;
5971
+ if (count === 1) {
5972
+ const angle = degreeToRadian(startAngle);
5973
+ return [
5974
+ {
5975
+ x: guide.center.x + Math.cos(angle) * guide.radius,
5976
+ y: guide.center.y + Math.sin(angle) * guide.radius
5977
+ }
5978
+ ];
5979
+ }
5980
+ return Array.from({ length: count }, (_, index) => {
5981
+ const angle = degreeToRadian(startAngle + (delta * index) / count);
5982
+ return {
5983
+ x: guide.center.x + Math.cos(angle) * guide.radius,
5984
+ y: guide.center.y + Math.sin(angle) * guide.radius
5985
+ };
5986
+ });
5987
+ };
5988
+ const computeClockCircleGuide = (viewBox, block, padding, layout) => {
5989
+ var _a;
5990
+ const innerWidth = Math.max(viewBox.width - padding.left - padding.right, 1);
5991
+ const innerHeight = Math.max(viewBox.height - padding.top - padding.bottom, 1);
5992
+ const center = {
5993
+ x: padding.left + innerWidth / 2,
5994
+ y: padding.top + innerHeight / 2
5995
+ };
5996
+ const ratio = (_a = layout.radiusRatio) !== null && _a !== void 0 ? _a : 0.7;
5997
+ const maxRadius = Math.max(Math.min(innerWidth - block.width, innerHeight - block.height) / 2, 1);
5998
+ return {
5999
+ center,
6000
+ radius: Math.max(1, maxRadius * ratio)
6001
+ };
6002
+ };
6003
+ const arcCenters = (count, inner, block, layout, fallbackStartAngle, fallbackEndAngle, defaultRatio = 0.88) => {
6004
+ var _a, _b, _c, _d, _e;
6005
+ const startAngle = (_b = (_a = layout.startAngle) !== null && _a !== void 0 ? _a : fallbackStartAngle) !== null && _b !== void 0 ? _b : -90;
6006
+ const endAngle = (_d = (_c = layout.endAngle) !== null && _c !== void 0 ? _c : fallbackEndAngle) !== null && _d !== void 0 ? _d : 270;
6007
+ const ratio = (_e = layout.radiusRatio) !== null && _e !== void 0 ? _e : defaultRatio;
6008
+ const rx = Math.max((inner.width - block.width) / 2, 1) * ratio;
6009
+ const ry = Math.max((inner.height - block.height) / 2, 1) * ratio;
6010
+ const center = {
6011
+ x: inner.x + inner.width / 2,
6012
+ y: inner.y + inner.height / 2
6013
+ };
6014
+ if (count === 1) {
6015
+ const angle = degreeToRadian((startAngle + endAngle) / 2);
6016
+ return [{ x: center.x + Math.cos(angle) * rx, y: center.y + Math.sin(angle) * ry }];
6017
+ }
6018
+ return Array.from({ length: count }, (_, index) => {
6019
+ const t = index / (count - 1);
6020
+ const angle = degreeToRadian(startAngle + angleDelta(startAngle, endAngle) * t);
6021
+ return {
6022
+ x: center.x + Math.cos(angle) * rx,
6023
+ y: center.y + Math.sin(angle) * ry
6024
+ };
6025
+ });
6026
+ };
6027
+ const angleDelta = (startAngle, endAngle) => {
6028
+ const delta = endAngle - startAngle;
6029
+ return Math.abs(delta) >= 360 ? 360 : delta;
6030
+ };
6031
+ const degreeToRadian = (degree) => (degree / 180) * Math.PI;
6032
+ const computeLinks = (blocks, distance) => {
6033
+ const links = [];
6034
+ for (let i = 0; i < blocks.length - 1; i++) {
6035
+ const from = blocks[i];
6036
+ const to = blocks[i + 1];
6037
+ const start = pointOnBlockEdge(from, to.center, distance);
6038
+ const end = pointOnBlockEdge(to, from.center, distance);
6039
+ links.push({
6040
+ from,
6041
+ to,
6042
+ start,
6043
+ end,
6044
+ points: [start, end]
6045
+ });
6046
+ }
6047
+ return links;
6048
+ };
6049
+ const pointOnBlockEdge = (block, toward, distance) => {
6050
+ const dx = toward.x - block.center.x;
6051
+ const dy = toward.y - block.center.y;
6052
+ if (dx === 0 && dy === 0) {
6053
+ return { x: block.center.x, y: block.center.y };
6054
+ }
6055
+ const scaleX = dx === 0 ? Number.POSITIVE_INFINITY : block.width / 2 / Math.abs(dx);
6056
+ const scaleY = dy === 0 ? Number.POSITIVE_INFINITY : block.height / 2 / Math.abs(dy);
6057
+ const scale = Math.min(scaleX, scaleY);
6058
+ const length = Math.sqrt(dx * dx + dy * dy) || 1;
6059
+ return {
6060
+ x: block.center.x + dx * scale + (dx / length) * distance,
6061
+ y: block.center.y + dy * scale + (dy / length) * distance
6062
+ };
6063
+ };
6064
+
6065
+ const DEFAULT_BLOCK_WIDTH = 180;
6066
+ const DEFAULT_BLOCK_HEIGHT = 400;
6067
+ const DEFAULT_BLOCK_WIDTH_RATIO = 0.24;
6068
+ const DEFAULT_BLOCK_GAP = 36;
6069
+ const DEFAULT_IMAGE_WIDTH = 48;
6070
+ const DEFAULT_IMAGE_HEIGHT = 48;
6071
+ const DEFAULT_IMAGE_GAP = 10;
6072
+ const DEFAULT_THEME_COLOR = '#e8543d';
6073
+ const isLandscape = (spec) => normalizeLayout(spec.layout).type === 'landscape';
6074
+ const isPortrait = (spec) => normalizeLayout(spec.layout).type === 'portrait';
6075
+ const isClock = (spec) => normalizeLayout(spec.layout).type === 'clock';
6076
+ const isArc = (spec) => normalizeLayout(spec.layout).type === 'arc';
6077
+ const isWing = (spec) => normalizeLayout(spec.layout).type === 'wing';
6078
+ const isLadder = (spec) => normalizeLayout(spec.layout).type === 'ladder';
6079
+ const getThemeColor = (spec) => { var _a; return (_a = spec.themeColor) !== null && _a !== void 0 ? _a : DEFAULT_THEME_COLOR; };
6080
+ const withAlpha = (color, alpha) => {
6081
+ const safeAlpha = Math.max(0, Math.min(1, alpha));
6082
+ if (!color) {
6083
+ return `rgba(0, 0, 0, ${safeAlpha})`;
6084
+ }
6085
+ const trimmed = color.trim();
6086
+ if (trimmed.startsWith('#')) {
6087
+ let hex = trimmed.slice(1);
6088
+ if (hex.length === 3 || hex.length === 4) {
6089
+ hex = hex
6090
+ .split('')
6091
+ .map(ch => ch + ch)
6092
+ .join('');
6093
+ }
6094
+ if (hex.length === 6 || hex.length === 8) {
6095
+ const r = parseInt(hex.slice(0, 2), 16);
6096
+ const g = parseInt(hex.slice(2, 4), 16);
6097
+ const b = parseInt(hex.slice(4, 6), 16);
6098
+ return `rgba(${r}, ${g}, ${b}, ${safeAlpha})`;
6099
+ }
6100
+ }
6101
+ const rgbMatch = trimmed.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);
6102
+ if (rgbMatch) {
6103
+ return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${safeAlpha})`;
6104
+ }
6105
+ return trimmed;
6106
+ };
6107
+ const resolveBlockWidth = (spec, viewWidth) => {
6108
+ var _a, _b, _c, _d, _e, _f, _g;
6109
+ if ((_a = spec.block) === null || _a === void 0 ? void 0 : _a.width) {
6110
+ return spec.block.width;
6111
+ }
6112
+ const ratio = (_c = (_b = spec.block) === null || _b === void 0 ? void 0 : _b.widthRatio) !== null && _c !== void 0 ? _c : DEFAULT_BLOCK_WIDTH_RATIO;
6113
+ const minWidth = (_e = (_d = spec.block) === null || _d === void 0 ? void 0 : _d.minWidth) !== null && _e !== void 0 ? _e : DEFAULT_BLOCK_WIDTH;
6114
+ const maxWidth = (_g = (_f = spec.block) === null || _f === void 0 ? void 0 : _f.maxWidth) !== null && _g !== void 0 ? _g : Math.max(minWidth, 320);
6115
+ return Math.max(minWidth, Math.min(maxWidth, Math.round(viewWidth * ratio)));
6116
+ };
6117
+ const getRegionGeometry = (ctx) => {
6118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6119
+ const region = (_c = (_b = (_a = ctx.chart) === null || _a === void 0 ? void 0 : _a.getAllRegions) === null || _b === void 0 ? void 0 : _b.call(_a)) === null || _c === void 0 ? void 0 : _c[0];
6120
+ const regionRect = (_d = region === null || region === void 0 ? void 0 : region.getLayoutRect) === null || _d === void 0 ? void 0 : _d.call(region);
6121
+ const regionStart = (_e = region === null || region === void 0 ? void 0 : region.getLayoutStartPoint) === null || _e === void 0 ? void 0 : _e.call(region);
6122
+ const chartRect = (_g = (_f = ctx.chart) === null || _f === void 0 ? void 0 : _f.getLayoutRect) === null || _g === void 0 ? void 0 : _g.call(_f);
6123
+ const bounds = (_h = ctx.getLayoutBounds) === null || _h === void 0 ? void 0 : _h.call(ctx);
6124
+ const width = Math.max((_m = (_k = (_j = regionRect === null || regionRect === void 0 ? void 0 : regionRect.width) !== null && _j !== void 0 ? _j : chartRect === null || chartRect === void 0 ? void 0 : chartRect.width) !== null && _k !== void 0 ? _k : (_l = bounds === null || bounds === void 0 ? void 0 : bounds.width) === null || _l === void 0 ? void 0 : _l.call(bounds)) !== null && _m !== void 0 ? _m : 0, 1);
6125
+ const height = Math.max((_r = (_p = (_o = regionRect === null || regionRect === void 0 ? void 0 : regionRect.height) !== null && _o !== void 0 ? _o : chartRect === null || chartRect === void 0 ? void 0 : chartRect.height) !== null && _p !== void 0 ? _p : (_q = bounds === null || bounds === void 0 ? void 0 : bounds.height) === null || _q === void 0 ? void 0 : _q.call(bounds)) !== null && _r !== void 0 ? _r : 0, 1);
6126
+ return {
6127
+ width,
6128
+ height,
6129
+ startX: (_s = regionStart === null || regionStart === void 0 ? void 0 : regionStart.x) !== null && _s !== void 0 ? _s : 0,
6130
+ startY: (_t = regionStart === null || regionStart === void 0 ? void 0 : regionStart.y) !== null && _t !== void 0 ? _t : 0
6131
+ };
6132
+ };
6133
+ const getLayout = (spec, ctx) => {
6134
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
6135
+ const { width, height, startX, startY } = getRegionGeometry(ctx);
6136
+ let blockWidth = resolveBlockWidth(spec, width);
6137
+ let blockHeight = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : DEFAULT_BLOCK_HEIGHT;
6138
+ if (isLandscape(spec) && !((_c = spec.block) === null || _c === void 0 ? void 0 : _c.width)) {
6139
+ const count = (_e = (_d = spec.data) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0;
6140
+ if (count > 0) {
6141
+ const padding = normalizePadding((_f = spec.block) === null || _f === void 0 ? void 0 : _f.padding);
6142
+ const innerWidth = Math.max(width - padding.left - padding.right, 1);
6143
+ const LANDSCAPE_IMAGE_GAP = 40;
6144
+ const LANDSCAPE_IMAGE_MIN_WIDTH = 80;
6145
+ const totalGap = LANDSCAPE_IMAGE_GAP * Math.max(count - 1, 0);
6146
+ const adaptive = (innerWidth - totalGap) / count;
6147
+ blockWidth = Math.max(LANDSCAPE_IMAGE_MIN_WIDTH, Math.floor(adaptive));
6148
+ }
6149
+ }
6150
+ if (isPortrait(spec) && !((_g = spec.block) === null || _g === void 0 ? void 0 : _g.height)) {
6151
+ const count = (_j = (_h = spec.data) === null || _h === void 0 ? void 0 : _h.length) !== null && _j !== void 0 ? _j : 0;
6152
+ if (count > 0) {
6153
+ const padding = normalizePadding((_k = spec.block) === null || _k === void 0 ? void 0 : _k.padding);
6154
+ const innerHeight = Math.max(height - padding.top - padding.bottom, 1);
6155
+ blockHeight = Math.max(DEFAULT_BLOCK_HEIGHT, Math.floor(innerHeight / count));
6156
+ }
6157
+ }
6158
+ const result = computeStorylineLayout((_l = spec.data) !== null && _l !== void 0 ? _l : [], {
6159
+ layout: spec.layout,
6160
+ viewBox: { width, height },
6161
+ block: {
6162
+ width: blockWidth,
6163
+ height: blockHeight
6164
+ },
6165
+ gap: (_o = (_m = spec.block) === null || _m === void 0 ? void 0 : _m.gap) !== null && _o !== void 0 ? _o : DEFAULT_BLOCK_GAP,
6166
+ padding: (_p = spec.block) === null || _p === void 0 ? void 0 : _p.padding,
6167
+ lineDistance: (_q = spec.line) === null || _q === void 0 ? void 0 : _q.distance
6168
+ });
6169
+ if (!startX && !startY) {
6170
+ return result;
6171
+ }
6172
+ return Object.assign(Object.assign({}, result), { blocks: result.blocks.map(block => (Object.assign(Object.assign({}, block), { x: block.x + startX, y: block.y + startY, center: {
6173
+ x: block.center.x + startX,
6174
+ y: block.center.y + startY
6175
+ } }))), 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 })) }))) });
6176
+ };
6177
+ const buildRichContent = (contentText, spec) => {
6178
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
6179
+ const fontSize = 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 : 12);
6180
+ const lineHeight = Number((_f = (_e = (_d = spec.content) === null || _d === void 0 ? void 0 : _d.style) === null || _e === void 0 ? void 0 : _e.lineHeight) !== null && _f !== void 0 ? _f : 18);
6181
+ const fill = (_j = (_h = (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.fill) !== null && _j !== void 0 ? _j : '#596173';
6182
+ return {
6183
+ type: 'rich',
6184
+ text: contentText.reduce((result, paragraph, index) => {
6185
+ const suffix = index === contentText.length - 1 ? '' : '\n';
6186
+ result.push({
6187
+ text: `${paragraph}${suffix}`,
6188
+ fontSize,
6189
+ lineHeight,
6190
+ fill
6191
+ });
6192
+ return result;
6193
+ }, [])
6194
+ };
6195
+ };
6196
+ const omitImageLayoutSpec = (imageSpec) => {
6197
+ if (!imageSpec) {
6198
+ return {};
6199
+ }
6200
+ const rest = __rest(imageSpec, ["width", "height", "position", "gap"]);
6201
+ return rest;
6202
+ };
6203
+ const getImageBox = (position, blockWidth, blockHeight, padding, width, height, _gap, visible) => {
6204
+ if (!visible) {
6205
+ return { x: padding.left, y: padding.top, width: 0, height: 0 };
6206
+ }
6207
+ switch (position) {
6208
+ case 'left':
6209
+ return { x: padding.left, y: (blockHeight - height) / 2, width, height };
6210
+ case 'right':
6211
+ return { x: blockWidth - padding.right - width, y: (blockHeight - height) / 2, width, height };
6212
+ case 'bottom':
6213
+ return { x: (blockWidth - width) / 2, y: blockHeight - padding.bottom - height, width, height };
6214
+ case 'top':
6215
+ default:
6216
+ return { x: (blockWidth - width) / 2, y: padding.top, width, height };
6217
+ }
6218
+ };
6219
+ const getTextBox = (position, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage) => {
6220
+ if (!hasImage) {
6221
+ return {
6222
+ x: padding.left,
6223
+ y: padding.top,
6224
+ width: blockWidth - padding.left - padding.right,
6225
+ height: blockHeight - padding.top - padding.bottom
6226
+ };
6227
+ }
6228
+ switch (position) {
6229
+ case 'left':
6230
+ return {
6231
+ x: padding.left + imageWidth + imageGap,
6232
+ y: padding.top,
6233
+ width: blockWidth - padding.left - padding.right - imageWidth - imageGap,
6234
+ height: blockHeight - padding.top - padding.bottom
6235
+ };
6236
+ case 'right':
6237
+ return {
6238
+ x: padding.left,
6239
+ y: padding.top,
6240
+ width: blockWidth - padding.left - padding.right - imageWidth - imageGap,
6241
+ height: blockHeight - padding.top - padding.bottom
6242
+ };
6243
+ case 'bottom':
6244
+ return {
6245
+ x: padding.left,
6246
+ y: padding.top,
6247
+ width: blockWidth - padding.left - padding.right,
6248
+ height: blockHeight - padding.top - padding.bottom - imageHeight - imageGap
6249
+ };
6250
+ case 'top':
6251
+ default:
6252
+ return {
6253
+ x: padding.left,
6254
+ y: padding.top + imageHeight + imageGap,
6255
+ width: blockWidth - padding.left - padding.right,
6256
+ height: blockHeight - padding.top - padding.bottom - imageHeight - imageGap
6257
+ };
6258
+ }
6259
+ };
6260
+ const buildSmoothCurvePath = (points) => {
6261
+ var _a, _b;
6262
+ if (points.length < 2) {
6263
+ return '';
6264
+ }
6265
+ if (points.length === 2) {
6266
+ return `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y}`;
6267
+ }
6268
+ let d = `M ${points[0].x} ${points[0].y}`;
6269
+ for (let i = 0; i < points.length - 1; i++) {
6270
+ const p0 = (_a = points[i - 1]) !== null && _a !== void 0 ? _a : points[i];
6271
+ const p1 = points[i];
6272
+ const p2 = points[i + 1];
6273
+ const p3 = (_b = points[i + 2]) !== null && _b !== void 0 ? _b : p2;
6274
+ const c1x = p1.x + (p2.x - p0.x) / 6;
6275
+ const c1y = p1.y + (p2.y - p0.y) / 6;
6276
+ const c2x = p2.x - (p3.x - p1.x) / 6;
6277
+ const c2y = p2.y - (p3.y - p1.y) / 6;
6278
+ d += ` C ${c1x} ${c1y}, ${c2x} ${c2y}, ${p2.x} ${p2.y}`;
6279
+ }
6280
+ return d;
6281
+ };
6282
+
6283
+ const CLOCK_CENTER_RADIUS_RATIO = 0.5;
6284
+ const CLOCK_CENTER_IMAGE_INSET_RATIO = 0.86;
6285
+ const CLOCK_ORBIT_RATIO = 0.58;
6286
+ const CLOCK_DOT_RATIO = 0.58;
6287
+ const CLOCK_TEXT_INNER_RATIO = 0.7;
6288
+ const CLOCK_TEXT_MAX_WIDTH = 200;
6289
+ const CLOCK_DOT_DIAMETER_RATIO = 0.24;
6290
+ const CLOCK_LEAD_LINE_GAP = 6;
6291
+ const CLOCK_TEXT_GAP_FROM_LEAD = 8;
6292
+ const CLOCK_ORBIT_DASH = [4, 4];
6293
+ const CLOCK_TITLE_FONT_SIZE = 18;
6294
+ const CLOCK_TITLE_LINE_HEIGHT = 24;
6295
+ const CLOCK_CONTENT_FONT_SIZE = 11;
6296
+ const CLOCK_CONTENT_LINE_HEIGHT = 15;
6297
+ const getClockGeometry = (spec, ctx) => {
6298
+ var _a, _b, _c;
6299
+ const { width, height, startX, startY } = getRegionGeometry(ctx);
6300
+ const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
6301
+ const innerWidth = Math.max(width - padding.left - padding.right, 1);
6302
+ const innerHeight = Math.max(height - padding.top - padding.bottom, 1);
6303
+ const cx = startX + padding.left + innerWidth / 2;
6304
+ const cy = startY + padding.top + innerHeight / 2;
6305
+ const R = Math.max(Math.min(innerWidth, innerHeight) / 2, 1);
6306
+ const count = (_c = (_b = spec.data) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
6307
+ const step = count > 0 ? (Math.PI * 2) / count : 0;
6308
+ return { cx, cy, R, count, step };
6309
+ };
6310
+ const getClockBlockAngle = (geom, index) => -Math.PI / 2 + geom.step * (index + 0.5);
6311
+ const polar = (cx, cy, r, angle) => ({
6312
+ x: cx + Math.cos(angle) * r,
6313
+ y: cy + Math.sin(angle) * r
6314
+ });
6315
+ const isOnLeftHalf = (angle) => Math.cos(angle) < 0;
6316
+ const buildClockCenterImageMark = (spec) => {
6317
+ var _a, _b, _c, _e;
6318
+ if (((_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.visible) === false) {
6319
+ return null;
6320
+ }
6321
+ const themeColor = getThemeColor(spec);
6322
+ const hasImage = !!((_b = spec.centerImage) === null || _b === void 0 ? void 0 : _b.image);
6323
+ return {
6324
+ type: 'group',
6325
+ name: 'storyline-clock-center',
6326
+ zIndex: vchart.LayoutZIndex.Mark + 2,
6327
+ children: [
6328
+ {
6329
+ type: 'symbol',
6330
+ name: 'storyline-clock-center-halo',
6331
+ interactive: false,
6332
+ style: {
6333
+ x: (_d, ctx) => getClockGeometry(spec, ctx).cx,
6334
+ y: (_d, ctx) => getClockGeometry(spec, ctx).cy,
6335
+ size: (_d, ctx) => {
6336
+ const g = getClockGeometry(spec, ctx);
6337
+ return g.R * CLOCK_CENTER_RADIUS_RATIO * 2.16;
6338
+ },
6339
+ symbolType: 'circle',
6340
+ fill: withAlpha(themeColor, 0.28),
6341
+ stroke: 'transparent'
6342
+ }
6343
+ },
6344
+ hasImage
6345
+ ? {
6346
+ type: 'image',
6347
+ name: 'storyline-clock-center-image',
6348
+ interactive: false,
6349
+ style: Object.assign({ x: (_d, ctx) => {
6350
+ const g = getClockGeometry(spec, ctx);
6351
+ return g.cx - g.R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO;
6352
+ }, y: (_d, ctx) => {
6353
+ const g = getClockGeometry(spec, ctx);
6354
+ return g.cy - g.R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO;
6355
+ }, width: (_d, ctx) => getClockGeometry(spec, ctx).R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO * 2, height: (_d, ctx) => getClockGeometry(spec, ctx).R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO * 2, image: (_c = spec.centerImage) === null || _c === void 0 ? void 0 : _c.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'cover', imagePosition: 'center', anchor: (_d, ctx) => {
6356
+ const g = getClockGeometry(spec, ctx);
6357
+ return [g.cx, g.cy];
6358
+ }, dx: (_d, ctx) => {
6359
+ var _a, _b;
6360
+ const g = getClockGeometry(spec, ctx);
6361
+ const rectW = g.R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO * 2;
6362
+ const userWidth = (_b = (_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.width;
6363
+ const w = typeof userWidth === 'number' ? userWidth : rectW;
6364
+ return (rectW - w) / 2;
6365
+ }, dy: (_d, ctx) => {
6366
+ var _a, _b;
6367
+ const g = getClockGeometry(spec, ctx);
6368
+ const rectH = g.R * CLOCK_CENTER_RADIUS_RATIO * CLOCK_CENTER_IMAGE_INSET_RATIO * 2;
6369
+ const userHeight = (_b = (_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.height;
6370
+ const h = typeof userHeight === 'number' ? userHeight : rectH;
6371
+ return (rectH - h) / 2;
6372
+ } }, (_e = spec.centerImage) === null || _e === void 0 ? void 0 : _e.style)
6373
+ }
6374
+ : {
6375
+ type: 'symbol',
6376
+ name: 'storyline-clock-center-placeholder',
6377
+ interactive: false,
6378
+ style: {
6379
+ x: (_d, ctx) => getClockGeometry(spec, ctx).cx,
6380
+ y: (_d, ctx) => getClockGeometry(spec, ctx).cy,
6381
+ size: (_d, ctx) => getClockGeometry(spec, ctx).R * CLOCK_CENTER_RADIUS_RATIO * 2,
6382
+ symbolType: 'circle',
6383
+ fill: '#ffffff',
6384
+ stroke: themeColor,
6385
+ lineWidth: 2
6386
+ }
6387
+ }
6388
+ ].filter(Boolean)
6389
+ };
6390
+ };
6391
+ const buildClockArcMark = (spec) => {
6392
+ const themeColor = getThemeColor(spec);
6393
+ const orbitPath = (_d, ctx) => {
6394
+ const g = getClockGeometry(spec, ctx);
6395
+ const r = g.R * CLOCK_ORBIT_RATIO;
6396
+ return [
6397
+ `M ${(g.cx + r).toFixed(2)} ${g.cy.toFixed(2)}`,
6398
+ `A ${r.toFixed(2)} ${r.toFixed(2)} 0 1 1 ${(g.cx - r).toFixed(2)} ${g.cy.toFixed(2)}`,
6399
+ `A ${r.toFixed(2)} ${r.toFixed(2)} 0 1 1 ${(g.cx + r).toFixed(2)} ${g.cy.toFixed(2)}`
6400
+ ].join(' ');
6401
+ };
6402
+ return {
6403
+ type: 'group',
6404
+ name: 'storyline-clock-orbit',
6405
+ zIndex: vchart.LayoutZIndex.Mark,
6406
+ children: [
6407
+ {
6408
+ type: 'path',
6409
+ name: 'storyline-clock-orbit-path',
6410
+ interactive: false,
6411
+ style: {
6412
+ path: orbitPath,
6413
+ stroke: withAlpha(themeColor, 0.7),
6414
+ lineWidth: 1,
6415
+ lineDash: CLOCK_ORBIT_DASH,
6416
+ fill: 'transparent',
6417
+ fillOpacity: 0
6418
+ }
6419
+ }
6420
+ ]
6421
+ };
6422
+ };
6423
+ const getClockDotCenter = (spec, ctx, index) => {
6424
+ const g = getClockGeometry(spec, ctx);
6425
+ const angle = getClockBlockAngle(g, index);
6426
+ const r = g.R * CLOCK_DOT_RATIO;
6427
+ return Object.assign(Object.assign({}, polar(g.cx, g.cy, r, angle)), { diameter: g.R * CLOCK_DOT_DIAMETER_RATIO, angle });
6428
+ };
6429
+ const getClockLeadLine = (spec, ctx, index) => {
6430
+ const g = getClockGeometry(spec, ctx);
6431
+ const angle = getClockBlockAngle(g, index);
6432
+ const dotR = (g.R * CLOCK_DOT_DIAMETER_RATIO) / 2;
6433
+ const start = polar(g.cx, g.cy, g.R * CLOCK_DOT_RATIO + dotR + CLOCK_LEAD_LINE_GAP, angle);
6434
+ const end = polar(g.cx, g.cy, g.R * CLOCK_TEXT_INNER_RATIO - CLOCK_TEXT_GAP_FROM_LEAD, angle);
6435
+ return { start, end };
6436
+ };
6437
+ const getClockTextRect = (spec, ctx, index) => {
6438
+ var _a;
6439
+ const g = getClockGeometry(spec, ctx);
6440
+ const { width: regionWidth, startX } = getRegionGeometry(ctx);
6441
+ const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
6442
+ const angle = getClockBlockAngle(g, index);
6443
+ const onLeft = isOnLeftHalf(angle);
6444
+ const rInner = g.R * CLOCK_TEXT_INNER_RATIO;
6445
+ const innerPoint = polar(g.cx, g.cy, rInner, angle);
6446
+ const leftEdge = startX + padding.left;
6447
+ const rightEdge = startX + regionWidth - padding.right;
6448
+ const width = onLeft
6449
+ ? Math.min(Math.max(innerPoint.x - leftEdge, 80), CLOCK_TEXT_MAX_WIDTH)
6450
+ : Math.min(Math.max(rightEdge - innerPoint.x, 80), CLOCK_TEXT_MAX_WIDTH);
6451
+ return { x: innerPoint.x, y: innerPoint.y, width, onLeft, anchorY: innerPoint.y };
6452
+ };
6453
+ const buildClockBlockMark = (spec, block, index) => {
6454
+ var _a, _b, _c;
6455
+ const hasImage = !!block.image;
6456
+ const themeColor = getThemeColor(spec);
6457
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
6458
+ const leadPath = (_d, ctx) => {
6459
+ const { start, end } = getClockLeadLine(spec, ctx, index);
6460
+ return `M ${start.x.toFixed(2)} ${start.y.toFixed(2)} L ${end.x.toFixed(2)} ${end.y.toFixed(2)}`;
6461
+ };
6462
+ const children = [
6463
+ {
6464
+ type: 'path',
6465
+ name: `storyline-clock-lead-${index}`,
6466
+ interactive: false,
6467
+ style: {
6468
+ path: leadPath,
6469
+ stroke: withAlpha(themeColor, 0.7),
6470
+ lineWidth: 1,
6471
+ lineDash: [3, 3],
6472
+ fill: 'transparent',
6473
+ fillOpacity: 0
6474
+ }
6475
+ },
6476
+ hasImage
6477
+ ? {
6478
+ type: 'image',
6479
+ name: `storyline-clock-dot-${index}`,
6480
+ interactive: false,
6481
+ style: {
6482
+ x: (_d, ctx) => {
6483
+ const dot = getClockDotCenter(spec, ctx, index);
6484
+ return dot.x - dot.diameter / 2;
6485
+ },
6486
+ y: (_d, ctx) => {
6487
+ const dot = getClockDotCenter(spec, ctx, index);
6488
+ return dot.y - dot.diameter / 2;
6489
+ },
6490
+ width: (_d, ctx) => getClockDotCenter(spec, ctx, index).diameter,
6491
+ height: (_d, ctx) => getClockDotCenter(spec, ctx, index).diameter,
6492
+ image: block.image,
6493
+ repeatX: 'no-repeat',
6494
+ repeatY: 'no-repeat',
6495
+ imageMode: 'cover',
6496
+ imagePosition: 'center'
6497
+ }
6498
+ }
6499
+ : {
6500
+ type: 'symbol',
6501
+ name: `storyline-clock-dot-${index}`,
6502
+ interactive: false,
6503
+ style: {
6504
+ x: (_d, ctx) => getClockDotCenter(spec, ctx, index).x,
6505
+ y: (_d, ctx) => getClockDotCenter(spec, ctx, index).y,
6506
+ size: (_d, ctx) => getClockDotCenter(spec, ctx, index).diameter,
6507
+ symbolType: 'circle',
6508
+ fill: themeColor,
6509
+ stroke: '#ffffff',
6510
+ lineWidth: 1.5
6511
+ }
6512
+ },
6513
+ block.title
6514
+ ? 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 - CLOCK_TITLE_LINE_HEIGHT, text: block.title, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, fontSize: CLOCK_TITLE_FONT_SIZE, lineHeight: CLOCK_TITLE_LINE_HEIGHT, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top' }, (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) })
6515
+ : null,
6516
+ contentText.length
6517
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-clock-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getClockTextRect(spec, ctx, index).x, y: (_d, ctx) => getClockTextRect(spec, ctx, index).anchorY + 4, width: (_d, ctx) => getClockTextRect(spec, ctx, index).width, maxLineWidth: (_d, ctx) => getClockTextRect(spec, ctx, index).width, text: buildRichContent(contentText, spec), fontSize: CLOCK_CONTENT_FONT_SIZE, lineHeight: CLOCK_CONTENT_LINE_HEIGHT, fill: '#3a3f4d', textAlign: (_d, ctx) => getClockTextRect(spec, ctx, index).onLeft ? 'right' : 'left', textBaseline: 'top', wordBreak: 'break-word' }, (_b = spec.content) === null || _b === void 0 ? void 0 : _b.style) })
6518
+ : null
6519
+ ];
6520
+ return {
6521
+ type: 'group',
6522
+ id: `storyline-block-${(_c = block.id) !== null && _c !== void 0 ? _c : index}`,
6523
+ name: `storyline-block-${index}`,
6524
+ zIndex: vchart.LayoutZIndex.Mark + 1,
6525
+ children: children.filter(Boolean)
6526
+ };
6527
+ };
6528
+
6529
+ const buildDefaultLineMark = (spec) => {
6530
+ var _a, _b, _c, _d;
6531
+ if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) === false || ((_c = (_b = spec.data) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) <= 1) {
6532
+ return null;
6533
+ }
6534
+ return {
6535
+ type: 'group',
6536
+ name: 'storyline-links',
6537
+ zIndex: vchart.LayoutZIndex.Mark,
6538
+ children: ((_d = spec.data) !== null && _d !== void 0 ? _d : []).slice(1).map((_, index) => {
6539
+ var _a;
6540
+ const _b = (_a = spec.line) !== null && _a !== void 0 ? _a : {}, { style = {}, type = 'line', showArrow = false, arrowSize = 8 } = _b, rest = __rest(_b, ["style", "type", "showArrow", "arrowSize"]);
6541
+ return Object.assign(Object.assign({ type: 'path', name: `storyline-link-${index}`, interactive: false }, rest), { style: Object.assign(Object.assign({ stroke: '#8a94a6', lineWidth: 1.5, fill: 'transparent', fillOpacity: 0 }, style), { path: (_datum, ctx) => {
6542
+ const link = getLayout(spec, ctx).links[index];
6543
+ if (!link) {
6544
+ return '';
6545
+ }
6546
+ return buildLinkPath(link.points, type, showArrow, arrowSize);
6547
+ } }) });
6548
+ })
6549
+ };
6550
+ };
6551
+ const getDefaultBlockMetrics = (spec, ctx, index) => {
6552
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
6553
+ const block = getLayout(spec, ctx).blocks[index];
6554
+ const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
6555
+ const imagePosition = (_d = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.position) !== null && _d !== void 0 ? _d : 'top';
6556
+ const imageWidth = (_f = (_e = spec.image) === null || _e === void 0 ? void 0 : _e.width) !== null && _f !== void 0 ? _f : DEFAULT_IMAGE_WIDTH;
6557
+ const imageHeight = (_h = (_g = spec.image) === null || _g === void 0 ? void 0 : _g.height) !== null && _h !== void 0 ? _h : DEFAULT_IMAGE_HEIGHT;
6558
+ const imageGap = (_k = (_j = spec.image) === null || _j === void 0 ? void 0 : _j.gap) !== null && _k !== void 0 ? _k : DEFAULT_IMAGE_GAP;
6559
+ const hasImage = !!((_m = (_l = spec.data) === null || _l === void 0 ? void 0 : _l[index]) === null || _m === void 0 ? void 0 : _m.image);
6560
+ const titleFontSize = Number((_q = (_p = (_o = spec.title) === null || _o === void 0 ? void 0 : _o.style) === null || _p === void 0 ? void 0 : _p.fontSize) !== null && _q !== void 0 ? _q : 18);
6561
+ const titleLineHeight = Number((_t = (_s = (_r = spec.title) === null || _r === void 0 ? void 0 : _r.style) === null || _s === void 0 ? void 0 : _s.lineHeight) !== null && _t !== void 0 ? _t : Math.round(titleFontSize * 1.35));
6562
+ const titleHeight = ((_v = (_u = spec.data) === null || _u === void 0 ? void 0 : _u[index]) === null || _v === void 0 ? void 0 : _v.title) ? titleLineHeight : 0;
6563
+ const blockWidth = (_w = block === null || block === void 0 ? void 0 : block.width) !== null && _w !== void 0 ? _w : resolveBlockWidth(spec, 0);
6564
+ const blockHeight = (_z = (_x = block === null || block === void 0 ? void 0 : block.height) !== null && _x !== void 0 ? _x : (_y = spec.block) === null || _y === void 0 ? void 0 : _y.height) !== null && _z !== void 0 ? _z : DEFAULT_BLOCK_HEIGHT;
6565
+ const imageBox = getImageBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
6566
+ const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
6567
+ const contentGap = ((_1 = (_0 = spec.data) === null || _0 === void 0 ? void 0 : _0[index]) === null || _1 === void 0 ? void 0 : _1.title) ? 8 : 0;
6568
+ return {
6569
+ block: {
6570
+ width: blockWidth,
6571
+ height: blockHeight
6572
+ },
6573
+ imageBox,
6574
+ textBox,
6575
+ contentBox: {
6576
+ y: textBox.y + titleHeight + contentGap,
6577
+ height: Math.max(0, textBox.height - titleHeight - contentGap)
6578
+ }
6579
+ };
6580
+ };
6581
+ const buildDefaultBlockMark = (spec, block, index) => {
6582
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
6583
+ const hasImage = !!block.image;
6584
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
6585
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 18);
6586
+ const titleLineHeight = Number((_f = (_e = (_d = spec.title) === null || _d === void 0 ? void 0 : _d.style) === null || _e === void 0 ? void 0 : _e.lineHeight) !== null && _f !== void 0 ? _f : Math.round(titleFontSize * 1.35));
6587
+ return {
6588
+ type: 'group',
6589
+ id: `storyline-block-${(_g = block.id) !== null && _g !== void 0 ? _g : index}`,
6590
+ name: `storyline-block-${index}`,
6591
+ zIndex: vchart.LayoutZIndex.Mark + 1,
6592
+ style: {
6593
+ x: (_datum, 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; },
6594
+ y: (_datum, 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; },
6595
+ width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).block.width,
6596
+ height: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).block.height
6597
+ },
6598
+ children: [
6599
+ {
6600
+ type: 'rect',
6601
+ name: `storyline-block-bg-${index}`,
6602
+ interactive: false,
6603
+ style: Object.assign({ x: 0, y: 0, width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).block.width, height: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).block.height, cornerRadius: 8, fill: '#ffffff', stroke: '#d7dce5', lineWidth: 1, shadowBlur: 6, shadowColor: 'rgba(0, 0, 0, 0.08)' }, (_h = spec.block) === null || _h === void 0 ? void 0 : _h.style)
6604
+ },
6605
+ hasImage
6606
+ ? 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 }, (_j = spec.image) === null || _j === void 0 ? void 0 : _j.style) })
6607
+ : null,
6608
+ block.title
6609
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, fontSize: titleFontSize, lineHeight: titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_k = spec.title) === null || _k === void 0 ? void 0 : _k.style) })
6610
+ : null,
6611
+ contentText.length
6612
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.x, y: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.y, width: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, text: buildRichContent(contentText, spec), maxLineWidth: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).textBox.width, fontSize: 12, lineHeight: 18, heightLimit: (_datum, ctx) => getDefaultBlockMetrics(spec, ctx, index).contentBox.height, textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_l = spec.content) === null || _l === void 0 ? void 0 : _l.style) })
6613
+ : null
6614
+ ].filter(Boolean)
6615
+ };
6616
+ };
6617
+ const buildLinkPath = (points, type, showArrow, arrowSize) => {
6618
+ const start = points[0];
6619
+ const end = points[points.length - 1];
6620
+ if (!start || !end) {
6621
+ return '';
6622
+ }
6623
+ let path;
6624
+ if (type === 'curve') {
6625
+ const dx = end.x - start.x;
6626
+ const dy = end.y - start.y;
6627
+ const curve = Math.max(Math.min(Math.sqrt(dx * dx + dy * dy) * 0.22, 80), 24);
6628
+ path =
6629
+ `M ${start.x} ${start.y} ` +
6630
+ `C ${start.x + dx / 2} ${start.y - curve} ${end.x - dx / 2} ${end.y + curve} ${end.x} ${end.y}`;
6631
+ }
6632
+ else if (type === 'polyline') {
6633
+ const mid = { x: (start.x + end.x) / 2, y: (start.y + end.y) / 2 };
6634
+ path = `M ${start.x} ${start.y} L ${mid.x} ${start.y} L ${mid.x} ${end.y} L ${end.x} ${end.y}`;
6635
+ }
6636
+ else {
6637
+ path = `M ${start.x} ${start.y} L ${end.x} ${end.y}`;
6638
+ }
6639
+ if (!showArrow) {
6640
+ return path;
6641
+ }
6642
+ return `${path} ${buildArrowPath(start, end, arrowSize)}`;
6643
+ };
6644
+ const buildArrowPath = (start, end, size) => {
6645
+ const angle = Math.atan2(end.y - start.y, end.x - start.x);
6646
+ const left = {
6647
+ x: end.x - Math.cos(angle - Math.PI / 6) * size,
6648
+ y: end.y - Math.sin(angle - Math.PI / 6) * size
6649
+ };
6650
+ const right = {
6651
+ x: end.x - Math.cos(angle + Math.PI / 6) * size,
6652
+ y: end.y - Math.sin(angle + Math.PI / 6) * size
6653
+ };
6654
+ return `M ${left.x} ${left.y} L ${end.x} ${end.y} L ${right.x} ${right.y}`;
6655
+ };
6656
+
6657
+ const LANDSCAPE_IMAGE_HEIGHT_RATIO = 0.42;
6658
+ const LANDSCAPE_DETACHED_GAP = 64;
6659
+ const LANDSCAPE_CONNECTOR_ARROW_SIZE = 9;
6660
+ const LANDSCAPE_CONNECTOR_X_RATIO = 0.2;
6661
+ const LANDSCAPE_TEXT_GAP_FROM_CONNECTOR = 12;
6662
+ const LANDSCAPE_CONTENT_LINES = 4;
6663
+ const LANDSCAPE_TITLE_LINE_HEIGHT = 19;
6664
+ const LANDSCAPE_CONTENT_LINE_HEIGHT = 18;
6665
+ const LANDSCAPE_CONTENT_FONT_SIZE = 12;
6666
+ const LANDSCAPE_TITLE_TO_CONTENT_GAP = 4;
6667
+ const getLandscapeImageCenter = (spec, ctx, index) => {
6668
+ var _a, _b, _c, _e;
6669
+ const lb = getLayout(spec, ctx).blocks[index];
6670
+ if (!lb) {
6671
+ return null;
6672
+ }
6673
+ const cx = (_b = (_a = lb.center) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : lb.x + lb.width / 2;
6674
+ const cy = (_e = (_c = lb.center) === null || _c === void 0 ? void 0 : _c.y) !== null && _e !== void 0 ? _e : lb.y + lb.height / 2;
6675
+ const stagger = (index % 2 === 0 ? -1 : 1) * lb.height * 0.1;
6676
+ return { x: cx, y: cy + stagger };
6677
+ };
6678
+ const buildLandscapeConnectingCurve = (spec) => {
6679
+ var _a, _b, _c, _e, _f, _g, _h;
6680
+ const themeColor = getThemeColor(spec);
6681
+ const lineStyle = (_b = (_a = spec.line) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {};
6682
+ const count = (_e = (_c = spec.data) === null || _c === void 0 ? void 0 : _c.length) !== null && _e !== void 0 ? _e : 0;
6683
+ const symbolSize = 14;
6684
+ const symbolChildren = [];
6685
+ for (let i = 0; i < count; i++) {
6686
+ const idx = i;
6687
+ symbolChildren.push({
6688
+ type: 'symbol',
6689
+ name: `storyline-landscape-curve-symbol-${idx}`,
6690
+ interactive: false,
6691
+ style: {
6692
+ symbolType: 'circle',
6693
+ size: symbolSize,
6694
+ fill: themeColor,
6695
+ x: (_d, ctx) => { var _a, _b; return (_b = (_a = getLandscapeImageCenter(spec, ctx, idx)) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0; },
6696
+ y: (_d, ctx) => { var _a, _b; return (_b = (_a = getLandscapeImageCenter(spec, ctx, idx)) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : 0; }
6697
+ }
6698
+ });
6699
+ }
6700
+ return {
6701
+ type: 'group',
6702
+ name: 'storyline-landscape-curve',
6703
+ zIndex: vchart.LayoutZIndex.Mark + 2,
6704
+ children: [
6705
+ {
6706
+ type: 'path',
6707
+ name: 'storyline-landscape-curve-path',
6708
+ interactive: false,
6709
+ style: {
6710
+ stroke: (_f = lineStyle.stroke) !== null && _f !== void 0 ? _f : themeColor,
6711
+ lineWidth: (_g = lineStyle.lineWidth) !== null && _g !== void 0 ? _g : 4,
6712
+ lineDash: (_h = lineStyle.lineDash) !== null && _h !== void 0 ? _h : [6, 5],
6713
+ lineCap: 'round',
6714
+ fill: 'transparent',
6715
+ fillOpacity: 0,
6716
+ path: (_d, ctx) => {
6717
+ const points = [];
6718
+ for (let i = 0; i < count; i++) {
6719
+ const center = getLandscapeImageCenter(spec, ctx, i);
6720
+ if (center) {
6721
+ points.push(center);
6722
+ }
6723
+ }
6724
+ return buildSmoothCurvePath(points);
6725
+ }
6726
+ }
6727
+ },
6728
+ ...symbolChildren
6729
+ ]
6730
+ };
6731
+ };
6732
+ const getLandscapeMetrics = (spec, blockWidth, blockHeight, index) => {
6733
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
6734
+ const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
6735
+ const titleFontSize = Number((_f = (_e = (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) === null || _e === void 0 ? void 0 : _e.fontSize) !== null && _f !== void 0 ? _f : 18);
6736
+ const titleLineHeight = Number((_j = (_h = (_g = spec.title) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.lineHeight) !== null && _j !== void 0 ? _j : Math.max(LANDSCAPE_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.35)));
6737
+ const contentFontSize = Number((_m = (_l = (_k = spec.content) === null || _k === void 0 ? void 0 : _k.style) === null || _l === void 0 ? void 0 : _l.fontSize) !== null && _m !== void 0 ? _m : LANDSCAPE_CONTENT_FONT_SIZE);
6738
+ const contentLineHeight = Number((_q = (_p = (_o = spec.content) === null || _o === void 0 ? void 0 : _o.style) === null || _p === void 0 ? void 0 : _p.lineHeight) !== null && _q !== void 0 ? _q : LANDSCAPE_CONTENT_LINE_HEIGHT);
6739
+ const imageHeight = Math.max((_s = (_r = spec.image) === null || _r === void 0 ? void 0 : _r.height) !== null && _s !== void 0 ? _s : Math.round(blockHeight * LANDSCAPE_IMAGE_HEIGHT_RATIO), titleLineHeight + padding.top + padding.bottom);
6740
+ const connectorGap = LANDSCAPE_DETACHED_GAP;
6741
+ const contentHeight = LANDSCAPE_CONTENT_LINES * contentLineHeight;
6742
+ const titleToContentGap = LANDSCAPE_TITLE_TO_CONTENT_GAP;
6743
+ const textHeight = titleLineHeight + titleToContentGap + contentHeight;
6744
+ const textOnTop = index % 2 === 0;
6745
+ let textBox;
6746
+ let contentBox;
6747
+ let imageBox;
6748
+ let connector;
6749
+ let groupTop;
6750
+ let groupHeight;
6751
+ const imageX = 0;
6752
+ const connectorX = imageX + blockWidth * LANDSCAPE_CONNECTOR_X_RATIO;
6753
+ const textX = connectorX + LANDSCAPE_TEXT_GAP_FROM_CONNECTOR;
6754
+ const textWidth = Math.max(blockWidth - (textX - imageX), 0);
6755
+ if (textOnTop) {
6756
+ const imageY = 0;
6757
+ const textY = imageY - connectorGap - textHeight;
6758
+ const connectorY1 = imageY;
6759
+ const connectorY2 = textY + titleLineHeight / 2;
6760
+ imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6761
+ textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
6762
+ contentBox = {
6763
+ x: textX,
6764
+ y: textY + titleLineHeight + titleToContentGap,
6765
+ width: textWidth,
6766
+ height: contentHeight
6767
+ };
6768
+ connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6769
+ groupTop = textY;
6770
+ groupHeight = imageHeight - groupTop;
6771
+ }
6772
+ else {
6773
+ const imageY = 0;
6774
+ const textY = imageY + imageHeight + connectorGap;
6775
+ const connectorY1 = imageY + imageHeight;
6776
+ const connectorY2 = textY + textHeight;
6777
+ imageBox = { x: imageX, y: imageY, width: blockWidth, height: imageHeight };
6778
+ textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
6779
+ contentBox = {
6780
+ x: textX,
6781
+ y: textY + titleLineHeight + titleToContentGap,
6782
+ width: textWidth,
6783
+ height: contentHeight
6784
+ };
6785
+ connector = { x1: connectorX, y1: connectorY1, x2: connectorX, y2: connectorY2 };
6786
+ groupTop = imageY;
6787
+ groupHeight = textY + textHeight - imageY;
6788
+ }
6789
+ return {
6790
+ padding,
6791
+ titleFontSize,
6792
+ titleLineHeight,
6793
+ contentFontSize,
6794
+ contentLineHeight,
6795
+ contentHeight,
6796
+ blockWidth,
6797
+ imageBox,
6798
+ textBox,
6799
+ contentBox,
6800
+ connector,
6801
+ textOnTop,
6802
+ groupTop,
6803
+ groupHeight
6804
+ };
6805
+ };
6806
+ const buildLandscapeBlockMark = (spec, block, index) => {
6807
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
6808
+ const hasImage = !!block.image;
6809
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
6810
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 18);
6811
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.round(titleFontSize * 1.35));
6812
+ const getMetrics = (ctx) => {
6813
+ var _a, _b, _c, _e;
6814
+ const layoutBlock = getLayout(spec, ctx).blocks[index];
6815
+ const w = (_a = layoutBlock === null || layoutBlock === void 0 ? void 0 : layoutBlock.width) !== null && _a !== void 0 ? _a : resolveBlockWidth(spec, 0);
6816
+ const h = (_e = (_b = layoutBlock === null || layoutBlock === void 0 ? void 0 : layoutBlock.height) !== null && _b !== void 0 ? _b : (_c = spec.block) === null || _c === void 0 ? void 0 : _c.height) !== null && _e !== void 0 ? _e : DEFAULT_BLOCK_HEIGHT;
6817
+ return getLandscapeMetrics(spec, w, h, index);
6818
+ };
6819
+ const blockStyle = (_j = (_h = spec.block) === null || _h === void 0 ? void 0 : _h.style) !== null && _j !== void 0 ? _j : {};
6820
+ const lineStyle = (_l = (_k = spec.line) === null || _k === void 0 ? void 0 : _k.style) !== null && _l !== void 0 ? _l : {};
6821
+ const themeColor = getThemeColor(spec);
6822
+ const connectorStroke = (_m = lineStyle.stroke) !== null && _m !== void 0 ? _m : themeColor;
6823
+ const connectorLineWidth = (_o = lineStyle.lineWidth) !== null && _o !== void 0 ? _o : 2;
6824
+ const connectorDash = (_p = lineStyle.lineDash) !== null && _p !== void 0 ? _p : [4, 4];
6825
+ return {
6826
+ type: 'group',
6827
+ id: `storyline-block-${(_q = block.id) !== null && _q !== void 0 ? _q : index}`,
6828
+ name: `storyline-block-${index}`,
6829
+ zIndex: vchart.LayoutZIndex.Mark + 1,
6830
+ style: {
6831
+ x: (_d, ctx) => {
6832
+ var _a;
6833
+ const lb = getLayout(spec, ctx).blocks[index];
6834
+ return (_a = lb === null || lb === void 0 ? void 0 : lb.x) !== null && _a !== void 0 ? _a : 0;
6835
+ },
6836
+ y: (_d, ctx) => {
6837
+ var _a, _b, _c, _e, _f, _g, _h;
6838
+ const lb = getLayout(spec, ctx).blocks[index];
6839
+ const m = getMetrics(ctx);
6840
+ 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;
6841
+ 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;
6842
+ const stagger = (index % 2 === 0 ? -1 : 1) * blockH * 0.1;
6843
+ return cy - m.imageBox.height / 2 + stagger;
6844
+ },
6845
+ width: (_d, ctx) => getMetrics(ctx).blockWidth,
6846
+ height: (_d, ctx) => getMetrics(ctx).groupHeight
6847
+ },
6848
+ children: [
6849
+ {
6850
+ type: 'rect',
6851
+ name: `storyline-block-image-bg-${index}`,
6852
+ interactive: false,
6853
+ 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: 8, fill: '#ffffff', stroke: themeColor, lineWidth: 2 }, blockStyle)
6854
+ },
6855
+ hasImage
6856
+ ? 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: 'cover', imagePosition: 'center' }, (_r = spec.image) === null || _r === void 0 ? void 0 : _r.style) })
6857
+ : null,
6858
+ {
6859
+ type: 'path',
6860
+ name: `storyline-block-connector-${index}`,
6861
+ interactive: false,
6862
+ style: {
6863
+ stroke: connectorStroke,
6864
+ lineWidth: connectorLineWidth,
6865
+ lineDash: connectorDash,
6866
+ fill: connectorStroke,
6867
+ path: (_d, ctx) => {
6868
+ const m = getMetrics(ctx);
6869
+ const tipSize = LANDSCAPE_CONNECTOR_ARROW_SIZE;
6870
+ const x = m.connector.x1;
6871
+ const y0 = m.connector.y1;
6872
+ const y1 = m.connector.y2;
6873
+ const tipDir = y1 < y0 ? -1 : 1;
6874
+ const baseY = y1 - tipDir * tipSize;
6875
+ const dashLine = `M ${x} ${y0} L ${x} ${baseY}`;
6876
+ const triangle = `M ${x - tipSize / 2} ${baseY} L ${x + tipSize / 2} ${baseY} L ${x} ${y1} Z`;
6877
+ return `${dashLine} ${triangle}`;
6878
+ }
6879
+ }
6880
+ },
6881
+ block.title
6882
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, fontSize: titleFontSize, lineHeight: titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_s = spec.title) === null || _s === void 0 ? void 0 : _s.style) })
6883
+ : null,
6884
+ contentText.length
6885
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildRichContent(contentText, spec), fontSize: LANDSCAPE_CONTENT_FONT_SIZE, lineHeight: LANDSCAPE_CONTENT_LINE_HEIGHT, textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_t = spec.content) === null || _t === void 0 ? void 0 : _t.style) })
6886
+ : null
6887
+ ].filter(Boolean)
6888
+ };
6889
+ };
6890
+
6891
+ const PORTRAIT_AXIS_WIDTH = 64;
6892
+ const PORTRAIT_AXIS_PADDING = 50;
6893
+ const PORTRAIT_IMAGE_WIDTH = 180;
6894
+ const PORTRAIT_IMAGE_HEIGHT = 110;
6895
+ const PORTRAIT_IMAGE_GAP_FROM_AXIS = 24;
6896
+ const PORTRAIT_SHADOW_OFFSET_X = 24;
6897
+ const PORTRAIT_SHADOW_OFFSET_Y = 16;
6898
+ const PORTRAIT_SHADOW_SCALE = 1;
6899
+ const PORTRAIT_TEXT_GAP_FROM_IMAGE = 8;
6900
+ const PORTRAIT_CONTENT_LINES = 3;
6901
+ const PORTRAIT_TITLE_LINE_HEIGHT = 19;
6902
+ const PORTRAIT_CONTENT_LINE_HEIGHT = 18;
6903
+ const PORTRAIT_CONTENT_FONT_SIZE = 12;
6904
+ const PORTRAIT_TITLE_TO_CONTENT_GAP = 4;
6905
+ const getPortraitAxisRect = (spec, ctx) => {
6906
+ const blocks = getLayout(spec, ctx).blocks;
6907
+ if (!blocks.length) {
6908
+ return { x: 0, y: 0, width: 0, height: 0 };
6909
+ }
6910
+ const firstCy = blocks[0].center.y;
6911
+ const lastCy = blocks[blocks.length - 1].center.y;
6912
+ const top = Math.min(firstCy, lastCy);
6913
+ const bottom = Math.max(firstCy, lastCy);
6914
+ const cx = blocks[0].center.x;
6915
+ return {
6916
+ x: cx - PORTRAIT_AXIS_WIDTH / 2,
6917
+ y: top - PORTRAIT_AXIS_PADDING,
6918
+ width: PORTRAIT_AXIS_WIDTH,
6919
+ height: bottom - top + PORTRAIT_AXIS_PADDING * 2
6920
+ };
6921
+ };
6922
+ const buildPortraitAxisMark = (spec) => {
6923
+ var _a, _b, _c, _e, _f, _g;
6924
+ const themeColor = getThemeColor(spec);
6925
+ const lineStyle = (_b = (_a = spec.line) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {};
6926
+ const defaultFill = {
6927
+ gradient: 'linear',
6928
+ x0: 0,
6929
+ y0: 0,
6930
+ x1: 0,
6931
+ y1: 1,
6932
+ stops: [
6933
+ { offset: 0, color: withAlpha(themeColor, 0.2) },
6934
+ { offset: 1, color: withAlpha(themeColor, 1) }
6935
+ ]
6936
+ };
6937
+ return {
6938
+ type: 'group',
6939
+ name: 'storyline-portrait-axis',
6940
+ zIndex: vchart.LayoutZIndex.Mark,
6941
+ children: [
6942
+ {
6943
+ type: 'rect',
6944
+ name: 'storyline-portrait-axis-rect',
6945
+ interactive: false,
6946
+ style: {
6947
+ fill: (_c = lineStyle.fill) !== null && _c !== void 0 ? _c : defaultFill,
6948
+ stroke: (_e = lineStyle.stroke) !== null && _e !== void 0 ? _e : false,
6949
+ lineWidth: (_f = lineStyle.lineWidth) !== null && _f !== void 0 ? _f : 0,
6950
+ cornerRadius: (_g = lineStyle.cornerRadius) !== null && _g !== void 0 ? _g : 0,
6951
+ x: (_d, ctx) => getPortraitAxisRect(spec, ctx).x,
6952
+ y: (_d, ctx) => getPortraitAxisRect(spec, ctx).y,
6953
+ width: (_d, ctx) => getPortraitAxisRect(spec, ctx).width,
6954
+ height: (_d, ctx) => getPortraitAxisRect(spec, ctx).height
6955
+ }
6956
+ }
6957
+ ]
6958
+ };
6959
+ };
6960
+ const getPortraitMetrics = (spec, blockWidth, blockHeight, index) => {
6961
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
6962
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 18);
6963
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.max(PORTRAIT_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.35)));
6964
+ const contentFontSize = Number((_k = (_j = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style) === null || _j === void 0 ? void 0 : _j.fontSize) !== null && _k !== void 0 ? _k : PORTRAIT_CONTENT_FONT_SIZE);
6965
+ const contentLineHeight = Number((_o = (_m = (_l = spec.content) === null || _l === void 0 ? void 0 : _l.style) === null || _m === void 0 ? void 0 : _m.lineHeight) !== null && _o !== void 0 ? _o : PORTRAIT_CONTENT_LINE_HEIGHT);
6966
+ const titleToContentGap = PORTRAIT_TITLE_TO_CONTENT_GAP;
6967
+ const imageWidth = (_q = (_p = spec.image) === null || _p === void 0 ? void 0 : _p.width) !== null && _q !== void 0 ? _q : PORTRAIT_IMAGE_WIDTH;
6968
+ const imageHeight = (_s = (_r = spec.image) === null || _r === void 0 ? void 0 : _r.height) !== null && _s !== void 0 ? _s : PORTRAIT_IMAGE_HEIGHT;
6969
+ const minContentHeight = PORTRAIT_CONTENT_LINES * contentLineHeight;
6970
+ const contentHeight = Math.max(minContentHeight, blockHeight - imageHeight / 2 - PORTRAIT_TEXT_GAP_FROM_IMAGE - titleLineHeight - titleToContentGap);
6971
+ const textHeight = titleLineHeight + titleToContentGap + contentHeight;
6972
+ const onLeft = index % 2 === 0;
6973
+ const axisHalf = PORTRAIT_AXIS_WIDTH / 2;
6974
+ const imageX = onLeft
6975
+ ? -axisHalf - PORTRAIT_IMAGE_GAP_FROM_AXIS - imageWidth
6976
+ : axisHalf + PORTRAIT_IMAGE_GAP_FROM_AXIS;
6977
+ const imageY = -imageHeight / 2;
6978
+ const textX = imageX;
6979
+ const textY = imageY + imageHeight + PORTRAIT_TEXT_GAP_FROM_IMAGE;
6980
+ const textWidth = imageWidth;
6981
+ const contentBox = {
6982
+ x: textX,
6983
+ y: textY + titleLineHeight + titleToContentGap,
6984
+ width: textWidth,
6985
+ height: contentHeight
6986
+ };
6987
+ const shadowOffsetX = PORTRAIT_SHADOW_OFFSET_X;
6988
+ const shadowOffsetY = PORTRAIT_SHADOW_OFFSET_Y;
6989
+ const shadowWidth = imageWidth * PORTRAIT_SHADOW_SCALE;
6990
+ const shadowHeight = imageHeight * PORTRAIT_SHADOW_SCALE;
6991
+ const baseShadowX = imageX - (shadowWidth - imageWidth) / 2;
6992
+ const baseShadowY = imageY - (shadowHeight - imageHeight) / 2;
6993
+ const shadowBox = {
6994
+ x: baseShadowX + (onLeft ? -shadowOffsetX : shadowOffsetX),
6995
+ y: baseShadowY + shadowOffsetY,
6996
+ width: shadowWidth,
6997
+ height: shadowHeight
6998
+ };
6999
+ return {
7000
+ onLeft,
7001
+ titleFontSize,
7002
+ titleLineHeight,
7003
+ contentFontSize,
7004
+ contentLineHeight,
7005
+ blockWidth,
7006
+ imageBox: { x: imageX, y: imageY, width: imageWidth, height: imageHeight },
7007
+ shadowBox,
7008
+ textBox: { x: textX, y: textY, width: textWidth, height: textHeight },
7009
+ contentBox
7010
+ };
7011
+ };
7012
+ const buildPortraitBlockMark = (spec, block, index) => {
7013
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
7014
+ const hasImage = !!block.image;
7015
+ const hasSubImage = !!block.subImage;
7016
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7017
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 18);
7018
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.max(PORTRAIT_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.35)));
7019
+ const showBackground = ((_h = spec.image) === null || _h === void 0 ? void 0 : _h.showBackground) === true;
7020
+ const getMetrics = (ctx) => {
7021
+ var _a, _b, _c, _e;
7022
+ const lb = getLayout(spec, ctx).blocks[index];
7023
+ const w = (_a = lb === null || lb === void 0 ? void 0 : lb.width) !== null && _a !== void 0 ? _a : resolveBlockWidth(spec, 0);
7024
+ const h = (_e = (_b = lb === null || lb === void 0 ? void 0 : lb.height) !== null && _b !== void 0 ? _b : (_c = spec.block) === null || _c === void 0 ? void 0 : _c.height) !== null && _e !== void 0 ? _e : DEFAULT_BLOCK_HEIGHT;
7025
+ return getPortraitMetrics(spec, w, h, index);
7026
+ };
7027
+ const themeColor = getThemeColor(spec);
7028
+ const blockStyle = (_k = (_j = spec.block) === null || _j === void 0 ? void 0 : _j.style) !== null && _k !== void 0 ? _k : {};
7029
+ return {
7030
+ type: 'group',
7031
+ id: `storyline-block-${(_l = block.id) !== null && _l !== void 0 ? _l : index}`,
7032
+ name: `storyline-block-${index}`,
7033
+ zIndex: vchart.LayoutZIndex.Mark + 1,
7034
+ style: {
7035
+ x: (_d, ctx) => {
7036
+ var _a, _b;
7037
+ const lb = getLayout(spec, ctx).blocks[index];
7038
+ return (_b = (_a = lb === null || lb === void 0 ? void 0 : lb.center) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0;
7039
+ },
7040
+ y: (_d, ctx) => {
7041
+ var _a, _b;
7042
+ const lb = getLayout(spec, ctx).blocks[index];
7043
+ return (_b = (_a = lb === null || lb === void 0 ? void 0 : lb.center) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : 0;
7044
+ }
7045
+ },
7046
+ children: [
7047
+ hasSubImage && showBackground
7048
+ ? {
7049
+ type: 'image',
7050
+ name: `storyline-block-shadow-image-${index}`,
7051
+ interactive: false,
7052
+ style: {
7053
+ x: (_d, ctx) => getMetrics(ctx).shadowBox.x,
7054
+ y: (_d, ctx) => getMetrics(ctx).shadowBox.y,
7055
+ width: (_d, ctx) => getMetrics(ctx).shadowBox.width,
7056
+ height: (_d, ctx) => getMetrics(ctx).shadowBox.height,
7057
+ image: block.subImage,
7058
+ repeatX: 'no-repeat',
7059
+ repeatY: 'no-repeat',
7060
+ imageMode: 'cover',
7061
+ imagePosition: 'center'
7062
+ }
7063
+ }
7064
+ : null,
7065
+ {
7066
+ type: 'rect',
7067
+ name: `storyline-block-image-bg-${index}`,
7068
+ interactive: false,
7069
+ 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: 8, fill: '#ffffff', stroke: themeColor, lineWidth: 2 }, blockStyle)
7070
+ },
7071
+ hasImage
7072
+ ? 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: 'cover', imagePosition: 'center' }, (_m = spec.image) === null || _m === void 0 ? void 0 : _m.style) })
7073
+ : null,
7074
+ block.title
7075
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).textBox.x, y: (_d, ctx) => getMetrics(ctx).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getMetrics(ctx).textBox.width, fontSize: titleFontSize, lineHeight: titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_o = spec.title) === null || _o === void 0 ? void 0 : _o.style) })
7076
+ : null,
7077
+ contentText.length
7078
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: (_d, ctx) => getMetrics(ctx).contentBox.x, y: (_d, ctx) => getMetrics(ctx).contentBox.y, width: (_d, ctx) => getMetrics(ctx).contentBox.width, height: (_d, ctx) => getMetrics(ctx).contentBox.height, maxLineWidth: (_d, ctx) => getMetrics(ctx).contentBox.width, heightLimit: (_d, ctx) => getMetrics(ctx).contentBox.height, text: buildRichContent(contentText, spec), fontSize: PORTRAIT_CONTENT_FONT_SIZE, lineHeight: PORTRAIT_CONTENT_LINE_HEIGHT, textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_p = spec.content) === null || _p === void 0 ? void 0 : _p.style) })
7079
+ : null
7080
+ ].filter(Boolean)
7081
+ };
7082
+ };
7083
+
7084
+ const ARC_BLOCK_IMAGE_SIZE = 140;
7085
+ const ARC_TEXT_GAP_FROM_IMAGE = 10;
7086
+ const ARC_TITLE_LINE_HEIGHT = 19;
7087
+ const ARC_CONTENT_LINE_HEIGHT = 17;
7088
+ const ARC_CONTENT_FONT_SIZE = 12;
7089
+ const ARC_TEXT_BOX_HEIGHT = 240;
7090
+ const ARC_TITLE_TO_CONTENT_GAP = 4;
7091
+ const ARC_TEXT_LEFT_PADDING = 20;
7092
+ const ARC_TEXT_BOX_MIN_WIDTH = 200;
7093
+ const ARC_CENTER_IMAGE_SIZE_RATIO = 0.4;
7094
+ const ARC_GAP_FROM_CENTER_IMAGE = 200;
7095
+ const isDownArc = (spec) => normalizeLayout(spec.layout).direction === 'down';
7096
+ const getArcCenterImageRect = (spec, ctx) => {
7097
+ var _a, _b, _c, _e, _f;
7098
+ const { width, height, startX, startY } = getRegionGeometry(ctx);
7099
+ const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
7100
+ const innerWidth = Math.max(width - padding.left - padding.right, 1);
7101
+ const innerHeight = Math.max(height - padding.top - padding.bottom, 1);
7102
+ const baseSize = Math.min(innerWidth, innerHeight) * ARC_CENTER_IMAGE_SIZE_RATIO;
7103
+ const w = Math.max((_c = (_b = spec.centerImage) === null || _b === void 0 ? void 0 : _b.width) !== null && _c !== void 0 ? _c : baseSize, 80);
7104
+ const h = Math.max((_f = (_e = spec.centerImage) === null || _e === void 0 ? void 0 : _e.height) !== null && _f !== void 0 ? _f : baseSize, 80);
7105
+ const cx = startX + padding.left + innerWidth / 2;
7106
+ const isDown = isDownArc(spec);
7107
+ const top = isDown
7108
+ ?
7109
+ startY + padding.top
7110
+ :
7111
+ startY + padding.top + innerHeight - h;
7112
+ return { x: cx - w / 2, y: top, width: w, height: h };
7113
+ };
7114
+ const getArcGeometry = (spec, ctx) => {
7115
+ var _a, _b, _c, _e;
7116
+ const { width, startX } = getRegionGeometry(ctx);
7117
+ const blockPadding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
7118
+ const innerWidth = Math.max(width - blockPadding.left - blockPadding.right, 1);
7119
+ const blockWidth = resolveBlockWidth(spec, width);
7120
+ const layoutOpt = normalizeLayout(spec.layout);
7121
+ const isDown = layoutOpt.direction === 'down';
7122
+ const startAngle = (_b = layoutOpt.startAngle) !== null && _b !== void 0 ? _b : (isDown ? 20 : 200);
7123
+ const endAngle = (_c = layoutOpt.endAngle) !== null && _c !== void 0 ? _c : (isDown ? 160 : 340);
7124
+ const ratio = (_e = layoutOpt.radiusRatio) !== null && _e !== void 0 ? _e : 0.88;
7125
+ const rx = Math.max((innerWidth - blockWidth) / 2, 1) * ratio;
7126
+ const centerRect = getArcCenterImageRect(spec, ctx);
7127
+ const centerTop = centerRect.y;
7128
+ const centerBottom = centerRect.y + centerRect.height;
7129
+ const sinStart = Math.sin((startAngle / 180) * Math.PI);
7130
+ let cy;
7131
+ let ry;
7132
+ if (isDown) {
7133
+ const denom = Math.max(1 - sinStart, 0.05);
7134
+ ry = (centerRect.height + ARC_GAP_FROM_CENTER_IMAGE) / denom;
7135
+ cy = centerTop - ry * sinStart;
7136
+ }
7137
+ else {
7138
+ const denom = Math.max(1 + sinStart, 0.05);
7139
+ ry = (centerRect.height + ARC_GAP_FROM_CENTER_IMAGE) / denom;
7140
+ cy = centerBottom - ry * sinStart;
7141
+ }
7142
+ return {
7143
+ cx: startX + blockPadding.left + innerWidth / 2,
7144
+ cy,
7145
+ rx,
7146
+ ry,
7147
+ startAngle,
7148
+ endAngle,
7149
+ centerTop,
7150
+ centerBottom
7151
+ };
7152
+ };
7153
+ const getArcBlockCenter = (spec, ctx, index) => {
7154
+ var _a, _b, _c, _e;
7155
+ const arc = getArcGeometry(spec, ctx);
7156
+ const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7157
+ if (count <= 0) {
7158
+ return { x: arc.cx, y: arc.cy };
7159
+ }
7160
+ const t = count === 1 ? 0.5 : index / (count - 1);
7161
+ const angle = ((arc.startAngle + (arc.endAngle - arc.startAngle) * t) / 180) * Math.PI;
7162
+ const px = arc.cx + Math.cos(angle) * arc.rx;
7163
+ const py = arc.cy + Math.sin(angle) * arc.ry;
7164
+ const nxRaw = Math.cos(angle) / arc.rx;
7165
+ const nyRaw = Math.sin(angle) / arc.ry;
7166
+ const nLen = Math.hypot(nxRaw, nyRaw) || 1;
7167
+ const nx = nxRaw / nLen;
7168
+ const ny = nyRaw / nLen;
7169
+ const imageHeight = (_e = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.height) !== null && _e !== void 0 ? _e : ARC_BLOCK_IMAGE_SIZE;
7170
+ const offset = imageHeight / 2;
7171
+ return { x: px + nx * offset, y: py + ny * offset };
7172
+ };
7173
+ const buildArcMark = (spec) => {
7174
+ var _a;
7175
+ if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) !== true) {
7176
+ return null;
7177
+ }
7178
+ const themeColor = getThemeColor(spec);
7179
+ return {
7180
+ type: 'group',
7181
+ name: 'storyline-arc',
7182
+ zIndex: vchart.LayoutZIndex.Mark,
7183
+ children: [
7184
+ {
7185
+ type: 'path',
7186
+ name: 'storyline-arc-path',
7187
+ interactive: false,
7188
+ style: {
7189
+ stroke: themeColor,
7190
+ lineWidth: 2,
7191
+ lineCap: 'round',
7192
+ fill: 'transparent',
7193
+ fillOpacity: 0,
7194
+ path: (_d, ctx) => {
7195
+ const arc = getArcGeometry(spec, ctx);
7196
+ const span = arc.endAngle - arc.startAngle;
7197
+ const samples = 64;
7198
+ const segments = [];
7199
+ for (let i = 0; i <= samples; i++) {
7200
+ const t = i / samples;
7201
+ const angle = ((arc.startAngle + span * t) / 180) * Math.PI;
7202
+ const x = arc.cx + Math.cos(angle) * arc.rx;
7203
+ const y = arc.cy + Math.sin(angle) * arc.ry;
7204
+ segments.push(`${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`);
7205
+ }
7206
+ return segments.join(' ');
7207
+ }
7208
+ }
7209
+ }
7210
+ ]
7211
+ };
7212
+ };
7213
+ const buildArcCenterImageMark = (spec) => {
7214
+ var _a, _b, _c, _e;
7215
+ const visible = ((_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.visible) !== false;
7216
+ if (!visible) {
7217
+ return null;
7218
+ }
7219
+ const themeColor = getThemeColor(spec);
7220
+ const hasImage = !!((_b = spec.centerImage) === null || _b === void 0 ? void 0 : _b.image);
7221
+ const symbolGradient = {
7222
+ gradient: 'linear',
7223
+ x0: 0.5,
7224
+ y0: 0,
7225
+ x1: 0.5,
7226
+ y1: 1,
7227
+ stops: [
7228
+ { offset: 0, color: withAlpha(themeColor, 0.15) },
7229
+ { offset: 1, color: themeColor }
7230
+ ]
7231
+ };
7232
+ return {
7233
+ type: 'group',
7234
+ name: 'storyline-arc-center',
7235
+ zIndex: vchart.LayoutZIndex.Mark,
7236
+ children: [
7237
+ {
7238
+ type: 'symbol',
7239
+ name: 'storyline-arc-center-symbol',
7240
+ interactive: false,
7241
+ style: {
7242
+ x: (_d, ctx) => {
7243
+ const r = getArcCenterImageRect(spec, ctx);
7244
+ return r.x + r.width / 2;
7245
+ },
7246
+ y: (_d, ctx) => {
7247
+ const r = getArcCenterImageRect(spec, ctx);
7248
+ return r.y + r.height / 2;
7249
+ },
7250
+ size: (_d, ctx) => {
7251
+ const r = getArcCenterImageRect(spec, ctx);
7252
+ return Math.max(r.width, r.height) * 1.1;
7253
+ },
7254
+ symbolType: 'circle',
7255
+ fill: symbolGradient,
7256
+ stroke: themeColor,
7257
+ lineWidth: 2
7258
+ }
7259
+ },
7260
+ hasImage
7261
+ ? Object.assign(Object.assign({ type: 'image', name: 'storyline-arc-center-image', interactive: false }, spec.centerImage), { style: Object.assign({ x: (_d, ctx) => getArcCenterImageRect(spec, ctx).x, y: (_d, ctx) => getArcCenterImageRect(spec, ctx).y, width: (_d, ctx) => getArcCenterImageRect(spec, ctx).width, height: (_d, ctx) => getArcCenterImageRect(spec, ctx).height, image: (_c = spec.centerImage) === null || _c === void 0 ? void 0 : _c.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'cover', imagePosition: 'center', anchor: (_d, ctx) => {
7262
+ const r = getArcCenterImageRect(spec, ctx);
7263
+ return [r.x + r.width / 2, r.y + r.height / 2];
7264
+ }, dx: (_d, ctx) => {
7265
+ var _a, _b;
7266
+ const r = getArcCenterImageRect(spec, ctx);
7267
+ const userWidth = (_b = (_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.width;
7268
+ const w = typeof userWidth === 'number' ? userWidth : r.width;
7269
+ return (r.width - w) / 2;
7270
+ }, dy: (_d, ctx) => {
7271
+ var _a, _b;
7272
+ const r = getArcCenterImageRect(spec, ctx);
7273
+ const userHeight = (_b = (_a = spec.centerImage) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.height;
7274
+ const h = typeof userHeight === 'number' ? userHeight : r.height;
7275
+ return (r.height - h) / 2;
7276
+ } }, (_e = spec.centerImage) === null || _e === void 0 ? void 0 : _e.style) })
7277
+ : null
7278
+ ].filter(Boolean)
7279
+ };
7280
+ };
7281
+ const getArcBlockMetrics = (spec) => {
7282
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
7283
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : 18);
7284
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.max(ARC_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.35)));
7285
+ const contentFontSize = Number((_k = (_j = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style) === null || _j === void 0 ? void 0 : _j.fontSize) !== null && _k !== void 0 ? _k : ARC_CONTENT_FONT_SIZE);
7286
+ const contentLineHeight = Number((_o = (_m = (_l = spec.content) === null || _l === void 0 ? void 0 : _l.style) === null || _m === void 0 ? void 0 : _m.lineHeight) !== null && _o !== void 0 ? _o : ARC_CONTENT_LINE_HEIGHT);
7287
+ const titleToContentGap = ARC_TITLE_TO_CONTENT_GAP;
7288
+ const textHeight = ARC_TEXT_BOX_HEIGHT;
7289
+ const contentHeight = Math.max(textHeight - titleLineHeight - titleToContentGap, contentLineHeight);
7290
+ const imageWidth = (_q = (_p = spec.image) === null || _p === void 0 ? void 0 : _p.width) !== null && _q !== void 0 ? _q : ARC_BLOCK_IMAGE_SIZE;
7291
+ const imageHeight = (_s = (_r = spec.image) === null || _r === void 0 ? void 0 : _r.height) !== null && _s !== void 0 ? _s : ARC_BLOCK_IMAGE_SIZE;
7292
+ const isDown = isDownArc(spec);
7293
+ const imageBox = {
7294
+ x: -imageWidth / 2,
7295
+ y: -imageHeight / 2,
7296
+ width: imageWidth,
7297
+ height: imageHeight
7298
+ };
7299
+ const textBoxWidth = Math.max(imageWidth - ARC_TEXT_LEFT_PADDING, ARC_TEXT_BOX_MIN_WIDTH);
7300
+ const textBox = {
7301
+ x: -imageWidth / 2 + ARC_TEXT_LEFT_PADDING,
7302
+ y: isDown ? imageBox.y + imageHeight + ARC_TEXT_GAP_FROM_IMAGE : imageBox.y - ARC_TEXT_GAP_FROM_IMAGE - textHeight,
7303
+ width: textBoxWidth,
7304
+ height: textHeight
7305
+ };
7306
+ const contentBox = {
7307
+ x: textBox.x,
7308
+ y: textBox.y + titleLineHeight + titleToContentGap,
7309
+ width: textBox.width,
7310
+ height: contentHeight
7311
+ };
7312
+ return {
7313
+ titleFontSize,
7314
+ titleLineHeight,
7315
+ contentFontSize,
7316
+ contentLineHeight,
7317
+ imageBox,
7318
+ textBox,
7319
+ contentBox,
7320
+ isDown
7321
+ };
7322
+ };
7323
+ const buildArcBlockMark = (spec, block, index) => {
7324
+ var _a, _b, _c, _e;
7325
+ const hasImage = !!block.image;
7326
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7327
+ const themeColor = getThemeColor(spec);
7328
+ const metrics = getArcBlockMetrics(spec);
7329
+ const connectorY = metrics.isDown ? metrics.imageBox.y + metrics.imageBox.height : metrics.textBox.y;
7330
+ const connectorHeight = metrics.isDown
7331
+ ? Math.max(metrics.textBox.y + metrics.textBox.height - (metrics.imageBox.y + metrics.imageBox.height), 0)
7332
+ : Math.max(metrics.imageBox.y - metrics.textBox.y, 0);
7333
+ return {
7334
+ type: 'group',
7335
+ id: `storyline-block-${(_a = block.id) !== null && _a !== void 0 ? _a : index}`,
7336
+ name: `storyline-block-${index}`,
7337
+ zIndex: vchart.LayoutZIndex.Mark + 1,
7338
+ style: {
7339
+ x: (_d, ctx) => getArcBlockCenter(spec, ctx, index).x,
7340
+ y: (_d, ctx) => getArcBlockCenter(spec, ctx, index).y
7341
+ },
7342
+ children: [
7343
+ {
7344
+ type: 'rect',
7345
+ name: `storyline-block-connector-${index}`,
7346
+ interactive: false,
7347
+ style: {
7348
+ x: metrics.imageBox.x,
7349
+ y: connectorY,
7350
+ width: 2,
7351
+ height: connectorHeight,
7352
+ fill: themeColor,
7353
+ fillOpacity: 0.6
7354
+ }
7355
+ },
7356
+ hasImage
7357
+ ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: metrics.imageBox.x, y: metrics.imageBox.y, width: metrics.imageBox.width, height: metrics.imageBox.height, image: block.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'cover', imagePosition: 'center' }, (_b = spec.image) === null || _b === void 0 ? void 0 : _b.style) })
7358
+ : {
7359
+ type: 'rect',
7360
+ name: `storyline-block-image-bg-${index}`,
7361
+ interactive: false,
7362
+ style: {
7363
+ x: metrics.imageBox.x,
7364
+ y: metrics.imageBox.y,
7365
+ width: metrics.imageBox.width,
7366
+ height: metrics.imageBox.height,
7367
+ cornerRadius: Math.min(metrics.imageBox.width, metrics.imageBox.height) / 2,
7368
+ fill: '#ffffff',
7369
+ stroke: themeColor,
7370
+ lineWidth: 2
7371
+ }
7372
+ },
7373
+ block.title
7374
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign({ x: metrics.textBox.x, y: metrics.textBox.y, text: block.title, maxLineWidth: metrics.textBox.width, fontSize: metrics.titleFontSize, lineHeight: metrics.titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: 'left', textBaseline: 'top' }, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style) })
7375
+ : null,
7376
+ contentText.length
7377
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign({ x: metrics.contentBox.x, y: metrics.contentBox.y, width: metrics.contentBox.width, height: metrics.contentBox.height, maxLineWidth: metrics.contentBox.width, heightLimit: metrics.contentBox.height, text: buildRichContent(contentText, spec), fontSize: ARC_CONTENT_FONT_SIZE, lineHeight: ARC_CONTENT_LINE_HEIGHT, textAlign: 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_e = spec.content) === null || _e === void 0 ? void 0 : _e.style) })
7378
+ : null
7379
+ ].filter(Boolean)
7380
+ };
7381
+ };
7382
+
7383
+ const WING_BLOCK_IMAGE_SIZE = 96;
7384
+ const WING_TEXT_GAP_FROM_IMAGE = 14;
7385
+ const WING_TITLE_LINE_HEIGHT = 30;
7386
+ const WING_TITLE_FONT_SIZE = 22;
7387
+ const WING_CONTENT_LINE_HEIGHT = 17;
7388
+ const WING_CONTENT_FONT_SIZE = 12;
7389
+ const WING_TEXT_BOX_WIDTH = 240;
7390
+ const WING_TEXT_BOX_HEIGHT = 110;
7391
+ const WING_TITLE_TO_CONTENT_GAP = 4;
7392
+ const getWingDirection = (spec) => {
7393
+ var _a;
7394
+ return (_a = normalizeLayout(spec.layout).direction) !== null && _a !== void 0 ? _a : 'left';
7395
+ };
7396
+ const getWingArcGeometry = (spec, ctx) => {
7397
+ var _a, _b, _c, _e;
7398
+ const { width, height, startX, startY } = getRegionGeometry(ctx);
7399
+ const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
7400
+ const innerWidth = Math.max(width - padding.left - padding.right, 1);
7401
+ const innerHeight = Math.max(height - padding.top - padding.bottom, 1);
7402
+ const layoutOpt = normalizeLayout(spec.layout);
7403
+ const direction = getWingDirection(spec);
7404
+ const defaultStart = direction === 'right' ? 110 : -70;
7405
+ const defaultEnd = direction === 'right' ? 250 : 70;
7406
+ const startAngle = (_b = layoutOpt.startAngle) !== null && _b !== void 0 ? _b : defaultStart;
7407
+ const endAngle = (_c = layoutOpt.endAngle) !== null && _c !== void 0 ? _c : defaultEnd;
7408
+ const ratio = (_e = layoutOpt.radiusRatio) !== null && _e !== void 0 ? _e : 0.92;
7409
+ const ry = (innerHeight / 2) * ratio;
7410
+ const rx = innerWidth * 0.6 * ratio;
7411
+ const cx = direction === 'right' ? startX + padding.left + innerWidth - rx * 0.1 : startX + padding.left + rx * 0.1;
7412
+ const cy = startY + padding.top + innerHeight / 2;
7413
+ return { cx, cy, rx, ry, startAngle, endAngle };
7414
+ };
7415
+ const getWingBlockCenter = (spec, ctx, index) => {
7416
+ var _a, _b;
7417
+ const arc = getWingArcGeometry(spec, ctx);
7418
+ const count = (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
7419
+ if (count <= 0) {
7420
+ return { x: arc.cx, y: arc.cy };
7421
+ }
7422
+ const t = count === 1 ? 0.5 : index / (count - 1);
7423
+ const angle = ((arc.startAngle + (arc.endAngle - arc.startAngle) * t) / 180) * Math.PI;
7424
+ return {
7425
+ x: arc.cx + Math.cos(angle) * arc.rx,
7426
+ y: arc.cy + Math.sin(angle) * arc.ry
7427
+ };
7428
+ };
7429
+ const isTextOnLeft = (spec, index) => {
7430
+ const direction = getWingDirection(spec);
7431
+ return direction === 'right' ? index % 2 === 1 : index % 2 === 0;
7432
+ };
7433
+ const buildWingArcMark = (spec) => {
7434
+ var _a, _b, _c, _e, _f, _g, _h, _j;
7435
+ if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) === false) {
7436
+ return null;
7437
+ }
7438
+ const themeColor = getThemeColor(spec);
7439
+ const lineStyle = ((_c = (_b = spec.line) === null || _b === void 0 ? void 0 : _b.style) !== null && _c !== void 0 ? _c : {});
7440
+ const startWidth = Math.max(Number((_e = lineStyle.startWidth) !== null && _e !== void 0 ? _e : 2), 0.5);
7441
+ const endWidth = Math.max(Number((_g = (_f = lineStyle.endWidth) !== null && _f !== void 0 ? _f : lineStyle.lineWidth) !== null && _g !== void 0 ? _g : 18), startWidth);
7442
+ return {
7443
+ type: 'group',
7444
+ name: 'storyline-wing-arc',
7445
+ zIndex: vchart.LayoutZIndex.Mark,
7446
+ children: [
7447
+ {
7448
+ type: 'path',
7449
+ name: 'storyline-wing-arc-path',
7450
+ interactive: false,
7451
+ style: {
7452
+ stroke: false,
7453
+ lineWidth: 0,
7454
+ fill: (_j = (_h = lineStyle.fill) !== null && _h !== void 0 ? _h : lineStyle.stroke) !== null && _j !== void 0 ? _j : themeColor,
7455
+ opacity: 0.95,
7456
+ path: (_d, ctx) => {
7457
+ const arc = getWingArcGeometry(spec, ctx);
7458
+ const span = arc.endAngle - arc.startAngle;
7459
+ const samples = 96;
7460
+ const pts = [];
7461
+ for (let i = 0; i <= samples; i++) {
7462
+ const t = i / samples;
7463
+ const angle = ((arc.startAngle + span * t) / 180) * Math.PI;
7464
+ const cx = arc.cx + Math.cos(angle) * arc.rx;
7465
+ const cy = arc.cy + Math.sin(angle) * arc.ry;
7466
+ const nxRaw = Math.cos(angle) / arc.rx;
7467
+ const nyRaw = Math.sin(angle) / arc.ry;
7468
+ const nLen = Math.hypot(nxRaw, nyRaw) || 1;
7469
+ pts.push({
7470
+ x: cx,
7471
+ y: cy,
7472
+ nx: nxRaw / nLen,
7473
+ ny: nyRaw / nLen,
7474
+ w: startWidth + (endWidth - startWidth) * t
7475
+ });
7476
+ }
7477
+ const segments = [];
7478
+ for (let i = 0; i < pts.length; i++) {
7479
+ const p = pts[i];
7480
+ const x = p.x + p.nx * (p.w / 2);
7481
+ const y = p.y + p.ny * (p.w / 2);
7482
+ segments.push(`${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`);
7483
+ }
7484
+ for (let i = pts.length - 1; i >= 0; i--) {
7485
+ const p = pts[i];
7486
+ const x = p.x - p.nx * (p.w / 2);
7487
+ const y = p.y - p.ny * (p.w / 2);
7488
+ segments.push(`L ${x.toFixed(2)} ${y.toFixed(2)}`);
7489
+ }
7490
+ segments.push('Z');
7491
+ return segments.join(' ');
7492
+ }
7493
+ }
7494
+ }
7495
+ ]
7496
+ };
7497
+ };
7498
+ const getWingBlockMetrics = (spec, index) => {
7499
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
7500
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : WING_TITLE_FONT_SIZE);
7501
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.max(WING_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.3)));
7502
+ const contentFontSize = Number((_k = (_j = (_h = spec.content) === null || _h === void 0 ? void 0 : _h.style) === null || _j === void 0 ? void 0 : _j.fontSize) !== null && _k !== void 0 ? _k : WING_CONTENT_FONT_SIZE);
7503
+ const contentLineHeight = Number((_o = (_m = (_l = spec.content) === null || _l === void 0 ? void 0 : _l.style) === null || _m === void 0 ? void 0 : _m.lineHeight) !== null && _o !== void 0 ? _o : WING_CONTENT_LINE_HEIGHT);
7504
+ const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;
7505
+ const textHeight = WING_TEXT_BOX_HEIGHT;
7506
+ const contentHeight = Math.max(textHeight - titleLineHeight - titleToContentGap, contentLineHeight);
7507
+ const imageWidth = (_q = (_p = spec.image) === null || _p === void 0 ? void 0 : _p.width) !== null && _q !== void 0 ? _q : WING_BLOCK_IMAGE_SIZE;
7508
+ const imageHeight = (_s = (_r = spec.image) === null || _r === void 0 ? void 0 : _r.height) !== null && _s !== void 0 ? _s : WING_BLOCK_IMAGE_SIZE;
7509
+ const imageBox = {
7510
+ x: -imageWidth / 2,
7511
+ y: -imageHeight / 2,
7512
+ width: imageWidth,
7513
+ height: imageHeight
7514
+ };
7515
+ const onLeft = isTextOnLeft(spec, index);
7516
+ const textWidth = WING_TEXT_BOX_WIDTH;
7517
+ const textX = onLeft
7518
+ ? -imageWidth / 2 - WING_TEXT_GAP_FROM_IMAGE - textWidth
7519
+ : imageWidth / 2 + WING_TEXT_GAP_FROM_IMAGE;
7520
+ const textY = -textHeight / 2;
7521
+ const textBox = { x: textX, y: textY, width: textWidth, height: textHeight };
7522
+ const contentBox = {
7523
+ x: textX,
7524
+ y: textY + titleLineHeight + titleToContentGap,
7525
+ width: textWidth,
7526
+ height: contentHeight
7527
+ };
7528
+ return {
7529
+ onLeft,
7530
+ titleFontSize,
7531
+ titleLineHeight,
7532
+ contentFontSize,
7533
+ contentLineHeight,
7534
+ imageBox,
7535
+ textBox,
7536
+ contentBox
7537
+ };
7538
+ };
7539
+ const buildWingBlockMark = (spec, block, index) => {
7540
+ var _a, _b, _c, _e, _f;
7541
+ const hasImage = !!block.image;
7542
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7543
+ const themeColor = getThemeColor(spec);
7544
+ const metrics = getWingBlockMetrics(spec, index);
7545
+ const showBackground = ((_a = spec.image) === null || _a === void 0 ? void 0 : _a.showBackground) === true;
7546
+ return {
7547
+ type: 'group',
7548
+ id: `storyline-block-${(_b = block.id) !== null && _b !== void 0 ? _b : index}`,
7549
+ name: `storyline-block-${index}`,
7550
+ zIndex: vchart.LayoutZIndex.Mark + 1,
7551
+ style: {
7552
+ x: (_d, ctx) => getWingBlockCenter(spec, ctx, index).x,
7553
+ y: (_d, ctx) => getWingBlockCenter(spec, ctx, index).y
7554
+ },
7555
+ children: [
7556
+ showBackground
7557
+ ? {
7558
+ type: 'symbol',
7559
+ name: `storyline-block-image-halo-${index}`,
7560
+ interactive: false,
7561
+ style: {
7562
+ x: 0,
7563
+ y: 0,
7564
+ size: Math.max(metrics.imageBox.width, metrics.imageBox.height) + 12,
7565
+ symbolType: 'circle',
7566
+ fill: withAlpha(themeColor, 0.18),
7567
+ stroke: themeColor,
7568
+ lineWidth: 1.5
7569
+ }
7570
+ }
7571
+ : null,
7572
+ hasImage
7573
+ ? Object.assign(Object.assign({ type: 'image', name: `storyline-block-image-${index}`, interactive: false }, omitImageLayoutSpec(spec.image)), { style: Object.assign({ x: metrics.imageBox.x, y: metrics.imageBox.y, width: metrics.imageBox.width, height: metrics.imageBox.height, image: block.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'cover', imagePosition: 'center' }, (_c = spec.image) === null || _c === void 0 ? void 0 : _c.style) })
7574
+ : {
7575
+ type: 'rect',
7576
+ name: `storyline-block-image-bg-${index}`,
7577
+ interactive: false,
7578
+ style: {
7579
+ x: metrics.imageBox.x,
7580
+ y: metrics.imageBox.y,
7581
+ width: metrics.imageBox.width,
7582
+ height: metrics.imageBox.height,
7583
+ cornerRadius: Math.min(metrics.imageBox.width, metrics.imageBox.height) / 2,
7584
+ fill: '#ffffff',
7585
+ stroke: themeColor,
7586
+ lineWidth: 2
7587
+ }
7588
+ },
7589
+ block.title
7590
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 10 }, spec.title), { style: Object.assign({ x: metrics.onLeft ? metrics.textBox.x + metrics.textBox.width : metrics.textBox.x, y: metrics.textBox.y, text: block.title, maxLineWidth: metrics.textBox.width, fontSize: metrics.titleFontSize, lineHeight: metrics.titleLineHeight, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: metrics.onLeft ? 'right' : 'left', textBaseline: 'top' }, (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) })
7591
+ : null,
7592
+ contentText.length
7593
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false, zIndex: vchart.LayoutZIndex.Mark + 10 }, spec.content), { textType: 'rich', style: Object.assign({ x: metrics.onLeft ? metrics.contentBox.x + metrics.contentBox.width : metrics.contentBox.x, y: metrics.contentBox.y, width: metrics.contentBox.width, height: metrics.contentBox.height, maxLineWidth: metrics.contentBox.width, heightLimit: metrics.contentBox.height, text: buildRichContent(contentText, spec), fontSize: WING_CONTENT_FONT_SIZE, lineHeight: WING_CONTENT_LINE_HEIGHT, textAlign: metrics.onLeft ? 'right' : 'left', textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#1f2430' }, (_f = spec.content) === null || _f === void 0 ? void 0 : _f.style) })
7594
+ : null
7595
+ ].filter(Boolean)
7596
+ };
7597
+ };
7598
+
7599
+ const LADDER_HEADLINE_FONT_RATIO = 0.42;
7600
+ const LADDER_HEADLINE_FONT_MIN = 80;
7601
+ const LADDER_HEADLINE_FONT_MAX = 240;
7602
+ const LADDER_DIAGONAL_LINE_WIDTH = 2;
7603
+ const LADDER_DIAGONAL_DASH = [12, 8];
7604
+ const LADDER_BLOCK_IMAGE_SIZE = 96;
7605
+ const LADDER_TITLE_FONT_SIZE = 28;
7606
+ const LADDER_TITLE_LINE_HEIGHT = 36;
7607
+ const LADDER_CONTENT_FONT_SIZE = 16;
7608
+ const LADDER_CONTENT_LINE_HEIGHT = 24;
7609
+ const isDownLadder = (spec) => normalizeLayout(spec.layout).direction === 'down';
7610
+ const getLadderDiagonalGeometry = (spec, ctx) => {
7611
+ var _a;
7612
+ const { width, height, startX, startY } = getRegionGeometry(ctx);
7613
+ const padding = normalizePadding((_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding);
7614
+ const innerX = startX + padding.left;
7615
+ const innerY = startY + padding.top;
7616
+ const innerW = Math.max(width - padding.left - padding.right, 1);
7617
+ const innerH = Math.max(height - padding.top - padding.bottom, 1);
7618
+ const isDown = isDownLadder(spec);
7619
+ const x0 = innerX;
7620
+ const x1 = innerX + innerW;
7621
+ const y0 = isDown ? innerY : innerY + innerH;
7622
+ const y1 = isDown ? innerY + innerH : innerY;
7623
+ const cx = (x0 + x1) / 2;
7624
+ const cy = (y0 + y1) / 2;
7625
+ const dx = x1 - x0;
7626
+ const dy = y1 - y0;
7627
+ const angleRad = (Math.atan2(dy, dx) / Math.PI) * 180;
7628
+ const fontSize = Math.max(LADDER_HEADLINE_FONT_MIN, Math.min(LADDER_HEADLINE_FONT_MAX, Math.round(innerH * LADDER_HEADLINE_FONT_RATIO)));
7629
+ return { x0, y0, x1, y1, cx, cy, angleRad, fontSize };
7630
+ };
7631
+ const getLadderHeadlineText = (spec) => {
7632
+ var _a, _b;
7633
+ const layoutOpt = normalizeLayout(spec.layout);
7634
+ if (typeof layoutOpt.headline === 'string' && layoutOpt.headline.length > 0) {
7635
+ return layoutOpt.headline;
7636
+ }
7637
+ const title = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.text;
7638
+ if (typeof title === 'string' && title.length > 0) {
7639
+ return title;
7640
+ }
7641
+ return 'storyline';
7642
+ };
7643
+ const buildLadderDiagonalMark = (spec) => {
7644
+ const themeColor = getThemeColor(spec);
7645
+ return {
7646
+ type: 'group',
7647
+ name: 'storyline-ladder-diagonal',
7648
+ zIndex: vchart.LayoutZIndex.Mark - 1,
7649
+ children: [
7650
+ {
7651
+ type: 'path',
7652
+ name: 'storyline-ladder-diagonal-line',
7653
+ interactive: false,
7654
+ style: {
7655
+ path: (_d, ctx) => {
7656
+ const g = getLadderDiagonalGeometry(spec, ctx);
7657
+ return `M ${g.x0} ${g.y0} L ${g.x1} ${g.y1}`;
7658
+ },
7659
+ stroke: withAlpha(themeColor, 0.85),
7660
+ lineWidth: LADDER_DIAGONAL_LINE_WIDTH,
7661
+ lineDash: LADDER_DIAGONAL_DASH,
7662
+ fill: 'transparent'
7663
+ }
7664
+ }
7665
+ ]
7666
+ };
7667
+ };
7668
+ const buildLadderHeadlineMark = (spec) => {
7669
+ const text = getLadderHeadlineText(spec);
7670
+ if (!text) {
7671
+ return null;
7672
+ }
7673
+ const themeColor = getThemeColor(spec);
7674
+ return {
7675
+ type: 'group',
7676
+ name: 'storyline-ladder-headline',
7677
+ zIndex: vchart.LayoutZIndex.Mark,
7678
+ style: {
7679
+ x: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).cx,
7680
+ y: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).cy,
7681
+ angle: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).angleRad
7682
+ },
7683
+ children: [
7684
+ {
7685
+ type: 'text',
7686
+ name: 'storyline-ladder-headline-text',
7687
+ interactive: false,
7688
+ style: {
7689
+ x: 0,
7690
+ y: 0,
7691
+ text,
7692
+ fontSize: (_d, ctx) => getLadderDiagonalGeometry(spec, ctx).fontSize,
7693
+ fontWeight: 900,
7694
+ fontFamily: 'Impact, "Arial Black", sans-serif',
7695
+ fill: withAlpha(themeColor, 0.92),
7696
+ textAlign: 'center',
7697
+ textBaseline: 'middle'
7698
+ }
7699
+ }
7700
+ ]
7701
+ };
7702
+ };
7703
+ const isOnLeft = (index) => index % 2 === 1;
7704
+ const getLadderBlockMetrics = (spec, ctx, index) => {
7705
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
7706
+ const block = getLayout(spec, ctx).blocks[index];
7707
+ const padding = normalizePadding((_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.padding) !== null && _b !== void 0 ? _b : 12);
7708
+ const imagePosition = isOnLeft(index) ? 'right' : 'left';
7709
+ const imageWidth = (_e = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.width) !== null && _e !== void 0 ? _e : LADDER_BLOCK_IMAGE_SIZE;
7710
+ const imageHeight = (_g = (_f = spec.image) === null || _f === void 0 ? void 0 : _f.height) !== null && _g !== void 0 ? _g : LADDER_BLOCK_IMAGE_SIZE;
7711
+ const imageGap = (_j = (_h = spec.image) === null || _h === void 0 ? void 0 : _h.gap) !== null && _j !== void 0 ? _j : DEFAULT_IMAGE_GAP;
7712
+ const hasImage = !!((_l = (_k = spec.data) === null || _k === void 0 ? void 0 : _k[index]) === null || _l === void 0 ? void 0 : _l.image);
7713
+ const titleFontSize = Number((_p = (_o = (_m = spec.title) === null || _m === void 0 ? void 0 : _m.style) === null || _o === void 0 ? void 0 : _o.fontSize) !== null && _p !== void 0 ? _p : LADDER_TITLE_FONT_SIZE);
7714
+ const titleLineHeight = Number((_s = (_r = (_q = spec.title) === null || _q === void 0 ? void 0 : _q.style) === null || _r === void 0 ? void 0 : _r.lineHeight) !== null && _s !== void 0 ? _s : Math.round(titleFontSize * (LADDER_TITLE_LINE_HEIGHT / LADDER_TITLE_FONT_SIZE)));
7715
+ const titleHeight = ((_u = (_t = spec.data) === null || _t === void 0 ? void 0 : _t[index]) === null || _u === void 0 ? void 0 : _u.title) ? titleLineHeight : 0;
7716
+ const blockWidth = (_v = block === null || block === void 0 ? void 0 : block.width) !== null && _v !== void 0 ? _v : resolveBlockWidth(spec, 0);
7717
+ const blockHeight = (_y = (_w = block === null || block === void 0 ? void 0 : block.height) !== null && _w !== void 0 ? _w : (_x = spec.block) === null || _x === void 0 ? void 0 : _x.height) !== null && _y !== void 0 ? _y : DEFAULT_BLOCK_HEIGHT;
7718
+ const imageBox = getImageBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
7719
+ const textBox = getTextBox(imagePosition, blockWidth, blockHeight, padding, imageWidth, imageHeight, imageGap, hasImage);
7720
+ const contentGap = ((_0 = (_z = spec.data) === null || _z === void 0 ? void 0 : _z[index]) === null || _0 === void 0 ? void 0 : _0.title) ? 8 : 0;
7721
+ return {
7722
+ block: { width: blockWidth, height: blockHeight },
7723
+ imageBox,
7724
+ textBox,
7725
+ contentBox: {
7726
+ y: textBox.y + titleHeight + contentGap,
7727
+ height: Math.max(0, textBox.height - titleHeight - contentGap)
7728
+ }
7729
+ };
7730
+ };
7731
+ const buildLadderBlockMark = (spec, block, index) => {
7732
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o;
7733
+ const hasImage = !!block.image;
7734
+ const onLeft = isOnLeft(index);
7735
+ const align = onLeft ? 'right' : 'left';
7736
+ const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];
7737
+ const titleFontSize = Number((_c = (_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _c !== void 0 ? _c : LADDER_TITLE_FONT_SIZE);
7738
+ const titleLineHeight = Number((_g = (_f = (_e = spec.title) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.lineHeight) !== null && _g !== void 0 ? _g : Math.round(titleFontSize * (LADDER_TITLE_LINE_HEIGHT / LADDER_TITLE_FONT_SIZE)));
7739
+ const showBackground = ((_h = spec.block) === null || _h === void 0 ? void 0 : _h.showBackground) === true;
7740
+ const getTitleX = (ctx) => {
7741
+ const m = getLadderBlockMetrics(spec, ctx, index);
7742
+ return align === 'right' ? m.textBox.x + m.textBox.width : m.textBox.x;
7743
+ };
7744
+ return {
7745
+ type: 'group',
7746
+ id: `storyline-block-${(_j = block.id) !== null && _j !== void 0 ? _j : index}`,
7747
+ name: `storyline-block-${index}`,
7748
+ zIndex: vchart.LayoutZIndex.Mark + 1,
7749
+ style: {
7750
+ 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; },
7751
+ 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; },
7752
+ width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.width,
7753
+ height: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).block.height
7754
+ },
7755
+ children: [
7756
+ showBackground
7757
+ ? {
7758
+ type: 'rect',
7759
+ name: `storyline-block-bg-${index}`,
7760
+ interactive: false,
7761
+ 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)' }, (_k = spec.block) === null || _k === void 0 ? void 0 : _k.style)
7762
+ }
7763
+ : null,
7764
+ hasImage
7765
+ ? 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 }, (_l = spec.image) === null || _l === void 0 ? void 0 : _l.style) })
7766
+ : null,
7767
+ block.title
7768
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-title-${index}`, interactive: false }, spec.title), { style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.y, text: block.title, maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, fontSize: titleFontSize, lineHeight: titleLineHeight, fontWeight: 'bold', fill: '#1f2430', stroke: '#fff', lineWidth: 5, lineJoin: 'round', textBaseline: 'top' }, (_m = spec.title) === null || _m === void 0 ? void 0 : _m.style), { textAlign: align }) })
7769
+ : null,
7770
+ contentText.length
7771
+ ? Object.assign(Object.assign({ type: 'text', name: `storyline-block-content-${index}`, interactive: false }, spec.content), { textType: 'rich', style: Object.assign(Object.assign({ x: (_d, ctx) => getTitleX(ctx), y: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.y, width: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, text: buildRichContent(contentText, spec), maxLineWidth: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).textBox.width, fontSize: LADDER_CONTENT_FONT_SIZE, lineHeight: LADDER_CONTENT_LINE_HEIGHT, heightLimit: (_d, ctx) => getLadderBlockMetrics(spec, ctx, index).contentBox.height, textBaseline: 'top', wordBreak: 'break-word', ellipsis: '...', fill: '#596173' }, (_o = spec.content) === null || _o === void 0 ? void 0 : _o.style), { textAlign: align }) })
7772
+ : null
7773
+ ].filter(Boolean)
7774
+ };
7775
+ };
7776
+
7777
+ class StorylineChartSpecTransformer extends vchart.CommonChartSpecTransformer {
7778
+ transformSpec(spec) {
7779
+ var _a;
7780
+ applyDefaultPadding(spec);
7781
+ const storylineSpec = Object.assign(Object.assign({}, spec), { data: [...((_a = spec.data) !== null && _a !== void 0 ? _a : [])] });
7782
+ spec.type = 'common';
7783
+ spec.data = [];
7784
+ spec.series = [];
7785
+ spec.axes = [];
7786
+ spec.customMark = buildStorylineMarks(storylineSpec);
7787
+ delete spec.layout;
7788
+ delete spec.title;
7789
+ super.transformSpec(spec);
7790
+ }
7791
+ }
7792
+ const applyDefaultPadding = (spec) => {
7793
+ var _a, _b, _c, _d;
7794
+ const LARGE = 100;
7795
+ const SMALL = 20;
7796
+ const TEXT_RESERVE = 280;
7797
+ const PORTRAIT_BOTTOM_RESERVE = 160;
7798
+ const arc = isArc(spec);
7799
+ const arcDown = arc && normalizeLayout(spec.layout).direction === 'down';
7800
+ const arcUp = arc && !arcDown;
7801
+ const portrait = isPortrait(spec);
7802
+ const ladder = isLadder(spec);
7803
+ const ladderHorizontalPadding = (() => {
7804
+ var _a, _b, _c, _d, _e, _f;
7805
+ if (!ladder) {
7806
+ return 0;
7807
+ }
7808
+ const blockWidth = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.minWidth) !== null && _b !== void 0 ? _b : resolveBlockWidth(spec, 0);
7809
+ const imageWidth = (_d = (_c = spec.image) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : 96;
7810
+ const imageGap = (_f = (_e = spec.image) === null || _e === void 0 ? void 0 : _e.gap) !== null && _f !== void 0 ? _f : DEFAULT_IMAGE_GAP;
7811
+ const innerPadding = 12 * 2;
7812
+ const contentWidth = Math.max(blockWidth - imageWidth - imageGap - innerPadding, DEFAULT_BLOCK_WIDTH * 0.5);
7813
+ return Math.round(contentWidth * 2);
7814
+ })();
7815
+ const ladderVerticalPadding = (() => {
7816
+ var _a, _b;
7817
+ if (!ladder) {
7818
+ return 0;
7819
+ }
7820
+ const blockHeight = (_b = (_a = spec.block) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : DEFAULT_BLOCK_HEIGHT;
7821
+ const chartHeight = spec.height;
7822
+ const heightCap = typeof chartHeight === 'number' && chartHeight > 0 ? Math.max(SMALL, Math.round(chartHeight * 0.18)) : Infinity;
7823
+ return Math.round(Math.min(blockHeight * 3, heightCap));
7824
+ })();
7825
+ const defaultTop = ladder ? ladderVerticalPadding : arcDown ? LARGE : arcUp ? TEXT_RESERVE : SMALL;
7826
+ const defaultBottom = ladder
7827
+ ? ladderVerticalPadding
7828
+ : arcDown
7829
+ ? TEXT_RESERVE
7830
+ : portrait
7831
+ ? PORTRAIT_BOTTOM_RESERVE
7832
+ : LARGE;
7833
+ const defaultLeft = ladder ? ladderHorizontalPadding : SMALL;
7834
+ const defaultRight = ladder ? ladderHorizontalPadding : SMALL;
7835
+ const p = spec.padding;
7836
+ if (p === undefined || p === null) {
7837
+ spec.padding = [defaultTop, defaultRight, defaultBottom, defaultLeft];
7838
+ return;
7839
+ }
7840
+ if (typeof p === 'number') {
7841
+ spec.padding = [
7842
+ Math.max(p, defaultTop),
7843
+ Math.max(p, defaultRight),
7844
+ Math.max(p, defaultBottom),
7845
+ Math.max(p, defaultLeft)
7846
+ ];
7847
+ return;
7848
+ }
7849
+ if (Array.isArray(p)) {
7850
+ const [t, r = defaultRight, b, l = defaultLeft] = p;
7851
+ spec.padding = [t !== null && t !== void 0 ? t : defaultTop, r, b !== null && b !== void 0 ? b : defaultBottom, l];
7852
+ return;
7853
+ }
7854
+ if (typeof p === 'object') {
7855
+ spec.padding = {
7856
+ top: (_a = p.top) !== null && _a !== void 0 ? _a : defaultTop,
7857
+ right: (_b = p.right) !== null && _b !== void 0 ? _b : defaultRight,
7858
+ bottom: (_c = p.bottom) !== null && _c !== void 0 ? _c : defaultBottom,
7859
+ left: (_d = p.left) !== null && _d !== void 0 ? _d : defaultLeft
7860
+ };
7861
+ }
7862
+ };
7863
+ const buildStorylineMarks = (spec) => {
7864
+ var _a;
7865
+ const lineMark = buildLineMark(spec);
7866
+ const blockMarks = ((_a = spec.data) !== null && _a !== void 0 ? _a : []).map((block, index) => buildBlockMark(spec, block, index));
7867
+ if (isLandscape(spec)) {
7868
+ return [...blockMarks, lineMark].filter(Boolean);
7869
+ }
7870
+ if (isPortrait(spec)) {
7871
+ return [lineMark, ...blockMarks].filter(Boolean);
7872
+ }
7873
+ if (isArc(spec)) {
7874
+ const centerImageMark = buildArcCenterImageMark(spec);
7875
+ const arcMark = buildArcMark(spec);
7876
+ return [centerImageMark, arcMark, ...blockMarks].filter(Boolean);
7877
+ }
7878
+ if (isClock(spec)) {
7879
+ const ringsMark = buildClockArcMark(spec);
7880
+ const centerImageMark = buildClockCenterImageMark(spec);
7881
+ return [ringsMark, ...blockMarks, centerImageMark].filter(Boolean);
7882
+ }
7883
+ if (isWing(spec)) {
7884
+ const arcMark = buildWingArcMark(spec);
7885
+ return [arcMark, ...blockMarks].filter(Boolean);
7886
+ }
7887
+ if (isLadder(spec)) {
7888
+ const diagonalMark = buildLadderDiagonalMark(spec);
7889
+ const headlineMark = buildLadderHeadlineMark(spec);
7890
+ return [diagonalMark, headlineMark, ...blockMarks].filter(Boolean);
7891
+ }
7892
+ return [lineMark, ...blockMarks].filter(Boolean);
7893
+ };
7894
+ const buildLineMark = (spec) => {
7895
+ var _a, _b, _c;
7896
+ if (((_a = spec.line) === null || _a === void 0 ? void 0 : _a.visible) === false || ((_c = (_b = spec.data) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) <= 1) {
7897
+ return null;
7898
+ }
7899
+ if (isLandscape(spec)) {
7900
+ return buildLandscapeConnectingCurve(spec);
7901
+ }
7902
+ if (isPortrait(spec)) {
7903
+ return buildPortraitAxisMark(spec);
7904
+ }
7905
+ return buildDefaultLineMark(spec);
7906
+ };
7907
+ const buildBlockMark = (spec, block, index) => {
7908
+ if (isLandscape(spec)) {
7909
+ return buildLandscapeBlockMark(spec, block, index);
7910
+ }
7911
+ if (isPortrait(spec)) {
7912
+ return buildPortraitBlockMark(spec, block, index);
7913
+ }
7914
+ if (isArc(spec)) {
7915
+ return buildArcBlockMark(spec, block, index);
7916
+ }
7917
+ if (isClock(spec)) {
7918
+ return buildClockBlockMark(spec, block, index);
7919
+ }
7920
+ if (isWing(spec)) {
7921
+ return buildWingBlockMark(spec, block, index);
7922
+ }
7923
+ if (isLadder(spec)) {
7924
+ return buildLadderBlockMark(spec, block, index);
7925
+ }
7926
+ return buildDefaultBlockMark(spec, block, index);
7927
+ };
7928
+
7929
+ class StorylineChart extends vchart.BaseChart {
7930
+ constructor() {
7931
+ super(...arguments);
7932
+ this.type = 'storyline';
7933
+ this.transformerConstructor = StorylineChartSpecTransformer;
7934
+ }
7935
+ init() {
7936
+ if (!this.isValid()) {
7937
+ return;
7938
+ }
7939
+ super.init();
7940
+ }
7941
+ isValid() {
7942
+ var _a, _b;
7943
+ const { data } = this._spec;
7944
+ if (!Array.isArray(data)) {
7945
+ (_b = (_a = this._option).onError) === null || _b === void 0 ? void 0 : _b.call(_a, 'Data is required and should be an array for storyline chart');
7946
+ return false;
7947
+ }
7948
+ return true;
7949
+ }
7950
+ }
7951
+ StorylineChart.type = 'storyline';
7952
+ StorylineChart.view = 'singleDefault';
7953
+ StorylineChart.transformerConstructor = StorylineChartSpecTransformer;
7954
+ const registerStorylineChart = (option) => {
7955
+ vchart.registerCommonChart();
7956
+ vchart.registerCustomMark();
7957
+ vchart.registerGroupMark();
7958
+ vchart.registerRectMark();
7959
+ vchart.registerTextMark();
7960
+ vchart.registerImageMark();
7961
+ vchart.registerLineMark();
7962
+ vchart.registerPathMark();
7963
+ vchart.registerArcMark();
7964
+ const vchartConstructor = (option === null || option === void 0 ? void 0 : option.VChart) || vchart.VChart;
7965
+ if (vchartConstructor) {
7966
+ vchartConstructor.useChart([StorylineChart]);
7967
+ }
7968
+ };
7969
+
5825
7970
  const SERIES_BREAK = 'seriesBreak';
5826
7971
 
5827
7972
  function generateZigzagPath(start, end, size, angle, isVertical = false) {
@@ -7961,6 +10106,8 @@
7961
10106
  exports.SequenceScatterPixel = SequenceScatterPixel;
7962
10107
  exports.SeriesBreakComponent = SeriesBreakComponent;
7963
10108
  exports.SeriesLabelComponent = SeriesLabelComponent;
10109
+ exports.StorylineChart = StorylineChart;
10110
+ exports.StorylineChartSpecTransformer = StorylineChartSpecTransformer;
7964
10111
  exports.TimelineChart = TimelineChart;
7965
10112
  exports.WordCloud3dChart = WordCloud3dChart;
7966
10113
  exports.WordCloud3dChartSpecTransformer = WordCloud3dChartSpecTransformer;
@@ -7972,6 +10119,7 @@
7972
10119
  exports.appendSeriesBreakConfig = appendSeriesBreakConfig;
7973
10120
  exports.appendSeriesLabelConfig = appendSeriesLabelConfig;
7974
10121
  exports.clearSVGSource = clearSVGSource;
10122
+ exports.computeStorylineLayout = computeStorylineLayout;
7975
10123
  exports.getBarLinkConfig = getBarLinkConfig;
7976
10124
  exports.getBarRegressionLineConfig = getBarRegressionLineConfig;
7977
10125
  exports.getHistogramRegressionLineConfig = getHistogramRegressionLineConfig;
@@ -7979,6 +10127,8 @@
7979
10127
  exports.getScatterRegressionLineConfig = getScatterRegressionLineConfig;
7980
10128
  exports.getSeriesBreakConfig = getSeriesBreakConfig;
7981
10129
  exports.getSeriesLabelConfig = getSeriesLabelConfig;
10130
+ exports.normalizeLayout = normalizeLayout;
10131
+ exports.normalizePadding = normalizePadding;
7982
10132
  exports.register3DPlugin = register3DPlugin;
7983
10133
  exports.registerAxis3dPlugin = registerAxis3dPlugin;
7984
10134
  exports.registerBar3dChart = registerBar3dChart;
@@ -8010,6 +10160,7 @@
8010
10160
  exports.registerSequenceScatterPixel = registerSequenceScatterPixel;
8011
10161
  exports.registerSeriesBreak = registerSeriesBreak;
8012
10162
  exports.registerSeriesLabel = registerSeriesLabel;
10163
+ exports.registerStorylineChart = registerStorylineChart;
8013
10164
  exports.registerTimelineChart = registerTimelineChart;
8014
10165
  exports.registerWordCloud3dChart = registerWordCloud3dChart;
8015
10166
  exports.registerWordCloud3dSeries = registerWordCloud3dSeries;