@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
@@ -23,13 +23,13 @@ __export(dual_axes_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(dual_axes_exports);
25
25
  var import_g2 = require("@antv/g2");
26
- var import_theme = require("../../util/theme");
26
+ var import_util = require("../../util");
27
+ var getSeriesField = (index) => `value_${index + 1}`;
27
28
  function transformData(series, categories) {
28
29
  return categories.map((category, index) => {
29
30
  const dataPoint = { category };
30
- series.forEach((s, i) => {
31
- const yField = s.axisYTitle || `value_${i + 1}`;
32
- dataPoint[yField] = s.data[index];
31
+ series.forEach((item, seriesIndex) => {
32
+ dataPoint[getSeriesField(seriesIndex)] = item.data[index];
33
33
  });
34
34
  return dataPoint;
35
35
  });
@@ -37,14 +37,19 @@ function transformData(series, categories) {
37
37
  var DualAxes = (options) => {
38
38
  const { container, width, height, theme: chartTheme = "default" } = options;
39
39
  let chart = null;
40
+ let hasRendered = false;
40
41
  const render = (config) => {
41
42
  const { categories, series, theme = chartTheme, title, axisXTitle, style = {} } = config;
42
43
  if (chart) {
43
44
  chart.destroy();
44
45
  }
45
46
  const { startAtZero = false } = style;
46
- const colors = (0, import_theme.normalizePalette)(style.palette, theme);
47
- const backgroundColor = style.backgroundColor || (0, import_theme.getBackgroundColor)(theme);
47
+ const requestedColors = style.palette ? (0, import_util.normalizePalette)(style.palette, theme) : [];
48
+ const defaultColors = (0, import_util.normalizePalette)(void 0, theme);
49
+ const colors = [
50
+ ...requestedColors,
51
+ ...defaultColors.filter((color) => !requestedColors.includes(color))
52
+ ];
48
53
  const data = transformData(series, categories);
49
54
  chart = new import_g2.Chart({
50
55
  container,
@@ -52,13 +57,34 @@ var DualAxes = (options) => {
52
57
  height,
53
58
  autoFit: true
54
59
  });
55
- const sortedSeries = [...series].sort((a, b) => {
60
+ const sortedSeries = series.map((item, originalIndex) => ({ item, originalIndex })).sort((a, b) => {
56
61
  const order = ["column", "line"];
57
- return order.indexOf(a.type) - order.indexOf(b.type);
62
+ return order.indexOf(a.item.type) - order.indexOf(b.item.type);
58
63
  });
59
- const children = sortedSeries.map((item, index) => {
60
- const yField = item.axisYTitle || `value_${index + 1}`;
61
- const color = colors[index % colors.length];
64
+ const seriesMeta = sortedSeries.map(({ item, originalIndex }, index) => ({
65
+ item,
66
+ yField: getSeriesField(originalIndex),
67
+ displayName: item.axisYTitle || getSeriesField(originalIndex),
68
+ color: colors[index % colors.length]
69
+ }));
70
+ const seriesByField = new Map(
71
+ seriesMeta.map(({ item, yField, displayName }) => [yField, { type: item.type, displayName }])
72
+ );
73
+ const cartesianAxisOptions = {
74
+ axisXTitle,
75
+ xLabels: categories,
76
+ chartWidth: width
77
+ };
78
+ const cartesianAxis = (0, import_util.getCartesianAxis)(cartesianAxisOptions);
79
+ const children = seriesMeta.map(({ item, yField, displayName, color }) => {
80
+ const tooltip = {
81
+ items: [
82
+ (datum) => ({
83
+ name: displayName,
84
+ value: datum[yField]
85
+ })
86
+ ]
87
+ };
62
88
  if (item.type === "column") {
63
89
  return {
64
90
  type: "interval",
@@ -68,16 +94,24 @@ var DualAxes = (options) => {
68
94
  color: () => yField
69
95
  },
70
96
  scale: {
71
- y: { nice: true, zero: startAtZero },
72
- color: { range: [color] }
97
+ y: { nice: true, zero: startAtZero }
73
98
  },
99
+ tooltip,
74
100
  axis: {
75
- y: { title: item.axisYTitle || "" }
101
+ y: {
102
+ ...cartesianAxis.y,
103
+ title: item.axisYTitle || "",
104
+ titleFill: color,
105
+ titleFontWeight: 500
106
+ }
76
107
  },
77
108
  style: {
78
- columnWidthRatio: 0.8,
109
+ fill: color,
110
+ fillOpacity: 0.86,
111
+ columnWidthRatio: import_util.CHART_STYLE_DEFAULTS.intervalWidthRatio,
79
112
  ...theme !== "academy" ? { radiusTopLeft: 4, radiusTopRight: 4 } : {}
80
- }
113
+ },
114
+ animate: (0, import_util.getChartAnimation)(hasRendered, "growInY")
81
115
  };
82
116
  } else {
83
117
  return {
@@ -89,52 +123,73 @@ var DualAxes = (options) => {
89
123
  color: () => yField
90
124
  },
91
125
  scale: {
92
- y: { independent: true, zero: startAtZero },
93
- color: { range: [color] }
126
+ y: { independent: true, zero: startAtZero }
94
127
  },
128
+ tooltip,
95
129
  axis: {
96
- y: { position: "right", title: item.axisYTitle || "" }
130
+ y: {
131
+ ...cartesianAxis.y,
132
+ position: "right",
133
+ title: item.axisYTitle || "",
134
+ titleFill: color,
135
+ titleFontWeight: 500,
136
+ grid: false
137
+ }
97
138
  },
98
139
  style: {
99
- lineWidth: 2
100
- }
140
+ stroke: color,
141
+ lineWidth: import_util.CHART_STYLE_DEFAULTS.lineWidth,
142
+ lineCap: "round",
143
+ lineJoin: "round"
144
+ },
145
+ state: (0, import_util.getLineHighlightState)(import_util.CHART_STYLE_DEFAULTS.lineWidth),
146
+ animate: (0, import_util.getChartAnimation)(hasRendered, "pathIn")
101
147
  };
102
148
  }
103
149
  });
104
150
  const chartOptions = {
105
- animate: false,
106
151
  type: "view",
107
152
  data,
108
- title: title ?? "",
153
+ title: title || "",
109
154
  children,
110
- axis: {
111
- x: { title: axisXTitle || false }
112
- },
155
+ ...(0, import_util.getCartesianLayout)(cartesianAxisOptions),
156
+ axis: { x: cartesianAxis.x },
113
157
  scale: {
114
- y: { nice: true }
158
+ y: { nice: true },
159
+ color: {
160
+ domain: seriesMeta.map(({ yField }) => yField),
161
+ range: seriesMeta.map(({ color }) => color)
162
+ }
115
163
  },
116
164
  legend: {
117
165
  color: {
118
- position: "top",
119
- itemMarker: (v, index) => {
120
- const seriesItem = series[index];
121
- return (seriesItem == null ? void 0 : seriesItem.type) === "line" ? "smooth" : "rect";
166
+ labelFormatter: (value) => {
167
+ var _a;
168
+ return ((_a = seriesByField.get(value)) == null ? void 0 : _a.displayName) || value;
169
+ },
170
+ itemMarker: (value) => {
171
+ var _a;
172
+ return ((_a = seriesByField.get(value)) == null ? void 0 : _a.type) === "line" ? "smooth" : "rect";
122
173
  }
123
174
  }
124
175
  },
125
- viewStyle: {
126
- viewFill: backgroundColor
176
+ interaction: {
177
+ tooltip: (0, import_util.getSharedTooltipInteraction)({ crosshairs: true }),
178
+ ...(0, import_util.getSeriesHighlightByColorInteraction)()
127
179
  },
128
- theme: (0, import_theme.getThemeObject)(theme)
180
+ viewStyle: style.backgroundColor ? { viewFill: style.backgroundColor } : void 0,
181
+ theme: (0, import_util.getThemeObject)(theme)
129
182
  };
130
183
  chart.options(chartOptions);
131
184
  chart.render();
185
+ hasRendered = true;
132
186
  };
133
187
  const destroy = () => {
134
188
  if (chart) {
135
189
  chart.destroy();
136
190
  chart = null;
137
191
  }
192
+ hasRendered = false;
138
193
  };
139
194
  return {
140
195
  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[];
@@ -23,32 +23,103 @@ __export(funnel_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(funnel_exports);
25
25
  var import_g2 = require("@antv/g2");
26
- var import_theme = require("../../util/theme");
26
+ var import_util = require("../../util");
27
+ var FUNNEL_LABELS = {
28
+ "en-US": {
29
+ baseline: "Baseline",
30
+ conversionRate: "Conversion Rate",
31
+ currentValue: "Current value",
32
+ dropOff: "Drop-off from previous",
33
+ overallConversionRate: "Overall conversion",
34
+ stageConversion: "Stage conversion"
35
+ },
36
+ "zh-CN": {
37
+ baseline: "基准",
38
+ conversionRate: "转化率",
39
+ currentValue: "当前值",
40
+ dropOff: "较上一步流失",
41
+ overallConversionRate: "整体转化率",
42
+ stageConversion: "阶段转化率"
43
+ }
44
+ };
45
+ var formatConversionRate = (start, end) => {
46
+ if (!Number.isFinite(start) || !Number.isFinite(end) || start === 0)
47
+ return "—";
48
+ return `${(end / start * 100).toFixed(1)}%`;
49
+ };
50
+ var formatMetricLabel = (label, value, locale) => locale === "zh-CN" ? `${label}:${value}` : `${label}: ${value}`;
27
51
  var Funnel = (options) => {
28
- const { container, width, height, theme: chartTheme = "default" } = options;
52
+ const { container, width, height, locale, theme: chartTheme = "default" } = options;
29
53
  let chart = null;
30
54
  const render = (config) => {
31
- var _a, _b, _c, _d, _e, _f;
32
- const { data = [], theme = chartTheme, title, style = {} } = config;
55
+ const {
56
+ data = [],
57
+ theme = chartTheme,
58
+ title,
59
+ locale: renderLocale = locale,
60
+ conversionRateLabel,
61
+ style = {}
62
+ } = config;
63
+ const chartLocale = (0, import_util.resolveChartLocale)(renderLocale);
64
+ const labels = FUNNEL_LABELS[chartLocale];
65
+ const numberFormatter = new Intl.NumberFormat(chartLocale);
66
+ const stageConversionRateLabel = conversionRateLabel ?? labels.conversionRate;
67
+ const overallConversionRateLabel = conversionRateLabel ?? labels.overallConversionRate;
33
68
  if (chart) {
34
69
  chart.destroy();
35
70
  }
36
- const colors = (0, import_theme.normalizePalette)(style.palette, theme);
37
- const backgroundColor = style.backgroundColor || (0, import_theme.getBackgroundColor)(theme);
38
- const conversionRate = (start, end) => `${(end / start * 100).toFixed(2)} %`;
71
+ const colors = (0, import_util.normalizePalette)(style.palette, theme);
72
+ const backgroundColor = style.backgroundColor || (0, import_util.getBackgroundColor)(theme);
73
+ const tokens = (0, import_util.getChartVisualTokens)(theme);
74
+ const formatValue = (value) => Number.isFinite(value) ? numberFormatter.format(value) : "—";
75
+ const metricsByCategory = new Map(
76
+ data.map((item, index) => {
77
+ const previous = data[index - 1];
78
+ return [
79
+ item.category,
80
+ {
81
+ conversion: previous ? formatConversionRate(previous.value, item.value) : labels.baseline,
82
+ dropOff: previous ? Math.max(0, previous.value - item.value) : null
83
+ }
84
+ ];
85
+ })
86
+ );
87
+ const funnelTooltip = {
88
+ title: "category",
89
+ items: [
90
+ (d) => ({
91
+ name: labels.currentValue,
92
+ value: formatValue(d.value)
93
+ }),
94
+ (d) => {
95
+ var _a;
96
+ return {
97
+ name: labels.stageConversion,
98
+ value: ((_a = metricsByCategory.get(d.category)) == null ? void 0 : _a.conversion) ?? "—"
99
+ };
100
+ },
101
+ (d) => {
102
+ var _a, _b;
103
+ return {
104
+ name: labels.dropOff,
105
+ value: ((_a = metricsByCategory.get(d.category)) == null ? void 0 : _a.dropOff) === null ? "—" : formatValue(((_b = metricsByCategory.get(d.category)) == null ? void 0 : _b.dropOff) ?? Number.NaN)
106
+ };
107
+ }
108
+ ]
109
+ };
39
110
  chart = new import_g2.Chart({
40
111
  container,
41
112
  width,
42
113
  height,
43
114
  autoFit: true,
44
- paddingLeft: 40,
45
- paddingRight: 68
115
+ paddingLeft: 56,
116
+ paddingRight: 118
46
117
  });
47
118
  const chartOptions = {
48
119
  animate: false,
49
120
  type: "view",
50
121
  data,
51
- title: title ?? "",
122
+ title: title || "",
52
123
  children: [
53
124
  {
54
125
  type: "interval",
@@ -66,109 +137,117 @@ var Funnel = (options) => {
66
137
  x: { padding: 0 },
67
138
  color: { range: colors }
68
139
  },
69
- legend: {
70
- color: {
71
- position: "top",
72
- layout: {
73
- justifyContent: "center"
74
- }
75
- }
76
- },
140
+ legend: false,
141
+ tooltip: funnelTooltip,
77
142
  labels: [
78
- // Inside label showing category and value
79
143
  {
80
144
  text: (d) => `${d.category}
81
- ${d.value}`,
145
+ ${formatValue(d.value)}`,
82
146
  position: "inside",
83
- transform: [{ type: "contrastReverse" }]
84
- },
85
- // Connecting line for conversion rate
86
- {
87
- text: (d, i) => i !== 0 ? "———" : "",
147
+ transform: [{ type: "contrastReverse" }, { type: "overflowStroke" }],
88
148
  style: {
89
- "font-size": "1px",
90
- color: "#666",
91
- "letter-spacing": "0px"
92
- },
93
- position: "top-right",
94
- fill: "#666",
95
- dx: 35,
96
- dy: -8
149
+ fontFamily: import_util.CHART_FONT_FAMILY,
150
+ fontSize: 12,
151
+ fontWeight: 500,
152
+ lineHeight: 17
153
+ }
97
154
  },
98
- // Conversion rate label text
99
155
  {
100
- text: (d, i) => i !== 0 ? "转化率" : "",
156
+ text: (_d, index) => index === 0 ? "" : "———",
101
157
  position: "top-right",
102
- textAlign: "left",
103
- textBaseline: "middle",
104
- fill: "#666",
105
- dx: 40
158
+ fill: tokens.textSecondary,
159
+ fillOpacity: 0.72,
160
+ dx: 18,
161
+ dy: -6,
162
+ style: {
163
+ fontFamily: import_util.CHART_FONT_FAMILY,
164
+ fontSize: 8,
165
+ fontWeight: 400,
166
+ letterSpacing: -2
167
+ }
106
168
  },
107
- // Conversion rate percentage
108
169
  {
109
- text: (d, i, dataArray) => i !== 0 ? conversionRate(dataArray[i - 1].value, dataArray[i].value) : "",
170
+ text: (_d, index, items) => index === 0 ? "" : formatMetricLabel(
171
+ stageConversionRateLabel,
172
+ formatConversionRate(items[index - 1].value, items[index].value),
173
+ chartLocale
174
+ ),
110
175
  position: "top-right",
111
176
  textAlign: "left",
112
177
  textBaseline: "middle",
113
- dx: 80
114
- }
115
- ],
116
- viewStyle: {
117
- viewFill: backgroundColor
118
- }
119
- },
120
- // Overall conversion rate connector
121
- {
122
- type: "connector",
123
- data: [
124
- {
125
- startX: (_a = data[0]) == null ? void 0 : _a.category,
126
- startY: (_b = data[data.length - 1]) == null ? void 0 : _b.category,
127
- endX: 0,
128
- endY: (((_c = data[0]) == null ? void 0 : _c.value) - ((_d = data[data.length - 1]) == null ? void 0 : _d.value)) / 2
178
+ fill: tokens.textPrimary,
179
+ dx: 44,
180
+ style: {
181
+ fontFamily: import_util.CHART_FONT_FAMILY,
182
+ fontSize: 11,
183
+ fontWeight: 500
184
+ }
129
185
  }
130
186
  ],
131
- encode: { x: "startX", x1: "startY", y: "endX", y1: "endY" },
132
187
  style: {
133
- stroke: "#666",
134
- markerEnd: false,
135
- connectLength1: -12,
136
- offset2: -20,
137
- connectorStroke: "#0649f2",
138
- lineDash: [12, 2]
188
+ fillOpacity: 0.94,
189
+ stroke: tokens.separator,
190
+ lineWidth: 2,
191
+ ...theme === "academy" ? {} : { radius: 4 }
139
192
  },
140
- labels: [
141
- {
142
- text: "转化率",
143
- position: "left",
144
- textAlign: "start",
145
- textBaseline: "middle",
146
- fill: "#666",
147
- dx: 10
148
- },
149
- {
150
- text: conversionRate((_e = data[0]) == null ? void 0 : _e.value, (_f = data[data.length - 1]) == null ? void 0 : _f.value),
151
- position: "left",
152
- textAlign: "start",
153
- dx: 50,
154
- fill: "#000"
193
+ state: {
194
+ active: {
195
+ fillOpacity: 1,
196
+ stroke: tokens.separator,
197
+ lineWidth: 3
155
198
  }
156
- ]
157
- }
199
+ },
200
+ viewStyle: style.backgroundColor ? { viewFill: backgroundColor } : void 0
201
+ },
202
+ ...data.length > 1 ? [
203
+ {
204
+ type: "connector",
205
+ data: [
206
+ {
207
+ startX: data[0].category,
208
+ startY: data[data.length - 1].category,
209
+ endX: 0,
210
+ endY: (data[0].value - data[data.length - 1].value) / 2
211
+ }
212
+ ],
213
+ encode: { x: "startX", x1: "startY", y: "endX", y1: "endY" },
214
+ tooltip: false,
215
+ style: {
216
+ stroke: tokens.axisLine,
217
+ strokeOpacity: theme === "academy" ? 1 : 0.82,
218
+ lineWidth: theme === "academy" ? 1 : 0.75,
219
+ markerEnd: false,
220
+ connectLength1: -12
221
+ },
222
+ labels: [
223
+ {
224
+ text: formatMetricLabel(
225
+ overallConversionRateLabel,
226
+ formatConversionRate(data[0].value, data[data.length - 1].value),
227
+ chartLocale
228
+ ),
229
+ position: "left",
230
+ textAlign: "start",
231
+ textBaseline: "middle",
232
+ fill: tokens.textPrimary,
233
+ dx: 8,
234
+ style: {
235
+ fontFamily: import_util.CHART_FONT_FAMILY,
236
+ fontSize: 11,
237
+ fontWeight: 500
238
+ }
239
+ }
240
+ ]
241
+ }
242
+ ] : []
158
243
  ],
159
244
  axis: false,
160
- tooltip: {
161
- items: [
162
- (d) => ({
163
- name: d.category,
164
- value: d.value
165
- })
166
- ]
167
- },
168
- viewStyle: {
169
- viewFill: backgroundColor
245
+ interaction: {
246
+ tooltip: true,
247
+ elementHighlight: true
170
248
  },
171
- theme: (0, import_theme.getThemeObject)(theme)
249
+ viewStyle: style.backgroundColor ? { viewFill: backgroundColor } : void 0,
250
+ theme: (0, import_util.getThemeObject)(theme)
172
251
  };
173
252
  chart.options(chartOptions);
174
253
  chart.render();
@@ -41,7 +41,6 @@ var Histogram = (options) => {
41
41
  chart.destroy();
42
42
  }
43
43
  const colors = (0, import_theme.normalizePalette)(style.palette, theme);
44
- const backgroundColor = style.backgroundColor || (0, import_theme.getBackgroundColor)(theme);
45
44
  chart = new import_g2.Chart({
46
45
  container,
47
46
  width,
@@ -83,9 +82,7 @@ var Histogram = (options) => {
83
82
  tooltip: {
84
83
  items: [{ channel: "y", name: "频数" }]
85
84
  },
86
- viewStyle: {
87
- viewFill: backgroundColor
88
- },
85
+ viewStyle: style.backgroundColor ? { viewFill: style.backgroundColor } : void 0,
89
86
  theme: (0, import_theme.getThemeObject)(theme)
90
87
  };
91
88
  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[];