Skip to content

Commit

Permalink
Label design changes
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelnesen committed Feb 13, 2025
1 parent c8f3f98 commit 8463e94
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const PERCENT_FONT_SIZE = 14;
const PERCENT_FONT_WEIGHT = 650;
const VALUE_FONT_SIZE = 11;
const TREND_INDICATOR_SPACING = 8;
const BUFFER_PADDING = 8;
const LABEL_VERTICAL_OFFSET = 2;

const TEXT_COLOR = 'rgba(31, 33, 36, 1)';
Expand Down Expand Up @@ -62,6 +61,62 @@ export function FunnelChartLabels({
return maxLabelWidth > labelWidth ? REDUCED_FONT_SIZE : LABEL_FONT_SIZE;
}, [labels, characterWidths, labelWidth]);

const canShowAllFormattedValues = useMemo(() => {
return labels.every((_, index) => {
const isLast = index === labels.length - 1;
const targetWidth = isLast
? barWidth - GROUP_OFFSET * 2
: labelWidth - GROUP_OFFSET * 2;

const percentWidth = estimateStringWidthWithOffset(
percentages[index],
PERCENT_FONT_SIZE,
PERCENT_FONT_WEIGHT,
);

const formattedValueWidth = estimateStringWidthWithOffset(
formattedValues[index],
VALUE_FONT_SIZE,
);

const trendIndicatorWidth = getTrendIndicatorData(
trends?.[index]?.reached,
).trendIndicatorWidth;

return (
percentWidth +
formattedValueWidth +
trendIndicatorWidth +
TREND_INDICATOR_SPACING * 2 <
targetWidth
);
});
}, [labels, barWidth, labelWidth, percentages, formattedValues, trends]);

const canShowAllTrendIndicatorsInline = useMemo(() => {
return labels.every((_, index) => {
const isLast = index === labels.length - 1;
const targetWidth = isLast
? barWidth - GROUP_OFFSET * 2
: labelWidth - GROUP_OFFSET * 2;

const percentWidth = estimateStringWidthWithOffset(
percentages[index],
PERCENT_FONT_SIZE,
PERCENT_FONT_WEIGHT,
);

const {trendIndicatorWidth} = getTrendIndicatorData(
trends?.[index]?.reached,
);

return (
percentWidth + TREND_INDICATOR_SPACING <
targetWidth - trendIndicatorWidth
);
});
}, [labels, barWidth, labelWidth, percentages, trends]);

return (
<Fragment>
{labels.map((label, index) => {
Expand All @@ -80,29 +135,12 @@ export function FunnelChartLabels({
PERCENT_FONT_WEIGHT,
);

const formattedValueWidth = estimateStringWidthWithOffset(
formattedValues[index],
VALUE_FONT_SIZE,
);

const {trendIndicatorProps, trendIndicatorWidth} =
getTrendIndicatorData(trends?.[index]?.reached);

// Position trend indicator at the right edge
const trendIndicatorX = targetWidth - trendIndicatorWidth;

// First check if we can show the trend indicator
const shouldShowTrendIndicator =
trendIndicatorProps != null &&
percentWidth + TREND_INDICATOR_SPACING < trendIndicatorX;

// Then check if we can show formatted value without overlapping trend indicator
const availableWidthForValue = shouldShowTrendIndicator
? trendIndicatorX - TREND_INDICATOR_SPACING - BUFFER_PADDING
: targetWidth;
const shouldShowFormattedValue =
percentWidth + formattedValueWidth < availableWidthForValue &&
(!trendIndicatorProps || shouldShowTrendIndicator);
const trendIndicatorX = canShowAllTrendIndicatorsInline
? targetWidth - trendIndicatorWidth
: 0;

return (
<g
Expand Down Expand Up @@ -145,7 +183,7 @@ export function FunnelChartLabels({
fontSize={PERCENT_FONT_SIZE}
fontWeight={PERCENT_FONT_WEIGHT}
/>
{shouldShowFormattedValue && (
{canShowAllFormattedValues && (
<SingleTextLine
color={VALUE_COLOR}
text={formattedValues[index]}
Expand All @@ -156,9 +194,13 @@ export function FunnelChartLabels({
fontSize={VALUE_FONT_SIZE}
/>
)}
{shouldShowTrendIndicator && (
{trendIndicatorProps && (
<g
transform={`translate(${trendIndicatorX}, ${-LABEL_VERTICAL_OFFSET})`}
transform={`translate(${trendIndicatorX}, ${
canShowAllTrendIndicatorsInline
? -LABEL_VERTICAL_OFFSET
: LINE_HEIGHT
})`}
>
<TrendIndicator {...trendIndicatorProps} />
</g>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,46 @@ import type {DataSeries} from '@shopify/polaris-viz-core';

import type {MetaDataTrendIndicator, FunnelChartMetaData} from '../types';

export function useBuildFunnelTrends(data: DataSeries[]) {
return useMemo(() => {
const primarySeries = data.find((series) => !series.isComparison);
const comparisonSeries = data.find((series) => series.isComparison);

if (
!primarySeries ||
!comparisonSeries ||
!primarySeries.metadata?.trends
) {
return undefined;
}

const trends: FunnelChartMetaData['trends'] = {};

primarySeries.data.forEach((_, index) => {
const reachedTrend = primarySeries.metadata?.trends[index];

if (!reachedTrend) return;

const droppedPercentageChange = calculateDroppedPercentageChange({
previousStepValue: primarySeries.data[index - 1]?.value,
currentStepValue: primarySeries.data[index]?.value,
comparisonPreviousStepValue: comparisonSeries.data[index - 1]?.value,
comparisonCurrentStepValue: comparisonSeries.data[index]?.value,
});

const droppedTrend =
index === 0 ? undefined : formatDroppedTrend(droppedPercentageChange);

trends[index] = {
reached: reachedTrend,
...(droppedTrend && {dropped: droppedTrend}),
};
});

return {trends};
}, [data]);
}

interface DropOffCalculationParams {
previousStepValue: number | null;
currentStepValue: number | null;
Expand Down Expand Up @@ -61,43 +101,3 @@ function formatDroppedTrend(percentageChange: number): MetaDataTrendIndicator {
direction: percentageChange < 0 ? 'upward' : 'downward',
};
}

export function useBuildFunnelTrends(data: DataSeries[]) {
return useMemo(() => {
const primarySeries = data.find((series) => !series.isComparison);
const comparisonSeries = data.find((series) => series.isComparison);

if (
!primarySeries ||
!comparisonSeries ||
!primarySeries.metadata?.trends
) {
return undefined;
}

const trends: FunnelChartMetaData['trends'] = {};

primarySeries.data.forEach((_, index) => {
const reachedTrend = primarySeries.metadata?.trends[index];

if (!reachedTrend) return;

const droppedPercentageChange = calculateDroppedPercentageChange({
previousStepValue: primarySeries.data[index - 1]?.value,
currentStepValue: primarySeries.data[index]?.value,
comparisonPreviousStepValue: comparisonSeries.data[index - 1]?.value,
comparisonCurrentStepValue: comparisonSeries.data[index]?.value,
});

const droppedTrend =
index === 0 ? undefined : formatDroppedTrend(droppedPercentageChange);

trends[index] = {
reached: reachedTrend,
...(droppedTrend && {dropped: droppedTrend}),
};
});

return {trends};
}, [data]);
}

0 comments on commit 8463e94

Please sign in to comment.