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

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 (53) hide show
  1. package/build/index.js +415 -418
  2. package/build/index.min.js +2 -2
  3. package/cjs/charts/storyline/interface.d.ts +2 -2
  4. package/cjs/charts/storyline/interface.js.map +1 -1
  5. package/cjs/charts/storyline/layouts/arc.d.ts +1 -1
  6. package/cjs/charts/storyline/layouts/arc.js +35 -98
  7. package/cjs/charts/storyline/layouts/arc.js.map +1 -1
  8. package/cjs/charts/storyline/layouts/clock.d.ts +1 -1
  9. package/cjs/charts/storyline/layouts/clock.js +32 -30
  10. package/cjs/charts/storyline/layouts/clock.js.map +1 -1
  11. package/cjs/charts/storyline/layouts/common.d.ts +53 -1
  12. package/cjs/charts/storyline/layouts/common.js +180 -23
  13. package/cjs/charts/storyline/layouts/common.js.map +1 -1
  14. package/cjs/charts/storyline/layouts/default.js +21 -21
  15. package/cjs/charts/storyline/layouts/default.js.map +1 -1
  16. package/cjs/charts/storyline/layouts/ladder.js +21 -20
  17. package/cjs/charts/storyline/layouts/ladder.js.map +1 -1
  18. package/cjs/charts/storyline/layouts/landscape.js +20 -21
  19. package/cjs/charts/storyline/layouts/landscape.js.map +1 -1
  20. package/cjs/charts/storyline/layouts/portrait.d.ts +1 -1
  21. package/cjs/charts/storyline/layouts/portrait.js +63 -55
  22. package/cjs/charts/storyline/layouts/portrait.js.map +1 -1
  23. package/cjs/charts/storyline/layouts/wing.d.ts +1 -0
  24. package/cjs/charts/storyline/layouts/wing.js +91 -49
  25. package/cjs/charts/storyline/layouts/wing.js.map +1 -1
  26. package/cjs/charts/storyline/storyline-transformer.js +18 -14
  27. package/cjs/charts/storyline/storyline-transformer.js.map +1 -1
  28. package/esm/charts/storyline/interface.d.ts +2 -2
  29. package/esm/charts/storyline/interface.js.map +1 -1
  30. package/esm/charts/storyline/layouts/arc.d.ts +1 -1
  31. package/esm/charts/storyline/layouts/arc.js +31 -96
  32. package/esm/charts/storyline/layouts/arc.js.map +1 -1
  33. package/esm/charts/storyline/layouts/clock.d.ts +1 -1
  34. package/esm/charts/storyline/layouts/clock.js +30 -29
  35. package/esm/charts/storyline/layouts/clock.js.map +1 -1
  36. package/esm/charts/storyline/layouts/common.d.ts +53 -1
  37. package/esm/charts/storyline/layouts/common.js +165 -20
  38. package/esm/charts/storyline/layouts/common.js.map +1 -1
  39. package/esm/charts/storyline/layouts/default.js +18 -19
  40. package/esm/charts/storyline/layouts/default.js.map +1 -1
  41. package/esm/charts/storyline/layouts/ladder.js +17 -18
  42. package/esm/charts/storyline/layouts/ladder.js.map +1 -1
  43. package/esm/charts/storyline/layouts/landscape.js +18 -21
  44. package/esm/charts/storyline/layouts/landscape.js.map +1 -1
  45. package/esm/charts/storyline/layouts/portrait.d.ts +1 -1
  46. package/esm/charts/storyline/layouts/portrait.js +60 -57
  47. package/esm/charts/storyline/layouts/portrait.js.map +1 -1
  48. package/esm/charts/storyline/layouts/wing.d.ts +1 -0
  49. package/esm/charts/storyline/layouts/wing.js +86 -49
  50. package/esm/charts/storyline/layouts/wing.js.map +1 -1
  51. package/esm/charts/storyline/storyline-transformer.js +20 -18
  52. package/esm/charts/storyline/storyline-transformer.js.map +1 -1
  53. package/package.json +4 -4
@@ -1,11 +1,8 @@
1
1
  import { LayoutZIndex } from "@visactor/vchart";
2
2
 
3
- import { buildRichContent, getRegionGeometry, getThemeColor, normalizeLayout, omitImageLayoutSpec, shouldShowImageBackground, withAlpha } from "./common";
3
+ import { buildRichContent, getImageBackgroundStyle, getChartGeometry, getRegionGeometry, getThemeColor, getTitleImageSize, normalizeLayout, omitImageLayoutSpec, resolveAdaptiveLineHeight, resolveTitleFontSize, shouldShowImageBackground } from "./common";
4
4
 
