Skip to content

Commit

Permalink
fix: TooltipTriggerArea fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 committed Sep 24, 2023
1 parent 2e8bf02 commit e0a7754
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 26 deletions.
7 changes: 6 additions & 1 deletion src/plugins/d3/examples/scatter/Basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ export const Basic = () => {
},
tooltip: {
renderer: (d) => {
const point = d.hovered.data as ScatterSeriesData;
const point = d.hovered[0]?.data as ScatterSeriesData;

if (!point) {
return null;
}

const title = point.custom.title;
const score = point.custom.user_score;
const date = dateTime({input: point.custom.date}).format('DD MMM YYYY');
Expand Down
1 change: 0 additions & 1 deletion src/plugins/d3/renderer/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ export const Chart = (props: Props) => {
offsetTop={top}
shapesData={shapesData}
svgContainer={svgRef.current}
xScale={xScale}
/>
)}
</g>
Expand Down
41 changes: 18 additions & 23 deletions src/plugins/d3/renderer/components/Tooltip/TooltipTriggerArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import throttle from 'lodash/throttle';
import {bisector, pointer, sort} from 'd3';
import type {Dispatch} from 'd3';

import type {ChartScale, ShapeData, PreparedBarXData, PointerPosition} from '../../hooks';
import type {ShapeData, PreparedBarXData, PointerPosition} from '../../hooks';

type Args = {
boundsWidth: number;
Expand All @@ -13,7 +13,6 @@ type Args = {
offsetLeft: number;
shapesData: ShapeData[];
svgContainer: SVGSVGElement | null;
xScale?: ChartScale;
};

type CalculationType = 'x-primary' | 'none';
Expand All @@ -32,16 +31,8 @@ const getCalculationType = (shapesData: ShapeData[]): CalculationType => {
};

export const TooltipTriggerArea = (args: Args) => {
const {
boundsWidth,
boundsHeight,
dispatcher,
offsetTop,
offsetLeft,
shapesData,
svgContainer,
xScale,
} = args;
const {boundsWidth, boundsHeight, dispatcher, offsetTop, offsetLeft, shapesData, svgContainer} =
args;
const rectRef = React.useRef<SVGRectElement>(null);
const calculationType = React.useMemo(() => {
return getCalculationType(shapesData);
Expand All @@ -54,9 +45,9 @@ export const TooltipTriggerArea = (args: Args) => {

const handleXprimaryMouseMove: React.MouseEventHandler<SVGRectElement> = (e) => {
const {left, top} = rectRef.current?.getBoundingClientRect() || {left: 0, top: 0};
const [x, y] = pointer(e, svgContainer);
const isXLinearOrTimeScale = xScale && 'invert' in xScale;
const xPosition = x - left - (isXLinearOrTimeScale ? 0 : offsetLeft);
const [pointerX, pointerY] = pointer(e, svgContainer);
const barWidthOffset = (shapesData[0] as PreparedBarXData).width / 2;
const xPosition = pointerX - left - barWidthOffset;
const xDataIndex = bisector((d) => d).center(xData, xPosition);
const xNodes = Array.from(
rectRef.current?.parentElement?.querySelectorAll(`[x="${xData[xDataIndex]}"]`) || [],
Expand All @@ -67,18 +58,22 @@ export const TooltipTriggerArea = (args: Args) => {
if (xNodes.length === 1 && isNodeContainsData(xNodes[0])) {
hoverShapeData = [xNodes[0].__data__];
} else if (xNodes.length > 1 && xNodes.every(isNodeContainsData)) {
const yData = xNodes.map((node) => (node.__data__ as PreparedBarXData).y);
const yPosition = y - top;
const yDataIndex = bisector((d) => d).center(yData, yPosition);

if (xNodes[yDataIndex]) {
xNodes.reverse();
hoverShapeData = [xNodes[yDataIndex].__data__];
const yPosition = pointerY - top;
const xyNode = xNodes.find((node, i) => {
const {y, height} = node.__data__ as PreparedBarXData;
if (i === xNodes.length - 1) {
return yPosition <= y + height;
}
return yPosition >= y && yPosition <= y + height;
});

if (xyNode) {
hoverShapeData = [xyNode.__data__];
}
}

if (hoverShapeData) {
const position: PointerPosition = [x - offsetLeft, y - offsetTop];
const position: PointerPosition = [pointerX - offsetLeft, pointerY - offsetTop];
dispatcher.call('hover-shape', e.target, hoverShapeData, position);
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/types/widget-data/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ export type TooltipDataChunk<T = any> =
export type ChartKitWidgetTooltip<T = any> = {
enabled?: boolean;
/** Specifies the renderer for the tooltip. If returned null default tooltip renderer will be used. */
renderer?: (args: {hovered: TooltipDataChunk<T>[]}) => React.ReactElement;
renderer?: (args: {hovered: TooltipDataChunk<T>[]}) => React.ReactElement | null;
};

0 comments on commit e0a7754

Please sign in to comment.