@antv/infographic 0.1.3 → 0.1.4

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 (171) hide show
  1. package/dist/infographic.min.js +110 -105
  2. package/dist/infographic.min.js.map +1 -1
  3. package/esm/constants/element.d.ts +1 -1
  4. package/esm/constants/index.d.ts +1 -0
  5. package/esm/constants/index.js +1 -0
  6. package/esm/constants/service.d.ts +1 -0
  7. package/esm/constants/service.js +1 -0
  8. package/esm/designs/components/Illus.js +1 -1
  9. package/esm/designs/structures/chart-wordcloud.d.ts +11 -0
  10. package/esm/designs/structures/chart-wordcloud.js +156 -0
  11. package/esm/designs/structures/hierarchy-tree.d.ts +2 -0
  12. package/esm/designs/structures/hierarchy-tree.js +179 -50
  13. package/esm/designs/structures/index.d.ts +2 -0
  14. package/esm/designs/structures/index.js +2 -0
  15. package/esm/designs/structures/sequence-stairs-front.d.ts +8 -0
  16. package/esm/designs/structures/sequence-stairs-front.js +116 -0
  17. package/esm/designs/types.d.ts +8 -0
  18. package/esm/editor/managers/state.js +1 -1
  19. package/esm/index.d.ts +2 -0
  20. package/esm/index.js +1 -0
  21. package/esm/options/parser.d.ts +1 -1
  22. package/esm/options/parser.js +33 -15
  23. package/esm/renderer/composites/icon.js +1 -1
  24. package/esm/renderer/composites/illus.js +1 -1
  25. package/esm/resource/loader.d.ts +2 -2
  26. package/esm/resource/loader.js +22 -11
  27. package/esm/resource/loaders/index.d.ts +1 -0
  28. package/esm/resource/loaders/index.js +1 -0
  29. package/esm/resource/loaders/remote.d.ts +1 -1
  30. package/esm/resource/loaders/remote.js +10 -2
  31. package/esm/resource/loaders/search.d.ts +1 -0
  32. package/esm/resource/loaders/search.js +51 -0
  33. package/esm/resource/types/index.d.ts +1 -0
  34. package/esm/resource/types/resource.d.ts +8 -1
  35. package/esm/resource/types/scene.d.ts +1 -0
  36. package/esm/resource/utils/data-uri.js +20 -11
  37. package/esm/resource/utils/parser.js +92 -1
  38. package/esm/resource/utils/ref.js +2 -2
  39. package/esm/runtime/Infographic.d.ts +7 -6
  40. package/esm/runtime/Infographic.js +48 -17
  41. package/esm/runtime/utils.d.ts +4 -2
  42. package/esm/runtime/utils.js +33 -13
  43. package/esm/syntax/index.d.ts +3 -0
  44. package/esm/syntax/index.js +101 -0
  45. package/esm/syntax/mapper.d.ts +3 -0
  46. package/esm/syntax/mapper.js +238 -0
  47. package/esm/syntax/parser.d.ts +14 -0
  48. package/esm/syntax/parser.js +142 -0
  49. package/esm/syntax/schema.d.ts +6 -0
  50. package/esm/syntax/schema.js +74 -0
  51. package/esm/syntax/types.d.ts +61 -0
  52. package/esm/syntax/types.js +1 -0
  53. package/esm/templates/built-in.js +4 -0
  54. package/esm/templates/hierarchy-tree.js +25 -11
  55. package/esm/templates/sequence-stairs.d.ts +2 -0
  56. package/esm/templates/sequence-stairs.js +42 -0
  57. package/esm/templates/word-cloud.d.ts +2 -0
  58. package/esm/templates/word-cloud.js +19 -0
  59. package/esm/themes/types.d.ts +1 -1
  60. package/esm/utils/design.d.ts +2 -0
  61. package/esm/utils/design.js +10 -0
  62. package/esm/utils/font.js +11 -1
  63. package/esm/utils/index.d.ts +1 -0
  64. package/esm/utils/index.js +1 -0
  65. package/lib/constants/element.d.ts +1 -1
  66. package/lib/constants/index.d.ts +1 -0
  67. package/lib/constants/index.js +1 -0
  68. package/lib/constants/service.d.ts +1 -0
  69. package/lib/constants/service.js +4 -0
  70. package/lib/designs/components/Illus.js +1 -1
  71. package/lib/designs/structures/chart-wordcloud.d.ts +11 -0
  72. package/lib/designs/structures/chart-wordcloud.js +160 -0
  73. package/lib/designs/structures/hierarchy-tree.d.ts +2 -0
  74. package/lib/designs/structures/hierarchy-tree.js +179 -50
  75. package/lib/designs/structures/index.d.ts +2 -0
  76. package/lib/designs/structures/index.js +2 -0
  77. package/lib/designs/structures/sequence-stairs-front.d.ts +8 -0
  78. package/lib/designs/structures/sequence-stairs-front.js +120 -0
  79. package/lib/designs/types.d.ts +8 -0
  80. package/lib/editor/managers/state.js +1 -1
  81. package/lib/index.d.ts +2 -0
  82. package/lib/index.js +4 -1
  83. package/lib/options/parser.d.ts +1 -1
  84. package/lib/options/parser.js +32 -14
  85. package/lib/renderer/composites/icon.js +1 -1
  86. package/lib/renderer/composites/illus.js +1 -1
  87. package/lib/resource/loader.d.ts +2 -2
  88. package/lib/resource/loader.js +21 -10
  89. package/lib/resource/loaders/index.d.ts +1 -0
  90. package/lib/resource/loaders/index.js +1 -0
  91. package/lib/resource/loaders/remote.d.ts +1 -1
  92. package/lib/resource/loaders/remote.js +10 -2
  93. package/lib/resource/loaders/search.d.ts +1 -0
  94. package/lib/resource/loaders/search.js +54 -0
  95. package/lib/resource/types/index.d.ts +1 -0
  96. package/lib/resource/types/resource.d.ts +8 -1
  97. package/lib/resource/types/scene.d.ts +1 -0
  98. package/lib/resource/utils/data-uri.js +20 -11
  99. package/lib/resource/utils/parser.js +92 -1
  100. package/lib/resource/utils/ref.js +2 -2
  101. package/lib/runtime/Infographic.d.ts +7 -6
  102. package/lib/runtime/Infographic.js +47 -16
  103. package/lib/runtime/utils.d.ts +4 -2
  104. package/lib/runtime/utils.js +35 -13
  105. package/lib/syntax/index.d.ts +3 -0
  106. package/lib/syntax/index.js +104 -0
  107. package/lib/syntax/mapper.d.ts +3 -0
  108. package/lib/syntax/mapper.js +242 -0
  109. package/lib/syntax/parser.d.ts +14 -0
  110. package/lib/syntax/parser.js +146 -0
  111. package/lib/syntax/schema.d.ts +6 -0
  112. package/lib/syntax/schema.js +77 -0
  113. package/lib/syntax/types.d.ts +61 -0
  114. package/lib/syntax/types.js +2 -0
  115. package/lib/templates/built-in.js +4 -0
  116. package/lib/templates/hierarchy-tree.js +25 -11
  117. package/lib/templates/sequence-stairs.d.ts +2 -0
  118. package/lib/templates/sequence-stairs.js +45 -0
  119. package/lib/templates/word-cloud.d.ts +2 -0
  120. package/lib/templates/word-cloud.js +22 -0
  121. package/lib/themes/types.d.ts +1 -1
  122. package/lib/utils/design.d.ts +2 -0
  123. package/lib/utils/design.js +13 -0
  124. package/lib/utils/font.js +11 -1
  125. package/lib/utils/index.d.ts +1 -0
  126. package/lib/utils/index.js +1 -0
  127. package/package.json +1 -1
  128. package/src/constants/element.ts +1 -1
  129. package/src/constants/index.ts +1 -0
  130. package/src/constants/service.ts +1 -0
  131. package/src/designs/components/Illus.tsx +1 -1
  132. package/src/designs/structures/chart-wordcloud.tsx +278 -0
  133. package/src/designs/structures/hierarchy-tree.tsx +212 -59
  134. package/src/designs/structures/index.ts +2 -0
  135. package/src/designs/structures/sequence-stairs-front.tsx +291 -0
  136. package/src/designs/types.ts +9 -0
  137. package/src/editor/managers/state.ts +1 -1
  138. package/src/index.ts +2 -0
  139. package/src/options/parser.ts +57 -28
  140. package/src/renderer/composites/icon.ts +1 -1
  141. package/src/renderer/composites/illus.ts +1 -1
  142. package/src/resource/loader.ts +22 -8
  143. package/src/resource/loaders/index.ts +1 -0
  144. package/src/resource/loaders/remote.ts +9 -2
  145. package/src/resource/loaders/search.ts +52 -0
  146. package/src/resource/types/index.ts +2 -1
  147. package/src/resource/types/resource.ts +12 -1
  148. package/src/resource/types/scene.ts +1 -0
  149. package/src/resource/utils/data-uri.ts +20 -11
  150. package/src/resource/utils/parser.ts +103 -2
  151. package/src/resource/utils/ref.ts +2 -2
  152. package/src/runtime/Infographic.tsx +74 -22
  153. package/src/runtime/utils.ts +38 -16
  154. package/src/syntax/index.ts +124 -0
  155. package/src/syntax/mapper.ts +362 -0
  156. package/src/syntax/parser.ts +171 -0
  157. package/src/syntax/schema.ts +98 -0
  158. package/src/syntax/types.ts +89 -0
  159. package/src/templates/built-in.ts +4 -0
  160. package/src/templates/hierarchy-tree.ts +34 -11
  161. package/src/templates/sequence-stairs.ts +44 -0
  162. package/src/templates/word-cloud.ts +21 -0
  163. package/src/themes/types.ts +1 -1
  164. package/src/utils/design.ts +14 -0
  165. package/src/utils/font.ts +11 -1
  166. package/src/utils/index.ts +1 -0
  167. package/esm/resource/types/font.d.ts +0 -12
  168. package/lib/resource/types/font.d.ts +0 -12
  169. package/src/resource/types/font.ts +0 -23
  170. /package/esm/resource/types/{font.js → scene.js} +0 -0
  171. /package/lib/resource/types/{font.js → scene.js} +0 -0