5
- const WING_BLOCK_IMAGE_SIZE = 160, WING_TEXT_GAP_FROM_IMAGE = 14, WING_TITLE_LINE_HEIGHT = 30, WING_TITLE_FONT_SIZE = 22, WING_CONTENT_LINE_HEIGHT = 17, WING_CONTENT_FONT_SIZE = 12, WING_TEXT_BOX_WIDTH = 240, WING_TEXT_BOX_HEIGHT = 110, WING_TITLE_TO_CONTENT_GAP = 4, getWingDirection = spec => {
6
- var _a;
7
- return null !== (_a = normalizeLayout(spec.layout).direction) && void 0 !== _a ? _a : "left";
8
- }, getWingArcGeometry = (spec, ctx) => {
5
+ const WING_BLOCK_IMAGE_SIZE = 160, WING_TEXT_GAP_FROM_IMAGE = 14, WING_TITLE_LINE_HEIGHT = 30, WING_TITLE_FONT_SIZE = 22, WING_CONTENT_LINE_HEIGHT = 17, WING_CONTENT_FONT_SIZE = 12, WING_TEXT_BOX_WIDTH = 240, WING_TEXT_BOX_HEIGHT = 110, WING_TITLE_TO_CONTENT_GAP = 4, WING_TITLE_IMAGE_WIDTH_RATIO = .6, WING_TITLE_IMAGE_MAX_WIDTH = 820, getWingDirection = spec => "right" === normalizeLayout(spec.layout).direction ? "right" : "left", getWingArcGeometry = (spec, ctx) => {
9
6
  var _a, _b, _c;
10
7
  const {width: width, height: height, startX: startX, startY: startY} = getRegionGeometry(ctx), innerWidth = Math.max(width, 1), innerHeight = Math.max(height, 1), layoutOpt = normalizeLayout(spec.layout), direction = getWingDirection(spec), defaultStart = "right" === direction ? 110 : -70, defaultEnd = "right" === direction ? 250 : 70, startAngle = null !== (_a = layoutOpt.startAngle) && void 0 !== _a ? _a : defaultStart, endAngle = null !== (_b = layoutOpt.endAngle) && void 0 !== _b ? _b : defaultEnd, ratio = null !== (_c = layoutOpt.radiusRatio) && void 0 !== _c ? _c : .92, rx = .6 * innerWidth * ratio;
11
8
  return {
@@ -75,14 +72,58 @@ export const buildWingArcMark = spec => {
75
72
  };
76
73
  };
77
74
 
75
+ export const buildWingTitleImageMark = spec => {
76
+ var _a;
77
+ return (null === (_a = spec.titleImage) || void 0 === _a ? void 0 : _a.image) && !1 !== spec.titleImage.visible ? {
78
+ type: "group",
79
+ name: "storyline-wing-title-image",
80
+ zIndex: LayoutZIndex.Mark + 8,
81
+ children: [ Object.assign(Object.assign({
82
+ type: "image",
83
+ name: "storyline-wing-title-image-node",
84
+ interactive: !1
85
+ }, spec.titleImage), {
86
+ style: Object.assign({
87
+ x: (_d, ctx) => {
88
+ const {width: width, height: height, startX: startX} = getChartGeometry(ctx, spec), size = getTitleImageSize(spec, width, height, {
89
+ widthRatio: .6,
90
+ maxWidth: 820
91
+ });
92
+ return "right" === getWingDirection(spec) ? startX : startX + width - size.width;
93
+ },
94
+ y: (_d, ctx) => getChartGeometry(ctx, spec).startY + 12,
95
+ width: (_d, ctx) => {
96
+ const {width: width, height: height} = getChartGeometry(ctx, spec);
97
+ return getTitleImageSize(spec, width, height, {
98
+ widthRatio: .6,
99
+ maxWidth: 820
100
+ }).width;
101
+ },
102
+ height: (_d, ctx) => {
103
+ const {width: width, height: height} = getChartGeometry(ctx, spec);
104
+ return getTitleImageSize(spec, width, height, {
105
+ widthRatio: .6,
106
+ maxWidth: 820
107
+ }).height;
108
+ },
109
+ image: spec.titleImage.image,
110
+ repeatX: "no-repeat",
111
+ repeatY: "no-repeat",
112
+ imageMode: "contain",
113
+ imagePosition: "center"
114
+ }, spec.titleImage.style)
115
+ }) ]
116
+ } : null;
117
+ };
118
+
78
119
  const WING_TEXT_IMAGE_GAP = 120, getWingBlockMetrics = (spec, ctx, index) => {
79
- var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
80
- const titleFontSize = Number(null !== (_c = null === (_b = null === (_a = spec.title) || void 0 === _a ? void 0 : _a.style) || void 0 === _b ? void 0 : _b.fontSize) && void 0 !== _c ? _c : 22), titleLineHeight = Number(null !== (_g = null === (_f = null === (_e = spec.title) || void 0 === _e ? void 0 : _e.style) || void 0 === _f ? void 0 : _f.lineHeight) && void 0 !== _g ? _g : Math.max(30, Math.round(1.3 * titleFontSize))), contentFontSize = Number(null !== (_k = null === (_j = null === (_h = spec.content) || void 0 === _h ? void 0 : _h.style) || void 0 === _j ? void 0 : _j.fontSize) && void 0 !== _k ? _k : 12), contentLineHeight = Number(null !== (_o = null === (_m = null === (_l = spec.content) || void 0 === _l ? void 0 : _l.style) || void 0 === _m ? void 0 : _m.lineHeight) && void 0 !== _o ? _o : 17), imageWidth = Number(null !== (_q = null === (_p = spec.image) || void 0 === _p ? void 0 : _p.width) && void 0 !== _q ? _q : 160), imageHeight = Number(null !== (_s = null === (_r = spec.image) || void 0 === _r ? void 0 : _r.height) && void 0 !== _s ? _s : 160), imageBox = {
120
+ var _a, _b, _c, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
121
+ const titleFontSize = resolveTitleFontSize(spec, ctx, null === (_b = null === (_a = spec.data) || void 0 === _a ? void 0 : _a[index]) || void 0 === _b ? void 0 : _b.title, 240, 22, [ 8, 30 ]), titleLineHeight = resolveAdaptiveLineHeight(titleFontSize, null === (_c = spec.title) || void 0 === _c ? void 0 : _c.style, 30, 1.3), contentFontSize = Number(null !== (_g = null === (_f = null === (_e = spec.content) || void 0 === _e ? void 0 : _e.style) || void 0 === _f ? void 0 : _f.fontSize) && void 0 !== _g ? _g : 12), contentLineHeight = Number(null !== (_k = null === (_j = null === (_h = spec.content) || void 0 === _h ? void 0 : _h.style) || void 0 === _j ? void 0 : _j.lineHeight) && void 0 !== _k ? _k : 17), imageWidth = Number(null !== (_m = null === (_l = spec.image) || void 0 === _l ? void 0 : _l.width) && void 0 !== _m ? _m : 160), imageHeight = Number(null !== (_p = null === (_o = spec.image) || void 0 === _o ? void 0 : _o.height) && void 0 !== _p ? _p : 160), imageBox = {
81
122
  x: -imageWidth / 2,
82
123
  y: -imageHeight / 2,
83
124
  width: imageWidth,
84
125
  height: imageHeight
85
- }, direction = getWingDirection(spec), count = null !== (_u = null === (_t = spec.data) || void 0 === _t ? void 0 : _t.length) && void 0 !== _u ? _u : 0;
126
+ }, direction = getWingDirection(spec), count = null !== (_r = null === (_q = spec.data) || void 0 === _q ? void 0 : _q.length) && void 0 !== _r ? _r : 0;
86
127
  let textBox, contentBox, connectorBox, onLeft, verticalAlign;
87
128
  if ("right" === direction && count > 0 && index === count - 1 || "left" === direction && 0 === index) {
88
129
  const textX = -120, textY = imageHeight / 2 + 120;
@@ -155,10 +196,10 @@ export const buildWingBlockMark = (spec, block, index) => {
155
196
  interactive: !1,
156
197
  zIndex: LayoutZIndex.Mark + 2,
157
198
  style: {
158
- x: (_d, ctx) => getWingBlockMetrics(spec, 0, index).connectorBox.x,
159
- y: (_d, ctx) => getWingBlockMetrics(spec, 0, index).connectorBox.y,
160
- width: (_d, ctx) => getWingBlockMetrics(spec, 0, index).connectorBox.width,
161
- height: (_d, ctx) => getWingBlockMetrics(spec, 0, index).connectorBox.height,
199
+ x: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).connectorBox.x,
200
+ y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).connectorBox.y,
201
+ width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).connectorBox.width,
202
+ height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).connectorBox.height,
162
203
  fill: themeColor,
163
204
  opacity: .6
164
205
  }
@@ -166,46 +207,42 @@ export const buildWingBlockMark = (spec, block, index) => {
166
207
  type: "symbol",
167
208
  name: `storyline-block-image-halo-${index}`,
168
209
  interactive: !1,
169
- style: {
210
+ style: Object.assign(Object.assign({
170
211
  x: 0,
171
212
  y: 0,
172
- size: (_d, ctx) => Math.max(getWingBlockMetrics(spec, 0, index).imageBox.width, getWingBlockMetrics(spec, 0, index).imageBox.height) + 12,
173
- symbolType: "circle",
174
- fill: withAlpha(themeColor, .18),
175
- stroke: themeColor,
213
+ size: (_d, ctx) => Math.max(getWingBlockMetrics(spec, ctx, index).imageBox.width, getWingBlockMetrics(spec, ctx, index).imageBox.height) + 12,
214
+ symbolType: "circle"
215
+ }, getImageBackgroundStyle(spec)), {
176
216
  lineWidth: 1.5
177
- }
217
+ })
178
218
  } : null, hasImage ? Object.assign(Object.assign({
179
219
  type: "image",
180
220
  name: `storyline-block-image-${index}`,
181
221
  interactive: !1
182
222
  }, omitImageLayoutSpec(spec.image)), {
183
223
  style: Object.assign({
184
- x: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.x,
185
- y: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.y,
186
- width: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.width,
187
- height: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.height,
188
- cornerRadius: (_d, ctx) => Math.min(getWingBlockMetrics(spec, 0, index).imageBox.width, getWingBlockMetrics(spec, 0, index).imageBox.height) / 2,
224
+ x: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.x,
225
+ y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.y,
226
+ width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.width,
227
+ height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.height,
228
+ cornerRadius: (_d, ctx) => Math.min(getWingBlockMetrics(spec, ctx, index).imageBox.width, getWingBlockMetrics(spec, ctx, index).imageBox.height) / 2,
189
229
  image: block.image,
190
230
  repeatX: "no-repeat",
191
231
  repeatY: "no-repeat",
192
- imageMode: "cover",
232
+ imageMode: "contain",
193
233
  imagePosition: "center"
194
234
  }, null === (_b = spec.image) || void 0 === _b ? void 0 : _b.style)
195
235
  }) : {
196
236
  type: "rect",
197
237
  name: `storyline-block-image-bg-${index}`,
198
238
  interactive: !1,
199
- style: {
200
- x: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.x,
201
- y: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.y,
202
- width: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.width,
203
- height: (_d, ctx) => getWingBlockMetrics(spec, 0, index).imageBox.height,
204
- cornerRadius: (_d, ctx) => Math.min(getWingBlockMetrics(spec, 0, index).imageBox.width, getWingBlockMetrics(spec, 0, index).imageBox.height) / 2,
205
- fill: "#ffffff",
206
- stroke: themeColor,
207
- lineWidth: 2
208
- }
239
+ style: Object.assign({
240
+ x: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.x,
241
+ y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.y,
242
+ width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.width,
243
+ height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).imageBox.height,
244
+ cornerRadius: (_d, ctx) => Math.min(getWingBlockMetrics(spec, ctx, index).imageBox.width, getWingBlockMetrics(spec, ctx, index).imageBox.height) / 2
245
+ }, getImageBackgroundStyle(spec))
209
246
  }, block.title ? Object.assign(Object.assign({
210
247
  type: "text",
211
248
  name: `storyline-block-title-${index}`,
@@ -214,21 +251,21 @@ export const buildWingBlockMark = (spec, block, index) => {
214
251
  }, spec.title), {
215
252
  style: Object.assign({
216
253
  x: (_d, ctx) => {
217
- const m = getWingBlockMetrics(spec, 0, index);
254
+ const m = getWingBlockMetrics(spec, ctx, index);
218
255
  return m.verticalAlign ? m.textBox.x + m.textBox.width / 2 : m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;
219
256
  },
220
- y: (_d, ctx) => getWingBlockMetrics(spec, 0, index).textBox.y,
257
+ y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.y,
221
258
  text: block.title,
222
- maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, 0, index).textBox.width,
223
- fontSize: (_d, ctx) => getWingBlockMetrics(spec, 0, index).titleFontSize,
224
- lineHeight: (_d, ctx) => getWingBlockMetrics(spec, 0, index).titleLineHeight,
259
+ maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).textBox.width,
260
+ fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleFontSize,
261
+ lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).titleLineHeight,
225
262
  fontWeight: "bold",
226
263
  fill: themeColor,
227
264
  stroke: "#fff",
228
265
  lineWidth: 5,
229
266
  lineJoin: "round",
230
267
  textAlign: (_d, ctx) => {
231
- const m = getWingBlockMetrics(spec, 0, index);
268
+ const m = getWingBlockMetrics(spec, ctx, index);
232
269
  return m.verticalAlign ? "center" : m.onLeft ? "right" : "left";
233
270
  },
234
271
  textBaseline: "top"
@@ -242,19 +279,19 @@ export const buildWingBlockMark = (spec, block, index) => {
242
279
  textType: "rich",
243
280
  style: Object.assign({
244
281
  x: (_d, ctx) => {
245
- const m = getWingBlockMetrics(spec, 0, index);
282
+ const m = getWingBlockMetrics(spec, ctx, index);
246
283
  return m.verticalAlign ? m.contentBox.x + m.contentBox.width / 2 : m.onLeft ? m.contentBox.x + m.contentBox.width : m.contentBox.x;
247
284
  },
248
- y: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentBox.y,
249
- width: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentBox.width,
250
- height: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentBox.height,
251
- maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentBox.width,
252
- heightLimit: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentBox.height,
285
+ y: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.y,
286
+ width: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width,
287
+ height: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height,
288
+ maxLineWidth: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.width,
289
+ heightLimit: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentBox.height,
253
290
  text: buildRichContent(contentText, spec),
254
- fontSize: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentFontSize,
255
- lineHeight: (_d, ctx) => getWingBlockMetrics(spec, 0, index).contentLineHeight,
291
+ fontSize: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentFontSize,
292
+ lineHeight: (_d, ctx) => getWingBlockMetrics(spec, ctx, index).contentLineHeight,
256
293
  textAlign: (_d, ctx) => {
257
- const m = getWingBlockMetrics(spec, 0, index);
294
+ const m = getWingBlockMetrics(spec, ctx, index);
258
295
  return m.verticalAlign ? "center" : m.onLeft ? "right" : "left";
259
296
  },
260
297
  textBaseline: "top",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/charts/storyline/layouts/wing.ts"],"names":[],"mappings":"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","file":"wing.js","sourcesContent":["import type { IExtensionGroupMarkSpec } from '@visactor/vchart';\nimport { LayoutZIndex } from '@visactor/vchart';\nimport type { IStorylineBlock, IStorylineSpec, StorylineWingDirection } from '../interface';\nimport {\n type ICustomMarkSpec,\n type LayoutContext,\n type StorylinePoint,\n buildRichContent,\n getRegionGeometry,\n getThemeColor,\n normalizeLayout,\n omitImageLayoutSpec,\n shouldShowImageBackground,\n withAlpha\n} from './common';\n\n// wing 布局:参考残奥时间线信息图\n// - 主脉络为椭圆弧的「翅膀」造型,可通过 direction 配置左右朝向\n// - direction: 'left' → 圆心锚在画布左侧,弧凸向右展开(默认)\n// - direction: 'right' → 圆心锚在画布右侧,弧凸向左展开\n// - 圆形 image 嵌在弧线上(中心位于弧线)\n// - title(年份感大字 + 主题色) + content 在 image 一侧水平展开\n// - 左右交替(弧线左侧 / 右侧)让节点错落\nconst WING_BLOCK_IMAGE_SIZE = 160;\nconst WING_TEXT_GAP_FROM_IMAGE = 14;\nconst WING_TITLE_LINE_HEIGHT = 30;\nconst WING_TITLE_FONT_SIZE = 22;\nconst WING_CONTENT_LINE_HEIGHT = 17;\nconst WING_CONTENT_FONT_SIZE = 12;\n// title + content 区域宽度\nconst WING_TEXT_BOX_WIDTH = 240;\n// title + content 区域总高度\nconst WING_TEXT_BOX_HEIGHT = 110;\nconst WING_TITLE_TO_CONTENT_GAP = 4;\n\nconst getWingDirection = (spec: IStorylineSpec): StorylineWingDirection => {\n return normalizeLayout(spec.layout).direction ?? 'left';\n};\n\n/**\n * 计算 wing 弧线的几何参数:\n * - direction='left':圆心位于 inner 左侧,采样区间 -70°→70°(cos>0),弧线点位于圆心右侧;\n * - direction='right':圆心位于 inner 右侧,采样区间 110°→250°(cos<0),弧线点位于圆心左侧。\n */\nconst getWingArcGeometry = (spec: IStorylineSpec, ctx: LayoutContext) => {\n const { width, height, startX, startY } = getRegionGeometry(ctx);\n // width/height 已经是 VChart 减去 spec.padding 后的 region 大小\n // 不要再重复减去 padding,直接用 region 几何信息定位弧线\n const innerWidth = Math.max(width, 1);\n const innerHeight = Math.max(height, 1);\n const layoutOpt = normalizeLayout(spec.layout);\n const direction = getWingDirection(spec);\n const defaultStart = direction === 'right' ? 110 : -70;\n const defaultEnd = direction === 'right' ? 250 : 70;\n const startAngle = layoutOpt.startAngle ?? defaultStart;\n const endAngle = layoutOpt.endAngle ?? defaultEnd;\n const ratio = layoutOpt.radiusRatio ?? 0.92;\n const ry = (innerHeight / 2) * ratio;\n const rx = innerWidth * 0.6 * ratio;\n // direction='right':圆心锚在 region 右侧,弧线点在左侧;direction='left':圆心锚在左侧\n const cx = direction === 'right' ? startX + innerWidth - rx * 0.1 : startX + rx * 0.1;\n const cy = startY + innerHeight / 2;\n return { cx, cy, rx, ry, startAngle, endAngle };\n};\n\n/**\n * 沿弧采样 block 中心 —— image 的圆心直接在弧线上,与时间线视觉对齐。\n */\nconst getWingBlockCenter = (spec: IStorylineSpec, ctx: LayoutContext, index: number): StorylinePoint => {\n const arc = getWingArcGeometry(spec, ctx);\n const count = spec.data?.length ?? 0;\n if (count <= 0) {\n return { x: arc.cx, y: arc.cy };\n }\n const t = count === 1 ? 0.5 : index / (count - 1);\n const angle = ((arc.startAngle + (arc.endAngle - arc.startAngle) * t) / 180) * Math.PI;\n return {\n x: arc.cx + Math.cos(angle) * arc.rx,\n y: arc.cy + Math.sin(angle) * arc.ry\n };\n};\n\n/**\n * 节点文字侧向:\n * - 左翅膀(弧凸向右):偶数节点的文字排在弧线左侧;\n * - 右翅膀(弧凸向左):偶数节点的文字排在弧线右侧(即镜像)。\n */\nconst isTextOnLeft = (spec: IStorylineSpec, index: number) => {\n const direction = getWingDirection(spec);\n return direction === 'right' ? index % 2 === 1 : index % 2 === 0;\n};\n\n/**\n * 主脉络曲线 mark:贯穿所有 block 的椭圆弧。\n * 用变宽的 filled path 模拟\"丝带\"——起点窄、终点宽,与信息图视觉一致。\n * 默认展示;用户可通过 spec.line.visible = false 关闭。\n */\nexport const buildWingArcMark = (spec: IStorylineSpec): IExtensionGroupMarkSpec | null => {\n if (spec.line?.visible === false) {\n return null;\n }\n const themeColor = getThemeColor(spec);\n const lineStyle = (spec.line?.style ?? {}) as Record<string, unknown>;\n const startWidth = Math.max(Number(lineStyle.startWidth ?? 50), 0.5);\n const endWidth = Math.max(Number(lineStyle.endWidth ?? lineStyle.lineWidth ?? 350), startWidth);\n return {\n type: 'group' as any,\n name: 'storyline-wing-arc',\n zIndex: LayoutZIndex.Mark,\n children: [\n {\n type: 'path',\n name: 'storyline-wing-arc-path',\n interactive: false,\n style: {\n stroke: false,\n lineWidth: 0,\n fill: (lineStyle.fill as string) ?? (lineStyle.stroke as string) ?? themeColor,\n opacity: 0.95,\n path: (_d: unknown, ctx: LayoutContext) => {\n const arc = getWingArcGeometry(spec, ctx);\n const span = arc.endAngle - arc.startAngle;\n const samples = 96;\n const pts: { x: number; y: number; nx: number; ny: number; w: number }[] = [];\n for (let i = 0; i <= samples; i++) {\n const t = i / samples;\n const angle = ((arc.startAngle + span * t) / 180) * Math.PI;\n const cx = arc.cx + Math.cos(angle) * arc.rx;\n const cy = arc.cy + Math.sin(angle) * arc.ry;\n const nxRaw = Math.cos(angle) / arc.rx;\n const nyRaw = Math.sin(angle) / arc.ry;\n const nLen = Math.hypot(nxRaw, nyRaw) || 1;\n pts.push({\n x: cx,\n y: cy,\n nx: nxRaw / nLen,\n ny: nyRaw / nLen,\n w: startWidth + (endWidth - startWidth) * t\n });\n }\n const segments: string[] = [];\n for (let i = 0; i < pts.length; i++) {\n const p = pts[i];\n const x = p.x + p.nx * (p.w / 2);\n const y = p.y + p.ny * (p.w / 2);\n segments.push(`${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`);\n }\n for (let i = pts.length - 1; i >= 0; i--) {\n const p = pts[i];\n const x = p.x - p.nx * (p.w / 2);\n const y = p.y - p.ny * (p.w / 2);\n segments.push(`L ${x.toFixed(2)} ${y.toFixed(2)}`);\n }\n segments.push('Z');\n return segments.join(' ');\n }\n }\n } as ICustomMarkSpec<'path'>\n ]\n };\n};\n\n// text box 与 image 的水平间距(image 左边缘到 text box 右边缘的距离)\nconst WING_TEXT_IMAGE_GAP = 120;\n\nconst getWingBlockMetrics = (spec: IStorylineSpec, ctx: LayoutContext, index: number) => {\n const titleFontSize = Number((spec.title?.style as Record<string, unknown>)?.fontSize ?? WING_TITLE_FONT_SIZE);\n const titleLineHeight = Number(\n (spec.title?.style as Record<string, unknown>)?.lineHeight ??\n Math.max(WING_TITLE_LINE_HEIGHT, Math.round(titleFontSize * 1.3))\n );\n const contentFontSize = Number((spec.content?.style as Record<string, unknown>)?.fontSize ?? WING_CONTENT_FONT_SIZE);\n const contentLineHeight = Number(\n (spec.content?.style as Record<string, unknown>)?.lineHeight ?? WING_CONTENT_LINE_HEIGHT\n );\n const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;\n const textHeight = WING_TEXT_BOX_HEIGHT;\n const contentHeight = 100000;\n\n const imageWidth = Number(spec.image?.width ?? WING_BLOCK_IMAGE_SIZE);\n const imageHeight = Number(spec.image?.height ?? WING_BLOCK_IMAGE_SIZE);\n const imageBox = {\n x: -imageWidth / 2,\n y: -imageHeight / 2,\n width: imageWidth,\n height: imageHeight\n };\n\n const direction = getWingDirection(spec);\n const count = spec.data?.length ?? 0;\n\n // 特殊块的垂直布局:文字在 image 下方,水平居中\n // - direction='right' → 最后一个 block\n // - direction='left' → 第一个 block\n const isSpecialBelow =\n (direction === 'right' && count > 0 && index === count - 1) || (direction === 'left' && index === 0);\n const isVerticalLayout = isSpecialBelow;\n\n const textWidth = WING_TEXT_BOX_WIDTH;\n let textBox;\n let contentBox;\n let connectorBox;\n let onLeft;\n let verticalAlign; // 'below' | 'above' | null\n\n if (isVerticalLayout) {\n // 垂直布局:text 在 image 下方,水平居中\n const textX = -textWidth / 2;\n const textY = imageHeight / 2 + WING_TEXT_IMAGE_GAP;\n textBox = { x: textX, y: textY, width: textWidth, height: textHeight };\n contentBox = {\n x: textX,\n y: textY + titleLineHeight + titleToContentGap,\n width: textWidth,\n height: contentHeight\n };\n // 垂直引导线:从 image 底部到 text 顶部\n connectorBox = {\n x: -1,\n y: imageHeight / 2,\n width: 2,\n height: WING_TEXT_IMAGE_GAP\n };\n onLeft = false;\n verticalAlign = 'below';\n } else {\n // 水平布局(默认):text 在 image 一侧\n const textOnLeft = direction === 'right';\n const textX = textOnLeft ? -imageWidth / 2 - WING_TEXT_IMAGE_GAP - textWidth : imageWidth / 2 + WING_TEXT_IMAGE_GAP;\n const textY = -textHeight / 2;\n textBox = { x: textX, y: textY, width: textWidth, height: textHeight };\n contentBox = {\n x: textX,\n y: textY + titleLineHeight + titleToContentGap,\n width: textWidth,\n height: contentHeight\n };\n // 水平引导线\n const imageEdgeX = textOnLeft ? -imageWidth / 2 : imageWidth / 2;\n const textEdgeX = textOnLeft ? textX + textWidth : textX;\n connectorBox = {\n x: Math.min(imageEdgeX, textEdgeX),\n y: 0,\n width: Math.abs(textEdgeX - imageEdgeX),\n height: 2\n };\n onLeft = textOnLeft;\n verticalAlign = null;\n }\n\n return {\n onLeft,\n verticalAlign,\n titleFontSize,\n titleLineHeight,\n contentFontSize,\n contentLineHeight,\n imageBox,\n textBox,\n contentBox,\n connectorBox\n };\n};\n\nexport const buildWingBlockMark = (\n spec: IStorylineSpec,\n block: IStorylineBlock,\n index: number\n): IExtensionGroupMarkSpec => {\n const hasImage = !!block.image;\n const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];\n const themeColor = getThemeColor(spec);\n // image 背后的装饰图元(halo)\n const showBackground = shouldShowImageBackground(spec);\n\n return {\n type: 'group' as any,\n id: `storyline-block-${block.id ?? index}`,\n name: `storyline-block-${index}`,\n zIndex: LayoutZIndex.Mark + 1,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockCenter(spec, ctx, index).x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockCenter(spec, ctx, index).y\n },\n children: [\n // 引导线:连接 image 和 text box\n {\n type: 'rect',\n name: `storyline-block-connector-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 2,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.height,\n fill: themeColor,\n opacity: 0.6\n }\n } as ICustomMarkSpec<'rect'>,\n showBackground\n ? ({\n type: 'symbol',\n name: `storyline-block-image-halo-${index}`,\n interactive: false,\n style: {\n x: 0,\n y: 0,\n size: (_d: unknown, ctx: LayoutContext) =>\n Math.max(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) + 12,\n symbolType: 'circle',\n fill: withAlpha(themeColor, 0.18),\n stroke: themeColor,\n lineWidth: 1.5\n }\n } as ICustomMarkSpec<'symbol'>)\n : null,\n hasImage\n ? ({\n type: 'image',\n name: `storyline-block-image-${index}`,\n interactive: false,\n ...omitImageLayoutSpec(spec.image),\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.height,\n cornerRadius: (_d: unknown, ctx: LayoutContext) =>\n Math.min(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) / 2,\n image: block.image,\n repeatX: 'no-repeat',\n repeatY: 'no-repeat',\n imageMode: 'cover',\n imagePosition: 'center',\n ...spec.image?.style\n }\n } as ICustomMarkSpec<'image'>)\n : ({\n type: 'rect',\n name: `storyline-block-image-bg-${index}`,\n interactive: false,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.height,\n cornerRadius: (_d: unknown, ctx: LayoutContext) =>\n Math.min(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) / 2,\n fill: '#ffffff',\n stroke: themeColor,\n lineWidth: 2\n }\n } as ICustomMarkSpec<'rect'>),\n block.title\n ? ({\n type: 'text',\n name: `storyline-block-title-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 10,\n ...spec.title,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return m.textBox.x + m.textBox.width / 2;\n }\n return m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;\n },\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).textBox.y,\n text: block.title,\n maxLineWidth: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).textBox.width,\n fontSize: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).titleFontSize,\n lineHeight: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).titleLineHeight,\n fontWeight: 'bold',\n fill: themeColor,\n stroke: '#fff',\n lineWidth: 5,\n lineJoin: 'round',\n textAlign: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return 'center';\n }\n return m.onLeft ? 'right' : 'left';\n },\n textBaseline: 'top',\n ...spec.title?.style\n }\n } as ICustomMarkSpec<'text'>)\n : null,\n contentText.length\n ? ({\n type: 'text',\n name: `storyline-block-content-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 10,\n ...spec.content,\n textType: 'rich',\n style: {\n x: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return m.contentBox.x + m.contentBox.width / 2;\n }\n return m.onLeft ? m.contentBox.x + m.contentBox.width : m.contentBox.x;\n },\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.height,\n maxLineWidth: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.width,\n heightLimit: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.height,\n text: buildRichContent(contentText, spec),\n fontSize: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentFontSize,\n lineHeight: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentLineHeight,\n textAlign: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return 'center';\n }\n return m.onLeft ? 'right' : 'left';\n },\n textBaseline: 'top',\n wordBreak: 'break-word',\n ellipsis: '...',\n fill: '#1f2430',\n ...spec.content?.style\n }\n } as ICustomMarkSpec<'text'>)\n : null\n ].filter(Boolean) as ICustomMarkSpec<any>[]\n };\n};\n"]}
1
+ {"version":3,"sources":["../src/charts/storyline/layouts/wing.ts"],"names":[],"mappings":"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","file":"wing.js","sourcesContent":["import type { IExtensionGroupMarkSpec } from '@visactor/vchart';\nimport { LayoutZIndex } from '@visactor/vchart';\nimport type { IStorylineBlock, IStorylineSpec, StorylineWingDirection } from '../interface';\nimport {\n type ICustomMarkSpec,\n type LayoutContext,\n type StorylinePoint,\n buildRichContent,\n getImageBackgroundStyle,\n getChartGeometry,\n getRegionGeometry,\n getThemeColor,\n getTitleImageSize,\n normalizeLayout,\n omitImageLayoutSpec,\n resolveAdaptiveLineHeight,\n resolveTitleFontSize,\n shouldShowImageBackground\n} from './common';\n\n// wing 布局:参考残奥时间线信息图\n// - 主脉络为椭圆弧的「翅膀」造型,可通过 direction 配置左右朝向\n// - direction: 'left' → 圆心锚在画布左侧,弧凸向右展开(默认)\n// - direction: 'right' → 圆心锚在画布右侧,弧凸向左展开\n// - 圆形 image 嵌在弧线上(中心位于弧线)\n// - title(年份感大字 + 主题色) + content 在 image 一侧水平展开\n// - 左右交替(弧线左侧 / 右侧)让节点错落\nconst WING_BLOCK_IMAGE_SIZE = 160;\nconst WING_TEXT_GAP_FROM_IMAGE = 14;\nconst WING_TITLE_LINE_HEIGHT = 30;\nconst WING_TITLE_FONT_SIZE = 22;\nconst WING_CONTENT_LINE_HEIGHT = 17;\nconst WING_CONTENT_FONT_SIZE = 12;\n// title + content 区域宽度\nconst WING_TEXT_BOX_WIDTH = 240;\n// title + content 区域总高度\nconst WING_TEXT_BOX_HEIGHT = 110;\nconst WING_TITLE_TO_CONTENT_GAP = 4;\nconst WING_TITLE_IMAGE_WIDTH_RATIO = 0.6;\nconst WING_TITLE_IMAGE_MAX_WIDTH = 820;\n\nconst getWingDirection = (spec: IStorylineSpec): StorylineWingDirection => {\n return normalizeLayout(spec.layout).direction === 'right' ? 'right' : 'left';\n};\n\n/**\n * 计算 wing 弧线的几何参数:\n * - direction='left':圆心位于 inner 左侧,采样区间 -70°→70°(cos>0),弧线点位于圆心右侧;\n * - direction='right':圆心位于 inner 右侧,采样区间 110°→250°(cos<0),弧线点位于圆心左侧。\n */\nconst getWingArcGeometry = (spec: IStorylineSpec, ctx: LayoutContext) => {\n const { width, height, startX, startY } = getRegionGeometry(ctx);\n // width/height 已经是 VChart 减去 spec.padding 后的 region 大小\n // 不要再重复减去 padding,直接用 region 几何信息定位弧线\n const innerWidth = Math.max(width, 1);\n const innerHeight = Math.max(height, 1);\n const layoutOpt = normalizeLayout(spec.layout);\n const direction = getWingDirection(spec);\n const defaultStart = direction === 'right' ? 110 : -70;\n const defaultEnd = direction === 'right' ? 250 : 70;\n const startAngle = layoutOpt.startAngle ?? defaultStart;\n const endAngle = layoutOpt.endAngle ?? defaultEnd;\n const ratio = layoutOpt.radiusRatio ?? 0.92;\n const ry = (innerHeight / 2) * ratio;\n const rx = innerWidth * 0.6 * ratio;\n // direction='right':圆心锚在 region 右侧,弧线点在左侧;direction='left':圆心锚在左侧\n const cx = direction === 'right' ? startX + innerWidth - rx * 0.1 : startX + rx * 0.1;\n const cy = startY + innerHeight / 2;\n return { cx, cy, rx, ry, startAngle, endAngle };\n};\n\n/**\n * 沿弧采样 block 中心 —— image 的圆心直接在弧线上,与时间线视觉对齐。\n */\nconst getWingBlockCenter = (spec: IStorylineSpec, ctx: LayoutContext, index: number): StorylinePoint => {\n const arc = getWingArcGeometry(spec, ctx);\n const count = spec.data?.length ?? 0;\n if (count <= 0) {\n return { x: arc.cx, y: arc.cy };\n }\n const t = count === 1 ? 0.5 : index / (count - 1);\n const angle = ((arc.startAngle + (arc.endAngle - arc.startAngle) * t) / 180) * Math.PI;\n return {\n x: arc.cx + Math.cos(angle) * arc.rx,\n y: arc.cy + Math.sin(angle) * arc.ry\n };\n};\n\n/**\n * 节点文字侧向:\n * - 左翅膀(弧凸向右):偶数节点的文字排在弧线左侧;\n * - 右翅膀(弧凸向左):偶数节点的文字排在弧线右侧(即镜像)。\n */\nconst isTextOnLeft = (spec: IStorylineSpec, index: number) => {\n const direction = getWingDirection(spec);\n return direction === 'right' ? index % 2 === 1 : index % 2 === 0;\n};\n\n/**\n * 主脉络曲线 mark:贯穿所有 block 的椭圆弧。\n * 用变宽的 filled path 模拟\"丝带\"——起点窄、终点宽,与信息图视觉一致。\n * 默认展示;用户可通过 spec.line.visible = false 关闭。\n */\nexport const buildWingArcMark = (spec: IStorylineSpec): IExtensionGroupMarkSpec | null => {\n if (spec.line?.visible === false) {\n return null;\n }\n const themeColor = getThemeColor(spec);\n const lineStyle = (spec.line?.style ?? {}) as Record<string, unknown>;\n const startWidth = Math.max(Number(lineStyle.startWidth ?? 50), 0.5);\n const endWidth = Math.max(Number(lineStyle.endWidth ?? lineStyle.lineWidth ?? 350), startWidth);\n return {\n type: 'group' as any,\n name: 'storyline-wing-arc',\n zIndex: LayoutZIndex.Mark,\n children: [\n {\n type: 'path',\n name: 'storyline-wing-arc-path',\n interactive: false,\n style: {\n stroke: false,\n lineWidth: 0,\n fill: (lineStyle.fill as string) ?? (lineStyle.stroke as string) ?? themeColor,\n opacity: 0.95,\n path: (_d: unknown, ctx: LayoutContext) => {\n const arc = getWingArcGeometry(spec, ctx);\n const span = arc.endAngle - arc.startAngle;\n const samples = 96;\n const pts: { x: number; y: number; nx: number; ny: number; w: number }[] = [];\n for (let i = 0; i <= samples; i++) {\n const t = i / samples;\n const angle = ((arc.startAngle + span * t) / 180) * Math.PI;\n const cx = arc.cx + Math.cos(angle) * arc.rx;\n const cy = arc.cy + Math.sin(angle) * arc.ry;\n const nxRaw = Math.cos(angle) / arc.rx;\n const nyRaw = Math.sin(angle) / arc.ry;\n const nLen = Math.hypot(nxRaw, nyRaw) || 1;\n pts.push({\n x: cx,\n y: cy,\n nx: nxRaw / nLen,\n ny: nyRaw / nLen,\n w: startWidth + (endWidth - startWidth) * t\n });\n }\n const segments: string[] = [];\n for (let i = 0; i < pts.length; i++) {\n const p = pts[i];\n const x = p.x + p.nx * (p.w / 2);\n const y = p.y + p.ny * (p.w / 2);\n segments.push(`${i === 0 ? 'M' : 'L'} ${x.toFixed(2)} ${y.toFixed(2)}`);\n }\n for (let i = pts.length - 1; i >= 0; i--) {\n const p = pts[i];\n const x = p.x - p.nx * (p.w / 2);\n const y = p.y - p.ny * (p.w / 2);\n segments.push(`L ${x.toFixed(2)} ${y.toFixed(2)}`);\n }\n segments.push('Z');\n return segments.join(' ');\n }\n }\n } as ICustomMarkSpec<'path'>\n ]\n };\n};\n\nexport const buildWingTitleImageMark = (spec: IStorylineSpec): IExtensionGroupMarkSpec | null => {\n if (!spec.titleImage?.image || spec.titleImage.visible === false) {\n return null;\n }\n return {\n type: 'group' as any,\n name: 'storyline-wing-title-image',\n zIndex: LayoutZIndex.Mark + 8,\n children: [\n {\n type: 'image',\n name: 'storyline-wing-title-image-node',\n interactive: false,\n ...spec.titleImage,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => {\n const { width, height, startX } = getChartGeometry(ctx, spec);\n const size = getTitleImageSize(spec, width, height, {\n widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,\n maxWidth: WING_TITLE_IMAGE_MAX_WIDTH\n });\n return getWingDirection(spec) === 'right' ? startX : startX + width - size.width;\n },\n y: (_d: unknown, ctx: LayoutContext) => {\n return getChartGeometry(ctx, spec).startY + 12;\n },\n width: (_d: unknown, ctx: LayoutContext) => {\n const { width, height } = getChartGeometry(ctx, spec);\n return getTitleImageSize(spec, width, height, {\n widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,\n maxWidth: WING_TITLE_IMAGE_MAX_WIDTH\n }).width;\n },\n height: (_d: unknown, ctx: LayoutContext) => {\n const { width, height } = getChartGeometry(ctx, spec);\n return getTitleImageSize(spec, width, height, {\n widthRatio: WING_TITLE_IMAGE_WIDTH_RATIO,\n maxWidth: WING_TITLE_IMAGE_MAX_WIDTH\n }).height;\n },\n image: spec.titleImage.image,\n repeatX: 'no-repeat',\n repeatY: 'no-repeat',\n imageMode: 'contain',\n imagePosition: 'center',\n ...spec.titleImage.style\n }\n } as ICustomMarkSpec<'image'>\n ]\n };\n};\n\n// text box 与 image 的水平间距(image 左边缘到 text box 右边缘的距离)\nconst WING_TEXT_IMAGE_GAP = 120;\n\nconst getWingBlockMetrics = (spec: IStorylineSpec, ctx: LayoutContext, index: number) => {\n const titleFontSize = resolveTitleFontSize(\n spec,\n ctx,\n spec.data?.[index]?.title,\n WING_TEXT_BOX_WIDTH,\n WING_TITLE_FONT_SIZE,\n [8, 30]\n );\n const titleLineHeight = resolveAdaptiveLineHeight(\n titleFontSize,\n spec.title?.style as Record<string, unknown> | undefined,\n WING_TITLE_LINE_HEIGHT,\n 1.3\n );\n const contentFontSize = Number((spec.content?.style as Record<string, unknown>)?.fontSize ?? WING_CONTENT_FONT_SIZE);\n const contentLineHeight = Number(\n (spec.content?.style as Record<string, unknown>)?.lineHeight ?? WING_CONTENT_LINE_HEIGHT\n );\n const titleToContentGap = WING_TITLE_TO_CONTENT_GAP;\n const textHeight = WING_TEXT_BOX_HEIGHT;\n const contentHeight = 100000;\n\n const imageWidth = Number(spec.image?.width ?? WING_BLOCK_IMAGE_SIZE);\n const imageHeight = Number(spec.image?.height ?? WING_BLOCK_IMAGE_SIZE);\n const imageBox = {\n x: -imageWidth / 2,\n y: -imageHeight / 2,\n width: imageWidth,\n height: imageHeight\n };\n\n const direction = getWingDirection(spec);\n const count = spec.data?.length ?? 0;\n\n // 特殊块的垂直布局:文字在 image 下方,水平居中\n // - direction='right' → 最后一个 block\n // - direction='left' → 第一个 block\n const isSpecialBelow =\n (direction === 'right' && count > 0 && index === count - 1) || (direction === 'left' && index === 0);\n const isVerticalLayout = isSpecialBelow;\n\n const textWidth = WING_TEXT_BOX_WIDTH;\n let textBox;\n let contentBox;\n let connectorBox;\n let onLeft;\n let verticalAlign; // 'below' | 'above' | null\n\n if (isVerticalLayout) {\n // 垂直布局:text 在 image 下方,水平居中\n const textX = -textWidth / 2;\n const textY = imageHeight / 2 + WING_TEXT_IMAGE_GAP;\n textBox = { x: textX, y: textY, width: textWidth, height: textHeight };\n contentBox = {\n x: textX,\n y: textY + titleLineHeight + titleToContentGap,\n width: textWidth,\n height: contentHeight\n };\n // 垂直引导线:从 image 底部到 text 顶部\n connectorBox = {\n x: -1,\n y: imageHeight / 2,\n width: 2,\n height: WING_TEXT_IMAGE_GAP\n };\n onLeft = false;\n verticalAlign = 'below';\n } else {\n // 水平布局(默认):text 在 image 一侧\n const textOnLeft = direction === 'right';\n const textX = textOnLeft ? -imageWidth / 2 - WING_TEXT_IMAGE_GAP - textWidth : imageWidth / 2 + WING_TEXT_IMAGE_GAP;\n const textY = -textHeight / 2;\n textBox = { x: textX, y: textY, width: textWidth, height: textHeight };\n contentBox = {\n x: textX,\n y: textY + titleLineHeight + titleToContentGap,\n width: textWidth,\n height: contentHeight\n };\n // 水平引导线\n const imageEdgeX = textOnLeft ? -imageWidth / 2 : imageWidth / 2;\n const textEdgeX = textOnLeft ? textX + textWidth : textX;\n connectorBox = {\n x: Math.min(imageEdgeX, textEdgeX),\n y: 0,\n width: Math.abs(textEdgeX - imageEdgeX),\n height: 2\n };\n onLeft = textOnLeft;\n verticalAlign = null;\n }\n\n return {\n onLeft,\n verticalAlign,\n titleFontSize,\n titleLineHeight,\n contentFontSize,\n contentLineHeight,\n imageBox,\n textBox,\n contentBox,\n connectorBox\n };\n};\n\nexport const buildWingBlockMark = (\n spec: IStorylineSpec,\n block: IStorylineBlock,\n index: number\n): IExtensionGroupMarkSpec => {\n const hasImage = !!block.image;\n const contentText = Array.isArray(block.content) ? block.content : block.content ? [block.content] : [];\n const themeColor = getThemeColor(spec);\n // image 背后的装饰图元(halo)\n const showBackground = shouldShowImageBackground(spec);\n\n return {\n type: 'group' as any,\n id: `storyline-block-${block.id ?? index}`,\n name: `storyline-block-${index}`,\n zIndex: LayoutZIndex.Mark + 1,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockCenter(spec, ctx, index).x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockCenter(spec, ctx, index).y\n },\n children: [\n // 引导线:连接 image 和 text box\n {\n type: 'rect',\n name: `storyline-block-connector-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 2,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).connectorBox.height,\n fill: themeColor,\n opacity: 0.6\n }\n } as ICustomMarkSpec<'rect'>,\n showBackground\n ? ({\n type: 'symbol',\n name: `storyline-block-image-halo-${index}`,\n interactive: false,\n style: {\n x: 0,\n y: 0,\n size: (_d: unknown, ctx: LayoutContext) =>\n Math.max(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) + 12,\n symbolType: 'circle',\n ...getImageBackgroundStyle(spec),\n lineWidth: 1.5\n }\n } as ICustomMarkSpec<'symbol'>)\n : null,\n hasImage\n ? ({\n type: 'image',\n name: `storyline-block-image-${index}`,\n interactive: false,\n ...omitImageLayoutSpec(spec.image),\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.height,\n cornerRadius: (_d: unknown, ctx: LayoutContext) =>\n Math.min(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) / 2,\n image: block.image,\n repeatX: 'no-repeat',\n repeatY: 'no-repeat',\n imageMode: 'contain',\n imagePosition: 'center',\n ...spec.image?.style\n }\n } as ICustomMarkSpec<'image'>)\n : ({\n type: 'rect',\n name: `storyline-block-image-bg-${index}`,\n interactive: false,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.x,\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).imageBox.height,\n cornerRadius: (_d: unknown, ctx: LayoutContext) =>\n Math.min(\n getWingBlockMetrics(spec, ctx, index).imageBox.width,\n getWingBlockMetrics(spec, ctx, index).imageBox.height\n ) / 2,\n ...getImageBackgroundStyle(spec)\n }\n } as ICustomMarkSpec<'rect'>),\n block.title\n ? ({\n type: 'text',\n name: `storyline-block-title-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 10,\n ...spec.title,\n style: {\n x: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return m.textBox.x + m.textBox.width / 2;\n }\n return m.onLeft ? m.textBox.x + m.textBox.width : m.textBox.x;\n },\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).textBox.y,\n text: block.title,\n maxLineWidth: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).textBox.width,\n fontSize: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).titleFontSize,\n lineHeight: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).titleLineHeight,\n fontWeight: 'bold',\n fill: themeColor,\n stroke: '#fff',\n lineWidth: 5,\n lineJoin: 'round',\n textAlign: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return 'center';\n }\n return m.onLeft ? 'right' : 'left';\n },\n textBaseline: 'top',\n ...spec.title?.style\n }\n } as ICustomMarkSpec<'text'>)\n : null,\n contentText.length\n ? ({\n type: 'text',\n name: `storyline-block-content-${index}`,\n interactive: false,\n zIndex: LayoutZIndex.Mark + 10,\n ...spec.content,\n textType: 'rich',\n style: {\n x: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return m.contentBox.x + m.contentBox.width / 2;\n }\n return m.onLeft ? m.contentBox.x + m.contentBox.width : m.contentBox.x;\n },\n y: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.y,\n width: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.width,\n height: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.height,\n maxLineWidth: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.width,\n heightLimit: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentBox.height,\n text: buildRichContent(contentText, spec),\n fontSize: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentFontSize,\n lineHeight: (_d: unknown, ctx: LayoutContext) => getWingBlockMetrics(spec, ctx, index).contentLineHeight,\n textAlign: (_d: unknown, ctx: LayoutContext) => {\n const m = getWingBlockMetrics(spec, ctx, index);\n if (m.verticalAlign) {\n return 'center';\n }\n return m.onLeft ? 'right' : 'left';\n },\n textBaseline: 'top',\n wordBreak: 'break-word',\n ellipsis: '...',\n fill: '#1f2430',\n ...spec.content?.style\n }\n } as ICustomMarkSpec<'text'>)\n : null\n ].filter(Boolean) as ICustomMarkSpec<any>[]\n };\n};\n"]}
@@ -1,8 +1,8 @@
1
1
  import { CommonChartSpecTransformer } from "@visactor/vchart";
2
2
 
3
- import { isArc, isClock, isLadder, isLandscape, isPortrait, isWing, normalizeLayout, resolveBlockWidth, DEFAULT_BLOCK_WIDTH, DEFAULT_IMAGE_GAP } from "./layouts/common";
3
+ import { isArc, isClock, isLadder, isLandscape, isPortrait, isWing, normalizeLayout, resolveBlockWidth, DEFAULT_BLOCK_WIDTH, DEFAULT_IMAGE_GAP, buildTopTitleImageMark, getTitleImageReservedHeight } from "./layouts/common";
4
4
 
5
- import { buildClockArcMark, buildClockBlockMark, buildClockCenterImageMark } from "./layouts/clock";
5
+ import { buildClockArcMark, buildClockBlockMark } from "./layouts/clock";
6
6
 
7
7
  import { buildDefaultBlockMark, buildDefaultLineMark } from "./layouts/default";
8
8
 
@@ -10,9 +10,9 @@ import { buildLandscapeBlockMark, buildLandscapeConnectingCurve } from "./layout
10
10
 
11
11
  import { buildPortraitAxisMark, buildPortraitBlockMark, PORTRAIT_CONTENT_HEIGHT_RATIO, PORTRAIT_IMAGE_HEIGHT_RATIO } from "./layouts/portrait";
12
12
 
13
- import { buildArcBlockMark, buildArcCenterImageMark, buildArcMark } from "./layouts/arc";
13
+ import { buildArcBlockMark, buildArcMark, buildArcTitleImageMark } from "./layouts/arc";
14
14
 
15
- import { buildWingArcMark, buildWingBlockMark } from "./layouts/wing";
15
+ import { buildWingArcMark, buildWingBlockMark, buildWingTitleImageMark } from "./layouts/wing";
16
16
 
17
17
  import { buildLadderBlockMark, buildLadderDiagonalMark, buildLadderHeadlineMark } from "./layouts/ladder";
18
18
 
@@ -30,7 +30,10 @@ export class StorylineChartSpecTransformer extends CommonChartSpecTransformer {
30
30
 
31
31
  const applyDefaultPadding = spec => {
32
32
  var _a, _b, _c, _d;
33
- const arc = isArc(spec), arcDown = arc && "down" === normalizeLayout(spec.layout).direction, arcUp = arc && !arcDown, portrait = isPortrait(spec), ladder = isLadder(spec), wing = isWing(spec), clock = isClock(spec), portraitBottomReserve = (() => {
33
+ const arc = isArc(spec), arcDown = arc && "down" === normalizeLayout(spec.layout).direction, arcUp = arc && !arcDown, portrait = isPortrait(spec), ladder = isLadder(spec), wing = isWing(spec), clock = isClock(spec), topTitleImageReserve = (() => {
34
+ var _a, _b, _c, _d;
35
+ return arc || ladder || !(null === (_a = spec.titleImage) || void 0 === _a ? void 0 : _a.image) || !1 === (null === (_b = spec.titleImage) || void 0 === _b ? void 0 : _b.visible) ? 0 : getTitleImageReservedHeight(spec, Number(null !== (_c = spec.width) && void 0 !== _c ? _c : 1e3), Number(null !== (_d = spec.height) && void 0 !== _d ? _d : 600));
36
+ })(), portraitBottomReserve = (() => {
34
37
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
35
38
  if (!portrait) return 0;
36
39
  const count = null !== (_b = null === (_a = spec.data) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0, canvasHeight = spec.height;
@@ -47,40 +50,39 @@ const applyDefaultPadding = spec => {
47
50
  if (!ladder) return 0;
48
51
  const blockHeight = null !== (_b = null === (_a = spec.block) || void 0 === _a ? void 0 : _a.height) && void 0 !== _b ? _b : 132, ideal = Math.round(3 * blockHeight), canvasHeight = spec.height, cap = canvasHeight ? Math.floor(.3 * canvasHeight) : ideal;
49
52
  return Math.min(ideal, cap);
50
- })(), defaultTop = clock ? 40 : ladder ? ladderVerticalPadding : arcDown ? 0 : arcUp ? 280 : 20, defaultBottom = clock ? 60 : portrait ? portraitBottomReserve : wing ? 300 : arcUp ? 0 : arcDown ? 280 : 100, arcHorizontalPadding = (() => {
53
+ })(), defaultTop = Math.max(topTitleImageReserve, clock ? 40 : ladder ? ladderVerticalPadding : arcDown ? 0 : arcUp ? 280 : 20), defaultBottom = clock ? 60 : portrait ? portraitBottomReserve : wing ? 300 : arcUp ? 0 : arcDown ? 280 : 100, arcHorizontalPadding = (() => {
51
54
  var _a, _b;
52
55
  if (!arc) return 20;
53
56
  const count = Math.max(null !== (_b = null === (_a = spec.data) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0, 1), canvasWidth = spec.width;
54
57
  return canvasWidth ? Math.round(canvasWidth / (count + 1)) : 20;
55
58
  })(), defaultLeft = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding, defaultRight = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding, p = spec.padding;
56
- if (null != p) if (Array.isArray(p)) {
59
+ if (null != p) if ("number" != typeof p) if (Array.isArray(p)) {
57
60
  const [t, r = defaultRight, b, l = defaultLeft] = p;
58
- spec.padding = [ null != t ? t : defaultTop, r, null != b ? b : defaultBottom, l ];
61
+ spec.padding = [ Math.max(null != t ? t : defaultTop, topTitleImageReserve), r, null != b ? b : defaultBottom, l ];
59
62
  } else "object" == typeof p && (spec.padding = {
60
- top: null !== (_a = p.top) && void 0 !== _a ? _a : defaultTop,
63
+ top: Math.max(null !== (_a = p.top) && void 0 !== _a ? _a : defaultTop, topTitleImageReserve),
61
64
  right: null !== (_b = p.right) && void 0 !== _b ? _b : defaultRight,
62
65
  bottom: null !== (_c = p.bottom) && void 0 !== _c ? _c : defaultBottom,
63
66
  left: null !== (_d = p.left) && void 0 !== _d ? _d : defaultLeft
64
- }); else spec.padding = [ defaultTop, defaultRight, defaultBottom, defaultLeft ];
67
+ }); else spec.padding = [ Math.max(p, topTitleImageReserve), p, p, p ]; else spec.padding = [ defaultTop, defaultRight, defaultBottom, defaultLeft ];
65
68
  }, buildStorylineMarks = spec => {
66
69
  var _a;
67
- const lineMark = buildLineMark(spec), blockMarks = (null !== (_a = spec.data) && void 0 !== _a ? _a : []).map(((block, index) => buildBlockMark(spec, block, index)));
68
- if (isLandscape(spec)) return [ ...blockMarks, lineMark ].filter(Boolean);
69
- if (isPortrait(spec)) return [ lineMark, ...blockMarks ].filter(Boolean);
70
+ const lineMark = buildLineMark(spec), blockMarks = (null !== (_a = spec.data) && void 0 !== _a ? _a : []).map(((block, index) => buildBlockMark(spec, block, index))), titleImageMark = buildTopTitleImageMark(spec);
71
+ if (isLandscape(spec)) return [ titleImageMark, ...blockMarks, lineMark ].filter(Boolean);
72
+ if (isPortrait(spec)) return [ lineMark, titleImageMark, ...blockMarks ].filter(Boolean);
70
73
  if (isArc(spec)) {
71
- return [ buildArcCenterImageMark(spec), buildArcMark(spec), ...blockMarks ].filter(Boolean);
74
+ return [ buildArcTitleImageMark(spec), buildArcMark(spec), ...blockMarks ].filter(Boolean);
72
75
  }
73
76
  if (isClock(spec)) {
74
- const ringsMark = buildClockArcMark(spec), centerImageMark = buildClockCenterImageMark(spec);
75
- return [ ringsMark, ...blockMarks, centerImageMark ].filter(Boolean);
77
+ return [ titleImageMark, buildClockArcMark(spec), ...blockMarks ].filter(Boolean);
76
78
  }
77
79
  if (isWing(spec)) {
78
- return [ buildWingArcMark(spec), ...blockMarks ].filter(Boolean);
80
+ return [ buildWingArcMark(spec), buildWingTitleImageMark(spec), ...blockMarks ].filter(Boolean);
79
81
  }
80
82
  if (isLadder(spec)) {
81
83
  return [ buildLadderDiagonalMark(spec), buildLadderHeadlineMark(spec), ...blockMarks ].filter(Boolean);
82
84
  }
83
- return [ lineMark, ...blockMarks ].filter(Boolean);
85
+ return [ titleImageMark, lineMark, ...blockMarks ].filter(Boolean);
84
86
  }, buildLineMark = spec => {
85
87
  var _a, _b, _c;
86
88
  return !1 === (null === (_a = spec.line) || void 0 === _a ? void 0 : _a.visible) || (null !== (_c = null === (_b = spec.data) || void 0 === _b ? void 0 : _b.length) && void 0 !== _c ? _c : 0) <= 1 ? null : isLandscape(spec) ? buildLandscapeConnectingCurve(spec) : isPortrait(spec) ? buildPortraitAxisMark(spec) : buildDefaultLineMark(spec);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/charts/storyline/storyline-transformer.ts"],"names":[],"mappings":"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","file":"storyline-transformer.js","sourcesContent":["import { CommonChartSpecTransformer, type IExtensionGroupMarkSpec } from '@visactor/vchart';\nimport type { IStorylineBlock, IStorylineSpec } from './interface';\nimport {\n isArc,\n isClock,\n isLadder,\n isLandscape,\n isPortrait,\n isWing,\n normalizeLayout,\n resolveBlockWidth,\n DEFAULT_BLOCK_WIDTH,\n DEFAULT_IMAGE_GAP\n} from './layouts/common';\nimport { buildClockArcMark, buildClockBlockMark, buildClockCenterImageMark } from './layouts/clock';\nimport { buildDefaultBlockMark, buildDefaultLineMark } from './layouts/default';\nimport { buildLandscapeBlockMark, buildLandscapeConnectingCurve } from './layouts/landscape';\nimport {\n buildPortraitAxisMark,\n buildPortraitBlockMark,\n PORTRAIT_CONTENT_HEIGHT_RATIO,\n PORTRAIT_IMAGE_HEIGHT_RATIO\n} from './layouts/portrait';\nimport { buildArcBlockMark, buildArcCenterImageMark, buildArcMark } from './layouts/arc';\nimport { buildWingArcMark, buildWingBlockMark } from './layouts/wing';\nimport { buildLadderBlockMark, buildLadderDiagonalMark, buildLadderHeadlineMark } from './layouts/ladder';\n\nexport class StorylineChartSpecTransformer extends CommonChartSpecTransformer<any> {\n transformSpec(spec: any): void {\n applyDefaultPadding(spec);\n const storylineSpec = {\n ...spec,\n data: [...(spec.data ?? [])]\n } as IStorylineSpec;\n\n spec.type = 'common' as any;\n spec.data = [];\n spec.series = [];\n spec.axes = [];\n spec.customMark = buildStorylineMarks(storylineSpec);\n delete spec.layout;\n delete spec.title;\n super.transformSpec(spec as any);\n }\n}\n\n/**\n * 图表默认 padding:\n * - arc up(dome 穹顶):centerImage 贴底 + textBox 在弧线上方,所以默认底部留 100px、顶部留 280px 给 textBox + 弧线呼吸空间;\n * - arc down(bowl 碗形):centerImage 贴顶 + textBox 在弧线下方,所以默认顶部留 100px、底部留 280px 给 textBox + 弧线呼吸空间;\n * - portrait:textBox 在 image 下方,最后一个 block 的 content 容易超出 region。底部 padding 默认 = 单个 block 的 content 高度\n * (即 regionHeight / count * 0.6),保证最后一个 block 有完整的 content 展示空间;\n * - ladder:四周默认留出 content 文本宽度,避免 block 沿对角线\"挤\"到画布边缘;\n * 用户在 spec.padding 中显式指定的值会被保留,仅在缺省时生效。\n */\nconst applyDefaultPadding = (spec: any) => {\n const LARGE = 100;\n const SMALL = 20;\n // 给 textBox(240px)+ 一定呼吸空间,避免内容超出画布\n const TEXT_RESERVE = 280;\n const arc = isArc(spec as IStorylineSpec);\n const arcDown = arc && normalizeLayout((spec as IStorylineSpec).layout).direction === 'down';\n const arcUp = arc && !arcDown;\n const portrait = isPortrait(spec as IStorylineSpec);\n const ladder = isLadder(spec as IStorylineSpec);\n const wing = isWing(spec as IStorylineSpec);\n const clock = isClock(spec as IStorylineSpec);\n // clock 辐射式布局:底部和顶部 blocks 的文字会向外延伸,需要在四周围留空间\n // portrait 底部 padding:精准预留最后一个 block 的 content 展示空间。\n // portrait 几何(layouts/portrait.ts):\n // - 每个 block center.y 等距放置\n // - image 中心 = block center;imageHeight ≈ slotHeight * PORTRAIT_IMAGE_HEIGHT_RATIO\n // - content 紧贴 image 下方:textY = image 底 + textGap;textHeight = titleLine + titleGap + contentHeight\n // - contentHeight ≈ slotHeight * PORTRAIT_CONTENT_HEIGHT_RATIO\n // 最后一个 block center 到 canvas 底部需要至少 imageH/2 + textGap + titleLine + titleGap + contentH。\n // transformSpec 阶段无法获得真实 region,使用 spec.height 估算 slotHeight;缺省回退到 LARGE。\n const portraitBottomReserve = (() => {\n if (!portrait) {\n return 0;\n }\n const count = (spec as IStorylineSpec).data?.length ?? 0;\n const canvasHeight = (spec as IStorylineSpec).height as number | undefined;\n if (!count || !canvasHeight) {\n return LARGE;\n }\n // 在 transformSpec 阶段还没经过 region 减去 padding 等步骤,\n // 这里直接用 canvasHeight / (count + 1) 作为 slotHeight 的近似上界,\n // 后续 layout 逻辑会基于真实 region 重新计算 imageH / contentH。\n const slotHeight = canvasHeight / (count + 1);\n const imageHeight = (spec as IStorylineSpec).image?.height ?? slotHeight * PORTRAIT_IMAGE_HEIGHT_RATIO;\n const contentHeight = slotHeight * PORTRAIT_CONTENT_HEIGHT_RATIO;\n const titleFontSize = Number((spec.title?.style as any)?.fontSize ?? 26);\n const titleLineHeight = Number((spec.title?.style as any)?.lineHeight ?? Math.round(titleFontSize * 1.35));\n const textGap = 8; // PORTRAIT_TEXT_GAP_FROM_IMAGE\n const titleToContentGap = 4; // PORTRAIT_TITLE_TO_CONTENT_GAP\n const breath = 16; // 额外呼吸空间\n return Math.max(\n LARGE,\n Math.round(imageHeight / 2 + textGap + titleLineHeight + titleToContentGap + contentHeight + breath)\n );\n })();\n // ladder:\n // - 左右 padding ≈ block content 宽度 × 2(保证两端 block 沿对角线水平有呼吸)\n // - 上下 padding ≈ block 高度 × 3(保证两端 block 沿对角线垂直留出充足画布留白)\n // 由于 transformSpec 阶段还无法获取真实 viewWidth,这里直接用 spec 中的估值。\n // 同时限制 padding 不超过 canvas 对应维度的 30%,否则 inner 区域会被挤压到不可见。\n const ladderHorizontalPadding = (() => {\n if (!ladder) {\n return 0;\n }\n const blockWidth = (spec as IStorylineSpec).block?.minWidth ?? resolveBlockWidth(spec as IStorylineSpec, 0);\n const imageWidth = (spec as IStorylineSpec).image?.width ?? 96; // UP_LADDER_BLOCK_IMAGE_SIZE\n const imageGap = (spec as IStorylineSpec).image?.gap ?? DEFAULT_IMAGE_GAP;\n const innerPadding = 12 * 2; // up-ladder 默认 block padding 12,左右共 24\n const contentWidth = Math.max(blockWidth - imageWidth - imageGap - innerPadding, DEFAULT_BLOCK_WIDTH * 0.5);\n const ideal = Math.round(contentWidth * 2);\n const canvasWidth = (spec as IStorylineSpec).width as number | undefined;\n const cap = canvasWidth ? Math.floor(canvasWidth * 0.3) : ideal;\n return Math.min(ideal, cap);\n })();\n const ladderVerticalPadding = (() => {\n if (!ladder) {\n return 0;\n }\n const blockHeight = (spec as IStorylineSpec).block?.height ?? 132;\n const ideal = Math.round(blockHeight * 3);\n const canvasHeight = (spec as IStorylineSpec).height as number | undefined;\n const cap = canvasHeight ? Math.floor(canvasHeight * 0.3) : ideal;\n return Math.min(ideal, cap);\n })();\n // arc up(dome): 顶部留给 textBox,底部紧贴(不要额外 padding)\n // arc down(bowl): 底部留给 textBox,顶部紧贴(不要额外 padding)\n // portrait: 底部留给最后一个 block 的 content\n // ladder: 四周均为 content 宽度\n // 其它:保持原默认 [SMALL, SMALL, LARGE, SMALL]\n const defaultTop = clock ? 40 : ladder ? ladderVerticalPadding : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL;\n const defaultBottom = clock\n ? 60\n : portrait\n ? portraitBottomReserve\n : wing\n ? 300\n : arcUp\n ? 0\n : arcDown\n ? TEXT_RESERVE\n : LARGE;\n // arc:左右 padding = content 宽度(canvasWidth / (count + 1)),保证内容沿弧线均匀分布\n const arcHorizontalPadding = (() => {\n if (!arc) {\n return SMALL;\n }\n const count = Math.max((spec as IStorylineSpec).data?.length ?? 0, 1);\n const canvasWidth = (spec as IStorylineSpec).width as number | undefined;\n if (!canvasWidth) {\n return SMALL;\n }\n return Math.round(canvasWidth / (count + 1));\n })();\n const defaultLeft = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;\n const defaultRight = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;\n\n const p = spec.padding;\n if (p == null) {\n spec.padding = [defaultTop, defaultRight, defaultBottom, defaultLeft];\n return;\n }\n if (Array.isArray(p)) {\n const [t, r = defaultRight, b, l = defaultLeft] = p;\n spec.padding = [t ?? defaultTop, r, b ?? defaultBottom, l];\n return;\n }\n if (typeof p === 'object') {\n spec.padding = {\n top: p.top ?? defaultTop,\n right: p.right ?? defaultRight,\n bottom: p.bottom ?? defaultBottom,\n left: p.left ?? defaultLeft\n };\n }\n};\n\nconst buildStorylineMarks = (spec: IStorylineSpec) => {\n const lineMark = buildLineMark(spec);\n const blockMarks = (spec.data ?? []).map((block, index) => buildBlockMark(spec, block, index));\n // landscape:连接曲线绘制在所有 block 之上,避免被 image 遮挡\n if (isLandscape(spec)) {\n return [...blockMarks, lineMark].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // portrait:lineMark 是中轴 rect,作为底层背景先绘制\n if (isPortrait(spec)) {\n return [lineMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // arc:先绘制 centerImage(最底层视觉锚点),再绘制贯穿 block 的弧线,最后绘制 block;\n // arc 不绘制 block 之间默认的连接线。direction = 'up' 时 centerImage 贴底(穹顶),\n // direction = 'down' 时 centerImage 贴顶(碗形)\n if (isArc(spec)) {\n const centerImageMark = buildArcCenterImageMark(spec);\n const arcMark = buildArcMark(spec);\n return [centerImageMark, arcMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // clock:辐射式信息盘 —— 圆环骨架 + 径向分隔线 → centerImage(盘心)→ blocks(楔形 + 外圈文字)\n if (isClock(spec)) {\n const ringsMark = buildClockArcMark(spec);\n const centerImageMark = buildClockCenterImageMark(spec);\n return [ringsMark, ...blockMarks, centerImageMark].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // wing:椭圆弧脉络 + 弧线上的圆形 image + 左右交替排列的 title/content;\n // 通过 layout.direction 控制翅膀朝向('left' | 'right')\n if (isWing(spec)) {\n const arcMark = buildWingArcMark(spec);\n return [arcMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // ladder:参考 Bauhaus 信息图 —— 对角线 + 沿对角线倾斜的 headline 大字 + 两侧错落 block\n if (isLadder(spec)) {\n const diagonalMark = buildLadderDiagonalMark(spec);\n const headlineMark = buildLadderHeadlineMark(spec);\n return [diagonalMark, headlineMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n return [lineMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n};\n\nconst buildLineMark = (spec: IStorylineSpec): IExtensionGroupMarkSpec | null => {\n if (spec.line?.visible === false || (spec.data?.length ?? 0) <= 1) {\n return null;\n }\n if (isLandscape(spec)) {\n return buildLandscapeConnectingCurve(spec);\n }\n if (isPortrait(spec)) {\n return buildPortraitAxisMark(spec);\n }\n return buildDefaultLineMark(spec);\n};\n\nconst buildBlockMark = (spec: IStorylineSpec, block: IStorylineBlock, index: number): IExtensionGroupMarkSpec => {\n if (isLandscape(spec)) {\n return buildLandscapeBlockMark(spec, block, index);\n }\n if (isPortrait(spec)) {\n return buildPortraitBlockMark(spec, block, index);\n }\n if (isArc(spec)) {\n return buildArcBlockMark(spec, block, index);\n }\n if (isClock(spec)) {\n return buildClockBlockMark(spec, block, index);\n }\n if (isWing(spec)) {\n return buildWingBlockMark(spec, block, index);\n }\n if (isLadder(spec)) {\n return buildLadderBlockMark(spec, block, index);\n }\n\n return buildDefaultBlockMark(spec, block, index);\n};\n"]}
1
+ {"version":3,"sources":["../src/charts/storyline/storyline-transformer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAgC,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EACL,KAAK,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,UAAU,EACV,MAAM,EACN,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,2BAA2B,EAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE1G,MAAM,OAAO,6BAA8B,SAAQ,0BAA+B;IAChF,aAAa,CAAC,IAAS;;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,aAAa,GAAG,gCACjB,IAAI,KACP,IAAI,EAAE,CAAC,GAAG,CAAC,MAAA,IAAI,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,GACX,CAAC;QAEpB,IAAI,CAAC,IAAI,GAAG,QAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,MAAM,CAAC;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC;QAClB,KAAK,CAAC,aAAa,CAAC,IAAW,CAAC,CAAC;IACnC,CAAC;CACF;AAWD,MAAM,mBAAmB,GAAG,CAAC,IAAS,EAAE,EAAE;;IACxC,MAAM,KAAK,GAAG,GAAG,CAAC;IAClB,MAAM,KAAK,GAAG,EAAE,CAAC;IAEjB,MAAM,YAAY,GAAG,GAAG,CAAC;IACzB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAsB,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,GAAG,IAAI,eAAe,CAAE,IAAuB,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC;IAC7F,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAsB,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAsB,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAsB,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAsB,CAAC,CAAC;IAC9C,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE;;QACjC,IACE,GAAG;YACH,MAAM;YACN,CAAC,CAAA,MAAC,IAAuB,CAAC,UAAU,0CAAE,KAAK,CAAA;YAC3C,CAAA,MAAC,IAAuB,CAAC,UAAU,0CAAE,OAAO,MAAK,KAAK,EACtD;YACA,OAAO,CAAC,CAAC;SACV;QACD,OAAO,2BAA2B,CAChC,IAAsB,EACtB,MAAM,CAAC,MAAC,IAAuB,CAAC,KAAK,mCAAI,IAAI,CAAC,EAC9C,MAAM,CAAC,MAAC,IAAuB,CAAC,MAAM,mCAAI,GAAG,CAAC,CAC/C,CAAC;IACJ,CAAC,CAAC,EAAE,CAAC;IAUL,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE;;QAClC,IAAI,CAAC,QAAQ,EAAE;YACb,OAAO,CAAC,CAAC;SACV;QACD,MAAM,KAAK,GAAG,MAAA,MAAC,IAAuB,CAAC,IAAI,0CAAE,MAAM,mCAAI,CAAC,CAAC;QACzD,MAAM,YAAY,GAAI,IAAuB,CAAC,MAA4B,CAAC;QAC3E,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,EAAE;YAC3B,OAAO,KAAK,CAAC;SACd;QAID,MAAM,UAAU,GAAG,YAAY,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAA,MAAC,IAAuB,CAAC,KAAK,0CAAE,MAAM,mCAAI,UAAU,GAAG,2BAA2B,CAAC;QACvG,MAAM,aAAa,GAAG,UAAU,GAAG,6BAA6B,CAAC;QACjE,MAAM,aAAa,GAAG,MAAM,CAAC,MAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAa,0CAAE,QAAQ,mCAAI,EAAE,CAAC,CAAC;QACzE,MAAM,eAAe,GAAG,MAAM,CAAC,MAAA,MAAC,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAa,0CAAE,UAAU,mCAAI,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC;QAC3G,MAAM,OAAO,GAAG,CAAC,CAAC;QAClB,MAAM,iBAAiB,GAAG,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC,GAAG,CACb,KAAK,EACL,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,OAAO,GAAG,eAAe,GAAG,iBAAiB,GAAG,aAAa,GAAG,MAAM,CAAC,CACrG,CAAC;IACJ,CAAC,CAAC,EAAE,CAAC;IAML,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE;;QACpC,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,CAAC,CAAC;SACV;QACD,MAAM,UAAU,GAAG,MAAA,MAAC,IAAuB,CAAC,KAAK,0CAAE,QAAQ,mCAAI,iBAAiB,CAAC,IAAsB,EAAE,CAAC,CAAC,CAAC;QAC5G,MAAM,UAAU,GAAG,MAAA,MAAC,IAAuB,CAAC,KAAK,0CAAE,KAAK,mCAAI,EAAE,CAAC;QAC/D,MAAM,QAAQ,GAAG,MAAA,MAAC,IAAuB,CAAC,KAAK,0CAAE,GAAG,mCAAI,iBAAiB,CAAC;QAC1E,MAAM,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,EAAE,mBAAmB,GAAG,GAAG,CAAC,CAAC;QAC5G,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,WAAW,GAAI,IAAuB,CAAC,KAA2B,CAAC;QACzE,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAChE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE;;QAClC,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,CAAC,CAAC;SACV;QACD,MAAM,WAAW,GAAG,MAAA,MAAC,IAAuB,CAAC,KAAK,0CAAE,MAAM,mCAAI,GAAG,CAAC;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAI,IAAuB,CAAC,MAA4B,CAAC;QAC3E,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC;IAML,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACzB,oBAAoB,EACpB,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CACzF,CAAC;IACF,MAAM,aAAa,GAAG,KAAK;QACzB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,QAAQ;YACR,CAAC,CAAC,qBAAqB;YACvB,CAAC,CAAC,IAAI;gBACJ,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,KAAK;oBACL,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,OAAO;wBACP,CAAC,CAAC,YAAY;wBACd,CAAC,CAAC,KAAK,CAAC;IAElB,MAAM,oBAAoB,GAAG,CAAC,GAAG,EAAE;;QACjC,IAAI,CAAC,GAAG,EAAE;YACR,OAAO,KAAK,CAAC;SACd;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAA,MAAC,IAAuB,CAAC,IAAI,0CAAE,MAAM,mCAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,MAAM,WAAW,GAAI,IAAuB,CAAC,KAA2B,CAAC;QACzE,IAAI,CAAC,WAAW,EAAE;YAChB,OAAO,KAAK,CAAC;SACd;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IACzF,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAE1F,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACvB,IAAI,CAAC,IAAI,IAAI,EAAE;QACb,IAAI,CAAC,OAAO,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;QACtE,OAAO;KACR;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;QACzB,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,OAAO;KACR;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACpB,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,UAAU,EAAE,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,aAAa,EAAE,CAAC,CAAC,CAAC;QAC3F,OAAO;KACR;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;QACzB,IAAI,CAAC,OAAO,GAAG;YACb,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,GAAG,mCAAI,UAAU,EAAE,oBAAoB,CAAC;YACxD,KAAK,EAAE,MAAA,CAAC,CAAC,KAAK,mCAAI,YAAY;YAC9B,MAAM,EAAE,MAAA,CAAC,CAAC,MAAM,mCAAI,aAAa;YACjC,IAAI,EAAE,MAAA,CAAC,CAAC,IAAI,mCAAI,WAAW;SAC5B,CAAC;KACH;AACH,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,IAAoB,EAAE,EAAE;;IACnD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,CAAC,MAAA,IAAI,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC/F,MAAM,cAAc,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAEpD,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACrB,OAAO,CAAC,cAAc,EAAE,GAAG,UAAU,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KAC/F;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KAC/F;IAID,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;QACf,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,CAAC,iBAAiB,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KACjG;IAED,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;QACjB,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,cAAc,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KAChG;IAGD,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;QAChB,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KAClG;IAED,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE;QAClB,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACnD,OAAO,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;KACjG;IACD,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAA8B,CAAC;AAChG,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAoB,EAAkC,EAAE;;IAC7E,IAAI,CAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,OAAO,MAAK,KAAK,IAAI,CAAC,MAAA,MAAA,IAAI,CAAC,IAAI,0CAAE,MAAM,mCAAI,CAAC,CAAC,IAAI,CAAC,EAAE;QACjE,OAAO,IAAI,CAAC;KACb;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACrB,OAAO,6BAA6B,CAAC,IAAI,CAAC,CAAC;KAC5C;IACD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC;KACpC;IACD,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAoB,EAAE,KAAsB,EAAE,KAAa,EAA2B,EAAE;IAC9G,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;QACrB,OAAO,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KACpD;IACD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,sBAAsB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KACnD;IACD,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;QACf,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KAC9C;IACD,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;QACjB,OAAO,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KAChD;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;QAChB,OAAO,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KAC/C;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE;QAClB,OAAO,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;KACjD;IAED,OAAO,qBAAqB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC,CAAC","file":"storyline-transformer.js","sourcesContent":["import { CommonChartSpecTransformer, type IExtensionGroupMarkSpec } from '@visactor/vchart';\nimport type { IStorylineBlock, IStorylineSpec } from './interface';\nimport {\n isArc,\n isClock,\n isLadder,\n isLandscape,\n isPortrait,\n isWing,\n normalizeLayout,\n resolveBlockWidth,\n DEFAULT_BLOCK_WIDTH,\n DEFAULT_IMAGE_GAP,\n buildTopTitleImageMark,\n getTitleImageReservedHeight\n} from './layouts/common';\nimport { buildClockArcMark, buildClockBlockMark } from './layouts/clock';\nimport { buildDefaultBlockMark, buildDefaultLineMark } from './layouts/default';\nimport { buildLandscapeBlockMark, buildLandscapeConnectingCurve } from './layouts/landscape';\nimport {\n buildPortraitAxisMark,\n buildPortraitBlockMark,\n PORTRAIT_CONTENT_HEIGHT_RATIO,\n PORTRAIT_IMAGE_HEIGHT_RATIO\n} from './layouts/portrait';\nimport { buildArcBlockMark, buildArcMark, buildArcTitleImageMark } from './layouts/arc';\nimport { buildWingArcMark, buildWingBlockMark, buildWingTitleImageMark } from './layouts/wing';\nimport { buildLadderBlockMark, buildLadderDiagonalMark, buildLadderHeadlineMark } from './layouts/ladder';\n\nexport class StorylineChartSpecTransformer extends CommonChartSpecTransformer<any> {\n transformSpec(spec: any): void {\n applyDefaultPadding(spec);\n const storylineSpec = {\n ...spec,\n data: [...(spec.data ?? [])]\n } as IStorylineSpec;\n\n spec.type = 'common' as any;\n spec.data = [];\n spec.series = [];\n spec.axes = [];\n spec.customMark = buildStorylineMarks(storylineSpec);\n delete spec.layout;\n delete spec.title;\n super.transformSpec(spec as any);\n }\n}\n\n/**\n * 图表默认 padding:\n * - arc up(dome 穹顶):titleImage 贴底 + textBox 在弧线上方,所以默认底部留 100px、顶部留 280px 给 textBox + 弧线呼吸空间;\n * - arc down(bowl 碗形):titleImage 贴顶 + textBox 在弧线下方,所以默认顶部留 100px、底部留 280px 给 textBox + 弧线呼吸空间;\n * - portrait:textBox 在 image 下方,最后一个 block 的 content 容易超出 region。底部 padding 默认 = 单个 block 的 content 高度\n * (即 regionHeight / count * 0.6),保证最后一个 block 有完整的 content 展示空间;\n * - ladder:四周默认留出 content 文本宽度,避免 block 沿对角线\"挤\"到画布边缘;\n * 用户在 spec.padding 中显式指定的值会被保留;顶部 titleImage 会额外保证最小 top padding,避免覆盖 region 内容。\n */\nconst applyDefaultPadding = (spec: any) => {\n const LARGE = 100;\n const SMALL = 20;\n // 给 textBox(240px)+ 一定呼吸空间,避免内容超出画布\n const TEXT_RESERVE = 280;\n const arc = isArc(spec as IStorylineSpec);\n const arcDown = arc && normalizeLayout((spec as IStorylineSpec).layout).direction === 'down';\n const arcUp = arc && !arcDown;\n const portrait = isPortrait(spec as IStorylineSpec);\n const ladder = isLadder(spec as IStorylineSpec);\n const wing = isWing(spec as IStorylineSpec);\n const clock = isClock(spec as IStorylineSpec);\n const topTitleImageReserve = (() => {\n if (\n arc ||\n ladder ||\n !(spec as IStorylineSpec).titleImage?.image ||\n (spec as IStorylineSpec).titleImage?.visible === false\n ) {\n return 0;\n }\n return getTitleImageReservedHeight(\n spec as IStorylineSpec,\n Number((spec as IStorylineSpec).width ?? 1000),\n Number((spec as IStorylineSpec).height ?? 600)\n );\n })();\n // clock 辐射式布局:底部和顶部 blocks 的文字会向外延伸,需要在四周围留空间\n // portrait 底部 padding:精准预留最后一个 block 的 content 展示空间。\n // portrait 几何(layouts/portrait.ts):\n // - 每个 block center.y 等距放置\n // - image 中心 = block center;imageHeight ≈ slotHeight * PORTRAIT_IMAGE_HEIGHT_RATIO\n // - content 紧贴 image 下方:textY = image 底 + textGap;textHeight = titleLine + titleGap + contentHeight\n // - contentHeight ≈ slotHeight * PORTRAIT_CONTENT_HEIGHT_RATIO\n // 最后一个 block center 到 canvas 底部需要至少 imageH/2 + textGap + titleLine + titleGap + contentH。\n // transformSpec 阶段无法获得真实 region,使用 spec.height 估算 slotHeight;缺省回退到 LARGE。\n const portraitBottomReserve = (() => {\n if (!portrait) {\n return 0;\n }\n const count = (spec as IStorylineSpec).data?.length ?? 0;\n const canvasHeight = (spec as IStorylineSpec).height as number | undefined;\n if (!count || !canvasHeight) {\n return LARGE;\n }\n // 在 transformSpec 阶段还没经过 region 减去 padding 等步骤,\n // 这里直接用 canvasHeight / (count + 1) 作为 slotHeight 的近似上界,\n // 后续 layout 逻辑会基于真实 region 重新计算 imageH / contentH。\n const slotHeight = canvasHeight / (count + 1);\n const imageHeight = (spec as IStorylineSpec).image?.height ?? slotHeight * PORTRAIT_IMAGE_HEIGHT_RATIO;\n const contentHeight = slotHeight * PORTRAIT_CONTENT_HEIGHT_RATIO;\n const titleFontSize = Number((spec.title?.style as any)?.fontSize ?? 26);\n const titleLineHeight = Number((spec.title?.style as any)?.lineHeight ?? Math.round(titleFontSize * 1.35));\n const textGap = 8; // PORTRAIT_TEXT_GAP_FROM_IMAGE\n const titleToContentGap = 4; // PORTRAIT_TITLE_TO_CONTENT_GAP\n const breath = 16; // 额外呼吸空间\n return Math.max(\n LARGE,\n Math.round(imageHeight / 2 + textGap + titleLineHeight + titleToContentGap + contentHeight + breath)\n );\n })();\n // ladder:\n // - 左右 padding ≈ block content 宽度 × 2(保证两端 block 沿对角线水平有呼吸)\n // - 上下 padding ≈ block 高度 × 3(保证两端 block 沿对角线垂直留出充足画布留白)\n // 由于 transformSpec 阶段还无法获取真实 viewWidth,这里直接用 spec 中的估值。\n // 同时限制 padding 不超过 canvas 对应维度的 30%,否则 inner 区域会被挤压到不可见。\n const ladderHorizontalPadding = (() => {\n if (!ladder) {\n return 0;\n }\n const blockWidth = (spec as IStorylineSpec).block?.minWidth ?? resolveBlockWidth(spec as IStorylineSpec, 0);\n const imageWidth = (spec as IStorylineSpec).image?.width ?? 96; // UP_LADDER_BLOCK_IMAGE_SIZE\n const imageGap = (spec as IStorylineSpec).image?.gap ?? DEFAULT_IMAGE_GAP;\n const innerPadding = 12 * 2; // up-ladder 默认 block padding 12,左右共 24\n const contentWidth = Math.max(blockWidth - imageWidth - imageGap - innerPadding, DEFAULT_BLOCK_WIDTH * 0.5);\n const ideal = Math.round(contentWidth * 2);\n const canvasWidth = (spec as IStorylineSpec).width as number | undefined;\n const cap = canvasWidth ? Math.floor(canvasWidth * 0.3) : ideal;\n return Math.min(ideal, cap);\n })();\n const ladderVerticalPadding = (() => {\n if (!ladder) {\n return 0;\n }\n const blockHeight = (spec as IStorylineSpec).block?.height ?? 132;\n const ideal = Math.round(blockHeight * 3);\n const canvasHeight = (spec as IStorylineSpec).height as number | undefined;\n const cap = canvasHeight ? Math.floor(canvasHeight * 0.3) : ideal;\n return Math.min(ideal, cap);\n })();\n // arc up(dome): 顶部留给 textBox,底部紧贴(不要额外 padding)\n // arc down(bowl): 底部留给 textBox,顶部紧贴(不要额外 padding)\n // portrait: 底部留给最后一个 block 的 content\n // ladder: 四周均为 content 宽度\n // 其它:保持原默认 [SMALL, SMALL, LARGE, SMALL]\n const defaultTop = Math.max(\n topTitleImageReserve,\n clock ? 40 : ladder ? ladderVerticalPadding : arcDown ? 0 : arcUp ? TEXT_RESERVE : SMALL\n );\n const defaultBottom = clock\n ? 60\n : portrait\n ? portraitBottomReserve\n : wing\n ? 300\n : arcUp\n ? 0\n : arcDown\n ? TEXT_RESERVE\n : LARGE;\n // arc:左右 padding = content 宽度(canvasWidth / (count + 1)),保证内容沿弧线均匀分布\n const arcHorizontalPadding = (() => {\n if (!arc) {\n return SMALL;\n }\n const count = Math.max((spec as IStorylineSpec).data?.length ?? 0, 1);\n const canvasWidth = (spec as IStorylineSpec).width as number | undefined;\n if (!canvasWidth) {\n return SMALL;\n }\n return Math.round(canvasWidth / (count + 1));\n })();\n const defaultLeft = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;\n const defaultRight = clock ? 40 : ladder ? ladderHorizontalPadding : arcHorizontalPadding;\n\n const p = spec.padding;\n if (p == null) {\n spec.padding = [defaultTop, defaultRight, defaultBottom, defaultLeft];\n return;\n }\n if (typeof p === 'number') {\n spec.padding = [Math.max(p, topTitleImageReserve), p, p, p];\n return;\n }\n if (Array.isArray(p)) {\n const [t, r = defaultRight, b, l = defaultLeft] = p;\n spec.padding = [Math.max(t ?? defaultTop, topTitleImageReserve), r, b ?? defaultBottom, l];\n return;\n }\n if (typeof p === 'object') {\n spec.padding = {\n top: Math.max(p.top ?? defaultTop, topTitleImageReserve),\n right: p.right ?? defaultRight,\n bottom: p.bottom ?? defaultBottom,\n left: p.left ?? defaultLeft\n };\n }\n};\n\nconst buildStorylineMarks = (spec: IStorylineSpec) => {\n const lineMark = buildLineMark(spec);\n const blockMarks = (spec.data ?? []).map((block, index) => buildBlockMark(spec, block, index));\n const titleImageMark = buildTopTitleImageMark(spec);\n // landscape:连接曲线绘制在所有 block 之上,避免被 image 遮挡\n if (isLandscape(spec)) {\n return [titleImageMark, ...blockMarks, lineMark].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // portrait:lineMark 是中轴 rect,作为底层背景先绘制\n if (isPortrait(spec)) {\n return [lineMark, titleImageMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // arc:先绘制 titleImage(视觉锚点),再绘制贯穿 block 的弧线,最后绘制 block;\n // arc 不绘制 block 之间默认的连接线。direction = 'up' 时 titleImage 贴底(穹顶),\n // direction = 'down' 时 titleImage 贴顶(碗形)\n if (isArc(spec)) {\n const arcTitleImageMark = buildArcTitleImageMark(spec);\n const arcMark = buildArcMark(spec);\n return [arcTitleImageMark, arcMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // clock:辐射式信息盘 —— 圆环骨架 + 径向分隔线 + blocks(楔形 + 外圈文字)\n if (isClock(spec)) {\n const ringsMark = buildClockArcMark(spec);\n return [titleImageMark, ringsMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // wing:椭圆弧脉络 + 弧线上的圆形 image + 左右交替排列的 title/content;\n // 通过 layout.direction 控制翅膀朝向('left' | 'right')\n if (isWing(spec)) {\n const arcMark = buildWingArcMark(spec);\n const wingTitleImageMark = buildWingTitleImageMark(spec);\n return [arcMark, wingTitleImageMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n // ladder:参考 Bauhaus 信息图 —— 对角线 + 沿对角线倾斜的 headline 大字 + 两侧错落 block\n if (isLadder(spec)) {\n const diagonalMark = buildLadderDiagonalMark(spec);\n const headlineMark = buildLadderHeadlineMark(spec);\n return [diagonalMark, headlineMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n }\n return [titleImageMark, lineMark, ...blockMarks].filter(Boolean) as IExtensionGroupMarkSpec[];\n};\n\nconst buildLineMark = (spec: IStorylineSpec): IExtensionGroupMarkSpec | null => {\n if (spec.line?.visible === false || (spec.data?.length ?? 0) <= 1) {\n return null;\n }\n if (isLandscape(spec)) {\n return buildLandscapeConnectingCurve(spec);\n }\n if (isPortrait(spec)) {\n return buildPortraitAxisMark(spec);\n }\n return buildDefaultLineMark(spec);\n};\n\nconst buildBlockMark = (spec: IStorylineSpec, block: IStorylineBlock, index: number): IExtensionGroupMarkSpec => {\n if (isLandscape(spec)) {\n return buildLandscapeBlockMark(spec, block, index);\n }\n if (isPortrait(spec)) {\n return buildPortraitBlockMark(spec, block, index);\n }\n if (isArc(spec)) {\n return buildArcBlockMark(spec, block, index);\n }\n if (isClock(spec)) {\n return buildClockBlockMark(spec, block, index);\n }\n if (isWing(spec)) {\n return buildWingBlockMark(spec, block, index);\n }\n if (isLadder(spec)) {\n return buildLadderBlockMark(spec, block, index);\n }\n\n return buildDefaultBlockMark(spec, block, index);\n};\n"]}