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

feat: 图表点击事件支持tooltip的position显示 #372

Merged
merged 3 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions src/area/demos/Area.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const AreaStackArgs = {
showCrosshairs: true,
enterable: true,
render: (options: any) => {
console.log(options.triggerInfo);
const title = options.data?.[0]?.data?.tm || options.title;
return <InfoCard {...options} title={title} />;
},
Expand Down
37 changes: 35 additions & 2 deletions src/hooks/useInterceptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,29 @@ export interface Interceptor {
bindElementEvents: (chart: Chart, options?: InterceptorOptions) => void;
}

export interface TriggerInfo {
x?: number;
y?: number;
clientX?: number;
clientY?: number;
tipX?: number;
tipY?: number;
type?: string;
}

const useInterceptors = () => {
const triggerActionRef: MutableRefObject<string> = useRef('');
const chartRef: MutableRefObject<Chart | null> = useRef(null);
const tooltipRef = useRef<HTMLDivElement | null>();
const triggerEventRef = useRef<TriggerInfo | null>();

const getTrigger = useCallback(() => triggerActionRef.current, [triggerActionRef]);
const getTrigger = useCallback(
(): TriggerInfo => ({
type: triggerActionRef.current,
...(triggerEventRef.current || {}),
}),
[triggerActionRef]
);
/* istanbul ignore next */
const setTrigger = useCallback(
(trigger) => {
Expand All @@ -34,6 +51,19 @@ const useInterceptors = () => {
const [, updated] = useState(0);

const interceptors: Interceptor = useMemo(() => {
const setPosition = (e: Event) => {
const position: TriggerInfo = {
x: e.x,
y: e.y,
clientX: e.clientX,
clientY: e.clientY,
};
const top = +String(tooltipRef.current?.style?.top).replace('px', '') || 0;
const left = +String(tooltipRef.current?.style?.left).replace('px', '') || 0;
position.tipX = (position.clientX || 0) - ((position.x || 0) - left);
position.tipY = (position.clientY || 0) - (position.y || 0) + top;
triggerEventRef.current = position;
};
return {
bindTooltip(r: any) {
tooltipRef.current = r?.current;
Expand All @@ -60,15 +90,18 @@ const useInterceptors = () => {
tooltipRef.current.style.left = `${revisedOffsetX}px`;
}
}
setPosition(event);
triggerActionRef.current = 'click';
chart.lockTooltip();
updated(new Date().getTime());
});
chart.on('element:mouseover', () => {
chart.on('element:mouseover', (event: Event) => {
// setPosition(event);
triggerActionRef.current = 'mouseover';
});
chart.on('element:mouseout', (e: Event) => {
triggerActionRef.current = 'mouseover';
triggerEventRef.current = undefined;
if (!e.event.relatedTarget) {
chart.unlockTooltip();
updated(new Date().getTime());
Expand Down
16 changes: 11 additions & 5 deletions src/info-card/InfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { InfoCardData } from './InfoCardBox';
import Item from './Item';

import './styles/infocard.less';
import { TriggerInfo } from '../hooks/useInterceptors';

export interface InfoCardProps {
title: string;
Expand All @@ -12,17 +13,22 @@ export interface InfoCardProps {
forwardKey: string;
valueKey: string;
formatter?: (value: string | number) => string | number;
trigger?: string;
triggerInfo?: TriggerInfo;
config?: ChartConfig;
injectComponent?: (options: { data: LooseObject; trigger?: string; forwardKey: string }) => JSX.Element;
injectComponent?: (options: {
data: LooseObject;
trigger?: string;
triggerInfo?: TriggerInfo;
forwardKey: string;
}) => JSX.Element;
}

const InfoCard = (props: InfoCardProps) => {
const {
title,
subTitle,
data = [],
trigger,
triggerInfo,
forwardKey,
valueKey,
config,
Expand All @@ -37,7 +43,7 @@ const InfoCard = (props: InfoCardProps) => {
return (
<>
{renderTooltip ? (
renderTooltip({ title, data, trigger, forwardKey, formatter })
renderTooltip({ title, data, trigger: triggerInfo?.type, triggerInfo, forwardKey, formatter })
) : (
<div data-testid="infoCard" key="default-infocard">
{title && (
Expand All @@ -62,7 +68,7 @@ const InfoCard = (props: InfoCardProps) => {
</div>
))}
</div>
{injectComponent?.({ data, trigger, forwardKey })}
{injectComponent?.({ data, trigger: triggerInfo?.type, triggerInfo, forwardKey })}
</div>
)}
</>
Expand Down
8 changes: 5 additions & 3 deletions src/info-card/InfoCardBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { TooltipItem } from '@antv/g2/lib/interface';
import { LegendObject } from '../legends/useLegends';
import { getShapeConfig } from '../utils/tools/shapeConfig';
import { getAxisFields } from '../utils/frameworks/axis';
import { TriggerInfo } from '../hooks/useInterceptors';

export interface TriggerItem extends Omit<TooltipItem, 'color'> {
title?: string;
Expand All @@ -30,7 +31,7 @@ export interface InfoCardData extends Legend {

export interface InfoCardProps {
legendObject: LegendObject;
getTrigger?: () => string;
getTrigger?: () => TriggerInfo;
// triggerItems: TriggerItem[];
acceptor: any;
options: ChartOptions;
Expand All @@ -53,7 +54,7 @@ const InfoCardBox = (props: InfoCardProps) => {

const [, update] = useState(0);

const trigger = getTrigger?.();
const triggerInfo = getTrigger?.();

/* istanbul ignore next */
const onMouseLeave = () => {
Expand Down Expand Up @@ -117,6 +118,7 @@ const InfoCardBox = (props: InfoCardProps) => {
setItems(covertItems);
});
}, [acceptor, chartType, nameKey, legendObject, options, config, setHoverItemD]);
console.log(getTrigger?.());

// Though it will run many times when items are changed.
// That is expected to update items, it seams it's better to direct use without useEffect.
Expand All @@ -130,7 +132,7 @@ const InfoCardBox = (props: InfoCardProps) => {
<InfoCard
title={title}
data={items}
trigger={trigger}
triggerInfo={triggerInfo}
forwardKey={forwardKey}
valueKey={valueKey}
config={config}
Expand Down
Loading