Skip to content

Commit

Permalink
feat(tooltip): 通过 pointer-events 属性来达到 tooltip 躲避鼠标的交互效果
Browse files Browse the repository at this point in the history
  • Loading branch information
simaQ committed Mar 23, 2020
1 parent d835f18 commit 2e750aa
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 78 deletions.
40 changes: 14 additions & 26 deletions src/chart/controller/tooltip.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { CONTAINER_CLASS } from '@antv/component/lib/tooltip/css-const';

import { deepMix, each, find, flatten, get, isArray, isEqual, isFunction, mix } from '@antv/util';
import { Crosshair, HtmlTooltip, IGroup } from '../../dependents';
import Geometry from '../../geometry/base';
Expand Down Expand Up @@ -46,8 +48,8 @@ export default class Tooltip extends Controller<TooltipOption> {
public init() { }

public render() {
this.option = this.view.getOptions().tooltip;
this.isVisible = this.option !== false;
const option = this.view.getOptions().tooltip;
this.isVisible = option !== false;
}

/**
Expand Down Expand Up @@ -272,17 +274,23 @@ export default class Tooltip extends Controller<TooltipOption> {
public layout() { }
public update() {
this.clear();
// 更新 tooltip 配置
this.option = this.view.getOptions().tooltip;
}

// 获取 tooltip 配置,因为用户可能会通过 view.tooltip() 重新配置 tooltip,所以就不做缓存,每次直接读取
private getTooltipCfg() {
const view = this.view;
const option = this.option;
const option = view.getOptions().tooltip;
const theme = view.getTheme();
const defaultCfg = get(theme, ['components', 'tooltip'], {});
return deepMix({}, defaultCfg, option);
const isTooltipLocked = view.isTooltipLocked();
const pointerEvents = (get(option, 'enterable') || isTooltipLocked) ? 'auto' : (defaultCfg.enterable ? 'auto' : 'none');
return deepMix({}, defaultCfg, {
domStyles: {
[`${CONTAINER_CLASS}`]: {
pointerEvents,
},
},
}, option);
}

private getTitle(items) {
Expand All @@ -309,26 +317,6 @@ export default class Tooltip extends Controller<TooltipOption> {
});

tooltip.init();

const tooltipContainer = tooltip.get('container');
if (cfg.enterable === false) {
// 优化体验,在 tooltip dom 上加绑事件
// 如果 tooltip 不允许进入
tooltipContainer.onmousemove = event => {
// 避免 tooltip 频繁闪烁
const point = this.view.getCanvas().getPointByClient(event.clientX, event.clientY);
this.view.emit('plot:mousemove', point);
};
}

// 优化:鼠标移入 tooltipContainer 然后再移出时,需要隐藏 tooltip
tooltipContainer.onmouseleave = () => {
if (!this.view.isTooltipLocked()) {
this.hideTooltip();
}
};


this.tooltip = tooltip;
}

Expand Down
71 changes: 19 additions & 52 deletions tests/bugs/tooltip-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,45 +90,6 @@ describe('tooltip', () => {
expect(tooltipItems.length).toBe(1);
});

it('tooltip avoid', () => {
const data = [
{ year: '1991', value: 15468 },
{ year: '1992', value: 16100 },
{ year: '1993', value: 15900 },
{ year: '1994', value: 17409 },
{ year: '1995', value: 17000 },
{ year: '1996', value: 31056 },
{ year: '1997', value: 31982 },
{ year: '1998', value: 32040 },
{ year: '1999', value: 33233 },
];
const chart = new Chart({
container: createDiv(),
width: 400,
height: 250,
});

chart.data(data);
chart.area().position('year*value');

const moveEvent = jest.fn();
chart.on('plot:mousemove', moveEvent);

chart.render();

const point = chart.getXY({ year: '1995', value: 17000 });
chart.showTooltip(point);

const tooltip = chart.ele.getElementsByClassName('g2-tooltip')[0];
const mousemoveEvent = new MouseEvent('mousemove', {
clientX: 100,
clientY: 100,
});
tooltip.dispatchEvent(mousemoveEvent);

expect(moveEvent).toBeCalled();
});

it('heatmap tooltip', () => {
const chart = new Chart({
container: createDiv(),
Expand Down Expand Up @@ -157,7 +118,7 @@ describe('tooltip', () => {
expect(tooltip).toBeDefined();
});

it('tooltip hide when mouseleave tooltipContainer', () => {
it('tooltip avoid', () => {
const data = [
{ year: '1991', value: 15468 },
{ year: '1992', value: 16100 },
Expand All @@ -177,28 +138,34 @@ describe('tooltip', () => {

chart.data(data);
chart.area().position('year*value');

const moveEvent = jest.fn();
chart.on('plot:mousemove', moveEvent);

chart.render();

const point = chart.getXY({ year: '1995', value: 17000 });
chart.showTooltip(point);

const tooltip = chart.ele.getElementsByClassName('g2-tooltip')[0];
const mousemoveEvent = new MouseEvent('mouseleave', {
clientX: 100,
clientY: 100,
// @ts-ignore
expect(chart.ele.getElementsByClassName('g2-tooltip')[0].style['pointer-events']).toBe('none');

chart.tooltip({
enterable: true,
});
tooltip.dispatchEvent(mousemoveEvent);
chart.hideTooltip();
chart.showTooltip(chart.getXY({ year: '1992', value: 16100 }));
// @ts-ignore
expect(tooltip.style.visibility).toBe('hidden');
expect(chart.ele.getElementsByClassName('g2-tooltip')[0].style['pointer-events']).toBe('auto');

chart.hideTooltip();
chart.tooltip({
enterable: false,
});
chart.lockTooltip();
chart.showTooltip(point);
tooltip.dispatchEvent(mousemoveEvent);
// @ts-ignore
expect(tooltip.style.visibility).toBe('visible');
expect(chart.ele.getElementsByClassName('g2-tooltip')[0].style['pointer-events']).toBe('auto');

chart.unlockTooltip();
chart.showTooltip(chart.getXY({ year: '1992', value: 16100 }));
// @ts-ignore
expect(chart.ele.getElementsByClassName('g2-tooltip')[0].style['pointer-events']).toBe('none');
});
});

0 comments on commit 2e750aa

Please sign in to comment.