From d6bfbcc5ab778c749fd66d22c5a5150116c48cd0 Mon Sep 17 00:00:00 2001 From: nitin <142569587+ehconitin@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:45:53 +0530 Subject: [PATCH] add max widths on bars (#15487) closes https://discord.com/channels/1130383047699738754/1433444230176440560 before: https://github.com/user-attachments/assets/db93c705-7c0a-407b-99d8-ecf8fd9eac1b after: https://github.com/user-attachments/assets/cb2a5e74-ea41-4381-9fbc-04efee12a50e --- .../components/CustomBarItem.tsx | 156 +++++++++++------- .../constants/MaximumBarWidth.ts | 1 + 2 files changed, 96 insertions(+), 61 deletions(-) create mode 100644 packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/constants/MaximumBarWidth.ts diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/CustomBarItem.tsx b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/CustomBarItem.tsx index 2142b3a8ba..1f5658b44a 100644 --- a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/CustomBarItem.tsx +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/components/CustomBarItem.tsx @@ -1,4 +1,5 @@ import { BAR_CHART_HOVER_BRIGHTNESS } from '@/page-layout/widgets/graph/graphWidgetBarChart/constants/BarChartHoverBrightness'; +import { BAR_CHART_MAXIMUM_WIDTH } from '@/page-layout/widgets/graph/graphWidgetBarChart/constants/MaximumBarWidth'; import { type BarDatum, type BarItemProps } from '@nivo/bar'; import { Text } from '@nivo/text'; import { useTheme } from '@nivo/theming'; @@ -162,8 +163,33 @@ export const CustomBarItem = ({ seriesIndex >= 0 ? seriesIndex : 'x' }`; - const clipPathX = !isHorizontal ? 0 : isNegativeValue ? 0 : -borderRadius; + const unconstrainedThicknessDimension = isHorizontal ? height : width; + const unconstrainedValueDimension = isHorizontal ? width : height; + const constrainedThicknessDimension = to( + unconstrainedThicknessDimension, + (dimension) => Math.min(dimension, BAR_CHART_MAXIMUM_WIDTH), + ); + + const centeringOffset = to(unconstrainedThicknessDimension, (dimension) => + dimension > BAR_CHART_MAXIMUM_WIDTH + ? (dimension - BAR_CHART_MAXIMUM_WIDTH) / 2 + : 0, + ); + + const centeringTransform = to(centeringOffset, (offset) => + isHorizontal ? `translate(0, ${offset})` : `translate(${offset}, 0)`, + ); + + const finalBarWidthDimension = isHorizontal + ? unconstrainedValueDimension + : constrainedThicknessDimension; + + const finalBarHeightDimension = isHorizontal + ? constrainedThicknessDimension + : unconstrainedValueDimension; + + const clipPathX = !isHorizontal ? 0 : isNegativeValue ? 0 : -borderRadius; const clipPathY = isHorizontal ? 0 : isNegativeValue ? -borderRadius : 0; const widthWithOffset = (v: number) => @@ -172,71 +198,79 @@ export const CustomBarItem = ({ Math.max(v + (isHorizontal ? 0 : borderRadius), 0); const clampRadius = (v: number) => Math.min(borderRadius, v / 2); - const clipRectWidth = to(width, (v) => widthWithOffset(v)); - const clipRectHeight = to(height, (v) => heightWithOffset(v)); - const clipRx = to(width, (v) => clampRadius(widthWithOffset(v))); - const clipRy = to(height, (v) => clampRadius(heightWithOffset(v))); + const clipRectWidth = to(finalBarWidthDimension, (v) => widthWithOffset(v)); + const clipRectHeight = to(finalBarHeightDimension, (v) => + heightWithOffset(v), + ); + const clipRx = to(finalBarWidthDimension, (v) => + clampRadius(widthWithOffset(v)), + ); + const clipRy = to(finalBarHeightDimension, (v) => + clampRadius(heightWithOffset(v)), + ); return ( - {shouldRoundFreeEnd && ( - - - - - - )} + + {shouldRoundFreeEnd && ( + + + + + + )} - Math.max(value, 0))} - height={to(height, (value) => Math.max(value, 0))} - fill={color} - strokeWidth={borderWidth} - stroke={borderColor} - focusable={isFocusable} - tabIndex={isFocusable ? 0 : undefined} - aria-label={ariaLabel ? ariaLabel(barData) : undefined} - aria-labelledby={ariaLabelledBy ? ariaLabelledBy(barData) : undefined} - aria-describedby={ - ariaDescribedBy ? ariaDescribedBy(barData) : undefined - } - aria-disabled={ariaDisabled ? ariaDisabled(barData) : undefined} - aria-hidden={ariaHidden ? ariaHidden(barData) : undefined} - onMouseEnter={isInteractive ? handleMouseEnter : undefined} - onMouseMove={isInteractive ? handleTooltip : undefined} - onMouseLeave={isInteractive ? handleMouseLeave : undefined} - onClick={isInteractive ? handleClick : undefined} - onFocus={isInteractive && isFocusable ? handleFocus : undefined} - onBlur={isInteractive && isFocusable ? handleBlur : undefined} - data-testid={`bar.item.${barData.id}.${barData.index}`} - /> + Math.max(value, 0))} + height={to(finalBarHeightDimension, (value) => Math.max(value, 0))} + fill={color} + strokeWidth={borderWidth} + stroke={borderColor} + focusable={isFocusable} + tabIndex={isFocusable ? 0 : undefined} + aria-label={ariaLabel ? ariaLabel(barData) : undefined} + aria-labelledby={ariaLabelledBy ? ariaLabelledBy(barData) : undefined} + aria-describedby={ + ariaDescribedBy ? ariaDescribedBy(barData) : undefined + } + aria-disabled={ariaDisabled ? ariaDisabled(barData) : undefined} + aria-hidden={ariaHidden ? ariaHidden(barData) : undefined} + onMouseEnter={isInteractive ? handleMouseEnter : undefined} + onMouseMove={isInteractive ? handleTooltip : undefined} + onMouseLeave={isInteractive ? handleMouseLeave : undefined} + onClick={isInteractive ? handleClick : undefined} + onFocus={isInteractive && isFocusable ? handleFocus : undefined} + onBlur={isInteractive && isFocusable ? handleBlur : undefined} + data-testid={`bar.item.${barData.id}.${barData.index}`} + /> - {shouldRenderLabel && ( - - {label} - - )} + {shouldRenderLabel && ( + + {label} + + )} + ); }; diff --git a/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/constants/MaximumBarWidth.ts b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/constants/MaximumBarWidth.ts new file mode 100644 index 0000000000..8712e335db --- /dev/null +++ b/packages/twenty-front/src/modules/page-layout/widgets/graph/graphWidgetBarChart/constants/MaximumBarWidth.ts @@ -0,0 +1 @@ +export const BAR_CHART_MAXIMUM_WIDTH = 32;