diff --git a/packages/polaris-viz/CHANGELOG.md b/packages/polaris-viz/CHANGELOG.md index 4ce2a1c948..91e7aeaaf4 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 + +### Changed + +- Limit `` legends from taking up more than 50% of the chart width. ## [12.2.2] - 2024-04-01 diff --git a/packages/polaris-viz/src/components/DonutChart/Chart.tsx b/packages/polaris-viz/src/components/DonutChart/Chart.tsx index 8936f62d52..71ae2731df 100644 --- a/packages/polaris-viz/src/components/DonutChart/Chart.tsx +++ b/packages/polaris-viz/src/components/DonutChart/Chart.tsx @@ -7,6 +7,7 @@ import { useUniqueId, ChartState, useChartContext, + estimateStringWidth, } from '@shopify/polaris-viz-core'; import type { DataPoint, @@ -17,7 +18,6 @@ import type { } from '@shopify/polaris-viz-core'; import {getContainerAlignmentForLegend} from '../../utilities'; -import {estimateLegendItemWidth} from '../Legend'; import type {ComparisonMetricProps} from '../ComparisonMetric'; import {LegendContainer, useLegend} from '../../components/LegendContainer'; import { @@ -40,7 +40,6 @@ import {InnerValue, LegendValues} from './components'; const ERROR_ANIMATION_PADDING = 40; const FULL_CIRCLE = Math.PI * 2; -const MAX_LEGEND_WIDTH_PERCENTAGE = 0.35; const RADIUS_PADDING = 20; export interface ChartProps { @@ -98,28 +97,8 @@ export function Chart({ ? 'vertical' : 'horizontal'; - const longestLegendWidth = data.reduce((previous, current) => { - const estimatedLegendWidth = estimateLegendItemWidth( - showLegendValues === true - ? `${current.name ?? ''} ${current.data[0].value}` - : `${current.name ?? ''}`, - characterWidths, - ); - - if (estimatedLegendWidth > previous) { - return estimatedLegendWidth; - } - - return previous; - }, 0); - const maxLegendWidth = - legendDirection === 'vertical' - ? Math.max( - longestLegendWidth, - dimensions.width * MAX_LEGEND_WIDTH_PERCENTAGE, - ) - : 0; + legendDirection === 'vertical' ? dimensions.width / 2 : 0; const {height, width, legend, setLegendDimensions, isLegendMounted} = useLegend({ @@ -131,6 +110,19 @@ export function Chart({ maxWidth: maxLegendWidth, }); + const longestLegendValueWidth = legend.reduce((previous, current) => { + const estimatedLegendWidth = estimateStringWidth( + `${labelFormatter(`${current.value || ''}`)}`, + characterWidths, + ); + + if (estimatedLegendWidth > previous) { + return estimatedLegendWidth; + } + + return previous; + }, 0); + const shouldUseColorVisionEvents = Boolean( width && height && isLegendMounted, ); @@ -147,7 +139,10 @@ export function Chart({ }, }); - if (!width || !height) return null; + if (!width || !height) { + return null; + } + const diameter = Math.min(height, width); const radius = diameter / 2; @@ -187,6 +182,7 @@ export function Chart({ data={data} activeIndex={activeIndex} labelFormatter={labelFormatter} + longestLegendValueWidth={longestLegendValueWidth} getColorVisionStyles={getColorVisionStyles} getColorVisionEventAttrs={getColorVisionEventAttrs} dimensions={{...dimensions, x: 0, y: 0}} diff --git a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.scss b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.scss index 1768cf3c1c..b435b0c60f 100644 --- a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.scss +++ b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.scss @@ -2,4 +2,5 @@ width: 100%; border-collapse: separate; border-spacing: 0 10px; + table-layout: fixed; } 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 61f1fa0a84..c5c9a9ceb7 100644 --- a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx +++ b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/LegendValues.tsx @@ -24,6 +24,7 @@ interface LegendContentProps { activeIndex: number; dimensions: BoundingRect; labelFormatter: LabelFormatter; + longestLegendValueWidth: number; renderHiddenLegendLabel?: RenderHiddenLegendLabel; getColorVisionStyles: ColorVisionInteractionMethods['getColorVisionStyles']; getColorVisionEventAttrs: ColorVisionInteractionMethods['getColorVisionEventAttrs']; @@ -33,6 +34,7 @@ export function LegendValues({ data: allData, activeIndex, labelFormatter, + longestLegendValueWidth, renderHiddenLegendLabel = (count) => `+${count} more`, getColorVisionStyles, getColorVisionEventAttrs, @@ -90,6 +92,7 @@ export function LegendValues({ value={value} trend={trend} index={index} + longestLegendValueWidth={longestLegendValueWidth} maxTrendIndicatorWidth={maxTrendIndicatorWidth} seriesColors={seriesColors} onDimensionChange={(dimensions) => { diff --git a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.scss b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.scss index 2b4a4aa20d..db17abbe06 100644 --- a/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.scss +++ b/packages/polaris-viz/src/components/DonutChart/components/LegendValues/components/LegendValueItem/LegendValueItem.scss @@ -7,10 +7,7 @@ text-wrap: nowrap; text-overflow: ellipsis; padding-left: 4px; -} - -.TableSpacer { - padding-left: 30px; + padding-right: 20px; } .alignLeft { 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 bb7420034b..391e08f3ee 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 @@ -21,6 +21,7 @@ interface Props { value?: string; trend?: MetaDataTrendIndicator; labelFormatter: LabelFormatter; + longestLegendValueWidth: number; seriesColors: Color[]; maxTrendIndicatorWidth: number; onDimensionChange: (dimensions: Dimensions) => void; @@ -33,6 +34,7 @@ export function LegendValueItem({ value, index, labelFormatter, + longestLegendValueWidth, trend, seriesColors, maxTrendIndicatorWidth, @@ -73,13 +75,12 @@ export function LegendValueItem({ style={{ color: selectedTheme.legend.labelColor, }} + title={name} > {name} - - - + - - {trend && valueExists && } - + {trend && valueExists && ( + + + + + + )} ); } diff --git a/packages/polaris-viz/src/components/DonutChart/stories/TruncatedLegends.stories.tsx b/packages/polaris-viz/src/components/DonutChart/stories/TruncatedLegends.stories.tsx new file mode 100644 index 0000000000..c8bf402be8 --- /dev/null +++ b/packages/polaris-viz/src/components/DonutChart/stories/TruncatedLegends.stories.tsx @@ -0,0 +1,50 @@ +import type {Story} from '@storybook/react'; + +export {META as default} from './meta'; + +import type {DonutChartProps} from '../../DonutChart'; + +import {DEFAULT_PROPS, Template} from './data'; + +export const TruncatedLegends: Story = Template.bind({}); + +TruncatedLegends.args = { + ...DEFAULT_PROPS, + showLegendValues: true, + legendPosition: 'right', + legendFullWidth: false, + labelFormatter: (value) => `$${value}`, + data: [ + { + name: 'This is a long name that will get truncated', + data: [{key: 'april - march', value: 50000}], + metadata: { + trend: { + value: '5%', + }, + }, + }, + { + name: 'This is another long name that will get truncated', + data: [{key: 'april - march', value: 250000}], + metadata: { + trend: { + value: '50%', + direction: 'downward', + trend: 'negative', + }, + }, + }, + { + name: 'This is the last long name that will get truncated', + data: [{key: 'april - march', value: 10000}], + metadata: { + trend: { + value: '100%', + direction: 'upward', + trend: 'positive', + }, + }, + }, + ], +};