Skip to content
Snippets Groups Projects
Unverified Commit b30af986 authored by Aleksandr Lesnenko's avatar Aleksandr Lesnenko Committed by GitHub
Browse files

fix echarts tooltip positioning (#47202)

parent 25d30ca9
Branches
Tags
No related merge requests found
......@@ -10,9 +10,9 @@ import type { ClickObject } from "metabase-lib";
import type { BaseCartesianChartModel } from "../cartesian/model/types";
import type { PieChartModel } from "../pie/model/types";
const TOOLTIP_POINTER_MARGIN = 10;
export const TOOLTIP_POINTER_MARGIN = 10;
const getTooltipPositionFn =
export const getTooltipPositionFn =
(containerRef: React.RefObject<HTMLDivElement>) =>
(
relativePoint: [number, number],
......@@ -38,7 +38,7 @@ const getTooltipPositionFn =
if (hasRightSpace) {
tooltipAbsoluteX = mouseX + TOOLTIP_POINTER_MARGIN;
} else if (hasLeftSpace) {
tooltipAbsoluteX = mouseX - tooltipTotalHeight;
tooltipAbsoluteX = mouseX - tooltipTotalWidth;
}
let tooltipAbsoluteY = 0;
......@@ -52,9 +52,9 @@ const getTooltipPositionFn =
}
const tooltipRelativeX = tooltipAbsoluteX - containerX;
const tooltipRelativey = tooltipAbsoluteY - containerY;
const tooltipRelativeY = tooltipAbsoluteY - containerY;
return [tooltipRelativeX, tooltipRelativey];
return [tooltipRelativeX, tooltipRelativeY];
};
export const getTooltipBaseOption = (
......
......@@ -3,7 +3,11 @@ import type { EChartsType } from "echarts/core";
import type { MutableRefObject } from "react";
import _ from "underscore";
import { useCloseTooltipOnScroll } from ".";
import {
TOOLTIP_POINTER_MARGIN,
getTooltipPositionFn,
useCloseTooltipOnScroll,
} from ".";
describe("useCloseTooltipOnScroll", () => {
let chartRefMock: MutableRefObject<EChartsType | undefined>;
......@@ -46,3 +50,123 @@ describe("useCloseTooltipOnScroll", () => {
});
});
});
describe("getTooltipPositionFn", () => {
const clientWidth = 1000;
const clientHeight = 1000;
const tooltipSize: [number, number] = [100, 50];
beforeEach(() => {
Object.defineProperty(document.documentElement, "clientWidth", {
value: clientWidth,
configurable: true,
});
Object.defineProperty(document.documentElement, "clientHeight", {
value: clientHeight,
configurable: true,
});
});
afterEach(() => {
jest.restoreAllMocks();
});
const setup = (cardPosition: [number, number]) => {
const containerRef = { current: document.createElement("div") };
jest.spyOn(containerRef.current, "getBoundingClientRect").mockReturnValue({
// relevant position of a card
x: cardPosition[0],
y: cardPosition[1],
// irrelevant properties
width: 500,
height: 500,
top: 50,
right: 550,
bottom: 550,
left: 50,
toJSON: jest.fn(),
});
return getTooltipPositionFn(containerRef);
};
it("positions tooltip to the top right when there is sufficient space", () => {
const cardPosition: [number, number] = [50, 50];
const relativeMousePoint: [number, number] = [100, 100];
const getTooltipPosition = setup(cardPosition);
const relativeTooltipPosition = getTooltipPosition(
relativeMousePoint,
null,
null,
null,
{
contentSize: tooltipSize,
},
);
expect(relativeTooltipPosition).toEqual([
100 + TOOLTIP_POINTER_MARGIN, // relative tooltip left = relative mouse X + margin
50 - TOOLTIP_POINTER_MARGIN, // relative tooltip top = relative mouse Y - tooltip height - margin
]);
});
it("positions tooltip to the top left when there is no space on the right", () => {
const cardPosition: [number, number] = [500, 50];
const relativeMousePoint: [number, number] = [450, 100];
const getTooltipPosition = setup(cardPosition);
const relativeTooltipPosition = getTooltipPosition(
relativeMousePoint,
null,
null,
null,
{
contentSize: tooltipSize,
},
);
expect(relativeTooltipPosition).toEqual([
350 - TOOLTIP_POINTER_MARGIN, // relative tooltip left = relative mouse X - tooltip width - margin
50 - TOOLTIP_POINTER_MARGIN, // relative tooltip top = relative mouse Y - tooltip height - margin
]);
});
it("positions tooltip to the bottom right when there is no space on the top", () => {
const cardPosition: [number, number] = [50, 0];
const relativeMousePoint: [number, number] = [100, 50];
const getTooltipPosition = setup(cardPosition);
const relativeTooltipPosition = getTooltipPosition(
relativeMousePoint,
null,
null,
null,
{
contentSize: tooltipSize,
},
);
expect(relativeTooltipPosition).toEqual([
100 + TOOLTIP_POINTER_MARGIN, // relative tooltip left = relative mouse X + margin
50 + TOOLTIP_POINTER_MARGIN, // relative tooltip top = relative mouse Y + margin
]);
});
it("positions tooltip to the bottom left when there is no space on the top and right", () => {
const cardPosition: [number, number] = [500, 0];
const relativeMousePoint: [number, number] = [450, 50];
const getTooltipPosition = setup(cardPosition);
const relativeTooltipPosition = getTooltipPosition(
relativeMousePoint,
null,
null,
null,
{
contentSize: tooltipSize,
},
);
expect(relativeTooltipPosition).toEqual([
350 - TOOLTIP_POINTER_MARGIN, // relative tooltip left = relative mouse X - tooltip width - margin
50 + TOOLTIP_POINTER_MARGIN, // relative tooltip top = relative mouse Y + margin
]);
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment