@visactor/vchart-extension 2.1.0-alpha.2 → 2.1.0-alpha.20

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