From dcbfe730b6d6d37a6de73a27a3ad8d99a4082073 Mon Sep 17 00:00:00 2001 From: Matt Vickers Date: Wed, 3 Apr 2024 12:35:26 -0500 Subject: [PATCH] Add seriesNameFormatter to DonutChart --- packages/polaris-viz/CHANGELOG.md | 6 +++++- .../src/components/DonutChart/Chart.tsx | 4 ++++ .../src/components/DonutChart/DonutChart.tsx | 3 +++ .../components/LegendValues/LegendValues.tsx | 3 +++ .../LegendValueItem/LegendValueItem.tsx | 4 +++- .../stories/FormattedValues.stories.tsx | 16 ++++++++++++++++ .../LegendContainer/hooks/useLegend.ts | 7 +++++-- 7 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 packages/polaris-viz/src/components/DonutChart/stories/FormattedValues.stories.tsx diff --git a/packages/polaris-viz/CHANGELOG.md b/packages/polaris-viz/CHANGELOG.md index 374adcdb0..edb062894 100644 --- a/packages/polaris-viz/CHANGELOG.md +++ b/packages/polaris-viz/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - +## Unreleased + +### Added + +- Added `seriesNameFormatter` prop to `` to allow consumers to format the series name. ## [12.3.0] - 2024-04-02 diff --git a/packages/polaris-viz/src/components/DonutChart/Chart.tsx b/packages/polaris-viz/src/components/DonutChart/Chart.tsx index 71ae2731d..f955488f5 100644 --- a/packages/polaris-viz/src/components/DonutChart/Chart.tsx +++ b/packages/polaris-viz/src/components/DonutChart/Chart.tsx @@ -46,6 +46,7 @@ export interface ChartProps { data: DataSeries[]; labelFormatter: LabelFormatter; legendPosition: LegendPosition; + seriesNameFormatter: LabelFormatter; showLegend: boolean; showLegendValues: boolean; state: ChartState; @@ -77,6 +78,7 @@ export function Chart({ renderInnerValueContent, renderLegendContent, renderHiddenLegendLabel, + seriesNameFormatter, total, }: ChartProps) { const {shouldAnimate, characterWidths} = useChartContext(); @@ -108,6 +110,7 @@ export function Chart({ direction: legendDirection, colors: seriesColor, maxWidth: maxLegendWidth, + seriesNameFormatter, }); const longestLegendValueWidth = legend.reduce((previous, current) => { @@ -187,6 +190,7 @@ export function Chart({ getColorVisionEventAttrs={getColorVisionEventAttrs} dimensions={{...dimensions, x: 0, y: 0}} renderHiddenLegendLabel={renderHiddenLegendLabel} + seriesNameFormatter={seriesNameFormatter} /> ); }; diff --git a/packages/polaris-viz/src/components/DonutChart/DonutChart.tsx b/packages/polaris-viz/src/components/DonutChart/DonutChart.tsx index fc6ad2307..2f333db57 100644 --- a/packages/polaris-viz/src/components/DonutChart/DonutChart.tsx +++ b/packages/polaris-viz/src/components/DonutChart/DonutChart.tsx @@ -27,6 +27,7 @@ export type DonutChartProps = { renderInnerValueContent?: RenderInnerValueContent; renderLegendContent?: RenderLegendContent; renderHiddenLegendLabel?: RenderHiddenLegendLabel; + seriesNameFormatter?: LabelFormatter; } & ChartProps; export function DonutChart(props: DonutChartProps) { @@ -49,6 +50,7 @@ export function DonutChart(props: DonutChartProps) { renderInnerValueContent, renderLegendContent, renderHiddenLegendLabel, + seriesNameFormatter = (value) => `${value}`, } = { ...DEFAULT_CHART_PROPS, ...props, @@ -76,6 +78,7 @@ export function DonutChart(props: DonutChartProps) { renderInnerValueContent={renderInnerValueContent} renderLegendContent={renderLegendContent} renderHiddenLegendLabel={renderHiddenLegendLabel} + seriesNameFormatter={seriesNameFormatter} theme={theme} /> diff --git a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx index c5c9a9ceb..7a5f9c9dc 100644 --- a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx +++ b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx @@ -28,6 +28,7 @@ interface LegendContentProps { renderHiddenLegendLabel?: RenderHiddenLegendLabel; getColorVisionStyles: ColorVisionInteractionMethods['getColorVisionStyles']; getColorVisionEventAttrs: ColorVisionInteractionMethods['getColorVisionEventAttrs']; + seriesNameFormatter: LabelFormatter; } export function LegendValues({ @@ -39,6 +40,7 @@ export function LegendValues({ getColorVisionStyles, getColorVisionEventAttrs, dimensions, + seriesNameFormatter, }: LegendContentProps) { const selectedTheme = useTheme(); const {theme} = useChartContext(); @@ -95,6 +97,7 @@ export function LegendValues({ longestLegendValueWidth={longestLegendValueWidth} maxTrendIndicatorWidth={maxTrendIndicatorWidth} seriesColors={seriesColors} + seriesNameFormatter={seriesNameFormatter} onDimensionChange={(dimensions) => { if (legendItemDimensions.current) { legendItemDimensions.current[index] = dimensions; diff --git a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.tsx b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.tsx index 102b68767..761f28c9d 100644 --- a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.tsx +++ b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.tsx @@ -23,6 +23,7 @@ interface Props { labelFormatter: LabelFormatter; longestLegendValueWidth: number; seriesColors: Color[]; + seriesNameFormatter: LabelFormatter; maxTrendIndicatorWidth: number; onDimensionChange: (dimensions: Dimensions) => void; getColorVisionStyles: ColorVisionInteractionMethods['getColorVisionStyles']; @@ -37,6 +38,7 @@ export function LegendValueItem({ longestLegendValueWidth, trend, seriesColors, + seriesNameFormatter, maxTrendIndicatorWidth, onDimensionChange, getColorVisionStyles, @@ -77,7 +79,7 @@ export function LegendValueItem({ }} title={name} > - {name} + {seriesNameFormatter(name)} diff --git a/packages/polaris-viz/src/components/DonutChart/stories/FormattedValues.stories.tsx b/packages/polaris-viz/src/components/DonutChart/stories/FormattedValues.stories.tsx new file mode 100644 index 000000000..27a0a3d98 --- /dev/null +++ b/packages/polaris-viz/src/components/DonutChart/stories/FormattedValues.stories.tsx @@ -0,0 +1,16 @@ +import type {Story} from '@storybook/react'; + +import type {DonutChartProps} from '../DonutChart'; + +import {DEFAULT_DATA, DEFAULT_PROPS, Template} from './data'; + +export {META as default} from './meta'; + +export const FormattedValues: Story = Template.bind({}); + +FormattedValues.args = { + ...DEFAULT_PROPS, + data: DEFAULT_DATA, + labelFormatter: (value) => `$${value}`, + seriesNameFormatter: (value) => `Name: ${value}`, +}; diff --git a/packages/polaris-viz/src/components/LegendContainer/hooks/useLegend.ts b/packages/polaris-viz/src/components/LegendContainer/hooks/useLegend.ts index 4ddbe4b54..4a0d792f4 100644 --- a/packages/polaris-viz/src/components/LegendContainer/hooks/useLegend.ts +++ b/packages/polaris-viz/src/components/LegendContainer/hooks/useLegend.ts @@ -4,6 +4,7 @@ import type { Dimensions, DataGroup, Direction, + LabelFormatter, } from '@shopify/polaris-viz-core'; import {LEGENDS_TOP_MARGIN} from '@shopify/polaris-viz-core'; @@ -32,6 +33,7 @@ export interface Props { dimensions?: Dimensions; direction?: Direction; maxWidth?: number; + seriesNameFormatter?: LabelFormatter; } export function useLegend({ @@ -41,6 +43,7 @@ export function useLegend({ showLegend, direction = 'horizontal', maxWidth = 0, + seriesNameFormatter = (value) => `${value}`, }: Props) { const defaultHeight = showLegend ? DEFAULT_LEGEND_HEIGHT : 0; @@ -57,7 +60,7 @@ export function useLegend({ const legends = data.map(({series, shape}) => { return series.map(({name, color, isComparison, data, metadata}) => { return { - name: name ?? '', + name: seriesNameFormatter(name ?? ''), ...(data && { value: data .reduce((totalSum, current) => totalSum + (current.value || 0), 0) @@ -77,7 +80,7 @@ export function useLegend({ color: color ?? colors[index], }; }); - }, [colors, data, showLegend]); + }, [colors, data, seriesNameFormatter, showLegend]); const {height, width} = useMemo(() => { if (showLegend === false) {