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

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 (143) hide show
  1. package/build/index.js +118 -17
  2. package/build/index.min.js +1 -1
  3. package/cjs/charts/3d/plugin.js +1 -1
  4. package/cjs/charts/3d/pyramid-3d.js +1 -1
  5. package/cjs/charts/3d/rect-3d.js +1 -1
  6. package/cjs/charts/3d/util.js +1 -1
  7. package/cjs/charts/axis-3d/axis-3d-mixin.js +1 -1
  8. package/cjs/charts/axis-3d/band-axis.js +1 -1
  9. package/cjs/charts/axis-3d/index.js +1 -1
  10. package/cjs/charts/axis-3d/linear-axis.js +1 -2
  11. package/cjs/charts/axis-3d/log-axis.js +1 -1
  12. package/cjs/charts/axis-3d/symlog-axis.js +1 -1
  13. package/cjs/charts/axis-3d/theme.js +1 -1
  14. package/cjs/charts/axis-3d/time-axis.js +1 -1
  15. package/cjs/charts/axis-3d/util.js +1 -1
  16. package/cjs/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  17. package/cjs/charts/combination-candlestick/combination-candlestick.js +1 -1
  18. package/cjs/charts/combination-candlestick/constant.js +1 -1
  19. package/cjs/charts/combination-candlestick/index.js +1 -1
  20. package/cjs/charts/combination-candlestick/interface.js +1 -1
  21. package/cjs/charts/conversion-funnel/arrow-data-transform.js +1 -1
  22. package/cjs/charts/conversion-funnel/constants.js +1 -1
  23. package/cjs/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  24. package/cjs/charts/conversion-funnel/conversion-funnel.js +1 -1
  25. package/cjs/charts/conversion-funnel/index.js +1 -1
  26. package/cjs/charts/conversion-funnel/interface.js +1 -1
  27. package/cjs/charts/conversion-funnel/util.js +1 -1
  28. package/cjs/charts/funnel-3d/chart.js +1 -1
  29. package/cjs/charts/funnel-3d/constant.js +1 -1
  30. package/cjs/charts/funnel-3d/index.js +1 -1
  31. package/cjs/charts/funnel-3d/interface.js +1 -1
  32. package/cjs/charts/funnel-3d/series-spec-transformer.js +1 -1
  33. package/cjs/charts/histogram-3d/chart.js +1 -2
  34. package/cjs/charts/histogram-3d/index.js +1 -1
  35. package/cjs/charts/histogram-3d/interface.js +1 -1
  36. package/cjs/charts/storyline/layouts/wing.js +92 -19
  37. package/cjs/charts/storyline/layouts/wing.js.map +1 -1
  38. package/cjs/charts/storyline/storyline-transformer.js +7 -3
  39. package/cjs/charts/storyline/storyline-transformer.js.map +1 -1
  40. package/cjs/components/bar-link/bar-link.js +1 -1
  41. package/cjs/components/bar-link/constant.js +1 -1
  42. package/cjs/components/bar-link/index.js +1 -1
  43. package/cjs/components/bar-link/type.js +1 -1
  44. package/cjs/components/bar-link/util.js +1 -1
  45. package/cjs/components/bar-regression-line/index.js +1 -1
  46. package/cjs/components/bar-regression-line/type.js +2 -1
  47. package/cjs/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  48. package/cjs/components/extension-mark-sync-state/index.js +1 -1
  49. package/cjs/components/extension-mark-sync-state/type.js +1 -1
  50. package/cjs/components/histogram-regression-line/index.js +1 -1
  51. package/cjs/components/histogram-regression-line/type.js +1 -1
  52. package/cjs/components/map-label/index.js +1 -1
  53. package/cjs/components/map-label/layout.js +1 -1
  54. package/cjs/components/map-label/map-label-transformer.js +1 -1
  55. package/cjs/components/map-label/map-label.js +1 -1
  56. package/cjs/components/map-label/theme.js +1 -1
  57. package/cjs/components/map-label/type.js +1 -1
  58. package/cjs/components/regression-line/index.js +1 -1
  59. package/cjs/components/regression-line/regression-line.js +1 -1
  60. package/cjs/components/regression-line/type.js +1 -1
  61. package/cjs/components/scatter-regression-line/index.js +1 -1
  62. package/cjs/components/scatter-regression-line/type.js +1 -1
  63. package/cjs/components/series-break/constant.js +1 -1
  64. package/cjs/components/series-break/index.js +1 -1
  65. package/cjs/components/series-break/series-break.js +1 -1
  66. package/cjs/components/series-break/type.js +1 -1
  67. package/cjs/components/series-break/util.js +1 -1
  68. package/cjs/components/series-label/constant.js +1 -1
  69. package/cjs/components/series-label/index.js +2 -1
  70. package/cjs/components/series-label/series-label.js +1 -1
  71. package/cjs/components/series-label/type.js +1 -1
  72. package/cjs/components/series-label/util.js +1 -1
  73. package/esm/charts/3d/plugin.js +1 -1
  74. package/esm/charts/3d/pyramid-3d.js +1 -1
  75. package/esm/charts/3d/rect-3d.js +1 -1
  76. package/esm/charts/3d/util.js +1 -1
  77. package/esm/charts/axis-3d/axis-3d-mixin.js +1 -1
  78. package/esm/charts/axis-3d/band-axis.js +1 -1
  79. package/esm/charts/axis-3d/index.js +1 -1
  80. package/esm/charts/axis-3d/linear-axis.js +1 -2
  81. package/esm/charts/axis-3d/log-axis.js +1 -1
  82. package/esm/charts/axis-3d/symlog-axis.js +1 -1
  83. package/esm/charts/axis-3d/theme.js +1 -1
  84. package/esm/charts/axis-3d/time-axis.js +1 -1
  85. package/esm/charts/axis-3d/util.js +1 -1
  86. package/esm/charts/combination-candlestick/combination-candlestick-transformer.js +1 -1
  87. package/esm/charts/combination-candlestick/combination-candlestick.js +1 -1
  88. package/esm/charts/combination-candlestick/constant.js +1 -1
  89. package/esm/charts/combination-candlestick/index.js +1 -1
  90. package/esm/charts/combination-candlestick/interface.js +1 -1
  91. package/esm/charts/conversion-funnel/arrow-data-transform.js +1 -1
  92. package/esm/charts/conversion-funnel/constants.js +1 -1
  93. package/esm/charts/conversion-funnel/conversion-funnel-transformer.js +1 -1
  94. package/esm/charts/conversion-funnel/conversion-funnel.js +1 -1
  95. package/esm/charts/conversion-funnel/index.js +1 -1
  96. package/esm/charts/conversion-funnel/interface.js +1 -1
  97. package/esm/charts/conversion-funnel/util.js +1 -1
  98. package/esm/charts/funnel-3d/chart.js +1 -1
  99. package/esm/charts/funnel-3d/constant.js +1 -1
  100. package/esm/charts/funnel-3d/index.js +1 -1
  101. package/esm/charts/funnel-3d/interface.js +1 -1
  102. package/esm/charts/funnel-3d/series-spec-transformer.js +1 -1
  103. package/esm/charts/histogram-3d/chart.js +1 -2
  104. package/esm/charts/histogram-3d/index.js +1 -1
  105. package/esm/charts/histogram-3d/interface.js +1 -1
  106. package/esm/charts/storyline/layouts/wing.js +92 -19
  107. package/esm/charts/storyline/layouts/wing.js.map +1 -1
  108. package/esm/charts/storyline/storyline-transformer.js +5 -3
  109. package/esm/charts/storyline/storyline-transformer.js.map +1 -1
  110. package/esm/components/bar-link/bar-link.js +1 -1
  111. package/esm/components/bar-link/constant.js +1 -1
  112. package/esm/components/bar-link/index.js +1 -1
  113. package/esm/components/bar-link/type.js +1 -1
  114. package/esm/components/bar-link/util.js +1 -1
  115. package/esm/components/bar-regression-line/index.js +1 -1
  116. package/esm/components/bar-regression-line/type.js +2 -1
  117. package/esm/components/extension-mark-sync-state/extension-mark-sync-state.js +1 -1
  118. package/esm/components/extension-mark-sync-state/index.js +1 -1
  119. package/esm/components/extension-mark-sync-state/type.js +1 -1
  120. package/esm/components/histogram-regression-line/index.js +1 -1
  121. package/esm/components/histogram-regression-line/type.js +1 -1
  122. package/esm/components/map-label/index.js +1 -1
  123. package/esm/components/map-label/layout.js +1 -1
  124. package/esm/components/map-label/map-label-transformer.js +1 -1
  125. package/esm/components/map-label/map-label.js +1 -1
  126. package/esm/components/map-label/theme.js +1 -1
  127. package/esm/components/map-label/type.js +1 -1
  128. package/esm/components/regression-line/index.js +1 -1
  129. package/esm/components/regression-line/regression-line.js +1 -1
  130. package/esm/components/regression-line/type.js +1 -1
  131. package/esm/components/scatter-regression-line/index.js +1 -1
  132. package/esm/components/scatter-regression-line/type.js +1 -1
  133. package/esm/components/series-break/constant.js +1 -1
  134. package/esm/components/series-break/index.js +1 -1
  135. package/esm/components/series-break/series-break.js +1 -1
  136. package/esm/components/series-break/type.js +1 -1
  137. package/esm/components/series-break/util.js +1 -1
  138. package/esm/components/series-label/constant.js +1 -1
  139. package/esm/components/series-label/index.js +2 -1
  140. package/esm/components/series-label/series-label.js +1 -1
  141. package/esm/components/series-label/type.js +1 -1
  142. package/esm/components/series-label/util.js +1 -1
  143. package/package.json +4 -4
