diff --git a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-goal-alpha-gauge-with-target-visually-looks-correct-1-snap.png b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-goal-alpha-gauge-with-target-visually-looks-correct-1-snap.png index eee2232f88d..3f6346b80b8 100644 Binary files a/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-goal-alpha-gauge-with-target-visually-looks-correct-1-snap.png and b/integration/tests/__image_snapshots__/all-test-ts-baseline-visual-tests-for-all-stories-goal-alpha-gauge-with-target-visually-looks-correct-1-snap.png differ diff --git "a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-max-offset-to-3-2-\317\200-1-snap.png" "b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-max-offset-to-3-2-\317\200-1-snap.png" index bff39934913..21900ee79d2 100644 Binary files "a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-max-offset-to-3-2-\317\200-1-snap.png" and "b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-max-offset-to-3-2-\317\200-1-snap.png" differ diff --git "a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-min-offset-to-\317\200-2-1-snap.png" "b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-min-offset-to-\317\200-2-1-snap.png" index 6f481b498fd..f1be92b2d2b 100644 Binary files "a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-min-offset-to-\317\200-2-1-snap.png" and "b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-limit-min-offset-to-\317\200-2-1-snap.png" differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-render-goal-with-asymetric-angle-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-render-goal-with-asymetric-angle-1-snap.png index 15f84a6d4fc..40c11b5ecb4 100644 Binary files a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-render-goal-with-asymetric-angle-1-snap.png and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-render-goal-with-asymetric-angle-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-show-custom-value-formatter-in-tooltip-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-show-custom-value-formatter-in-tooltip-1-snap.png new file mode 100644 index 00000000000..ba0ce2ea046 Binary files /dev/null and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-sagitta-offset-should-show-custom-value-formatter-in-tooltip-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-dark-should-render-gauge-with-target-story-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-dark-should-render-gauge-with-target-story-1-snap.png index 8f0d0d601b7..fd1ff32da0a 100644 Binary files a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-dark-should-render-gauge-with-target-story-1-snap.png and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-dark-should-render-gauge-with-target-story-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-dark-should-render-gauge-with-target-story-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-dark-should-render-gauge-with-target-story-1-snap.png index 484b95600d5..ccbf5bfaed8 100644 Binary files a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-dark-should-render-gauge-with-target-story-1-snap.png and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-dark-should-render-gauge-with-target-story-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-light-should-render-gauge-with-target-story-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-light-should-render-gauge-with-target-story-1-snap.png index ccf1633d5aa..85d585561df 100644 Binary files a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-light-should-render-gauge-with-target-story-1-snap.png and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-eui-light-should-render-gauge-with-target-story-1-snap.png differ diff --git a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-light-should-render-gauge-with-target-story-1-snap.png b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-light-should-render-gauge-with-target-story-1-snap.png index eee2232f88d..3f6346b80b8 100644 Binary files a/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-light-should-render-gauge-with-target-story-1-snap.png and b/integration/tests/__image_snapshots__/goal-stories-test-ts-goal-stories-theme-light-should-render-gauge-with-target-story-1-snap.png differ diff --git a/integration/tests/goal_stories.test.ts b/integration/tests/goal_stories.test.ts index bb0c13dac99..09ecc746431 100644 --- a/integration/tests/goal_stories.test.ts +++ b/integration/tests/goal_stories.test.ts @@ -42,6 +42,13 @@ describe('Goal stories', () => { 'http://localhost:9001/?path=/story/goal-alpha--gauge-with-target&knob-angleStart (n * π/8)=11&knob-angleEnd (n * π/8)=-3', ); }); + + it('should show custom value formatter in tooltip', async () => { + await common.expectChartWithMouseAtUrlToMatchScreenshot( + 'http://localhost:9001/?path=/story/goal-alpha--gauge-with-target&knob-test tooltip value formatter=true', + { right: 245, bottom: 120 }, + ); + }); }); eachTheme.describe((_, params) => { diff --git a/packages/charts/api/charts.api.md b/packages/charts/api/charts.api.md index c9550997542..bb7f72cfc3f 100644 --- a/packages/charts/api/charts.api.md +++ b/packages/charts/api/charts.api.md @@ -980,6 +980,8 @@ export interface GoalSpec extends Spec { ticks: number[]; // (undocumented) tickValueFormatter: GoalLabelAccessor; + // (undocumented) + tooltipValueFormatter: ValueFormatter; } // @public (undocumented) diff --git a/packages/charts/src/chart_types/goal_chart/layout/types/viewmodel_types.ts b/packages/charts/src/chart_types/goal_chart/layout/types/viewmodel_types.ts index 07829c5d553..a84b195e6a9 100644 --- a/packages/charts/src/chart_types/goal_chart/layout/types/viewmodel_types.ts +++ b/packages/charts/src/chart_types/goal_chart/layout/types/viewmodel_types.ts @@ -9,9 +9,10 @@ import { getGreensColorScale } from '../../../../common/color_library_wrappers'; import { Pixels, PointObject } from '../../../../common/geometry'; import { SpecType } from '../../../../specs/constants'; +import { ValueFormatter } from '../../../../utils/common'; import { LIGHT_THEME } from '../../../../utils/themes/light_theme'; import { Theme } from '../../../../utils/themes/theme'; -import { BandFillColorAccessorInput } from '../../specs'; +import { BandFillColorAccessorInput, GoalLabelAccessor } from '../../specs'; import { GoalSubtype } from '../../specs/constants'; /** @internal */ @@ -36,7 +37,7 @@ export interface BulletViewModel { ticks: Array; labelMajor: string; labelMinor: string; - centralMajor: string; + centralMajor: string | GoalLabelAccessor; centralMinor: string; highestValue: number; lowestValue: number; @@ -44,6 +45,7 @@ export interface BulletViewModel { belowBaseCount: number; angleStart: number; angleEnd: number; + tooltipValueFormatter: ValueFormatter; } /** @internal */ @@ -80,6 +82,7 @@ export const defaultGoalSpec = { bandLabels: [], angleStart: Math.PI + Math.PI / 4, angleEnd: -Math.PI / 4, + tooltipValueFormatter: (value: number) => String(value), }; /** @internal */ @@ -97,6 +100,7 @@ export const nullGoalViewModel = { belowBaseCount: 0, angleStart: 0, angleEnd: 0, + tooltipValueFormatter: () => '', }; /** @internal */ diff --git a/packages/charts/src/chart_types/goal_chart/layout/viewmodel/viewmodel.ts b/packages/charts/src/chart_types/goal_chart/layout/viewmodel/viewmodel.ts index 7cf8b1531a8..68ad0462f10 100644 --- a/packages/charts/src/chart_types/goal_chart/layout/viewmodel/viewmodel.ts +++ b/packages/charts/src/chart_types/goal_chart/layout/viewmodel/viewmodel.ts @@ -39,7 +39,6 @@ export function shapeViewModel(spec: GoalSpec, theme: Theme, chartDimensions: Di angleStart, angleEnd, } = spec; - const [lowestValue, highestValue] = [base, ...(target ? [target] : []), actual, ...bands, ...ticks].reduce( ([min, max], value) => [Math.min(min, value), Math.max(max, value)], [Infinity, -Infinity], @@ -84,6 +83,7 @@ export function shapeViewModel(spec: GoalSpec, theme: Theme, chartDimensions: Di belowBaseCount, angleStart, angleEnd, + tooltipValueFormatter: () => '', }; const pickQuads: PickFunction = (x, y) => diff --git a/packages/charts/src/chart_types/goal_chart/specs/index.ts b/packages/charts/src/chart_types/goal_chart/specs/index.ts index adc3b8c216c..e6ba4c4c796 100644 --- a/packages/charts/src/chart_types/goal_chart/specs/index.ts +++ b/packages/charts/src/chart_types/goal_chart/specs/index.ts @@ -13,7 +13,7 @@ import { Color } from '../../../common/colors'; import { Spec } from '../../../specs'; import { SpecType } from '../../../specs/constants'; import { getConnect, specComponentFactory } from '../../../state/spec_factory'; -import { LabelAccessor } from '../../../utils/common'; +import { LabelAccessor, ValueFormatter } from '../../../utils/common'; import { defaultGoalSpec } from '../layout/types/viewmodel_types'; import { GoalSubtype } from './constants'; @@ -59,6 +59,7 @@ export interface GoalSpec extends Spec { angleStart: number; angleEnd: number; bandLabels: string[]; + tooltipValueFormatter: ValueFormatter; } type SpecRequiredProps = Pick; @@ -84,5 +85,6 @@ export const Goal: React.FunctionComponent(defaultProps), ); diff --git a/packages/charts/src/chart_types/goal_chart/state/selectors/tooltip.ts b/packages/charts/src/chart_types/goal_chart/state/selectors/tooltip.ts index 306c5effee8..cf2727c5d28 100644 --- a/packages/charts/src/chart_types/goal_chart/state/selectors/tooltip.ts +++ b/packages/charts/src/chart_types/goal_chart/state/selectors/tooltip.ts @@ -30,6 +30,7 @@ export const getTooltipInfoSelector = createCustomCachedSelector( if (!spec) { return EMPTY_TOOLTIP; } + const { tooltipValueFormatter, id } = spec; const tooltipInfo: TooltipInfo = { header: null, @@ -43,11 +44,11 @@ export const getTooltipInfoSelector = createCustomCachedSelector( isHighlighted: false, isVisible: true, seriesIdentifier: { - specId: spec.id, - key: spec.id, + specId: id, + key: id, }, value, - formattedValue: `${value}`, + formattedValue: tooltipValueFormatter(value), datum: value, }); }); diff --git a/packages/charts/src/components/accessibility/types.tsx b/packages/charts/src/components/accessibility/types.tsx index a7967aeb264..99e90ba07be 100644 --- a/packages/charts/src/components/accessibility/types.tsx +++ b/packages/charts/src/components/accessibility/types.tsx @@ -31,7 +31,7 @@ export function ScreenReaderTypes({
Chart type:
{chartTypeDescription}
- {validGoalChart && goalChartData ? ( + {validGoalChart && goalChartData && !isNaN(goalChartData.maximum) ? ( <>
Minimum:
{goalChartData.minimum}
diff --git a/storybook/stories/goal/2_gauge_with_target.story.tsx b/storybook/stories/goal/2_gauge_with_target.story.tsx index f10369f9a70..745d3041719 100644 --- a/storybook/stories/goal/2_gauge_with_target.story.tsx +++ b/storybook/stories/goal/2_gauge_with_target.story.tsx @@ -70,10 +70,11 @@ export const Example = () => { bandFillColor={useColors ? ({ value }: BandFillColorAccessorInput) => bandFillColor(value) : undefined} labelMajor="Revenue 2020 YTD " labelMinor="(thousand USD) " - centralMajor={`${actual}`} + centralMajor={() => `$${actual}k USD`} centralMinor="" angleStart={angleStart} angleEnd={angleEnd} + tooltipValueFormatter={(d) => `$${d}k USD`} /> );