From 38a880bc3e6fc71c1f46626254e5712a74da45f7 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Thu, 2 Oct 2025 09:38:08 -0600 Subject: [PATCH] add date formatting to bar level --- .../hooks/useOptions/useXAxis/useXAxis.ts | 1 - .../useSeriesOptions/barSeriesBuilder.ts | 19 +- .../useSeriesOptions/lineSeriesBuilder.ts | 6 +- .../stories/BusterChart.BarChart.stories.tsx | 240 ++++++++++++++++++ 4 files changed, 250 insertions(+), 16 deletions(-) diff --git a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useXAxis/useXAxis.ts b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useXAxis/useXAxis.ts index 310c1cc40..c25ad290e 100644 --- a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useXAxis/useXAxis.ts +++ b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useOptions/useXAxis/useXAxis.ts @@ -203,7 +203,6 @@ export const useXAxis = ({ return formatLabel(value, firstXColumnLabelFormat); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I had a devil of a time trying to type this... This is a hack to get the type to work return DEFAULT_X_AXIS_TICK_CALLBACK.call( this, value, diff --git a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.ts b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.ts index 41d127d22..22837d26b 100644 --- a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.ts +++ b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/barSeriesBuilder.ts @@ -11,6 +11,7 @@ import { DEFAULT_CHART_LAYOUT } from '../../ChartJSTheme'; import type { ChartProps } from '../../core'; import { dataLabelFontColorContrast, formatBarAndLineDataLabel } from '../../helpers'; import { defaultLabelOptionConfig } from '../useChartSpecificOptions/labelOptionConfig'; +import { createTickDates } from './createTickDate'; import { createTrendlineOnSeries } from './createTrendlines'; import type { SeriesBuilderProps } from './interfaces'; import type { LabelBuilderProps } from './useSeriesOptions'; @@ -352,23 +353,21 @@ const getFormattedValueAndSetBarDataLabels = ( export const barSeriesBuilder_labels = ({ datasetOptions, columnLabelFormats, -}: Pick) => { - const ticksKey = datasetOptions.ticksKey; - - const containsADateStyle = datasetOptions.ticksKey.some((tick) => { - const selectedColumnLabelFormat = columnLabelFormats[tick.key]; - return selectedColumnLabelFormat?.style === 'date'; - }); - const selectedJoinCharacter = containsADateStyle ? JOIN_CHARACTER_DATE : JOIN_CHARACTER; + xAxisKeys, +}: Pick) => { + const dateTicks = createTickDates(datasetOptions.ticks, xAxisKeys, columnLabelFormats); + if (dateTicks) { + return dateTicks; + } const labels = datasetOptions.ticks.flatMap((item) => { return item .map((item, index) => { - const key = ticksKey[index]?.key || ''; + const key = datasetOptions.ticksKey[index]?.key || ''; const columnLabelFormat = columnLabelFormats[key]; return formatLabel(item, columnLabelFormat); }) - .join(selectedJoinCharacter); + .join(JOIN_CHARACTER); }); return labels; diff --git a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.ts b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.ts index 475cb30ec..f93a87360 100644 --- a/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.ts +++ b/apps/web/src/components/ui/charts/BusterChartJS/hooks/useSeriesOptions/lineSeriesBuilder.ts @@ -216,13 +216,9 @@ export const lineSeriesBuilder_labels = ({ xAxisKeys, columnLabelFormats, }: LabelBuilderProps): (string | Date)[] => { - const dateTicks = createTickDates(datasetOptions.ticks, xAxisKeys, columnLabelFormats); - if (dateTicks) { - return dateTicks; - } - return barSeriesBuilder_labels({ datasetOptions, columnLabelFormats, + xAxisKeys, }); }; diff --git a/apps/web/src/components/ui/charts/stories/BusterChart.BarChart.stories.tsx b/apps/web/src/components/ui/charts/stories/BusterChart.BarChart.stories.tsx index c83b41149..f2f5a0350 100644 --- a/apps/web/src/components/ui/charts/stories/BusterChart.BarChart.stories.tsx +++ b/apps/web/src/components/ui/charts/stories/BusterChart.BarChart.stories.tsx @@ -1657,3 +1657,243 @@ export const BarChartWithSortedDayOfWeek: Story = { ], }, }; + +export const BarWithProblemQuarters: Story = { + args: { + colors: [ + '#B399FD', + '#FC8497', + '#FBBC30', + '#279EFF', + '#E83562', + '#41F8FF', + '#F3864F', + '#C82184', + '#31FCB4', + '#E83562', + ], + barLayout: 'vertical', + barSortBy: [], + goalLines: [], + gridLines: true, + pieSortBy: 'value', + showLegend: null, + trendlines: [], + scatterAxis: { + x: [], + y: [], + size: [], + tooltip: null, + category: [], + }, + barGroupType: 'stack', + metricHeader: null, + pieChartAxis: { + x: [], + y: [], + tooltip: null, + }, + lineGroupType: null, + pieDonutWidth: 40, + xAxisDataZoom: false, + barAndLineAxis: { + x: ['quarter'], + y: ['product_count'], + colorBy: [], + tooltip: null, + category: ['metric_seasoncategory'], + }, + columnSettings: {}, + comboChartAxis: { + x: [], + y: [], + y2: [], + colorBy: [], + tooltip: null, + category: [], + }, + disableTooltip: false, + metricColumnId: '', + scatterDotSize: [3, 15], + xAxisAxisTitle: null, + yAxisAxisTitle: null, + yAxisScaleType: 'linear', + metricSubHeader: null, + y2AxisAxisTitle: null, + y2AxisScaleType: 'linear', + metricValueLabel: null, + pieLabelPosition: 'none', + tableColumnOrder: null, + barShowTotalAtTop: false, + categoryAxisTitle: null, + pieDisplayLabelAs: 'number', + pieShowInnerLabel: true, + selectedChartType: 'bar', + tableColumnWidths: null, + xAxisTimeInterval: null, + columnLabelFormats: { + quarter: { + isUTC: false, + style: 'date', + prefix: '', + suffix: '', + currency: 'USD', + columnType: 'number', + dateFormat: 'auto', + multiplier: 1, + displayName: '', + compactNumbers: false, + convertNumberTo: 'quarter', + useRelativeTime: false, + numberSeparatorStyle: null, + maximumFractionDigits: 2, + minimumFractionDigits: 0, + makeLabelHumanReadable: true, + replaceMissingDataWith: 0, + }, + product_count: { + isUTC: false, + style: 'number', + prefix: '', + suffix: '', + currency: 'USD', + columnType: 'number', + dateFormat: 'auto', + multiplier: 1, + displayName: 'Product Count', + compactNumbers: false, + convertNumberTo: null, + useRelativeTime: false, + numberSeparatorStyle: ',', + maximumFractionDigits: 0, + minimumFractionDigits: 0, + makeLabelHumanReadable: true, + replaceMissingDataWith: 0, + }, + metric_seasoncategory: { + isUTC: false, + style: 'string', + prefix: '', + suffix: '', + currency: 'USD', + columnType: 'text', + dateFormat: 'auto', + multiplier: 1, + displayName: 'Season Category', + compactNumbers: false, + convertNumberTo: null, + useRelativeTime: false, + numberSeparatorStyle: null, + maximumFractionDigits: 2, + minimumFractionDigits: 0, + makeLabelHumanReadable: true, + replaceMissingDataWith: null, + }, + }, + pieInnerLabelTitle: null, + showLegendHeadline: false, + xAxisLabelRotation: 'auto', + xAxisShowAxisLabel: true, + xAxisShowAxisTitle: true, + yAxisShowAxisLabel: true, + yAxisShowAxisTitle: true, + y2AxisShowAxisLabel: true, + y2AxisShowAxisTitle: true, + metricValueAggregate: 'sum', + tableColumnFontColor: null, + tableHeaderFontColor: null, + yAxisStartAxisAtZero: null, + y2AxisStartAxisAtZero: true, + pieInnerLabelAggregate: 'sum', + pieMinimumSlicePercentage: 0, + tableHeaderBackgroundColor: null, + data: [ + { + quarter: 1, + metric_seasoncategory: 'High Season', + product_count: 55, + }, + { + quarter: 1, + metric_seasoncategory: 'Low Season', + product_count: 18, + }, + { + quarter: 1, + metric_seasoncategory: 'Regular Season', + product_count: 174, + }, + { + quarter: 2, + metric_seasoncategory: 'High Season', + product_count: 27, + }, + { + quarter: 2, + metric_seasoncategory: 'Low Season', + product_count: 60, + }, + { + quarter: 2, + metric_seasoncategory: 'Regular Season', + product_count: 156, + }, + { + quarter: 3, + metric_seasoncategory: 'High Season', + product_count: 2, + }, + { + quarter: 3, + metric_seasoncategory: 'Low Season', + product_count: 181, + }, + { + quarter: 3, + metric_seasoncategory: 'Regular Season', + product_count: 82, + }, + { + quarter: 4, + metric_seasoncategory: 'High Season', + product_count: 136, + }, + { + quarter: 4, + metric_seasoncategory: 'Low Season', + product_count: 22, + }, + { + quarter: 4, + metric_seasoncategory: 'Regular Season', + product_count: 108, + }, + ], + columnMetadata: [ + { + name: 'quarter', + min_value: 1, + max_value: 4, + unique_values: 4, + simple_type: 'number', + type: 'numeric', + }, + { + name: 'metric_seasoncategory', + min_value: 'High Season', + max_value: 'Regular Season', + unique_values: 3, + simple_type: 'text', + type: 'text', + }, + { + name: 'product_count', + min_value: 2, + max_value: 181, + unique_values: 12, + simple_type: 'number', + type: 'int8', + }, + ], + }, +};