package/build/index.js CHANGED
@@ -7563,9 +7563,14 @@
7563
7563
  const WING_BLOCK_IMAGE_SIZE = 160;
7564
7564
  const WING_TITLE_LINE_HEIGHT = 30;
7565
7565
  const WING_TITLE_FONT_SIZE = 22;
7566
+ const WING_TITLE_MIN_FONT_SIZE = 14;
7567
+ const WING_TITLE_MAX_FONT_SIZE = 30;
7566
7568
  const WING_CONTENT_LINE_HEIGHT = 17;
7567
7569
  const WING_CONTENT_FONT_SIZE = 12;
7568
7570
  const WING_TEXT_BOX_WIDTH = 240;
7571
+ const WING_TEXT_BOX_MIN_WIDTH = 240;
7572
+ const WING_TEXT_BOX_MAX_WIDTH = 360;
7573
+ const WING_TEXT_BOX_WIDTH_RATIO = 0.24;
7569
7574
  const WING_TEXT_BOX_HEIGHT = 110;
7570
7575
  const WING_TITLE_TO_CONTENT_GAP = 4;
7571
7576
  const WING_TITLE_IMAGE_WIDTH_RATIO = 0.6;
@@ -7574,6 +7579,7 @@
7574
7579
  const WING_IMAGE_MIN_SCALE = 0.52;
