diff --git a/__tests__/integration/snapshots/tooltip/aapl-area-missing-data-transpose/step0.html b/__tests__/integration/snapshots/tooltip/aapl-area-missing-data-transpose/step0.html
index 5decce0b1d..a45e4b4c89 100644
--- a/__tests__/integration/snapshots/tooltip/aapl-area-missing-data-transpose/step0.html
+++ b/__tests__/integration/snapshots/tooltip/aapl-area-missing-data-transpose/step0.html
@@ -12,5 +12,35 @@
+ >
+
+
+
+
+ close
+
+
+
+ NaN
+
+
+
;
diff --git a/__tests__/integration/snapshots/tooltip/mock-line-falsy/step0.html b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step0.html
new file mode 100644
index 0000000000..7d03c7466f
--- /dev/null
+++ b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step0.html
@@ -0,0 +1,46 @@
+;
diff --git a/__tests__/integration/snapshots/tooltip/mock-line-falsy/step1.html b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step1.html
new file mode 100644
index 0000000000..d5d37285e0
--- /dev/null
+++ b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step1.html
@@ -0,0 +1,46 @@
+;
diff --git a/__tests__/integration/snapshots/tooltip/mock-line-falsy/step2.html b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step2.html
new file mode 100644
index 0000000000..0dd86785e7
--- /dev/null
+++ b/__tests__/integration/snapshots/tooltip/mock-line-falsy/step2.html
@@ -0,0 +1,46 @@
+;
diff --git a/__tests__/integration/snapshots/tooltip/profit-interval-legend-filter-ordinal/step1.html b/__tests__/integration/snapshots/tooltip/profit-interval-legend-filter-ordinal/step1.html
index 61f734aaf7..7b0e5071af 100644
--- a/__tests__/integration/snapshots/tooltip/profit-interval-legend-filter-ordinal/step1.html
+++ b/__tests__/integration/snapshots/tooltip/profit-interval-legend-filter-ordinal/step1.html
@@ -42,5 +42,34 @@
387264
+
+
+
+
+ start
+
+
+
+ 0
+
+
;
diff --git a/__tests__/plots/tooltip/index.ts b/__tests__/plots/tooltip/index.ts
index 4a8dd5c924..a977728dd6 100644
--- a/__tests__/plots/tooltip/index.ts
+++ b/__tests__/plots/tooltip/index.ts
@@ -58,3 +58,4 @@ export { aaplLineSliderFilter } from './appl-line-slider-filter';
export { aaplLineAreaBasicSample } from './aapl-line-area-basic-sample';
export { aaplAreaMissingDataTranspose } from './aapl-area-missing-data-transpose';
export { alphabetIntervalBrushTooltip } from './alphabet-interval-brush-tooltip';
+export { mockLineFalsy } from './mock-line-falsy';
diff --git a/__tests__/plots/tooltip/london-tube-lines-geo.ts b/__tests__/plots/tooltip/london-tube-lines-geo.ts
index cb0eba232c..83bfa94f90 100644
--- a/__tests__/plots/tooltip/london-tube-lines-geo.ts
+++ b/__tests__/plots/tooltip/london-tube-lines-geo.ts
@@ -22,6 +22,7 @@ export async function londonTubeLineGeo(): Promise {
width: 700,
height: 500,
padding: 10,
+ interaction: { tooltip: { filter: (d) => d.value !== null } },
children: [
{
type: 'geoPath',
diff --git a/__tests__/plots/tooltip/mock-line-falsy.ts b/__tests__/plots/tooltip/mock-line-falsy.ts
new file mode 100644
index 0000000000..3ede337de5
--- /dev/null
+++ b/__tests__/plots/tooltip/mock-line-falsy.ts
@@ -0,0 +1,48 @@
+import { G2Spec } from '../../../src';
+import { seriesTooltipSteps } from './utils';
+
+export function mockLineFalsy(): G2Spec {
+ return {
+ type: 'line',
+ data: [
+ {
+ city: '杭州',
+ value: 400,
+ },
+ {
+ city: '上海',
+ value: 300,
+ },
+ {
+ city: '北京',
+ value: null,
+ },
+ {
+ city: '河北',
+ value: 0,
+ },
+ {
+ city: '苏州',
+ value: 500,
+ },
+ {
+ city: '海南',
+ value: undefined,
+ },
+ {
+ city: '成都',
+ value: 400,
+ },
+ {
+ city: '重庆',
+ value: 200,
+ },
+ ],
+ encode: {
+ x: 'city',
+ y: 'value',
+ },
+ };
+}
+
+mockLineFalsy.steps = seriesTooltipSteps([200, 300], [275, 300], [420, 300]);
diff --git a/src/interaction/tooltip.ts b/src/interaction/tooltip.ts
index be03c695a8..a7ffc40558 100644
--- a/src/interaction/tooltip.ts
+++ b/src/interaction/tooltip.ts
@@ -102,6 +102,11 @@ function destroyTooltip(root) {
}
}
+function showUndefined(item) {
+ const { value } = item;
+ return { ...item, value: value === undefined ? 'undefined' : value };
+}
+
function singleItem(element) {
const { __data__: datum } = element;
const { title, items = [] } = datum;
@@ -110,7 +115,8 @@ function singleItem(element) {
.map(({ color = itemColorOf(element), ...item }) => ({
...item,
color,
- }));
+ }))
+ .map(showUndefined);
return {
...(title && { title }),
items: newItems,
@@ -164,22 +170,24 @@ function groupItems(
data.map((d) => d.title),
key,
).filter(defined);
- const newItems = data.flatMap((datum, i) => {
- const element = elements[i];
- const { items = [], title } = datum;
- return items
- .filter(defined)
- .map(({ color = itemColorOf(element), name, ...item }) => {
- const name1 = groupName
- ? groupNameOf(scale, datum) || name
- : name || groupNameOf(scale, datum);
- return {
- ...item,
- color,
- name: name1 || title,
- };
- });
- });
+ const newItems = data
+ .flatMap((datum, i) => {
+ const element = elements[i];
+ const { items = [], title } = datum;
+ return items
+ .filter(defined)
+ .map(({ color = itemColorOf(element), name, ...item }) => {
+ const name1 = groupName
+ ? groupNameOf(scale, datum) || name
+ : name || groupNameOf(scale, datum);
+ return {
+ ...item,
+ color,
+ name: name1 || title,
+ };
+ });
+ })
+ .map(showUndefined);
return {
...(T.length > 0 && { title: T.join(',') }),
items: unique(newItems, (d) => `(${key(d.name)}, ${key(d.value)})`),
diff --git a/src/runtime/transform.ts b/src/runtime/transform.ts
index 6117cf44b8..5a05506115 100644
--- a/src/runtime/transform.ts
+++ b/src/runtime/transform.ts
@@ -170,13 +170,11 @@ export function extractTooltip(
: definedChannel
? encode[channel].value[i]
: null;
- if (value1) {
- values[i] = {
- name: name1,
- color,
- value: normalizedValueFormatter(value1),
- };
- }
+ values[i] = {
+ name: name1,
+ color,
+ value: normalizedValueFormatter(value1),
+ };
}
return values;
}