@antv/gpt-vis 1.0.0 → 1.0.1

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 (92) hide show
  1. package/README.md +66 -1
  2. package/README.zh-CN.md +66 -1
  3. package/dist/cjs/types/index.d.ts +2 -1
  4. package/dist/cjs/util/animation.d.ts +2 -0
  5. package/dist/cjs/util/animation.js +38 -0
  6. package/dist/cjs/util/components.d.ts +15 -0
  7. package/dist/cjs/util/components.js +94 -0
  8. package/dist/cjs/util/crosshair-axis-labels.d.ts +9 -0
  9. package/dist/cjs/util/crosshair-axis-labels.js +304 -0
  10. package/dist/cjs/util/index.d.ts +6 -0
  11. package/dist/cjs/util/index.js +33 -0
  12. package/dist/cjs/util/interaction.d.ts +14 -0
  13. package/dist/cjs/util/interaction.js +89 -0
  14. package/dist/cjs/util/theme.d.ts +18 -24
  15. package/dist/cjs/util/theme.js +303 -120
  16. package/dist/cjs/util/tokens.d.ts +31 -0
  17. package/dist/cjs/util/tokens.js +98 -0
  18. package/dist/cjs/vis/area/index.d.ts +2 -2
  19. package/dist/cjs/vis/area/index.js +76 -31
  20. package/dist/cjs/vis/bar/index.d.ts +2 -2
  21. package/dist/cjs/vis/bar/index.js +22 -19
  22. package/dist/cjs/vis/boxplot/index.js +1 -4
  23. package/dist/cjs/vis/column/index.d.ts +2 -2
  24. package/dist/cjs/vis/column/index.js +28 -18
  25. package/dist/cjs/vis/dual-axes/index.d.ts +2 -2
  26. package/dist/cjs/vis/dual-axes/index.js +89 -34
  27. package/dist/cjs/vis/funnel/index.d.ts +4 -2
  28. package/dist/cjs/vis/funnel/index.js +171 -92
  29. package/dist/cjs/vis/histogram/index.js +1 -4
  30. package/dist/cjs/vis/line/index.d.ts +2 -2
  31. package/dist/cjs/vis/line/index.js +71 -31
  32. package/dist/cjs/vis/liquid/index.d.ts +2 -2
  33. package/dist/cjs/vis/liquid/index.js +41 -16
  34. package/dist/cjs/vis/pie/index.d.ts +2 -2
  35. package/dist/cjs/vis/pie/index.js +26 -16
  36. package/dist/cjs/vis/radar/index.d.ts +2 -2
  37. package/dist/cjs/vis/radar/index.js +21 -29
  38. package/dist/cjs/vis/sankey/index.js +1 -4
  39. package/dist/cjs/vis/scatter/index.d.ts +2 -2
  40. package/dist/cjs/vis/scatter/index.js +40 -17
  41. package/dist/cjs/vis/treemap/index.js +1 -4
  42. package/dist/cjs/vis/venn/index.js +1 -4
  43. package/dist/cjs/vis/violin/index.js +1 -1
  44. package/dist/cjs/vis/waterfall/index.js +1 -1
  45. package/dist/cjs/vis/word-cloud/index.d.ts +3 -2
  46. package/dist/cjs/vis/word-cloud/index.js +125 -10
  47. package/dist/esm/types/index.d.ts +2 -1
  48. package/dist/esm/util/animation.d.ts +2 -0
  49. package/dist/esm/util/animation.js +17 -0
  50. package/dist/esm/util/components.d.ts +15 -0
  51. package/dist/esm/util/components.js +67 -0
  52. package/dist/esm/util/crosshair-axis-labels.d.ts +9 -0
  53. package/dist/esm/util/crosshair-axis-labels.js +328 -0
  54. package/dist/esm/util/index.d.ts +6 -0
  55. package/dist/esm/util/index.js +6 -0
  56. package/dist/esm/util/interaction.d.ts +14 -0
  57. package/dist/esm/util/interaction.js +73 -0
  58. package/dist/esm/util/theme.d.ts +18 -24
  59. package/dist/esm/util/theme.js +302 -126
  60. package/dist/esm/util/tokens.d.ts +31 -0
  61. package/dist/esm/util/tokens.js +64 -0
  62. package/dist/esm/vis/area/index.d.ts +2 -2
  63. package/dist/esm/vis/area/index.js +91 -41
  64. package/dist/esm/vis/bar/index.d.ts +2 -2
  65. package/dist/esm/vis/bar/index.js +28 -29
  66. package/dist/esm/vis/boxplot/index.js +4 -5
  67. package/dist/esm/vis/column/index.d.ts +2 -2
  68. package/dist/esm/vis/column/index.js +36 -29
  69. package/dist/esm/vis/dual-axes/index.d.ts +2 -2
  70. package/dist/esm/vis/dual-axes/index.js +115 -42
  71. package/dist/esm/vis/funnel/index.d.ts +4 -2
  72. package/dist/esm/vis/funnel/index.js +156 -83
  73. package/dist/esm/vis/histogram/index.js +4 -5
  74. package/dist/esm/vis/line/index.d.ts +2 -2
  75. package/dist/esm/vis/line/index.js +80 -37
  76. package/dist/esm/vis/liquid/index.d.ts +2 -2
  77. package/dist/esm/vis/liquid/index.js +41 -14
  78. package/dist/esm/vis/pie/index.d.ts +2 -2
  79. package/dist/esm/vis/pie/index.js +36 -16
  80. package/dist/esm/vis/radar/index.d.ts +2 -2
  81. package/dist/esm/vis/radar/index.js +21 -34
  82. package/dist/esm/vis/sankey/index.js +4 -5
  83. package/dist/esm/vis/scatter/index.d.ts +2 -2
  84. package/dist/esm/vis/scatter/index.js +41 -25
  85. package/dist/esm/vis/treemap/index.js +4 -5
  86. package/dist/esm/vis/venn/index.js +4 -5
  87. package/dist/esm/vis/violin/index.js +5 -13
  88. package/dist/esm/vis/waterfall/index.js +5 -7
  89. package/dist/esm/vis/word-cloud/index.d.ts +3 -2
  90. package/dist/esm/vis/word-cloud/index.js +158 -10
  91. package/dist/umd/index.min.js +1 -1
  92. package/package.json +18 -15
