diff --git a/web/src/components/ui/charts/BusterChartJS/ChartJSTheme.ts b/web/src/components/ui/charts/BusterChartJS/ChartJSTheme.ts
index afbaa4653..a267b6f07 100644
--- a/web/src/components/ui/charts/BusterChartJS/ChartJSTheme.ts
+++ b/web/src/components/ui/charts/BusterChartJS/ChartJSTheme.ts
@@ -117,7 +117,7 @@ ChartJS.defaults.font = {
});
[ChartJS.defaults.scales.linear, ChartJS.defaults.scales.logarithmic].forEach((scale) => {
- scale.ticks.z = 100;
+ scale.ticks.z = 0; //this used to be a 100, but I changed it for datalabels sake
scale.ticks.backdropColor = backgroundColor;
scale.ticks.showLabelBackdrop = true;
scale.ticks.autoSkipPadding = 2;
diff --git a/web/src/components/ui/charts/BusterChartJS/helpers/formatBarAndLineDataLabel.ts b/web/src/components/ui/charts/BusterChartJS/helpers/formatBarAndLineDataLabel.ts
index 34e4359e7..0dc344801 100644
--- a/web/src/components/ui/charts/BusterChartJS/helpers/formatBarAndLineDataLabel.ts
+++ b/web/src/components/ui/charts/BusterChartJS/helpers/formatBarAndLineDataLabel.ts
@@ -9,6 +9,7 @@ export const formatBarAndLineDataLabel = (
columnLabelFormat: ColumnLabelFormat
) => {
if (!percentageMode) {
+ console.log('formatBarAndLineDataLabel', value, columnLabelFormat);
return formatLabel(value, columnLabelFormat);
}
diff --git a/web/src/components/ui/charts/stories/BusterChart.LineChart.stories.tsx b/web/src/components/ui/charts/stories/BusterChart.LineChart.stories.tsx
index a788b64a6..c71748d53 100644
--- a/web/src/components/ui/charts/stories/BusterChart.LineChart.stories.tsx
+++ b/web/src/components/ui/charts/stories/BusterChart.LineChart.stories.tsx
@@ -611,3 +611,162 @@ export const PercentageStackedLineMultipleWithDataLabels: Story = {
}
}
};
+
+export const HasMixedNullAndNumberValuesSingleLineWithMissingDataZero: Story = {
+ args: {
+ selectedChartType: ChartType.Line,
+ data: Array.from({ length: 12 }, (_, i) => ({
+ date: new Date(2024, 0, i + 1).toISOString(),
+ revenue: i === 5 ? null : i * 100
+ })),
+ barAndLineAxis: {
+ x: ['date'],
+ y: ['revenue'],
+ category: []
+ },
+ className: 'w-[800px] h-[400px]',
+ columnSettings: {
+ revenue: {
+ showDataLabels: true
+ }
+ },
+ columnLabelFormats: {
+ date: {
+ columnType: 'date',
+ style: 'date',
+ dateFormat: 'auto',
+ minimumFractionDigits: 0,
+ maximumFractionDigits: 0
+ } satisfies IColumnLabelFormat,
+ revenue: {
+ columnType: 'number',
+ style: 'currency',
+ currency: 'USD',
+ replaceMissingDataWith: 0
+ } satisfies IColumnLabelFormat
+ }
+ }
+};
+
+export const HasMixedNullAndNumberValuesSingleLineWithMissingDataNull: Story = {
+ args: {
+ selectedChartType: ChartType.Line,
+ data: Array.from({ length: 12 }, (_, i) => ({
+ date: new Date(2024, 0, i + 1).toISOString(),
+ revenue: i === 5 ? null : i * 100
+ })),
+ barAndLineAxis: {
+ x: ['date'],
+ y: ['revenue'],
+ category: []
+ },
+ className: 'w-[800px] h-[400px]',
+ columnSettings: {
+ revenue: {
+ showDataLabels: true
+ }
+ },
+ columnLabelFormats: {
+ date: {
+ columnType: 'date',
+ style: 'date',
+ dateFormat: 'auto',
+ minimumFractionDigits: 0,
+ maximumFractionDigits: 0
+ } satisfies IColumnLabelFormat,
+ revenue: {
+ columnType: 'number',
+ style: 'currency',
+ currency: 'USD',
+ replaceMissingDataWith: null
+ } satisfies IColumnLabelFormat
+ }
+ }
+};
+
+export const HasMixedNullAndNumberValuesSingleMultiLine: Story = {
+ args: {
+ selectedChartType: ChartType.Line,
+ data: Array.from({ length: 12 }, (_, i) => ({
+ date: new Date(2024, 0, i + 1).toISOString(),
+ revenue: i % 5 === 0 ? null : i * 100,
+ profit: i % 7 === 0 ? null : i * 200
+ })),
+ barAndLineAxis: {
+ x: ['date'],
+ y: ['revenue', 'profit'],
+ category: []
+ },
+
+ className: 'w-[800px] h-[400px]',
+ columnSettings: {
+ revenue: {
+ showDataLabels: true
+ },
+ profit: {
+ showDataLabels: true
+ }
+ },
+ columnLabelFormats: {
+ date: {
+ columnType: 'date',
+ style: 'date',
+ dateFormat: 'auto',
+ minimumFractionDigits: 0,
+ maximumFractionDigits: 0
+ } satisfies IColumnLabelFormat,
+ revenue: {
+ columnType: 'number',
+ style: 'currency',
+ currency: 'USD'
+ } satisfies IColumnLabelFormat,
+ profit: {
+ columnType: 'number',
+ style: 'currency',
+ currency: 'USD'
+ } satisfies IColumnLabelFormat
+ }
+ }
+};
+
+export const HasNullValuesWithCategoryMultiLine: Story = {
+ args: {
+ selectedChartType: ChartType.Line,
+ data: Array.from({ length: 3 }).flatMap((_, productIndex) => {
+ const category = ['Product A', 'Product B', 'Product C'][productIndex];
+ return Array.from({ length: 12 }, (_, i) => ({
+ date: new Date(2024, 0, i + 1).toISOString(),
+ revenue:
+ i % 5 === 0 || (productIndex === 0 && i % 7 === 0) ? null : i * 100 + productIndex * 1000,
+ category
+ }));
+ }),
+ barAndLineAxis: {
+ x: ['date'],
+ y: ['revenue'],
+ category: ['category']
+ },
+ columnSettings: {
+ revenue: {
+ showDataLabels: true
+ }
+ },
+ columnLabelFormats: {
+ date: {
+ columnType: 'date',
+ style: 'date',
+ dateFormat: 'auto'
+ },
+ category: {
+ columnType: 'text',
+ style: 'string'
+ },
+ revenue: {
+ columnType: 'number',
+ style: 'currency',
+ currency: 'USD',
+ replaceMissingDataWith: 0
+ }
+ }
+ }
+};
diff --git a/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_PillContainers/ReasoningMessagePills.tsx b/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_PillContainers/ReasoningMessagePills.tsx
index 3fa9d75b2..5cfdb50bc 100644
--- a/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_PillContainers/ReasoningMessagePills.tsx
+++ b/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_PillContainers/ReasoningMessagePills.tsx
@@ -63,7 +63,7 @@ export const ReasoningMessagePills: React.FC<{
animate={pills.length > 0 ? 'visible' : 'hidden'}
className={'flex w-full flex-wrap gap-1.5 overflow-hidden'}>
{pills.map((pill) => (
-
+
))}
diff --git a/web/src/layouts/AppAssetCheckLayout/useGetAsset.tsx b/web/src/layouts/AppAssetCheckLayout/useGetAsset.tsx
index 0598dbff5..8685e6fd0 100644
--- a/web/src/layouts/AppAssetCheckLayout/useGetAsset.tsx
+++ b/web/src/layouts/AppAssetCheckLayout/useGetAsset.tsx
@@ -1,3 +1,5 @@
+'use client';
+
import { useGetMetric, useGetMetricData } from '@/api/buster_rest/metrics';
import { useGetDashboard } from '@/api/buster_rest/dashboards';
import { RustApiError } from '@/api/buster_rest/errors';