From cb4297120183ac082e936efcd5573e778215662d Mon Sep 17 00:00:00 2001 From: bdknox Date: Mon, 5 Jun 2023 15:32:27 -0400 Subject: [PATCH] Add option for positioning tooltip for LineCanvas * Defaults to the existing behavior to be at the cursor, but optionally can be placed at the point that the data in the tooltip is representing --- packages/line/src/LineCanvas.js | 24 +++++++++++++++--- packages/line/src/props.js | 1 + website/src/data/components/line/defaults.ts | 2 ++ website/src/data/components/line/props.ts | 26 ++++++++++++++++++-- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/packages/line/src/LineCanvas.js b/packages/line/src/LineCanvas.js index d47660d152..2881b87577 100644 --- a/packages/line/src/LineCanvas.js +++ b/packages/line/src/LineCanvas.js @@ -67,6 +67,7 @@ const LineCanvas = ({ onMouseLeave, onClick, tooltip, + tooltipPosition = LineCanvasDefaultProps.tooltipPosition, canvasRef, }) => { @@ -276,7 +277,7 @@ const LineCanvas = ({ [canvasEl, margin, innerWidth, innerHeight, delaunay] ) - const { showTooltipFromEvent, hideTooltip } = useTooltip() + const { showTooltipAt, showTooltipFromEvent, hideTooltip } = useTooltip() const handleMouseHover = useCallback( event => { @@ -284,12 +285,29 @@ const LineCanvas = ({ setCurrentPoint(point) if (point) { - showTooltipFromEvent(createElement(tooltip, { point }), event) + if (tooltipPosition === 'point') { + showTooltipAt( + createElement(tooltip, { point }), + [point.x + margin.left, point.y + margin.top], + 'top' + ) + } else { + showTooltipFromEvent(createElement(tooltip, { point }), event) + } } else { hideTooltip() } }, - [getPointFromMouseEvent, setCurrentPoint, showTooltipFromEvent, hideTooltip, tooltip] + [ + getPointFromMouseEvent, + setCurrentPoint, + showTooltipAt, + showTooltipFromEvent, + hideTooltip, + tooltip, + tooltipPosition, + margin, + ] ) const handleMouseLeave = useCallback( diff --git a/packages/line/src/props.js b/packages/line/src/props.js index b2eeaa9d75..2d37be97f6 100644 --- a/packages/line/src/props.js +++ b/packages/line/src/props.js @@ -212,4 +212,5 @@ export const LineDefaultProps = { export const LineCanvasDefaultProps = { ...commonDefaultProps, pixelRatio: typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1, + tooltipPostion: 'cursor', } diff --git a/website/src/data/components/line/defaults.ts b/website/src/data/components/line/defaults.ts index 53890c6fc1..5952e8278f 100644 --- a/website/src/data/components/line/defaults.ts +++ b/website/src/data/components/line/defaults.ts @@ -89,4 +89,6 @@ export default { enableCrosshair: true, crosshairType: 'bottom-left', + + tooltipPosition: 'cursor', } diff --git a/website/src/data/components/line/props.ts b/website/src/data/components/line/props.ts index 1cf545d814..1a5b77736d 100644 --- a/website/src/data/components/line/props.ts +++ b/website/src/data/components/line/props.ts @@ -80,7 +80,7 @@ const props: ChartProperty[] = [ If you use a time scale, you must provide a time format as values are converted to Date objects. - + Under the hood, nivo uses [d3-format](https://github.com/d3/d3-format), please have a look at it for available formats, you can also pass a function which will receive the raw value and should return the formatted one. @@ -163,7 +163,7 @@ const props: ChartProperty[] = [ If you use a time scale, you must provide a time format as values are converted to Date objects. - + Under the hood, nivo uses [d3-format](https://github.com/d3/d3-format), please have a look at it for available formats, you can also pass a function which will receive the raw value and should return the formatted one. @@ -446,6 +446,28 @@ const props: ChartProperty[] = [ type: 'Function', required: false, }, + { + key: 'tooltipPosition', + flavors: ['canvas'], + group: 'Interactivity', + help: `Tooltip position when hovering`, + type: 'string', + required: false, + defaultValue: defaults.tooltipPosition, + control: { + type: 'choices', + choices: [ + { + label: 'cursor', + value: 'cursor', + }, + { + label: 'point', + value: 'point', + }, + ], + }, + }, { key: 'enableSlices', group: 'Interactivity',