From 4d78fdc33be072ca178c6706d4c0030beb174498 Mon Sep 17 00:00:00 2001 From: Emma Cunningham Date: Fri, 2 Aug 2019 07:04:18 -0700 Subject: [PATCH] fix: disable tooltip when details or custom content is null (#280) --- .../xy_chart/annotations/annotation_utils.ts | 5 +- src/chart_types/xy_chart/utils/specs.ts | 3 +- src/components/annotation_tooltips.tsx | 13 ++++- src/index.ts | 1 + stories/annotations.tsx | 56 +++++++++++++++++++ 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/chart_types/xy_chart/annotations/annotation_utils.ts b/src/chart_types/xy_chart/annotations/annotation_utils.ts index 56f802336f..a73ca3b75c 100644 --- a/src/chart_types/xy_chart/annotations/annotation_utils.ts +++ b/src/chart_types/xy_chart/annotations/annotation_utils.ts @@ -23,6 +23,7 @@ import { Scale, ScaleType } from '../../../utils/scales/scales'; import { Point } from '../store/chart_state'; import { computeXScaleOffset, getAxesSpecForSpecId, isHorizontalRotation } from '../store/utils'; +export type AnnotationTooltipFormatter = (details?: string) => JSX.Element | null; export interface AnnotationTooltipState { annotationType: AnnotationType; isVisible: boolean; @@ -31,7 +32,7 @@ export interface AnnotationTooltipState { transform: string; top?: number; left?: number; - renderTooltip?: (details?: string) => JSX.Element; + renderTooltip?: AnnotationTooltipFormatter; } export interface AnnotationDetails { headerText?: string; @@ -925,7 +926,7 @@ export function computeRectAnnotationTooltipState( annotationRects: AnnotationRectProps[], chartRotation: Rotation, chartDimensions: Dimensions, - renderTooltip?: (details?: string) => JSX.Element, + renderTooltip?: AnnotationTooltipFormatter, ): AnnotationTooltipState { const cursorPosition = getRotatedCursor(rawCursorPosition, chartDimensions, chartRotation); diff --git a/src/chart_types/xy_chart/utils/specs.ts b/src/chart_types/xy_chart/utils/specs.ts index 578298fd2b..7c0bf94639 100644 --- a/src/chart_types/xy_chart/utils/specs.ts +++ b/src/chart_types/xy_chart/utils/specs.ts @@ -11,6 +11,7 @@ import { Omit, RecursivePartial } from '../../../utils/commons'; import { AnnotationId, AxisId, GroupId, SpecId } from '../../../utils/ids'; import { ScaleContinuousType, ScaleType } from '../../../utils/scales/scales'; import { CurveType } from '../../../utils/curves'; +import { AnnotationTooltipFormatter } from '../annotations/annotation_utils'; import { DataSeriesColorsValues } from './series'; export type Datum = any; @@ -313,7 +314,7 @@ export interface RectAnnotationDatum { export type RectAnnotationSpec = BaseAnnotationSpec & { annotationType: 'rectangle'; /** Custom rendering function for tooltip */ - renderTooltip?: (details?: string) => JSX.Element; + renderTooltip?: AnnotationTooltipFormatter; /** Data values defined with coordinates and details */ dataValues: RectAnnotationDatum[]; /** Custom annotation style */ diff --git a/src/components/annotation_tooltips.tsx b/src/components/annotation_tooltips.tsx index 7d3255f153..97b12de29e 100644 --- a/src/components/annotation_tooltips.tsx +++ b/src/components/annotation_tooltips.tsx @@ -2,7 +2,11 @@ import { inject, observer } from 'mobx-react'; import React from 'react'; import { isLineAnnotation } from '../chart_types/xy_chart/utils/specs'; import { AnnotationId } from '../utils/ids'; -import { AnnotationDimensions, AnnotationLineProps } from '../chart_types/xy_chart/annotations/annotation_utils'; +import { + AnnotationDimensions, + AnnotationLineProps, + AnnotationTooltipFormatter, +} from '../chart_types/xy_chart/annotations/annotation_utils'; import { ChartStore } from '../chart_types/xy_chart/store/chart_state'; interface AnnotationTooltipProps { @@ -114,10 +118,15 @@ export const AnnotationTooltip = inject('chartStore')(observer(AnnotationTooltip function RectAnnotationTooltip(props: { details?: string; position: { transform: string; top: number; left: number }; - customTooltip?: (details?: string) => JSX.Element; + customTooltip?: AnnotationTooltipFormatter; }) { const { details, position, customTooltip } = props; const tooltipContent = customTooltip ? customTooltip(details) : details; + + if (!tooltipContent) { + return null; + } + return (
diff --git a/src/index.ts b/src/index.ts index b3e2e58275..fdb5ab6bbf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,3 +25,4 @@ export { RectAnnotationSpec, } from './chart_types/xy_chart/utils/specs'; export { GeometryValue } from './chart_types/xy_chart/rendering/rendering'; +export { AnnotationTooltipFormatter } from './chart_types/xy_chart/annotations/annotation_utils'; diff --git a/stories/annotations.tsx b/stories/annotations.tsx index fef1d469f2..85cd15acf4 100644 --- a/stories/annotations.tsx +++ b/stories/annotations.tsx @@ -3,6 +3,7 @@ import { storiesOf } from '@storybook/react'; import React from 'react'; import { AnnotationDomainTypes, + AnnotationTooltipFormatter, Axis, BarSeries, Chart, @@ -607,4 +608,59 @@ storiesOf('Annotations', module) /> ); + }) + .add('[rect] tooltip visibility dependent on content', () => { + const tooltipOptions = { + 'default formatter, details defined': 'default_defined', + 'default formatter, details undefined': 'default_undefined', + 'custom formatter, return element': 'custom_element', + 'custom formatter, return null': 'custom_null', + }; + + const tooltipFormat = select('tooltip format', tooltipOptions, 'default_defined'); + + const isDefaultDefined = tooltipFormat === 'default_defined'; + + const dataValues = [ + { + coordinates: { + x0: 0, + x1: 1, + y0: 0, + y1: 7, + }, + details: isDefaultDefined ? 'foo' : undefined, + }, + ]; + + const isCustomTooltipElement = tooltipFormat === 'custom_element'; + const tooltipFormatter: AnnotationTooltipFormatter = () => { + if (!isCustomTooltipElement) { + return null; + } + + return
{'custom formatter'}
; + }; + + const isCustomTooltip = tooltipFormat.includes('custom'); + + return ( + + + + + + + ); });