@@ -11,7 +11,7 @@ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symb
11
11
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
12
12
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
13
13
  import { Chart } from '@antv/g2';
14
- import { getBackgroundColor, getThemeObject, normalizePalette } from "../../util/theme";
14
+ import { CHART_STYLE_DEFAULTS, getCartesianAxis, getCartesianLayout, getChartAnimation, getLineHighlightState, getSeriesHighlightByColorInteraction, getSharedTooltipInteraction, getThemeObject, normalizePalette } from "../../util";
15
15
 
16
16
  /**
17
17
  * DualAxesSeriesItem defines a single series in the dual-axes chart.
@@ -29,14 +29,16 @@ import { getBackgroundColor, getThemeObject, normalizePalette } from "../../util
29
29
  * Transform series data to G2 format.
30
30
  * Combines multiple series into a single data array with categories.
31
31
  */
32
+ var getSeriesField = function getSeriesField(index) {
33
+ return "value_".concat(index + 1);
34
+ };
32
35
  function transformData(series, categories) {
33
36
  return categories.map(function (category, index) {
34
37
  var dataPoint = {
35
38
  category: category
36
39
  };
37
- series.forEach(function (s, i) {
38
- var yField = s.axisYTitle || "value_".concat(i + 1);
39
- dataPoint[yField] = s.data[index];
40
+ series.forEach(function (item, seriesIndex) {
41
+ dataPoint[getSeriesField(seriesIndex)] = item.data[index];
40
42
  });
41
43
  return dataPoint;
42
44
  });
@@ -80,6 +82,7 @@ export var DualAxes = function DualAxes(options) {
80
82
  _options$theme = options.theme,
81
83
  chartTheme = _options$theme === void 0 ? 'default' : _options$theme;
82
84
  var chart = null;
85
+ var hasRendered = false;
83
86
 
84
87
  /**
85
88
  * Render the dual-axes chart with the given configuration.
@@ -100,8 +103,11 @@ export var DualAxes = function DualAxes(options) {
100
103
  }
101
104
  var _style$startAtZero = style.startAtZero,
102
105
  startAtZero = _style$startAtZero === void 0 ? false : _style$startAtZero;
103
- var colors = normalizePalette(style.palette, theme);
104
- var backgroundColor = style.backgroundColor || getBackgroundColor(theme);
106
+ var requestedColors = style.palette ? normalizePalette(style.palette, theme) : [];
107
+ var defaultColors = normalizePalette(undefined, theme);
108
+ var colors = [].concat(_toConsumableArray(requestedColors), _toConsumableArray(defaultColors.filter(function (color) {
109
+ return !requestedColors.includes(color);
110
+ })));
105
111
 
106
112
  // Transform data
107
113
  var data = transformData(series, categories);
@@ -115,15 +121,55 @@ export var DualAxes = function DualAxes(options) {
115
121
  });
116
122
 
117
123
  // Sort series: column first, then line (line rendered last appears on top)
118
- var sortedSeries = _toConsumableArray(series).sort(function (a, b) {
124
+ var sortedSeries = series.map(function (item, originalIndex) {
125
+ return {
126
+ item: item,
127
+ originalIndex: originalIndex
128
+ };
129
+ }).sort(function (a, b) {
119
130
  var order = ['column', 'line'];
120
- return order.indexOf(a.type) - order.indexOf(b.type);
131
+ return order.indexOf(a.item.type) - order.indexOf(b.item.type);
121
132
  });
133
+ var seriesMeta = sortedSeries.map(function (_ref, index) {
134
+ var item = _ref.item,
135
+ originalIndex = _ref.originalIndex;
136
+ return {
137
+ item: item,
138
+ yField: getSeriesField(originalIndex),
139
+ displayName: item.axisYTitle || getSeriesField(originalIndex),
140
+ color: colors[index % colors.length]
141
+ };
142
+ });
143
+ var seriesByField = new Map(seriesMeta.map(function (_ref2) {
144
+ var item = _ref2.item,
145
+ yField = _ref2.yField,
146
+ displayName = _ref2.displayName;
147
+ return [yField, {
148
+ type: item.type,
149
+ displayName: displayName
150
+ }];
151
+ }));
152
+ var cartesianAxisOptions = {
153
+ axisXTitle: axisXTitle,
154
+ xLabels: categories,
155
+ chartWidth: width
156
+ };
157
+ var cartesianAxis = getCartesianAxis(cartesianAxisOptions);
122
158
 
123
159
  // Create children configurations for each series
124
- var children = sortedSeries.map(function (item, index) {
125
- var yField = item.axisYTitle || "value_".concat(index + 1);
126
- var color = colors[index % colors.length];
160
+ var children = seriesMeta.map(function (_ref3) {
161
+ var item = _ref3.item,
162
+ yField = _ref3.yField,
163
+ displayName = _ref3.displayName,
164
+ color = _ref3.color;
165
+ var tooltip = {
166
+ items: [function (datum) {
167
+ return {
168
+ name: displayName,
169
+ value: datum[yField]
170
+ };
171
+ }]
172
+ };
127
173
  if (item.type === 'column') {
128
174
  return {
129
175
  type: 'interval',
@@ -138,22 +184,25 @@ export var DualAxes = function DualAxes(options) {
138
184
  y: {
139
185
  nice: true,
140
186
  zero: startAtZero
141
- },
142
- color: {
143
- range: [color]
144
187
  }
145
188
  },
189
+ tooltip: tooltip,
146
190
  axis: {
147
- y: {
148
- title: item.axisYTitle || ''
149
- }
191
+ y: _objectSpread(_objectSpread({}, cartesianAxis.y), {}, {
192
+ title: item.axisYTitle || '',
193
+ titleFill: color,
194
+ titleFontWeight: 500
195
+ })
150
196
  },
151
197
  style: _objectSpread({
152
- columnWidthRatio: 0.8
198
+ fill: color,
199
+ fillOpacity: 0.86,
200
+ columnWidthRatio: CHART_STYLE_DEFAULTS.intervalWidthRatio
153
201
  }, theme !== 'academy' ? {
154
202
  radiusTopLeft: 4,
155
203
  radiusTopRight: 4
156
- } : {})
204
+ } : {}),
205
+ animate: getChartAnimation(hasRendered, 'growInY')
157
206
  };
158
207
  } else {
159
208
  // line type
@@ -171,20 +220,26 @@ export var DualAxes = function DualAxes(options) {
171
220
  y: {
172
221
  independent: true,
173
222
  zero: startAtZero
174
- },
175
- color: {
176
- range: [color]
177
223
  }
178
224
  },
225
+ tooltip: tooltip,
179
226
  axis: {
180
- y: {
227
+ y: _objectSpread(_objectSpread({}, cartesianAxis.y), {}, {
181
228
  position: 'right',
182
- title: item.axisYTitle || ''
183
- }
229
+ title: item.axisYTitle || '',
230
+ titleFill: color,
231
+ titleFontWeight: 500,
232
+ grid: false
233
+ })
184
234
  },
185
235
  style: {
186
- lineWidth: 2
187
- }
236
+ stroke: color,
237
+ lineWidth: CHART_STYLE_DEFAULTS.lineWidth,
238
+ lineCap: 'round',
239
+ lineJoin: 'round'
240
+ },
241
+ state: getLineHighlightState(CHART_STYLE_DEFAULTS.lineWidth),
242
+ animate: getChartAnimation(hasRendered, 'pathIn')
188
243
  };
189
244
  }
190
245
  });
@@ -192,38 +247,55 @@ export var DualAxes = function DualAxes(options) {
192
247
  // Configure chart options
193
248
  // Note: Using 'any' type due to G2's complex type system with transformations
194
249
  // This is consistent with how G2 5.0 is used elsewhere in the codebase
195
- var chartOptions = {
196
- animate: false,
250
+ var chartOptions = _objectSpread(_objectSpread({
197
251
  type: 'view',
198
252
  data: data,
199
- title: title !== null && title !== void 0 ? title : '',
200
- children: children,
253
+ title: title || '',
254
+ children: children
255
+ }, getCartesianLayout(cartesianAxisOptions)), {}, {
201
256
  axis: {
202
- x: {
203
- title: axisXTitle || false
204
- }
257
+ x: cartesianAxis.x
205
258
  },
206
259
  scale: {
207
260
  y: {
208
261
  nice: true
262
+ },
263
+ color: {
264
+ domain: seriesMeta.map(function (_ref4) {
265
+ var yField = _ref4.yField;
266
+ return yField;
267
+ }),
268
+ range: seriesMeta.map(function (_ref5) {
269
+ var color = _ref5.color;
270
+ return color;
271
+ })
209
272
  }
210
273
  },
211
274
  legend: {
212
275
  color: {
213
- position: 'top',
214
- itemMarker: function itemMarker(v, index) {
215
- var seriesItem = series[index];
216
- return (seriesItem === null || seriesItem === void 0 ? void 0 : seriesItem.type) === 'line' ? 'smooth' : 'rect';
276
+ labelFormatter: function labelFormatter(value) {
277
+ var _seriesByField$get;
278
+ return ((_seriesByField$get = seriesByField.get(value)) === null || _seriesByField$get === void 0 ? void 0 : _seriesByField$get.displayName) || value;
279
+ },
280
+ itemMarker: function itemMarker(value) {
281
+ var _seriesByField$get2;
282
+ return ((_seriesByField$get2 = seriesByField.get(value)) === null || _seriesByField$get2 === void 0 ? void 0 : _seriesByField$get2.type) === 'line' ? 'smooth' : 'rect';
217
283
  }
218
284
  }
219
285
  },
220
- viewStyle: {
221
- viewFill: backgroundColor
222
- },
286
+ interaction: _objectSpread({
287
+ tooltip: getSharedTooltipInteraction({
288
+ crosshairs: true
289
+ })
290
+ }, getSeriesHighlightByColorInteraction()),
291
+ viewStyle: style.backgroundColor ? {
292
+ viewFill: style.backgroundColor
293
+ } : undefined,
223
294
  theme: getThemeObject(theme)
224
- };
295
+ });
225
296
  chart.options(chartOptions);
226
297
  chart.render();
298
+ hasRendered = true;
227
299
  };
228
300
 
229
301
  /**
@@ -234,6 +306,7 @@ export var DualAxes = function DualAxes(options) {
234
306
  chart.destroy();
235
307
  chart = null;
236
308
  }
309
+ hasRendered = false;
237
310
  };
238
311
  return {
239
312
  render: render,
@@ -1,4 +1,4 @@
1
- import type { VisualizationOptions } from '../../types';
1
+ import type { VisualizationOptions, VisualizationTheme } from '../../types';
2
2
  /**
3
3
  * FunnelDataItem is the type for each data item in the funnel chart.
4
4
  */
@@ -12,8 +12,10 @@ export type FunnelDataItem = {
12
12
  export interface FunnelConfig {
13
13
  type?: 'funnel';
14
14
  data: FunnelDataItem[];
15
- theme?: 'default' | 'academy' | 'dark';
15
+ theme?: VisualizationTheme;
16
16
  title?: string;
17
+ locale?: string;
18
+ conversionRateLabel?: string;
17
19
  style?: {
18
20
  backgroundColor?: string;
19
21
  palette?: string[];
@@ -1,5 +1,17 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
8
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
11
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
12
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
1
13
  import { Chart } from '@antv/g2';
2
- import { getBackgroundColor, getThemeObject, normalizePalette } from "../../util/theme";
14
+ import { CHART_FONT_FAMILY, getBackgroundColor, getChartVisualTokens, getThemeObject, normalizePalette, resolveChartLocale } from "../../util";
3
15
 
4
16
  /**
5
17
  * FunnelDataItem is the type for each data item in the funnel chart.
@@ -13,6 +25,32 @@ import { getBackgroundColor, getThemeObject, normalizePalette } from "../../util
13
25
  * FunnelInstance represents a funnel chart instance with render and destroy methods.
14
26
  */
15
27
 
28
+ var FUNNEL_LABELS = {
29
+ 'en-US': {
30
+ baseline: 'Baseline',
31
+ conversionRate: 'Conversion Rate',
32
+ currentValue: 'Current value',
33
+ dropOff: 'Drop-off from previous',
34
+ overallConversionRate: 'Overall conversion',
35
+ stageConversion: 'Stage conversion'
36
+ },
37
+ 'zh-CN': {
38
+ baseline: '基准',
39
+ conversionRate: '转化率',
40
+ currentValue: '当前值',
41
+ dropOff: '较上一步流失',
42
+ overallConversionRate: '整体转化率',
43
+ stageConversion: '阶段转化率'
44
+ }
45
+ };
46
+ var formatConversionRate = function formatConversionRate(start, end) {
47
+ if (!Number.isFinite(start) || !Number.isFinite(end) || start === 0) return '—';
48
+ return "".concat((end / start * 100).toFixed(1), "%");
49
+ };
50
+ var formatMetricLabel = function formatMetricLabel(label, value, locale) {
51
+ return locale === 'zh-CN' ? "".concat(label, "\uFF1A").concat(value) : "".concat(label, ": ").concat(value);
52
+ };
53
+
16
54
  /**
17
55
  * Funnel chart component using G2 5.0.
18
56
  *
@@ -42,6 +80,7 @@ export var Funnel = function Funnel(options) {
42
80
  var container = options.container,
43
81
  width = options.width,
44
82
  height = options.height,
83
+ locale = options.locale,
45
84
  _options$theme = options.theme,
46
85
  chartTheme = _options$theme === void 0 ? 'default' : _options$theme;
47
86
  var chart = null;
@@ -50,14 +89,21 @@ export var Funnel = function Funnel(options) {
50
89
  * Render the funnel chart with the given configuration.
51
90
  */
52
91
  var render = function render(config) {
53
- var _data$, _data, _data$2, _data2, _data$3, _data3;
54
92
  var _config$data = config.data,
55
93
  data = _config$data === void 0 ? [] : _config$data,
56
94
  _config$theme = config.theme,
57
95
  theme = _config$theme === void 0 ? chartTheme : _config$theme,
58
96
  title = config.title,
97
+ _config$locale = config.locale,
98
+ renderLocale = _config$locale === void 0 ? locale : _config$locale,
99
+ conversionRateLabel = config.conversionRateLabel,
59
100
  _config$style = config.style,
60
101
  style = _config$style === void 0 ? {} : _config$style;
102
+ var chartLocale = resolveChartLocale(renderLocale);
103
+ var labels = FUNNEL_LABELS[chartLocale];
104
+ var numberFormatter = new Intl.NumberFormat(chartLocale);
105
+ var stageConversionRateLabel = conversionRateLabel !== null && conversionRateLabel !== void 0 ? conversionRateLabel : labels.conversionRate;
106
+ var overallConversionRateLabel = conversionRateLabel !== null && conversionRateLabel !== void 0 ? conversionRateLabel : labels.overallConversionRate;
61
107
 
62
108
  // Clean up previous chart if exists
63
109
  if (chart) {
@@ -67,10 +113,37 @@ export var Funnel = function Funnel(options) {
67
113
  // Get colors from style.palette or theme defaults
68
114
  var colors = normalizePalette(style.palette, theme);
69
115
  var backgroundColor = style.backgroundColor || getBackgroundColor(theme);
70
-
71
- // Helper function to calculate conversion rate
72
- var conversionRate = function conversionRate(start, end) {
73
- return "".concat((end / start * 100).toFixed(2), " %");
116
+ var tokens = getChartVisualTokens(theme);
117
+ var formatValue = function formatValue(value) {
118
+ return Number.isFinite(value) ? numberFormatter.format(value) : '—';
119
+ };
120
+ var metricsByCategory = new Map(data.map(function (item, index) {
121
+ var previous = data[index - 1];
122
+ return [item.category, {
123
+ conversion: previous ? formatConversionRate(previous.value, item.value) : labels.baseline,
124
+ dropOff: previous ? Math.max(0, previous.value - item.value) : null
125
+ }];
126
+ }));
127
+ var funnelTooltip = {
128
+ title: 'category',
129
+ items: [function (d) {
130
+ return {
131
+ name: labels.currentValue,
132
+ value: formatValue(d.value)
133
+ };
134
+ }, function (d) {
135
+ var _metricsByCategory$ge, _metricsByCategory$ge2;
136
+ return {
137
+ name: labels.stageConversion,
138
+ value: (_metricsByCategory$ge = (_metricsByCategory$ge2 = metricsByCategory.get(d.category)) === null || _metricsByCategory$ge2 === void 0 ? void 0 : _metricsByCategory$ge2.conversion) !== null && _metricsByCategory$ge !== void 0 ? _metricsByCategory$ge : '—'
139
+ };
140
+ }, function (d) {
141
+ var _metricsByCategory$ge3, _metricsByCategory$ge4, _metricsByCategory$ge5;
142
+ return {
143
+ name: labels.dropOff,
144
+ value: ((_metricsByCategory$ge3 = metricsByCategory.get(d.category)) === null || _metricsByCategory$ge3 === void 0 ? void 0 : _metricsByCategory$ge3.dropOff) === null ? '—' : formatValue((_metricsByCategory$ge4 = (_metricsByCategory$ge5 = metricsByCategory.get(d.category)) === null || _metricsByCategory$ge5 === void 0 ? void 0 : _metricsByCategory$ge5.dropOff) !== null && _metricsByCategory$ge4 !== void 0 ? _metricsByCategory$ge4 : Number.NaN)
145
+ };
146
+ }]
74
147
  };
75
148
 
76
149
  // Create chart
@@ -79,8 +152,8 @@ export var Funnel = function Funnel(options) {
79
152
  width: width,
80
153
  height: height,
81
154
  autoFit: true,
82
- paddingLeft: 40,
83
- paddingRight: 68
155
+ paddingLeft: 56,
156
+ paddingRight: 118
84
157
  });
85
158
 
86
159
  // Configure chart options
@@ -90,7 +163,7 @@ export var Funnel = function Funnel(options) {
90
163
  animate: false,
91
164
  type: 'view',
92
165
  data: data,
93
- title: title !== null && title !== void 0 ? title : '',
166
+ title: title || '',
94
167
  children: [{
95
168
  type: 'interval',
96
169
  data: data,
@@ -116,73 +189,78 @@ export var Funnel = function Funnel(options) {
116
189
  range: colors
117
190
  }
118
191
  },
119
- legend: {
120
- color: {
121
- position: 'top',
122
- layout: {
123
- justifyContent: 'center'
124
- }
125
- }
126
- },
127
- labels: [
128
- // Inside label showing category and value
129
- {
192
+ legend: false,
193
+ tooltip: funnelTooltip,
194
+ labels: [{
130
195
  text: function text(d) {
131
- return "".concat(d.category, "\n").concat(d.value);
196
+ return "".concat(d.category, "\n").concat(formatValue(d.value));
132
197
  },
133
198
  position: 'inside',
134
199
  transform: [{
135
200
  type: 'contrastReverse'
136
- }]
137
- },
138
- // Connecting line for conversion rate
139
- {
140
- text: function text(d, i) {
141
- return i !== 0 ? '———' : '';
142
- },
201
+ }, {
202
+ type: 'overflowStroke'
203
+ }],
143
204
  style: {
144
- 'font-size': '1px',
145
- color: '#666',
146
- 'letter-spacing': '0px'
147
- },
148
- position: 'top-right',
149
- fill: '#666',
150
- dx: 35,
151
- dy: -8
152
- },
153
- // Conversion rate label text
154
- {
155
- text: function text(d, i) {
156
- return i !== 0 ? '转化率' : '';
205
+ fontFamily: CHART_FONT_FAMILY,
206
+ fontSize: 12,
207
+ fontWeight: 500,
208
+ lineHeight: 17
209
+ }
210
+ }, {
211
+ text: function text(_d, index) {
212
+ return index === 0 ? '' : '———';
157
213
  },
158
214
  position: 'top-right',
159
- textAlign: 'left',
160
- textBaseline: 'middle',
161
- fill: '#666',
162
- dx: 40
163
- },
164
- // Conversion rate percentage
165
- {
166
- text: function text(d, i, dataArray) {
167
- return i !== 0 ? conversionRate(dataArray[i - 1].value, dataArray[i].value) : '';
215
+ fill: tokens.textSecondary,
216
+ fillOpacity: 0.72,
217
+ dx: 18,
218
+ dy: -6,
219
+ style: {
220
+ fontFamily: CHART_FONT_FAMILY,
221
+ fontSize: 8,
222
+ fontWeight: 400,
223
+ letterSpacing: -2
224
+ }
225
+ }, {
226
+ text: function text(_d, index, items) {
227
+ return index === 0 ? '' : formatMetricLabel(stageConversionRateLabel, formatConversionRate(items[index - 1].value, items[index].value), chartLocale);
168
228
  },
169
229
  position: 'top-right',
170
230
  textAlign: 'left',
171
231
  textBaseline: 'middle',
172
- dx: 80
232
+ fill: tokens.textPrimary,
233
+ dx: 44,
234
+ style: {
235
+ fontFamily: CHART_FONT_FAMILY,
236
+ fontSize: 11,
237
+ fontWeight: 500
238
+ }
173
239
  }],
174
- viewStyle: {
240
+ style: _objectSpread({
241
+ fillOpacity: 0.94,
242
+ stroke: tokens.separator,
243
+ lineWidth: 2
244
+ }, theme === 'academy' ? {} : {
245
+ radius: 4
246
+ }),
247
+ state: {
248
+ active: {
249
+ fillOpacity: 1,
250
+ stroke: tokens.separator,
251
+ lineWidth: 3
252
+ }
253
+ },
254
+ viewStyle: style.backgroundColor ? {
175
255
  viewFill: backgroundColor
176
- }
177
- },
178
- // Overall conversion rate connector
179
- {
256
+ } : undefined
257
+ }].concat(_toConsumableArray(data.length > 1 ? [{
180
258
  type: 'connector',
181
259
  data: [{
182
- startX: (_data$ = data[0]) === null || _data$ === void 0 ? void 0 : _data$.category,
183
- startY: (_data = data[data.length - 1]) === null || _data === void 0 ? void 0 : _data.category,
260
+ startX: data[0].category,
261
+ startY: data[data.length - 1].category,
184
262
  endX: 0,
185
- endY: (((_data$2 = data[0]) === null || _data$2 === void 0 ? void 0 : _data$2.value) - ((_data2 = data[data.length - 1]) === null || _data2 === void 0 ? void 0 : _data2.value)) / 2
263
+ endY: (data[0].value - data[data.length - 1].value) / 2
186
264
  }],
187
265
  encode: {
188
266
  x: 'startX',
@@ -190,41 +268,36 @@ export var Funnel = function Funnel(options) {
190
268
  y: 'endX',
191
269
  y1: 'endY'
192
270
  },
271
+ tooltip: false,
193
272
  style: {
194
- stroke: '#666',
273
+ stroke: tokens.axisLine,
274
+ strokeOpacity: theme === 'academy' ? 1 : 0.82,
275
+ lineWidth: theme === 'academy' ? 1 : 0.75,
195
276
  markerEnd: false,
196
- connectLength1: -12,
197
- offset2: -20,
198
- connectorStroke: '#0649f2',
199
- lineDash: [12, 2]
277
+ connectLength1: -12
200
278
  },
201
279
  labels: [{
202
- text: '转化率',
280
+ text: formatMetricLabel(overallConversionRateLabel, formatConversionRate(data[0].value, data[data.length - 1].value), chartLocale),
203
281
  position: 'left',
204
282
  textAlign: 'start',
205
283
  textBaseline: 'middle',
206
- fill: '#666',
207
- dx: 10
208
- }, {
209
- text: conversionRate((_data$3 = data[0]) === null || _data$3 === void 0 ? void 0 : _data$3.value, (_data3 = data[data.length - 1]) === null || _data3 === void 0 ? void 0 : _data3.value),
210
- position: 'left',
211
- textAlign: 'start',
212
- dx: 50,
213
- fill: '#000'
284
+ fill: tokens.textPrimary,
285
+ dx: 8,
286
+ style: {
287
+ fontFamily: CHART_FONT_FAMILY,
288
+ fontSize: 11,
289
+ fontWeight: 500
290
+ }
214
291
  }]
215
- }],
292
+ }] : [])),
216
293
  axis: false,
217
- tooltip: {
218
- items: [function (d) {
219
- return {
220
- name: d.category,
221
- value: d.value
222
- };
223
- }]
294
+ interaction: {
295
+ tooltip: true,
296
+ elementHighlight: true
224
297
  },
225
- viewStyle: {
298
+ viewStyle: style.backgroundColor ? {
226
299
  viewFill: backgroundColor
227
- },
300
+ } : undefined,
228
301
  theme: getThemeObject(theme)
229
302
  };
230
303
  chart.options(chartOptions);
@@ -1,5 +1,5 @@
1
1
  import { Chart } from '@antv/g2';
2
- import { getBackgroundColor, getThemeObject, normalizePalette } from "../../util/theme";
2
+ import { getThemeObject, normalizePalette } from "../../util/theme";
3
3
 
4
4
  /**
5
5
  * HistogramConfig defines the configuration for rendering the histogram chart.
@@ -61,7 +61,6 @@ export var Histogram = function Histogram(options) {
61
61
 
62
62
  // Get colors from style.palette or theme defaults
63
63
  var colors = normalizePalette(style.palette, theme);
64
- var backgroundColor = style.backgroundColor || getBackgroundColor(theme);
65
64
 
66
65
  // Create chart
67
66
  chart = new Chart({
@@ -122,9 +121,9 @@ export var Histogram = function Histogram(options) {
122
121
  name: '频数'
123
122
  }]
124
123
  },
125
- viewStyle: {
126
- viewFill: backgroundColor
127
- },
124
+ viewStyle: style.backgroundColor ? {
125
+ viewFill: style.backgroundColor
126
+ } : undefined,
128
127
  theme: getThemeObject(theme)
129
128
  };
130
129
  chart.options(chartOptions);
@@ -1,4 +1,4 @@
1
- import type { VisualizationOptions } from '../../types';
1
+ import type { VisualizationOptions, VisualizationTheme } from '../../types';
2
2
  /**
3
3
  * LineDataItem is the type for each data item in the line chart.
4
4
  */
@@ -16,7 +16,7 @@ export interface LineConfig {
16
16
  title?: string;
17
17
  axisXTitle?: string;
18
18
  axisYTitle?: string;
19
- theme?: 'default' | 'academy' | 'dark';
19
+ theme?: VisualizationTheme;
20
20
  style?: {
21
21
  backgroundColor?: string;
22
22
  palette?: string[];