Skip to content

Commit 6032c29

Browse files
authored
fix(highlighter): hide it when tooltip type is None (#482)
If the tooltip type is hidden (TooltipType.None) then the tooltip should not be shown. This add the check on the selector and includes also a smoke test. fix #478, fix #479
1 parent 77c4a74 commit 6032c29

File tree

9 files changed

+311
-80
lines changed

9 files changed

+311
-80
lines changed

.playground/playgroud.tsx

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,5 @@
11
import React from 'react';
2-
import {
3-
Axis,
4-
Chart,
5-
getAxisId,
6-
getSpecId,
7-
Position,
8-
ScaleType,
9-
Settings,
10-
LIGHT_THEME,
11-
niceTimeFormatter,
12-
LineAnnotation,
13-
AnnotationDomainTypes,
14-
BarSeries,
15-
RectAnnotation,
16-
TooltipType,
17-
} from '../src';
2+
import { Chart, Settings, TooltipType, LineSeries } from '../src';
183
import { KIBANA_METRICS } from '../src/utils/data_samples/test_dataset_kibana';
194
export class Playground extends React.Component {
205
chartRef: React.RefObject<Chart> = React.createRef();
@@ -43,50 +28,17 @@ export class Playground extends React.Component {
4328
}
4429
};
4530
render() {
46-
const data = KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(0, 7);
47-
4831
return (
4932
<>
5033
<button onClick={this.onSnapshot}>Snapshot</button>
5134
<div className="chart">
52-
<Chart ref={this.chartRef}>
53-
<Settings theme={LIGHT_THEME} showLegend={true} tooltip={TooltipType.Crosshairs} />
54-
<Axis
55-
id={getAxisId('time')}
56-
position={Position.Bottom}
57-
tickFormat={niceTimeFormatter([data[0][0], data[data.length - 1][0]])}
58-
/>
59-
<Axis id={getAxisId('count')} position={Position.Left} />
60-
<LineAnnotation
61-
id="line annotation"
62-
dataValues={[
63-
{
64-
dataValue: data[5][0],
65-
details: 'hello tooltip',
66-
},
67-
]}
68-
domainType={AnnotationDomainTypes.XDomain}
69-
marker={<div style={{ width: 10, height: 10, background: 'red' }} />}
70-
/>
71-
<RectAnnotation
72-
id="rect annotation"
73-
dataValues={[
74-
{
75-
coordinates: {
76-
x1: data[3][0],
77-
},
78-
details: 'hello',
79-
},
80-
]}
81-
/>
82-
<BarSeries
83-
id={getSpecId('series bars chart')}
84-
xScaleType={ScaleType.Linear}
85-
yScaleType={ScaleType.Linear}
35+
<Chart>
36+
<Settings tooltip={{ type: TooltipType.Crosshairs }} showLegend />
37+
<LineSeries
38+
id="lines"
8639
xAccessor={0}
8740
yAccessors={[1]}
88-
data={data}
89-
yScaleToDataExtent={true}
41+
data={KIBANA_METRICS.metrics.kibana_os_load[0].data}
9042
/>
9143
</Chart>
9244
</div>

src/chart_types/xy_chart/state/chart_state.interactions.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,8 @@ describe('Chart state pointer interactions', () => {
212212
store.dispatch(specParsed());
213213
store.dispatch(onPointerMove({ x: 10, y: 10 + 70 }, 0));
214214
const tooltipData = getTooltipValuesAndGeometriesSelector(store.getState());
215-
expect(tooltipData.tooltipValues.length).toBe(2);
216-
expect(tooltipData.tooltipValues[0].isXValue).toBe(true);
217-
expect(tooltipData.tooltipValues[1].isXValue).toBe(false);
218-
expect(tooltipData.tooltipValues[1].isHighlighted).toBe(true);
215+
// no tooltip values exist if we have a TooltipType === None
216+
expect(tooltipData.tooltipValues.length).toBe(0);
219217
let isTooltipVisible = isTooltipVisibleSelector(store.getState());
220218
expect(isTooltipVisible).toBe(false);
221219

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { GlobalChartState, chartStoreReducer } from '../../../state/chart_state';
2+
import { createStore, Store } from 'redux';
3+
import { upsertSpec, specParsed } from '../../../state/actions/specs';
4+
import { MockSeriesSpec, MockGlobalSpec } from '../../../mocks/specs';
5+
import { updateParentDimensions } from '../../../state/actions/chart_settings';
6+
import { getTooltipValuesAndGeometriesSelector } from './selectors/get_tooltip_values_highlighted_geoms';
7+
import { onPointerMove } from '../../../state/actions/mouse';
8+
import { TooltipType } from '../utils/interactions';
9+
10+
describe('XYChart - State tooltips', () => {
11+
let store: Store<GlobalChartState>;
12+
beforeEach(() => {
13+
const storeReducer = chartStoreReducer('chartId');
14+
store = createStore(storeReducer);
15+
store.dispatch(upsertSpec(MockSeriesSpec.bar({ data: [{ x: 1, y: 10 }, { x: 2, y: 5 }] })));
16+
store.dispatch(upsertSpec(MockGlobalSpec.settings()));
17+
store.dispatch(specParsed());
18+
store.dispatch(updateParentDimensions({ width: 100, height: 100, top: 0, left: 0 }));
19+
});
20+
21+
describe('should compute tooltip values depending on tooltip type', () => {
22+
it.each<[TooltipType, number, number]>([
23+
[TooltipType.None, 0, 0],
24+
[TooltipType.Follow, 1, 2],
25+
[TooltipType.VerticalCursor, 1, 2],
26+
[TooltipType.Crosshairs, 1, 2],
27+
])('tooltip type %s', (tooltipType, expectedHgeomsLength, expectedTooltipValuesLength) => {
28+
store.dispatch(onPointerMove({ x: 25, y: 50 }, 0));
29+
store.dispatch(
30+
upsertSpec(
31+
MockGlobalSpec.settings({
32+
tooltip: {
33+
type: tooltipType,
34+
},
35+
}),
36+
),
37+
);
38+
store.dispatch(specParsed());
39+
const state = store.getState();
40+
const tooltipValues = getTooltipValuesAndGeometriesSelector(state);
41+
expect(tooltipValues.tooltipValues).toHaveLength(expectedTooltipValuesLength);
42+
expect(tooltipValues.highlightedGeometries).toHaveLength(expectedHgeomsLength);
43+
});
44+
});
45+
});

src/chart_types/xy_chart/state/selectors/get_specs.test.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,12 @@
11
import { getSeriesSpecsSelector } from './get_specs';
22
import { getInitialState } from '../../../../state/chart_state';
3-
import { ChartTypes } from '../../..';
4-
import { SpecTypes } from '../../utils/specs';
3+
import { MockSeriesSpec } from '../../../../mocks/specs';
54

65
describe('selector - get_specs', () => {
76
const state = getInitialState('chartId1');
8-
const barSpec1 = {
9-
id: 'bars1',
10-
chartType: ChartTypes.XYAxis,
11-
specType: SpecTypes.Series,
12-
};
13-
const barSpec2 = {
14-
id: 'bars2',
15-
chartType: ChartTypes.XYAxis,
16-
specType: SpecTypes.Series,
17-
};
187
beforeEach(() => {
19-
state.specs['bars1'] = barSpec1;
20-
state.specs['bars2'] = barSpec2;
8+
state.specs['bars1'] = MockSeriesSpec.bar({ id: 'bars1' });
9+
state.specs['bars2'] = MockSeriesSpec.bar({ id: 'bars2' });
2110
});
2211
it('shall return the same ref objects', () => {
2312
const series = getSeriesSpecsSelector(state);

src/chart_types/xy_chart/state/selectors/get_tooltip_values_highlighted_geoms.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ function getTooltipAndHighlightFromXValue(
6767
if (!scales.xScale || !scales.yScales) {
6868
return EMPTY_VALUES;
6969
}
70+
if (tooltipType === TooltipType.None) {
71+
return EMPTY_VALUES;
72+
}
7073
let x = orientedProjectedPointerPosition.x;
7174
let y = orientedProjectedPointerPosition.y;
7275
if (externalPointerEvent && isValidExternalPointerEvent(externalPointerEvent, scales.xScale)) {

src/mocks/specs/specs.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ import {
1010
BasicSeriesSpec,
1111
SpecTypes,
1212
SeriesTypes,
13+
Position,
1314
} from '../../chart_types/xy_chart/utils/specs';
1415
import { getSpecId, getGroupId } from '../../utils/ids';
1516
import { ScaleType } from '../../utils/scales/scales';
1617
import { ChartTypes } from '../../chart_types';
18+
import { SettingsSpec } from '../../specs';
19+
import { TooltipType } from '../../chart_types/xy_chart/utils/interactions';
20+
import { LIGHT_THEME } from '../../utils/themes/light_theme';
1721

1822
export class MockSeriesSpec {
1923
private static readonly barBase: BarSeriesSpec = {
@@ -104,13 +108,10 @@ export class MockSeriesSpec {
104108
switch (type) {
105109
case 'line':
106110
return MockSeriesSpec.lineBase;
107-
break;
108111
case 'bar':
109112
return MockSeriesSpec.barBase;
110-
break;
111113
case 'area':
112114
return MockSeriesSpec.areaBase;
113-
break;
114115
default:
115116
return MockSeriesSpec.barBase;
116117
}
@@ -133,3 +134,29 @@ export class MockSeriesSpecs {
133134
return [];
134135
}
135136
}
137+
138+
export class MockGlobalSpec {
139+
private static readonly settingsBase: SettingsSpec = {
140+
id: '__global__settings___',
141+
chartType: ChartTypes.Global,
142+
specType: SpecTypes.Settings,
143+
rendering: 'canvas' as 'canvas',
144+
rotation: 0 as 0,
145+
animateData: true,
146+
showLegend: false,
147+
resizeDebounce: 10,
148+
debug: false,
149+
tooltip: {
150+
type: TooltipType.VerticalCursor,
151+
snap: true,
152+
},
153+
legendPosition: Position.Right,
154+
showLegendDisplayValue: true,
155+
hideDuplicateAxes: false,
156+
theme: LIGHT_THEME,
157+
};
158+
159+
static settings(partial?: Partial<SettingsSpec>): SettingsSpec {
160+
return mergePartial<SettingsSpec>(MockGlobalSpec.settingsBase, partial, { mergeOptionalPartialValues: true });
161+
}
162+
}

src/specs/settings.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export type DefaultSettingsProps =
112112
export const DEFAULT_TOOLTIP_TYPE = TooltipType.VerticalCursor;
113113
export const DEFAULT_TOOLTIP_SNAP = true;
114114

115-
export const DEFAULT_SETTINGS_SPEC = {
115+
export const DEFAULT_SETTINGS_SPEC: SettingsSpec = {
116116
id: '__global__settings___',
117117
chartType: ChartTypes.Global,
118118
specType: SpecTypes.Settings,
@@ -125,7 +125,6 @@ export const DEFAULT_SETTINGS_SPEC = {
125125
tooltip: {
126126
type: DEFAULT_TOOLTIP_TYPE,
127127
snap: DEFAULT_TOOLTIP_SNAP,
128-
value: '',
129128
},
130129
legendPosition: Position.Right,
131130
showLegendDisplayValue: true,

0 commit comments

Comments
 (0)