Skip to content

Commit

Permalink
feat(tooltip): stickTo vertical middle of the cursor (#1163)
Browse files Browse the repository at this point in the history
The `Settings.tooltip.stickTo` prop, used to fix the tooltip movement on the free axis cursor, is enhanced with `Middle`, `Center` and `MousePosition` values. `MousePosition` is the default behavior that moves the tooltip along the free axis following the cursor position. `Middle` and `Center` can be used to fix the tooltip position in the middle of the chart respective for horizontally laid charts and the vertical ones.

fix #1108

Co-authored-by: Nick Partridge <[email protected]>
  • Loading branch information
markov00 and nickofthyme authored Jun 3, 2021
1 parent 76e8dca commit 380363b
Show file tree
Hide file tree
Showing 38 changed files with 386 additions and 481 deletions.
16 changes: 15 additions & 1 deletion api/charts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2020,12 +2020,26 @@ export type TooltipProps = TooltipPortalSettings<'chart'> & {
headerFormatter?: TooltipValueFormatter;
unit?: string;
customTooltip?: CustomTooltip;
stickTo?: Position;
stickTo?: TooltipStickTo;
};

// @public
export type TooltipSettings = TooltipType | TooltipProps;

// @public
export const TooltipStickTo: Readonly<{
Top: "top";
Bottom: "bottom";
Middle: "middle";
Left: "left";
Right: "right";
Center: "center";
MousePosition: "MousePosition";
}>;

// @public (undocumented)
export type TooltipStickTo = $Values<typeof TooltipStickTo>;

// @public
export const TooltipType: Readonly<{
VerticalCursor: "vertical";
Expand Down
20 changes: 15 additions & 5 deletions integration/server/generate/vrt_page_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ ReactDOM.render(<VRTPage />, document.getElementById('story-root') as HTMLElemen
`.trim();
}

function pageTemplate(imports, routes) {
function pageTemplate(imports, routes, urls) {
return `
import React, { Suspense } from 'react';
Expand All @@ -57,7 +57,16 @@ ${imports.join('\n')}
export function VRTPage() {
const path = new URL(window.location.toString()).searchParams.get('path');
if(!path) {
return <h1>missing url path</h1>;
return (<>
<h1>missing url path</h1>
<ul>
${urls
.map((url) => {
return `<li><a href="?path=${url}">${url.slice(7)}</a></li>`;
})
.join('\n')}
</ul>
</>);
}
return (
<Suspense fallback={<div>Loading...</div>}>
Expand All @@ -74,16 +83,17 @@ function compileVRTPage(examples) {
acc.push(...exampleFiles);
return acc;
}, []);
const { imports, routes } = flatExamples.reduce(
const { imports, routes, urls } = flatExamples.reduce(
(acc, { filePath, url }, index) => {
acc.imports.push(compileImportTemplate(index, filePath));
acc.routes.push(compileRouteTemplate(index, url));
acc.urls.push(url);
return acc;
},
{ imports: [], routes: [] },
{ imports: [], routes: [], urls: [] },
);

fs.writeFileSync(path.join('integration', 'tmp', 'vrt_page.tsx'), pageTemplate(imports, routes));
fs.writeFileSync(path.join('integration', 'tmp', 'vrt_page.tsx'), pageTemplate(imports, routes, urls));
fs.writeFileSync(path.join('integration', 'tmp', 'index.tsx'), indexTemplate());
}

Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/goal_chart/state/chart_state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,10 @@ export class GoalState implements InternalChartState {
const { position } = state.interactions.pointer.current;
return {
isRotated: false,
x1: position.x,
y1: position.y,
x: position.x,
width: 0,
y: position.y,
height: 0,
};
}

Expand Down
19 changes: 10 additions & 9 deletions src/chart_types/heatmap/state/selectors/get_tooltip_anchor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import createCachedSelector from 're-reselect';

import { TooltipAnchorPosition } from '../../../../components/tooltip/types';
import { AnchorPosition } from '../../../../components/portal/types';
import { GlobalChartState } from '../../../../state/chart_state';
import { getChartIdSelector } from '../../../../state/selectors/get_chart_id';
import { computeChartDimensionsSelector } from './compute_chart_dimensions';
Expand All @@ -32,20 +32,21 @@ function getCurrentPointerPosition(state: GlobalChartState) {
/** @internal */
export const getTooltipAnchorSelector = createCachedSelector(
[getPickedShapes, computeChartDimensionsSelector, getCurrentPointerPosition],
(shapes, chartDimensions, position): TooltipAnchorPosition => {
(shapes, chartDimensions, position): AnchorPosition => {
if (Array.isArray(shapes) && shapes.length > 0) {
const firstShape = shapes[0];
return {
isRotated: false,
x1: firstShape.x + chartDimensions.left + firstShape.width / 2,
y1: firstShape.y - chartDimensions.top + firstShape.height,
x: firstShape.x + chartDimensions.left,
width: firstShape.width,
y: firstShape.y - chartDimensions.top,
height: firstShape.height,
};
}
return {
isRotated: false,

x1: position.x,
y1: position.y,
x: position.x,
width: 0,
y: position.y,
height: 0,
};
},
)(getChartIdSelector);
6 changes: 4 additions & 2 deletions src/chart_types/partition_chart/state/chart_state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,10 @@ export class PartitionState implements InternalChartState {
const { position } = state.interactions.pointer.current;
return {
isRotated: false,
x1: position.x,
y1: position.y,
x: position.x,
width: 0,
y: position.y,
height: 0,
};
}

Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/wordcloud/state/chart_state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ export class WordcloudState implements InternalChartState {
const { position } = state.interactions.pointer.current;
return {
isRotated: false,
x1: position.x,
y1: position.y,
x: position.x,
width: 0,
y: position.y,
height: 0,
};
}

Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/xy_chart/annotations/line/tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,10 @@ describe('Annotation tooltips', () => {
isVisible: true,
annotationType: AnnotationType.Rectangle,
anchor: {
left: 18,
top: 9,
x: 18,
y: 9,
width: 0,
height: 0,
},
});
annotationRectangle.hideTooltips = true;
Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/xy_chart/annotations/rect/tooltip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ describe('Rect annotation tooltip', () => {
isVisible: true,
annotationType: AnnotationType.Rectangle,
anchor: {
top: cursorPosition.y,
left: cursorPosition.x,
x: cursorPosition.x,
y: cursorPosition.y,
width: 0,
height: 0,
},
datum: { coordinates: { x0: 0, x1: 10, y0: 0, y1: 10 } },
};
Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/xy_chart/annotations/rect/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ export function getRectAnnotationTooltipState(
isVisible: true,
annotationType: AnnotationType.Rectangle,
anchor: {
left: cursorPosition.x,
top: cursorPosition.y,
x: cursorPosition.x,
y: cursorPosition.y,
width: 0,
height: 0,
},
datum,
};
Expand Down
6 changes: 4 additions & 2 deletions src/chart_types/xy_chart/annotations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,10 @@ export interface AnnotationTooltipState {
annotationType: AnnotationType;
datum: LineAnnotationDatum | RectAnnotationDatum;
anchor: {
top: number;
left: number;
x: number;
y: number;
width: number;
height: number;
};
customTooltipDetails?: AnnotationTooltipFormatter;
customTooltip?: CustomAnnotationTooltip;
Expand Down
6 changes: 3 additions & 3 deletions src/chart_types/xy_chart/annotations/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { MockGlobalSpec } from '../../../mocks/specs';
import { Position, Rotation } from '../../../utils/common';
import { Dimensions } from '../../../utils/dimensions';
import { AnnotationDomainType } from '../utils/specs';
import { getAnnotationAxis, getTransformedCursor, invertTranformedCursor } from './utils';
import { getAnnotationAxis, getTransformedCursor, invertTransformedCursor } from './utils';

describe('Annotation utils', () => {
const groupId = 'foo-group';
Expand Down Expand Up @@ -74,7 +74,7 @@ describe('Annotation utils', () => {
};
it.each<Rotation>([0, 90, -90, 180])('Should invert rotated cursor - rotation %d', (rotation) => {
expect(
invertTranformedCursor(
invertTransformedCursor(
getTransformedCursor(cursorPosition, chartDimensions, rotation),
chartDimensions,
rotation,
Expand All @@ -84,7 +84,7 @@ describe('Annotation utils', () => {

it.each<Rotation>([0, 90, -90, 180])('Should invert rotated projected cursor - rotation %d', (rotation) => {
expect(
invertTranformedCursor(
invertTransformedCursor(
getTransformedCursor(cursorPosition, chartDimensions, rotation, true),
chartDimensions,
rotation,
Expand Down
2 changes: 1 addition & 1 deletion src/chart_types/xy_chart/annotations/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function getTransformedCursor(
}

/** @internal */
export function invertTranformedCursor(
export function invertTransformedCursor(
cursorPosition: Point,
chartDimensions: Dimensions,
chartRotation: Rotation | null,
Expand Down
Loading

0 comments on commit 380363b

Please sign in to comment.