@@ -41,6 +41,10 @@ const components_1 = require("../components");
41
41
  const layouts_1 = require("../layouts");
42
42
  const utils_1 = require("../utils");
43
43
  const registry_1 = require("./registry");
44
+ const distributedPadding = (rawPadding, size) => {
45
+ const maxPadding = Math.max(0, size / 2 - 1);
46
+ return Math.min(rawPadding, maxPadding);
47
+ };
44
48
  const HierarchyTree = (props) => {
45
49
  const { Title, Items, data,
46
50
  // 布局配置
@@ -52,7 +56,11 @@ const HierarchyTree = (props) => {
52
56
  // 装饰元素配置
53
57
  edgeMarker = 'none', markerSize = 12,
54
58
  // 着色模式配置
55
- colorMode = 'branch', options, } = props;
59
+ colorMode = 'branch',
60
+ // 布局方向
61
+ orientation = 'top-bottom', options, } = props;
62
+ const isHorizontal = orientation === 'left-right' || orientation === 'right-left';
63
+ const mainSign = orientation === 'bottom-top' || orientation === 'right-left' ? -1 : 1;
56
64
  const { title, desc } = data;
57
65
  const colorPrimary = (0, utils_1.getColorPrimary)(options);
58
66
  // 内置工具方法:数据预处理
@@ -65,19 +73,52 @@ const HierarchyTree = (props) => {
65
73
  return list;
66
74
  };
67
75
  // 内置工具方法:生成圆角路径
68
- const createRoundedPath = (x1, y1, x2, y2, radius) => {
69
- const midY = y1 + (y2 - y1) / 2;
70
- const effectiveRadius = Math.min(radius, Math.abs(y2 - y1) / 2, Math.abs(x2 - x1) / 2);
76
+ const createRoundedPath = (x1, y1, x2, y2, radius, direction = 'vertical') => {
77
+ const isVertical = direction === 'vertical';
78
+ const deltaMain = isVertical ? y2 - y1 : x2 - x1;
79
+ const deltaCross = isVertical ? x2 - x1 : y2 - y1;
80
+ const signMain = deltaMain === 0 ? 1 : Math.sign(deltaMain);
81
+ const signCross = deltaCross === 0 ? 1 : Math.sign(deltaCross);
82
+ const midMain = isVertical ? y1 + deltaMain / 2 : x1 + deltaMain / 2;
83
+ const effectiveRadius = Math.min(radius, Math.abs(deltaMain) / 2, Math.abs(deltaCross) / 2);
71
84
  if (effectiveRadius === 0) {
72
- return `M ${x1} ${y1} L ${x1} ${midY} L ${x2} ${midY} L ${x2} ${y2}`;
85
+ return isVertical
86
+ ? `M ${x1} ${y1} L ${x1} ${midMain} L ${x2} ${midMain} L ${x2} ${y2}`
87
+ : `M ${x1} ${y1} L ${midMain} ${y1} L ${midMain} ${y2} L ${x2} ${y2}`;
88
+ }
89
+ if (isVertical) {
90
+ return `M ${x1} ${y1}
91
+ L ${x1} ${midMain - signMain * effectiveRadius}
92
+ Q ${x1} ${midMain} ${x1 + signCross * effectiveRadius} ${midMain}
93
+ L ${x2 - signCross * effectiveRadius} ${midMain}
94
+ Q ${x2} ${midMain} ${x2} ${midMain + signMain * effectiveRadius}
95
+ L ${x2} ${y2}`;
73
96
  }
74
97
  return `M ${x1} ${y1}
75
- L ${x1} ${midY - effectiveRadius}
76
- Q ${x1} ${midY} ${x1 + (x2 > x1 ? effectiveRadius : -effectiveRadius)} ${midY}
77
- L ${x2 - (x2 > x1 ? effectiveRadius : -effectiveRadius)} ${midY}
78
- Q ${x2} ${midY} ${x2} ${midY + effectiveRadius}
98
+ L ${midMain - signMain * effectiveRadius} ${y1}
99
+ Q ${midMain} ${y1} ${midMain} ${y1 + signCross * effectiveRadius}
100
+ L ${midMain} ${y2 - signCross * effectiveRadius}
101
+ Q ${midMain} ${y2} ${midMain + signMain * effectiveRadius} ${y2}
79
102
  L ${x2} ${y2}`;
80
103
  };
104
+ const getLayoutPoint = (node) => {
105
+ const { x, y } = node;
106
+ return isHorizontal ? { x: y * mainSign, y: x } : { x, y: y * mainSign };
107
+ };
108
+ const getNodeRect = (node, bounds, offsets) => {
109
+ const { x, y } = getLayoutPoint(node);
110
+ const centerX = x + offsets.x;
111
+ const top = y + offsets.y;
112
+ const centerY = top + bounds.height / 2;
113
+ return {
114
+ centerX,
115
+ centerY,
116
+ left: centerX - bounds.width / 2,
117
+ right: centerX + bounds.width / 2,
118
+ top,
119
+ bottom: top + bounds.height,
120
+ };
121
+ };
81
122
  // 内置工具方法:构建层级数据
82
123
  const buildHierarchyData = (list) => {
83
124
  if (!list.length)
@@ -130,12 +171,13 @@ const HierarchyTree = (props) => {
130
171
  };
131
172
  // 内置工具方法:渲染单个节点
132
173
  const renderNode = (node, levelBounds, btnBounds, offsets, gradientDefs, allNodes) => {
133
- const { x, y, depth, data: nodeData, parent } = node;
174
+ const { depth, data: nodeData, parent } = node;
134
175
  const indexes = nodeData._originalIndex;
135
176
  const NodeComponent = (0, utils_1.getItemComponent)(Items, depth);
136
177
  const bounds = levelBounds.get(depth);
137
- const nodeX = x + offsets.x - bounds.width / 2;
138
- const nodeY = y + offsets.y;
178
+ const nodeRect = getNodeRect(node, bounds, offsets);
179
+ const nodeX = nodeRect.left;
180
+ const nodeY = nodeRect.top;
139
181
  const elements = {
140
182
  items: [],
141
183
  btns: [],
@@ -158,45 +200,94 @@ const HierarchyTree = (props) => {
158
200
  // 父子连线
159
201
  if (parent) {
160
202
  const parentBounds = levelBounds.get(parent.depth);
203
+ const parentRect = getNodeRect(parent, parentBounds, offsets);
161
204
  // 计算父节点的子节点数量和当前节点在兄弟中的索引
162
205
  const siblings = allNodes.filter((n) => n.parent === parent);
163
206
  const siblingIndex = siblings.findIndex((s) => s === node);
164
207
  const siblingCount = siblings.length;
165
208
  // 计算连接线起点
166
209
  let parentX;
210
+ let parentY;
167
211
  if (edgeOrigin === 'distributed' && siblingCount > 1) {
168
212
  // 分布式起点:根据子节点数量分配起点位置
169
- const startX = parent.x + offsets.x - parentBounds.width / 2 + edgeOriginPadding;
170
- const endX = parent.x + offsets.x + parentBounds.width / 2 - edgeOriginPadding;
171
- const segmentWidth = (endX - startX) / siblingCount;
172
- parentX = startX + segmentWidth * siblingIndex + segmentWidth / 2;
213
+ if (isHorizontal) {
214
+ const padding = distributedPadding(edgeOriginPadding, parentBounds.height);
215
+ const startY = parentRect.top + padding;
216
+ const endY = parentRect.bottom - padding;
217
+ const segmentHeight = (endY - startY) / siblingCount;
218
+ parentY = startY + segmentHeight * siblingIndex + segmentHeight / 2;
219
+ parentX =
220
+ (mainSign > 0 ? parentRect.right : parentRect.left) +
221
+ edgeOffset * mainSign;
222
+ }
223
+ else {
224
+ const padding = distributedPadding(edgeOriginPadding, parentBounds.width);
225
+ const startX = parentRect.left + padding;
226
+ const endX = parentRect.right - padding;
227
+ const segmentWidth = (endX - startX) / siblingCount;
228
+ parentX = startX + segmentWidth * siblingIndex + segmentWidth / 2;
229
+ parentY =
230
+ (mainSign > 0 ? parentRect.bottom : parentRect.top) +
231
+ edgeOffset * mainSign;
232
+ }
173
233
  }
174
234
  else {
175
235
  // 中心起点:所有线从节点中心出发
176
- parentX = parent.x + offsets.x;
236
+ parentX = isHorizontal
237
+ ? (mainSign > 0 ? parentRect.right : parentRect.left) +
238
+ edgeOffset * mainSign
239
+ : parentRect.centerX;
240
+ parentY = isHorizontal
241
+ ? parentRect.centerY
242
+ : (mainSign > 0 ? parentRect.bottom : parentRect.top) +
243
+ edgeOffset * mainSign;
177
244
  }
178
- const parentY = parent.y + offsets.y + parentBounds.height + edgeOffset;
179
- const childX = x + offsets.x;
180
- let childY = y + offsets.y - edgeOffset;
245
+ const baseChildX = isHorizontal
246
+ ? (mainSign > 0 ? nodeRect.left : nodeRect.right) -
247
+ edgeOffset * mainSign
248
+ : nodeRect.centerX;
249
+ const baseChildY = isHorizontal
250
+ ? nodeRect.centerY
251
+ : (mainSign > 0 ? nodeRect.top : nodeRect.bottom) -
252
+ edgeOffset * mainSign;
253
+ let childX = baseChildX;
254
+ let childY = baseChildY;
181
255
  // 调整终点位置(为箭头留出空间)
182
256
  if (edgeMarker === 'arrow') {
183
- childY -= markerSize;
257
+ if (isHorizontal) {
258
+ childX -= markerSize * mainSign;
259
+ }
260
+ else {
261
+ childY -= markerSize * mainSign;
262
+ }
184
263
  }
185
264
  // 生成路径
186
265
  let pathD;
187
266
  if (edgeType === 'curved') {
188
267
  // 使用贝塞尔曲线绘制曲线连接
189
- const midY = parentY + (childY - parentY) / 2;
190
- pathD = `M ${parentX} ${parentY} C ${parentX} ${midY}, ${childX} ${midY}, ${childX} ${childY}`;
268
+ if (isHorizontal) {
269
+ const midX = parentX + (childX - parentX) / 2;
270
+ pathD = `M ${parentX} ${parentY} C ${midX} ${parentY}, ${midX} ${childY}, ${childX} ${childY}`;
271
+ }
272
+ else {
273
+ const midY = parentY + (childY - parentY) / 2;
274
+ pathD = `M ${parentX} ${parentY} C ${parentX} ${midY}, ${childX} ${midY}, ${childX} ${childY}`;
275
+ }
191
276
  }
192
277
  else if (edgeCornerRadius > 0) {
193
278
  // 使用圆角路径
194
- pathD = createRoundedPath(parentX, parentY, childX, childY, edgeCornerRadius);
279
+ pathD = createRoundedPath(parentX, parentY, childX, childY, edgeCornerRadius, isHorizontal ? 'horizontal' : 'vertical');
195
280
  }
196
281
  else {
197
282
  // 使用直角折线
198
- const midY = parentY + (childY - parentY) / 2;
199
- pathD = `M ${parentX} ${parentY} L ${parentX} ${midY} L ${childX} ${midY} L ${childX} ${childY}`;
283
+ if (isHorizontal) {
284
+ const midX = parentX + (childX - parentX) / 2;
285
+ pathD = `M ${parentX} ${parentY} L ${midX} ${parentY} L ${midX} ${childY} L ${childX} ${childY}`;
286
+ }
287
+ else {
288
+ const midY = parentY + (childY - parentY) / 2;
289
+ pathD = `M ${parentX} ${parentY} L ${parentX} ${midY} L ${childX} ${midY} L ${childX} ${childY}`;
290
+ }
200
291
  }
201
292
  // 确定连接线颜色
202
293
  let strokeColor = colorPrimary;
@@ -228,17 +319,29 @@ const HierarchyTree = (props) => {
228
319
  ? (0, utils_1.getPaletteColor)(options, colorIndexes)
229
320
  : (0, utils_1.getColorPrimary)(options);
230
321
  // 三角形箭头
231
- const arrowPoints = [
232
- { x: childX, y: y + offsets.y - edgeOffset },
233
- {
234
- x: childX - markerSize / 2,
235
- y: y + offsets.y - edgeOffset - markerSize,
236
- },
237
- {
238
- x: childX + markerSize / 2,
239
- y: y + offsets.y - edgeOffset - markerSize,
240
- },
241
- ];
322
+ const arrowPoints = isHorizontal
323
+ ? [
324
+ { x: baseChildX, y: baseChildY },
325
+ {
326
+ x: baseChildX - markerSize * mainSign,
327
+ y: baseChildY - markerSize / 2,
328
+ },
329
+ {
330
+ x: baseChildX - markerSize * mainSign,
331
+ y: baseChildY + markerSize / 2,
332
+ },
333
+ ]
334
+ : [
335
+ { x: baseChildX, y: baseChildY },
336
+ {
337
+ x: baseChildX - markerSize / 2,
338
+ y: baseChildY - markerSize * mainSign,
339
+ },
340
+ {
341
+ x: baseChildX + markerSize / 2,
342
+ y: baseChildY - markerSize * mainSign,
343
+ },
344
+ ];
242
345
  elements.deco.push((0, jsx_runtime_1.jsx)(jsx_1.Polygon, { points: arrowPoints, fill: arrowColor, width: markerSize, height: markerSize }));
243
346
  }
244
347
  // 添加连接点装饰
@@ -252,16 +355,20 @@ const HierarchyTree = (props) => {
252
355
  ? (0, utils_1.getPaletteColor)(options, parentColorIndexes)
253
356
  : (0, utils_1.getColorPrimary)(options);
254
357
  // 父节点连接点
255
- elements.deco.push((0, jsx_runtime_1.jsx)(jsx_1.Ellipse, { x: parentX - markerSize, y: parent.y +
256
- offsets.y +
257
- parentBounds.height +
258
- edgeOffset -
259
- markerSize, width: markerSize * 2, height: markerSize * 2, fill: parentDotColor }));
358
+ elements.deco.push((0, jsx_runtime_1.jsx)(jsx_1.Ellipse, { x: (isHorizontal
359
+ ? mainSign > 0
360
+ ? parentRect.right + edgeOffset
361
+ : parentRect.left - edgeOffset
362
+ : parentX) - markerSize, y: (isHorizontal
363
+ ? parentY
364
+ : mainSign > 0
365
+ ? parentRect.bottom + edgeOffset
366
+ : parentRect.top - edgeOffset) - markerSize, width: markerSize * 2, height: markerSize * 2, fill: parentDotColor }));
260
367
  // 子节点连接点
261
368
  const childDotColor = edgeColorMode === 'gradient'
262
369
  ? (0, utils_1.getPaletteColor)(options, colorIndexes)
263
370
  : (0, utils_1.getColorPrimary)(options);
264
- elements.deco.push((0, jsx_runtime_1.jsx)(jsx_1.Ellipse, { x: childX - markerSize, y: y + offsets.y - edgeOffset - markerSize, width: markerSize * 2, height: markerSize * 2, fill: childDotColor }));
371
+ elements.deco.push((0, jsx_runtime_1.jsx)(jsx_1.Ellipse, { x: baseChildX - markerSize, y: baseChildY - markerSize, width: markerSize * 2, height: markerSize * 2, fill: childDotColor }));
265
372
  }
266
373
  }
267
374
  return elements;
@@ -279,13 +386,30 @@ const HierarchyTree = (props) => {
279
386
  nodesByParent.forEach((siblings) => {
280
387
  if (siblings.length <= 1)
281
388
  return;
282
- const sorted = siblings.slice().sort((a, b) => a.x - b.x);
283
- const siblingY = sorted[0].y + offsets.y - btnBounds.height - 5;
389
+ const sorted = siblings
390
+ .slice()
391
+ .sort((a, b) => isHorizontal
392
+ ? getLayoutPoint(a).y - getLayoutPoint(b).y
393
+ : getLayoutPoint(a).x - getLayoutPoint(b).x);
394
+ if (sorted.length === 0)
395
+ return;
284
396
  for (let i = 0; i < sorted.length - 1; i++) {
285
- const btnX = (sorted[i].x + sorted[i + 1].x) / 2 + offsets.x - btnBounds.width / 2;
397
+ const current = getLayoutPoint(sorted[i]);
398
+ const next = getLayoutPoint(sorted[i + 1]);
286
399
  const parentIndexes = sorted[i].data._originalIndex.slice(0, -1);
287
400
  const insertIndex = sorted[i].data._originalIndex.at(-1) + 1;
288
- btns.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [...parentIndexes, insertIndex], x: btnX, y: siblingY }));
401
+ if (isHorizontal) {
402
+ const btnX = current.x +
403
+ offsets.x +
404
+ (mainSign > 0 ? -btnBounds.width - 5 : btnBounds.width + 5);
405
+ const btnY = (current.y + next.y) / 2 + offsets.y - btnBounds.height / 2;
406
+ btns.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [...parentIndexes, insertIndex], x: btnX, y: btnY }));
407
+ }
408
+ else {
409
+ const siblingY = current.y + offsets.y - btnBounds.height - 5;
410
+ const btnX = (current.x + next.x) / 2 + offsets.x - btnBounds.width / 2;
411
+ btns.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [...parentIndexes, insertIndex], x: btnX, y: siblingY }));
412
+ }
289
413
  }
290
414
  });
291
415
  return btns;
@@ -304,12 +428,15 @@ const HierarchyTree = (props) => {
304
428
  const { levelBounds, maxWidth, maxHeight } = computeLevelBounds(root);
305
429
  const treeLayout = d3
306
430
  .tree()
307
- .nodeSize([maxWidth + nodeGap, maxHeight + levelGap])
431
+ .nodeSize(isHorizontal
432
+ ? [maxHeight + nodeGap, maxWidth + levelGap]
433
+ : [maxWidth + nodeGap, maxHeight + levelGap])
308
434
  .separation(() => 1);
309
435
  const nodes = treeLayout(root).descendants();
310
436
  // 计算偏移量
311
- const minX = Math.min(...nodes.map((d) => d.x));
312
- const minY = Math.min(...nodes.map((d) => d.y));
437
+ const layoutPoints = nodes.map((d) => getLayoutPoint(d));
438
+ const minX = Math.min(...layoutPoints.map((d) => d.x));
439
+ const minY = Math.min(...layoutPoints.map((d) => d.y));
313
440
  const offsets = {
314
441
  x: Math.max(0, -minX + maxWidth / 2),
315
442
  y: Math.max(0, -minY + btnBounds.height + 10),
@@ -323,6 +450,8 @@ const HierarchyTree = (props) => {
323
450
  nodes.forEach((node, index) => {
324
451
  // 将扁平索引附加到节点数据上,用于 node-flat 模式
325
452
  node.data._flatIndex = index;
453
+ const { x, y } = getLayoutPoint(node);
454
+ node.__layout = { x, y };
326
455
  });
327
456
  nodes.forEach((node) => {
328
457
  const { items, btns, deco } = renderNode(node, levelBounds, btnBounds, offsets, gradientDefs, nodes);
@@ -2,6 +2,7 @@ export * from './chart-bar';
2
2
  export * from './chart-column';
3
3
  export * from './chart-line';
4
4
  export * from './chart-pie';
5
+ export * from './chart-wordcloud';
5
6
  export * from './compare-binary-horizontal';
6
7
  export * from './compare-hierarchy-left-right';
7
8
  export * from './compare-hierarchy-row';
@@ -30,6 +31,7 @@ export * from './sequence-mountain';
30
31
  export * from './sequence-pyramid';
31
32
  export * from './sequence-roadmap-vertical';
32
33
  export * from './sequence-snake-steps';
34
+ export * from './sequence-stairs-front';
33
35
  export * from './sequence-steps';
34
36
  export * from './sequence-timeline';
35
37
  export * from './sequence-zigzag-pucks-3d';
@@ -19,6 +19,7 @@ __exportStar(require("./chart-bar"), exports);
19
19
  __exportStar(require("./chart-column"), exports);
20
20
  __exportStar(require("./chart-line"), exports);
21
21
  __exportStar(require("./chart-pie"), exports);
22
+ __exportStar(require("./chart-wordcloud"), exports);
22
23
  __exportStar(require("./compare-binary-horizontal"), exports);
23
24
  __exportStar(require("./compare-hierarchy-left-right"), exports);
24
25
  __exportStar(require("./compare-hierarchy-row"), exports);
@@ -50,6 +51,7 @@ __exportStar(require("./sequence-mountain"), exports);
50
51
  __exportStar(require("./sequence-pyramid"), exports);
51
52
  __exportStar(require("./sequence-roadmap-vertical"), exports);
52
53
  __exportStar(require("./sequence-snake-steps"), exports);
54
+ __exportStar(require("./sequence-stairs-front"), exports);
53
55
  __exportStar(require("./sequence-steps"), exports);
54
56
  __exportStar(require("./sequence-timeline"), exports);
55
57
  __exportStar(require("./sequence-zigzag-pucks-3d"), exports);
@@ -0,0 +1,8 @@
1
+ import type { ComponentType } from '../../jsx';
2
+ import type { BaseStructureProps } from './types';
3
+ export interface SequenceStairsFrontProps extends BaseStructureProps {
4
+ gap?: number;
5
+ perspectiveFactor?: number;
6
+ width?: number;
7
+ }
8
+ export declare const SequenceStairsFront: ComponentType<SequenceStairsFrontProps>;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SequenceStairsFront = void 0;
4
+ const jsx_runtime_1 = require("@antv/infographic/jsx-runtime");
5
+ const jsx_1 = require("../../jsx");
6
+ const components_1 = require("../components");
7
+ const layouts_1 = require("../layouts");
8
+ const utils_1 = require("../utils");
9
+ const registry_1 = require("./registry");
10
+ const SequenceStairsFront = (props) => {
11
+ const { Title, Item, data, options, gap = 16, perspectiveFactor = 0.2, width = 720, } = props;
12
+ const { title, desc, items = [] } = data;
13
+ const TitleComponent = Title;
14
+ const titleContent = TitleComponent ? ((0, jsx_runtime_1.jsx)(TitleComponent, { title: title, desc: desc })) : null;
15
+ if (items.length === 0) {
16
+ const btnAddElement = (0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [0], x: 0, y: 0 });
17
+ return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: (0, jsx_runtime_1.jsx)(components_1.BtnsGroup, { children: btnAddElement }) })] }));
18
+ }
19
+ const colorPrimary = (0, utils_1.getColorPrimary)(options);
20
+ const btnBounds = (0, jsx_1.getElementBounds)((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [0] }));
21
+ const itemBounds = (0, jsx_1.getElementBounds)((0, jsx_runtime_1.jsx)(Item, { indexes: [0], data: data, datum: items[0] || {}, positionH: "center" }));
22
+ const connectorGap = 12;
23
+ const baseConnectorWidth = Math.min(width * 0.1, 100);
24
+ const bottomStepWidth = Math.min(width * 0.45, Math.max(80, width - itemBounds.width - connectorGap - baseConnectorWidth));
25
+ const baseDepth = Math.max(24, bottomStepWidth * perspectiveFactor * 0.35);
26
+ const baseStepHeight = 56;
27
+ const minStepHeight = baseStepHeight * 0.7;
28
+ const heightStep = items.length > 1
29
+ ? (baseStepHeight - minStepHeight) / (items.length - 1)
30
+ : 0;
31
+ const topMargin = Math.max(btnBounds.height + baseDepth + 20, baseDepth + 28);
32
+ const centerX = bottomStepWidth / 2;
33
+ const itemX = bottomStepWidth + baseConnectorWidth + connectorGap;
34
+ const stepHeights = items.map((_, index) => baseStepHeight - heightStep * index);
35
+ const stepDepths = items.map((_, index) => Math.max(baseDepth * (1 - index * 0.05), baseDepth * 0.7));
36
+ const stepYs = [];
37
+ const depthFromTop = [];
38
+ const lastIndex = items.length - 1;
39
+ stepYs[lastIndex] = topMargin;
40
+ depthFromTop[lastIndex] = 0;
41
+ for (let i = lastIndex - 1; i >= 0; i -= 1) {
42
+ depthFromTop[i] = depthFromTop[i + 1] + stepDepths[i] + gap;
43
+ stepYs[i] = stepYs[i + 1] + stepDepths[i] + stepHeights[i + 1] + gap;
44
+ }
45
+ const totalDepthSpan = depthFromTop[0] || stepDepths[0] || baseDepth;
46
+ const minStepWidth = bottomStepWidth * (0.55 + perspectiveFactor * 0.1);
47
+ const widthShrink = bottomStepWidth - minStepWidth;
48
+ const stepWidths = items.map((_, index) => {
49
+ const ratio = totalDepthSpan === 0 ? 1 : depthFromTop[index] / totalDepthSpan;
50
+ return minStepWidth + widthShrink * ratio;
51
+ });
52
+ const connectorWidths = stepWidths.map((stepWidth) => {
53
+ const connectorStartX = centerX + stepWidth / 2;
54
+ return Math.max(0, itemX - connectorGap - connectorStartX);
55
+ });
56
+ const stepElements = [];
57
+ const itemElements = [];
58
+ const btnElements = [];
59
+ const connectorElements = [];
60
+ const spineElements = [];
61
+ const spineTop = 0;
62
+ const spineBottom = (stepYs[0] || topMargin) + (stepHeights[0] || baseStepHeight);
63
+ const arrowHeight = spineBottom - spineTop;
64
+ const arrowHeadHeight = 35;
65
+ const topStepWidth = stepWidths[lastIndex] || minStepWidth;
66
+ const arrowTopWidth = topStepWidth * 0.8;
67
+ const arrowNeckWidth = arrowTopWidth * 0.65;
68
+ const arrowBottomWidth = (stepWidths[0] || bottomStepWidth) * 0.9;
69
+ spineElements.push((0, jsx_runtime_1.jsx)(jsx_1.Polygon, { points: [
70
+ { x: centerX, y: spineTop },
71
+ { x: centerX + arrowTopWidth / 2, y: spineTop + arrowHeadHeight },
72
+ { x: centerX + arrowNeckWidth / 2, y: spineTop + arrowHeadHeight },
73
+ { x: centerX + arrowBottomWidth / 2, y: spineBottom },
74
+ { x: centerX - arrowBottomWidth / 2, y: spineBottom },
75
+ { x: centerX - arrowNeckWidth / 2, y: spineTop + arrowHeadHeight },
76
+ { x: centerX - arrowTopWidth / 2, y: spineTop + arrowHeadHeight },
77
+ ], fill: "rgba(0,0,0,0.12)", width: arrowBottomWidth, height: arrowHeight, "data-element-type": "shape" }));
78
+ let previousCenterY = stepYs[lastIndex] + stepHeights[lastIndex] / 2;
79
+ items.forEach((item, index) => {
80
+ const indexes = [index];
81
+ const stepWidth = stepWidths[index];
82
+ const stepDepth = stepDepths[index];
83
+ const stepX = centerX - stepWidth / 2;
84
+ const stepHeight = stepHeights[index];
85
+ const stepY = stepYs[index];
86
+ const topY = stepY - stepDepth;
87
+ const rectCenterY = stepY + stepHeight / 2;
88
+ const stepColor = (0, utils_1.getPaletteColor)(options, indexes) || colorPrimary;
89
+ stepElements.push((0, jsx_runtime_1.jsx)(jsx_1.Rect, { x: stepX, y: stepY, width: stepWidth, height: stepHeight, fill: stepColor, "data-element-type": "shape" }), (0, jsx_runtime_1.jsx)(jsx_1.Polygon, { points: [
90
+ { x: stepX, y: stepY },
91
+ { x: stepX + stepWidth, y: stepY },
92
+ { x: stepX + stepWidth - stepDepth / 2, y: topY },
93
+ { x: stepX + stepDepth / 2, y: topY },
94
+ ], fill: stepColor, opacity: "0.3", width: stepWidth, height: stepDepth, "data-element-type": "shape" }), (0, jsx_runtime_1.jsx)(jsx_1.Text, { x: stepX, y: stepY, width: stepWidth, height: stepHeight, fontSize: stepHeight / 2, fontWeight: "bold", alignHorizontal: "center", alignVertical: "middle", fill: "#ffffff", children: String(index + 1).padStart(2, '0') }));
95
+ const connectorStartX = stepX + stepWidth;
96
+ const connectorEndY = rectCenterY;
97
+ const connectorWidth = connectorWidths[index];
98
+ const lineEndX = connectorStartX + connectorWidth;
99
+ connectorElements.push((0, jsx_runtime_1.jsx)(jsx_1.Path, { d: `M ${connectorStartX} ${connectorEndY} L ${lineEndX} ${connectorEndY}`, stroke: stepColor, strokeWidth: 2, fill: "none", width: connectorWidth, height: 2, "data-element-type": "shape" }), (0, jsx_runtime_1.jsx)(jsx_1.Path, { d: `M ${lineEndX} ${connectorEndY} L ${lineEndX} ${connectorEndY}`, stroke: stepColor, strokeWidth: 6, strokeLinecap: "round", width: 1, height: 1, "data-element-type": "shape" }));
100
+ const itemY = rectCenterY - itemBounds.height / 2;
101
+ itemElements.push((0, jsx_runtime_1.jsx)(Item, { indexes: indexes, datum: item, data: data, x: itemX, y: itemY, positionV: "middle" }));
102
+ btnElements.push((0, jsx_runtime_1.jsx)(components_1.BtnRemove, { indexes: indexes, x: itemX + itemBounds.width + 10, y: itemY + itemBounds.height / 2 - btnBounds.height / 2 }));
103
+ if (index === 0) {
104
+ btnElements.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [0], x: itemX + (itemBounds.width - btnBounds.width) / 2, y: itemY - btnBounds.height - 12 }));
105
+ }
106
+ else {
107
+ btnElements.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: indexes, x: itemX + (itemBounds.width - btnBounds.width) / 2, y: (previousCenterY + rectCenterY) / 2 - btnBounds.height / 2 }));
108
+ }
109
+ previousCenterY = rectCenterY;
110
+ });
111
+ const lastCenterY = previousCenterY;
112
+ const lastItemY = lastCenterY - itemBounds.height / 2;
113
+ btnElements.push((0, jsx_runtime_1.jsx)(components_1.BtnAdd, { indexes: [items.length], x: itemX + (itemBounds.width - btnBounds.width) / 2, y: lastItemY + itemBounds.height + 12 }));
114
+ return ((0, jsx_runtime_1.jsxs)(layouts_1.FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, (0, jsx_runtime_1.jsxs)(jsx_1.Group, { children: [(0, jsx_runtime_1.jsx)(jsx_1.Group, { children: spineElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: stepElements }), (0, jsx_runtime_1.jsx)(jsx_1.Group, { children: connectorElements }), (0, jsx_runtime_1.jsx)(components_1.ItemsGroup, { children: itemElements }), (0, jsx_runtime_1.jsx)(components_1.BtnsGroup, { children: btnElements })] })] }));
115
+ };
116
+ exports.SequenceStairsFront = SequenceStairsFront;
117
+ (0, registry_1.registerStructure)('sequence-stairs-front', {
118
+ component: exports.SequenceStairsFront,
119
+ composites: ['title', 'item'],
120
+ });
@@ -20,6 +20,14 @@ export interface ParsedDesignsOptions {
20
20
  item: WithProps<Item>;
21
21
  items: WithProps<Item>[];
22
22
  }