7575
7580
  const WING_IMAGE_MAX_SCALE = 1.2;
7576
7581
  const WING_BOTTOM_TEXT_IMAGE_GAP_RATIO = 1.35;
7582
+ const WING_PATH_EDGE_GAP = 8;
7577
7583
  const clamp = (value, min, max) => Math.max(min, Math.min(max, value));
7578
7584
  const getWingDirection = (spec) => {
7579
7585
  return normalizeLayout(spec.layout).direction === 'right' ? 'right' : 'left';
@@ -7599,6 +7605,65 @@
7599
7605
  const endScale = clamp(endWidth / WING_DEFAULT_PATH_END_WIDTH, WING_IMAGE_MIN_SCALE, WING_IMAGE_MAX_SCALE);
7600
7606
  return startScale + (endScale - startScale) * getWingBlockPathRatio(spec, index);
7601
7607
  };
7608
+ const getConfiguredTextBoxWidth = (spec) => {
7609
+ var _a, _b, _c;
7610
+ const style = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style;
7611
+ const width = Number((_c = (_b = style === null || style === void 0 ? void 0 : style.width) !== null && _b !== void 0 ? _b : style === null || style === void 0 ? void 0 : style.maxLineWidth) !== null && _c !== void 0 ? _c : WING_TEXT_BOX_WIDTH);
7612
+ return Number.isFinite(width) && width > 0 ? width : WING_TEXT_BOX_WIDTH;
7613
+ };
7614
+ const getWingTextBoxWidth = (spec, ctx) => {
7615
+ const { width } = getRegionGeometry(ctx, spec);
7616
+ const configuredWidth = getConfiguredTextBoxWidth(spec);
7617
+ const adaptiveWidth = Math.max(configuredWidth, Math.round(width * WING_TEXT_BOX_WIDTH_RATIO));
7618
+ return clamp(adaptiveWidth, WING_TEXT_BOX_MIN_WIDTH, WING_TEXT_BOX_MAX_WIDTH);
7619
+ };
7620
+ const estimateTextWidth = (text, fontSize) => Array.from(text).reduce((sum, char) => {
7621
+ if (char.trim().length === 0) {
7622
+ return sum + fontSize * 0.32;
7623
+ }
7624
+ return sum + fontSize * (char.charCodeAt(0) > 255 ? 1.05 : 0.62);
7625
+ }, 0);
7626
+ const measureWingTitleWidth = (title, fontSize, style) => {
7627
+ var _a;
7628
+ if (!title) {
7629
+ return 0;
7630
+ }
7631
+ try {
7632
+ const size = vchart.measureText(title, {
7633
+ fontSize,
7634
+ fontFamily: style.fontFamily,
7635
+ fontWeight: (_a = style.fontWeight) !== null && _a !== void 0 ? _a : 'bold'
7636
+ });
7637
+ return Number.isFinite(size.width) && size.width > 0 ? size.width : estimateTextWidth(title, fontSize);
7638
+ }
7639
+ catch (_err) {
7640
+ return estimateTextWidth(title, fontSize);
7641
+ }
7642
+ };
7643
+ const getMeasuredTitleLineCount = (title, fontSize, textWidth, style) => {
7644
+ if (!title) {
7645
+ return 0;
7646
+ }
7647
+ const measuredWidth = measureWingTitleWidth(title, fontSize, style);
7648
+ return Math.max(1, Math.min(BLOCK_TITLE_MAX_LINES, Math.ceil(measuredWidth / Math.max(textWidth * 0.96, 1))));
7649
+ };
7650
+ const resolveWingTitleFontSize = (spec, index, textWidth) => {
7651
+ var _a, _b, _c, _e;
7652
+ const style = ((_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {});
7653
+ const configuredFontSize = style.fontSize;
7654
+ if (configuredFontSize != null) {
7655
+ return Number(configuredFontSize);
7656
+ }
7657
+ const title = (_e = (_c = spec.data) === null || _c === void 0 ? void 0 : _c[index]) === null || _e === void 0 ? void 0 : _e.title;
7658
+ const measuredWidth = measureWingTitleWidth(title, WING_TITLE_FONT_SIZE, style);
7659
+ if (!measuredWidth) {
7660
+ return WING_TITLE_FONT_SIZE;
7661
+ }
7662
+ const widthLimit = textWidth * BLOCK_TITLE_MAX_LINES * 0.96;
7663
+ const measuredPerFont = measuredWidth / WING_TITLE_FONT_SIZE;
7664
+ const fittedFontSize = Math.floor(widthLimit / Math.max(measuredPerFont, 1));
7665
+ return clamp(fittedFontSize, WING_TITLE_MIN_FONT_SIZE, WING_TITLE_MAX_FONT_SIZE);
7666
+ };
7602
7667
  const getWingArcGeometry = (spec, ctx) => {
7603
7668
  var _a, _b, _c;
7604
7669
  const { width, height, startX, startY } = getRegionGeometry(ctx);
@@ -7611,10 +7676,15 @@
7611
7676
  const startAngle = (_a = layoutOpt.startAngle) !== null && _a !== void 0 ? _a : defaultStart;
7612
7677
  const endAngle = (_b = layoutOpt.endAngle) !== null && _b !== void 0 ? _b : defaultEnd;
7613
7678
  const ratio = (_c = layoutOpt.radiusRatio) !== null && _c !== void 0 ? _c : 0.92;
7614
- const ry = (innerHeight / 2) * ratio;
7679
+ const { startWidth, endWidth } = getWingPathWidthRange(spec);
7680
+ const topPathWidth = direction === 'right' ? endWidth : startWidth;
7681
+ const pathTopInset = Math.min(Math.max(innerHeight / 2 - 1, 0), Math.ceil(topPathWidth / 2 + WING_PATH_EDGE_GAP));
7682
+ const arcHeight = Math.max(innerHeight - pathTopInset, 1);
7683
+ const ry = (arcHeight / 2) * ratio;
7615
7684
  const rx = innerWidth * 0.6 * ratio;
7685
+ const topSin = Math.min(Math.sin((startAngle / 180) * Math.PI), Math.sin((endAngle / 180) * Math.PI), 0);
7616
7686
  const cx = direction === 'right' ? startX + innerWidth - rx * 0.1 : startX + rx * 0.1;
7617
- const cy = startY + innerHeight / 2;
7687
+ const cy = startY + pathTopInset - topSin * ry;
7618
7688
  return { cx, cy, rx, ry, startAngle, endAngle };
7619
7689
  };
7620
7690
  const getWingBlockCenter = (spec, ctx, index) => {
@@ -7722,7 +7792,29 @@
7722
7792
  name: 'storyline-wing-title-image',
7723
7793
  zIndex: vchart.LayoutZIndex.Mark + 8,
7724
7794
  children: [
7725
- Object.assign(Object.assign({ type: 'image', name: 'storyline-wing-title-image-node', interactive: false }, spec.titleImage), { style: Object.assign({ x: (_d, ctx) => {
7795
+ Object.assign(Object.assign({ type: 'rect', name: 'storyline-wing-title-image-node', interactive: false }, spec.titleImage), { _debug_bounds: true, style: Object.assign({ _debug_bounds: true, x: (_d, ctx) => {
7796
+ const { width, height, startX } = getChartGeometry(ctx, spec);
7797
+ const size = getTitleImageSize(spec, width, height, {
7798
+ widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,
7799
+ maxWidth: WING_TITLE_IMAGE_MAX_WIDTH
7800
+ });
7801
+ return getWingDirection(spec) === 'right' ? startX : startX + width - size.width;
7802
+ }, fill: 'red', y: (_d, ctx) => {
7803
+ return getChartGeometry(ctx, spec).startY + 12;
7804
+ }, width: (_d, ctx) => {
7805
+ const { width, height } = getChartGeometry(ctx, spec);
7806
+ return getTitleImageSize(spec, width, height, {
7807
+ widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,
7808
+ maxWidth: WING_TITLE_IMAGE_MAX_WIDTH
7809
+ }).width;
7810
+ }, height: (_d, ctx) => {
7811
+ const { width, height } = getChartGeometry(ctx, spec);
7812
+ return getTitleImageSize(spec, width, height, {
7813
+ widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,
7814
+ maxWidth: WING_TITLE_IMAGE_MAX_WIDTH
7815
+ }).height;
7816
+ }, image: spec.titleImage.image, repeatX: 'no-repeat', repeatY: 'no-repeat', imageMode: 'contain', imagePosition: 'center' }, spec.titleImage.style) }),
7817
+ Object.assign(Object.assign({ type: 'image', name: 'storyline-wing-title-image-node', interactive: false }, spec.titleImage), { _debug_bounds: true, style: Object.assign({ _debug_bounds: true, x: (_d, ctx) => {
7726
7818
  const { width, height, startX } = getChartGeometry(ctx, spec);
7727
7819
  const size = getTitleImageSize(spec, width, height, {
7728
7820
  widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,
@@ -7749,18 +7841,20 @@
7749
7841
  };
7750
7842
  const WING_TEXT_IMAGE_GAP = 120;
7751
7843
  const getWingBlockMetrics = (spec, ctx, index) => {
7752
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
7753
- const titleFontSize = resolveTitleFontSize(spec, ctx, (_b = (_a = spec.data) === null || _a === void 0 ? void 0 : _a[index]) === null || _b === void 0 ? void 0 : _b.title, WING_TEXT_BOX_WIDTH, WING_TITLE_FONT_SIZE, [8, 30]);
7754
- const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, (_c = spec.title) === null || _c === void 0 ? void 0 : _c.style, WING_TITLE_LINE_HEIGHT, 1.3);
7755
- const titleHeight = getBlockTitleHeight(titleLineHeight, (_f = (_e = spec.data) === null || _e === void 0 ? void 0 : _e[index]) === null || _f === void 0 ? void 0 : _f.title, WING_TEXT_BOX_WIDTH, titleFontSize);
7756
- const contentFontSize = Number((_j = (_h = (_g = spec.content) === null || _g === void 0 ? void 0 : _g.style) === null || _h === void 0 ? void 0 : _h.fontSize) !== null && _j !== void 0 ? _j : WING_CONTENT_FONT_SIZE);
7757
- const contentLineHeight = Number((_m = (_l = (_k = spec.content) === null || _k === void 0 ? void 0 : _k.style) === null || _l === void 0 ? void 0 : _l.lineHeight) !== null && _m !== void 0 ? _m : WING_CONTENT_LINE_HEIGHT);
7844
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
7845
+ const textWidth = getWingTextBoxWidth(spec, ctx);
7846
+ const titleStyle = ((_b = (_a = spec.title) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {});
7847
+ const titleFontSize = resolveWingTitleFontSize(spec, index, textWidth);
7848
+ const titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, titleStyle, WING_TITLE_LINE_HEIGHT, 1.3);
7849
+ const titleHeight = titleLineHeight * getMeasuredTitleLineCount((_e = (_c = spec.data) === null || _c === void 0 ? void 0 : _c[index]) === null || _e === void 0 ? void 0 : _e.title, titleFontSize, textWidth, titleStyle);
7850
+ const contentFontSize = Number((_h = (_g = (_f = spec.content) === null || _f === void 0 ? void 0 : _f.style) === null || _g === void 0 ? void 0 : _g.fontSize) !== null && _h !== void 0 ? _h : WING_CONTENT_FONT_SIZE);
7851
+ const contentLineHeight = Number((_l = (_k = (_j = spec.content) === null || _j === void 0 ? void 0 : _j.style) === null || _k === void 0 ? void 0 : _k.lineHeight) !== null && _l !== void 0 ? _l : WING_CONTENT_LINE_HEIGHT);
7758
7852
  const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;
7759
7853
  const textHeight = WING_TEXT_BOX_HEIGHT;
7760
7854
  const contentHeight = 100000;
7761
7855
  const imageScale = getWingBlockImageScale(spec, index);
7762
- const imageWidth = Math.round(Number((_p = (_o = spec.image) === null || _o === void 0 ? void 0 : _o.width) !== null && _p !== void 0 ? _p : WING_BLOCK_IMAGE_SIZE) * imageScale);
7763
- const imageHeight = Math.round(Number((_r = (_q = spec.image) === null || _q === void 0 ? void 0 : _q.height) !== null && _r !== void 0 ? _r : WING_BLOCK_IMAGE_SIZE) * imageScale);
7856
+ const imageWidth = Math.round(Number((_o = (_m = spec.image) === null || _m === void 0 ? void 0 : _m.width) !== null && _o !== void 0 ? _o : WING_BLOCK_IMAGE_SIZE) * imageScale);
7857
+ const imageHeight = Math.round(Number((_q = (_p = spec.image) === null || _p === void 0 ? void 0 : _p.height) !== null && _q !== void 0 ? _q : WING_BLOCK_IMAGE_SIZE) * imageScale);
7764
7858
  const imageBox = {
7765
7859
  x: -imageWidth / 2,
7766
7860
  y: -imageHeight / 2,
@@ -7768,11 +7862,10 @@
7768
7862
  height: imageHeight
7769
7863
  };
7770
7864
  const direction = getWingDirection(spec);
7771
- const count = (_t = (_s = spec.data) === null || _s === void 0 ? void 0 : _s.length) !== null && _t !== void 0 ? _t : 0;
7865
+ const count = (_s = (_r = spec.data) === null || _r === void 0 ? void 0 : _r.length) !== null && _s !== void 0 ? _s : 0;
7772
7866
  const isSpecialBelow = (direction === 'right' && count > 0 && index === count - 1) || (direction === 'left' && index === 0);
7773
7867
  const isBottomAbove = isWingBottomBlock(spec, ctx, index);
7774
7868
  const isVerticalLayout = isBottomAbove || isSpecialBelow;
7775
- const textWidth = WING_TEXT_BOX_WIDTH;
7776
7869
  let textBox;
7777
7870
  let contentBox;
7778
7871
  let connectorBox;
@@ -7906,7 +7999,7 @@
7906
7999
  return m.textBox.x + m.textBox.width / 2;
7907
8000
  }
7908
8001
  return m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;
7909
- }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y, text: block.title, height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleHeight, heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => {
8002
+ }, y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y, width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.width, maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.width, text: block.title, height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleHeight, heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight * BLOCK_TITLE_MAX_LINES, lineClamp: BLOCK_TITLE_MAX_LINES, fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleFontSize, lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight, fontWeight: 'bold', fill: themeColor, stroke: '#fff', lineWidth: 5, lineJoin: 'round', textAlign: (_d, ctx) => {
7910
8003
  const m = getWingBlockMetrics(spec, ctx, index);
7911
8004
  if (m.verticalAlign) {
7912
8005
  return 'center';
@@ -7952,19 +8045,27 @@
7952
8045
  var _a, _b, _c, _d;
7953
8046
  const LARGE = 100;
7954
8047
  const SMALL = 20;
8048
+ const WING_BASE_PADDING = 40;
8049
+ const WING_DIRECTION_PADDING = 100;
8050
+ const WING_TITLE_IMAGE_BOTTOM = 4;
7955
8051
  const TEXT_RESERVE = 280;
7956
8052
  const arc = isArc(spec);
7957
8053
  const arcDown = arc && normalizeLayout(spec.layout).direction === 'down';
7958
8054
  const arcUp = arc && !arcDown;
7959
8055
  const portrait = isPortrait(spec);
7960
8056
  const wing = isWing(spec);
8057
+ const wingDirection = wing ? normalizeLayout(spec.layout).direction : undefined;
8058
+ const wingLeft = wing && wingDirection !== 'right';
8059
+ const wingRight = wing && wingDirection === 'right';
8060
+ const wingTopPadding = wingRight ? WING_DIRECTION_PADDING : WING_BASE_PADDING;
8061
+ const wingBottomPadding = wingLeft ? WING_DIRECTION_PADDING : WING_BASE_PADDING;
7961
8062
  const clock = isClock(spec);
7962
8063
  const topTitleImageReserve = (() => {
7963
8064
  var _a, _b, _c, _d;
7964
8065
  if (arc || !((_a = spec.titleImage) === null || _a === void 0 ? void 0 : _a.image) || ((_b = spec.titleImage) === null || _b === void 0 ? void 0 : _b.visible) === false) {
7965
8066
  return 0;
7966
8067
  }
7967
- return getTitleImageReservedHeight(spec, Number((_c = spec.width) !== null && _c !== void 0 ? _c : 1000), Number((_d = spec.height) !== null && _d !== void 0 ? _d : 600));
8068
+ return getTitleImageReservedHeight(spec, Number((_c = spec.width) !== null && _c !== void 0 ? _c : 1000), Number((_d = spec.height) !== null && _d !== void 0 ? _d : 600), wing ? { bottom: WING_TITLE_IMAGE_BOTTOM } : undefined);
7968
8069
  })();
7969
8070
  const portraitBottomReserve = (() => {
7970
8071
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
@@ -7986,13 +8087,13 @@
7986
8087
  const breath = 16;
7987
8088
  return Math.max(LARGE, Math.round(imageHeight / 2 + textGap + titleLineHeight + titleToContentGap + contentHeight + breath));
7988
8089
  })();
7989
- const defaultTop = Math.max(topTitleImageReserve, clock ? 40 : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL);
8090
+ const defaultTop = Math.max(topTitleImageReserve, clock ? 40 : wing ? wingTopPadding : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL);
7990
8091
  const defaultBottom = clock
7991
8092
  ? 60
7992
8093
  : portrait
7993
8094
  ? portraitBottomReserve
7994
8095
  : wing
7995
- ? 300
8096
+ ? wingBottomPadding
7996
8097
  : arcUp
7997
8098
  ? 100
7998
8099
  : arcDown