Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: tooltip 在 geometry 之前显示时,位置不对 #1429

Merged
merged 1 commit into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/f2/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export {
ImageGuide,
TagGuide,
} from './guide';
export { default as Tooltip, withTooltip, TooltipView } from './tooltip';
export { default as Tooltip, withTooltip, TooltipView, TooltipProps } from './tooltip';
export { default as Treemap, withTreemap, TreemapView } from './treemap';
export { default as Sunburst, withSunburst, SunburstView } from './sunburst';
export { default as PieLabel, withPieLabel, PieLabelView } from './pieLabel';
Expand Down
4 changes: 2 additions & 2 deletions packages/f2/src/components/tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import withTooltip from './withTooltip';
import withTooltip, { TooltipProps } from './withTooltip';
import TooltipView from './tooltipView';

export { withTooltip, TooltipView };
export { TooltipProps, withTooltip, TooltipView };
export default withTooltip(TooltipView);
4 changes: 2 additions & 2 deletions packages/f2/src/components/tooltip/tooltipView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export default class TooltipView extends Component {
}
render() {
const { props, context } = this;
const { records, point, coord } = props;
const { records, coord } = props;
const {
left: coordLeft,
top: coordTop,
Expand All @@ -181,7 +181,7 @@ export default class TooltipView extends Component {
// width: coordWidth,
} = coord;
const firstRecord = records[0];
const { x, y } = point;
const { x, y } = firstRecord;
const { name: xFirstText, value: yFirstText } = firstRecord;
const {
background: customBackground,
Expand Down
98 changes: 74 additions & 24 deletions packages/f2/src/components/tooltip/withTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,61 @@
import { jsx } from '../../jsx';
import { isArray, isFunction, find } from '@antv/util';
import Component from '../../base/component';
import equal from '../../base/equal';
import { DataRecord, px, TextAttrs, LineAttrs, RectAttrs } from '../../types';
import { ChartChildProps } from '../../chart';

export interface TooltipProps extends ChartChildProps {
/**
* 顶部边距
*/
padding?: px;
/**
* 显示事件名,默认为 press, 可以为 touchstart 等
*/
triggerOn?: string;
/**
* 消失的事件名,默认为 pressend, 可以为 touchend 等
*/
triggerOff?: string;
/**
* 是否一直显示
*/
alwaysShow?: boolean;
/**
* 是否显示十字线
*/
showCrosshairs?: boolean;
/**
* 十字线类型
*/
crosshairsType?: 'x' | 'y' | 'xy';
/**
* 十字线样式
*/
crosshairsStyle?: LineAttrs;
snap?: boolean;
/**
* 名称样式
*/
nameStyle?: TextAttrs;
/**
* 值样式
*/
valueStyle?: TextAttrs;
/**
* 背景样式
*/
background?: RectAttrs;
}

export interface TooltipState {
records: DataRecord[];
}

export default (View) => {
return class Tooltip extends Component {
isPressEvent = false;
constructor(props) {
return class Tooltip extends Component<TooltipProps, TooltipState> {
constructor(props: TooltipProps) {
super(props);
this.state = {
records: null,
Expand All @@ -28,33 +78,39 @@ export default (View) => {
this._initEvent();
}

didUpdate() {
// 主动触发的 press 等事件不需要重新执行 didUpdate
if (this.isPressEvent) {
// 重置
this.isPressEvent = false;
return;
willReceiveProps(nextProps) {
const { defaultItem: nextDefaultItem } = nextProps;
const { defaultItem: lastDefaultItem } = this.props;
if (!equal(nextDefaultItem, lastDefaultItem)) {
this._showByData(nextDefaultItem);
}
this._initShow();
}

_initShow() {
const { props } = this;
const { chart, defaultItem } = props;
const { defaultItem } = props;
if (defaultItem) {
const point = chart.getPosition(defaultItem);
this.show(point);
this._showByData(defaultItem);
}
}

_showByData(dataItem) {
const { props } = this;
const { chart } = props;
// 因为 tooltip 有可能在 geometry 之前,所以需要等 geometry render 完后再执行
setTimeout(() => {
const point = chart.getPosition(dataItem);
this.show(point);
}, 0);
}

_initEvent() {
const { context, props } = this;
const { canvas } = context;
const { triggerOn = 'press', triggerOff = 'pressend', alwaysShow = false } = props;

canvas.on(triggerOn, (ev) => {
const { points } = ev;
this.isPressEvent = true;
this.show(points[0]);
});

Expand All @@ -67,17 +123,13 @@ export default (View) => {

show(point) {
const { props } = this;
const { chart, coord, onChange } = props;
const { chart, onChange } = props;
const snapRecords = chart.getSnapRecords(point);
if (!snapRecords || !snapRecords.length) return;
const legendItems = chart.getLegendItems();
const { origin, xField, yField } = snapRecords[0];
const { xField, yField } = snapRecords[0];
const xScale = chart.getScale(xField);
const yScale = chart.getScale(yField);
const showPoint = coord.convertPoint({
x: xScale.scale(origin[xField]),
y: yScale.scale(origin[yField]),
});

const records = snapRecords.map((record) => {
const { origin, xField, yField } = record;
Expand Down Expand Up @@ -108,7 +160,6 @@ export default (View) => {
return;
}
this.setState({
point: showPoint,
records,
});
if (isFunction(onChange)) {
Expand All @@ -118,7 +169,6 @@ export default (View) => {

hide() {
this.setState({
point: null,
records: null,
});
}
Expand All @@ -129,10 +179,10 @@ export default (View) => {
if (visible === false) {
return null;
}
const { point, records } = state;
const { records } = state;
if (!records || !records.length) return null;

return <View {...props} point={point} records={records} />;
return <View {...props} records={records} />;
}
};
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 23 additions & 3 deletions packages/f2/test/components/tooltip/tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,31 @@ describe('tooltip', () => {
expect(context).toMatchImageSnapshot();
});

it('Tooltip 默认展示, tooltip 在 geometry 之前', async () => {
const context = createContext('Tooltip 默认展示, tooltip 在 geometry 之前');
const { props } = (
<Canvas context={context} pixelRatio={1}>
<Chart data={data}>
<Axis field="genre" />
<Axis field="sold" />
<Tooltip alwaysShow={true} defaultItem={data[0]} snap showCrosshairs />
<Interval x="genre" y="sold" color="genre" />
</Chart>
</Canvas>
);

const canvas = new Canvas(props);
canvas.render();

await delay(1000);
expect(context).toMatchImageSnapshot();
});

it('Tooltip 默认展示更新', async () => {
const context = createContext('Tooltip 默认展示更新');
const { props } = (
<Canvas context={context} pixelRatio={1}>
<Chart data={data}>
<Chart data={[...data]}>
<Axis field="genre" />
<Axis field="sold" />
<Legend />
Expand All @@ -190,11 +210,11 @@ describe('tooltip', () => {
</Chart>
);

canvas.update({children: newChart});
canvas.update({ children: newChart });
await delay(500);
expect(context).toMatchImageSnapshot();
});

it('Tooltip 不触发回调的情形', async () => {
const context = createContext('Tooltip 不触发回调的情形');
const onChangeMockCallback = jest.fn();
Expand Down