23
+ export interface NullableParsedDesignsOptions {
24
+ structure: WithProps<Structure> | null;
25
+ title: {
26
+ component: ComponentType<any> | null;
27
+ };
28
+ item: WithProps<Item> | null;
29
+ items: (WithProps<Item> | null)[];
30
+ }
23
31
  type WithType<T> = T & {
24
32
  type: string;
25
33
  };
@@ -108,7 +108,7 @@ class StateManager {
108
108
  "item-label" /* ElementTypeEnum.ItemLabel */ === role ||
109
109
  "item-desc" /* ElementTypeEnum.ItemDesc */ === role ||
110
110
  "item-value" /* ElementTypeEnum.ItemValue */ === role ||
111
- "items-illus" /* ElementTypeEnum.ItemsIllus */ === role;
111
+ "item-illus" /* ElementTypeEnum.ItemIllus */ === role;
112
112
  const indexes = isItemElement ? (0, utils_2.getIndexesFromElement)(element) : undefined;
113
113
  if (isItemElement) {
114
114
  const datum = (0, utils_1.getDatumByIndexes)(data, indexes);
package/lib/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export { Defs, Ellipse, Fragment, Group, Path, Polygon, Rect, Text, cloneElement
7
7
  export { getFont, getFonts, getPalette, getPaletteColor, registerFont, registerPalette, registerPattern, setDefaultFont, } from './renderer';
8
8
  export { loadSVGResource, registerResourceLoader } from './resource';
9
9
  export { Infographic } from './runtime';
10
+ export { parseSyntax } from './syntax';
10
11
  export { getTemplate, getTemplates, registerTemplate } from './templates';
11
12
  export { getTheme, getThemes, registerTheme } from './themes';
12
13
  export { parseSVG } from './utils';
@@ -14,6 +15,7 @@ export type { EditBarOptions } from './editor';
14
15
  export type { Bounds, ComponentType, DefsProps, EllipseProps, FragmentProps, GroupProps, JSXElement, JSXElementConstructor, JSXNode, PathProps, Point, PolygonProps, RectProps, RenderableNode, SVGAttributes, SVGProps, TextProps, WithChildren, } from './jsx';
15
16
  export type { InfographicOptions, ParsedInfographicOptions } from './options';
16
17
  export type { GradientConfig, IRenderer, LinearGradient, Palette, PatternConfig, PatternGenerator, PatternStyle, RadialGradient, RoughConfig, StylizeConfig, } from './renderer';
18
+ export type { SyntaxError, SyntaxParseResult } from './syntax';
17
19
  export type { ParsedTemplateOptions, TemplateOptions } from './templates';
18
20
  export type { ThemeColors, ThemeConfig, ThemeSeed } from './themes';
19
21
  export type { Data, Font, FontWeightName, ImageResource, ItemDatum, TextHorizontalAlign, TextVerticalAlign, } from './types';
package/lib/index.js CHANGED
@@ -17,7 +17,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.parseSVG = exports.registerTheme = exports.getThemes = exports.getTheme = exports.registerTemplate = exports.getTemplates = exports.getTemplate = exports.Infographic = exports.registerResourceLoader = exports.loadSVGResource = exports.setDefaultFont = exports.registerPattern = exports.registerPalette = exports.registerFont = exports.getPaletteColor = exports.getPalette = exports.getFonts = exports.getFont = exports.renderSVG = exports.jsxs = exports.jsxDEV = exports.jsx = exports.getElementsBounds = exports.getElementBounds = exports.getCombinedBounds = exports.createLayout = exports.createFragment = exports.cloneElement = exports.Text = exports.Rect = exports.Polygon = exports.Path = exports.Group = exports.Fragment = exports.Ellipse = exports.Defs = exports.ResizeElement = exports.Plugin = exports.EditBar = exports.ZoomWheel = exports.SelectHighlight = exports.Interaction = exports.HotkeyHistory = exports.DragElement = exports.DblClickEditText = exports.ClickSelect = exports.BrushSelect = exports.getThemeColors = exports.getItemProps = exports.VERSION = void 0;
20
+ exports.registerTheme = exports.getThemes = exports.getTheme = exports.registerTemplate = exports.getTemplates = exports.getTemplate = exports.parseSyntax = exports.Infographic = exports.registerResourceLoader = exports.loadSVGResource = exports.setDefaultFont = exports.registerPattern = exports.registerPalette = exports.registerFont = exports.getPaletteColor = exports.getPalette = exports.getFonts = exports.getFont = exports.renderSVG = exports.jsxs = exports.jsxDEV = exports.jsx = exports.getElementsBounds = exports.getElementBounds = exports.getCombinedBounds = exports.createLayout = exports.createFragment = exports.cloneElement = exports.Text = exports.Rect = exports.Polygon = exports.Path = exports.Group = exports.Fragment = exports.Ellipse = exports.Defs = exports.ResizeElement = exports.Plugin = exports.EditBar = exports.ZoomWheel = exports.SelectHighlight = exports.Interaction = exports.HotkeyHistory = exports.DragElement = exports.DblClickEditText = exports.ClickSelect = exports.BrushSelect = exports.getThemeColors = exports.getItemProps = exports.VERSION = void 0;
21
+ exports.parseSVG = void 0;
21
22
  const package_json_1 = __importDefault(require("../package.json"));
22
23
  exports.VERSION = package_json_1.default.version;
23
24
  __exportStar(require("./designs"), exports);
@@ -70,6 +71,8 @@ Object.defineProperty(exports, "loadSVGResource", { enumerable: true, get: funct
70
71
  Object.defineProperty(exports, "registerResourceLoader", { enumerable: true, get: function () { return resource_1.registerResourceLoader; } });
71
72
  var runtime_1 = require("./runtime");
72
73
  Object.defineProperty(exports, "Infographic", { enumerable: true, get: function () { return runtime_1.Infographic; } });
74
+ var syntax_1 = require("./syntax");
75
+ Object.defineProperty(exports, "parseSyntax", { enumerable: true, get: function () { return syntax_1.parseSyntax; } });
73
76
  var templates_1 = require("./templates");
74
77
  Object.defineProperty(exports, "getTemplate", { enumerable: true, get: function () { return templates_1.getTemplate; } });
75
78
  Object.defineProperty(exports, "getTemplates", { enumerable: true, get: function () { return templates_1.getTemplates; } });
@@ -1,2 +1,2 @@
1
1
  import type { InfographicOptions, ParsedInfographicOptions } from './types';
2
- export declare function parseOptions(options: InfographicOptions): ParsedInfographicOptions;
2
+ export declare function parseOptions(options: Partial<InfographicOptions>): Partial<ParsedInfographicOptions>;