additional fixes to chart types

This commit is contained in:
Nate Kelley 2025-07-03 16:52:53 -06:00
parent 4cdde9203f
commit 2a8db894a3
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
151 changed files with 782 additions and 829 deletions

View File

@ -0,0 +1,10 @@
//ONLY USED IN COMPONENTS
export type BusterChartPropsBase = {
onMounted: () => void;
onInitialAnimationEnd: () => void;
className?: string;
animate?: boolean;
data: Record<string, string | null | Date | number>[];
isDarkMode?: boolean;
readOnly?: boolean;
};

View File

@ -1 +1,2 @@
export * from './interfaces';
export * from './chartBaseInterfaces';

View File

@ -1,2 +0,0 @@
export * from './shareInterfaces';
export * from './verificationInterfaces';

View File

@ -1,29 +0,0 @@
export enum ShareRole {
OWNER = 'owner', //owner of the asset
FULL_ACCESS = 'fullAccess', //same as owner, can share with others
CAN_EDIT = 'canEdit', //can edit, cannot share
CAN_FILTER = 'canFilter', //can filter dashboard
CAN_VIEW = 'canView' //can view asset
}
export enum ShareAssetType {
METRIC = 'metric',
DASHBOARD = 'dashboard',
COLLECTION = 'collection',
CHAT = 'chat'
}
export interface BusterShare {
individual_permissions: null | BusterShareIndividual[];
public_expiry_date: string | null;
public_enabled_by: string | null;
publicly_accessible: boolean;
public_password: string | null;
permission: ShareRole; //this is the permission the user has to the metric, dashboard or collection
}
export interface BusterShareIndividual {
email: string;
role: ShareRole;
name?: string;
}

View File

@ -1,8 +0,0 @@
export enum VerificationStatus {
NOT_REQUESTED = 'notRequested',
REQUESTED = 'requested',
IN_REVIEW = 'inReview',
VERIFIED = 'verified',
BACKLOGGED = 'backlogged',
NOT_VERIFIED = 'notVerified'
}

View File

@ -1,5 +1,5 @@
import type { DataMetadata, IDataResult } from '../metric';
import type { DataMetadata, DataResult } from '@buster/server-shared/metrics';
export interface RunSQLResponse {
data: IDataResult;
data: DataResult;
data_metadata: DataMetadata;
}

View File

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { BusterChatListItem } from '@/api/asset_interfaces/chat/chatInterfaces';
import { mainApi } from '../instances';
import type { ChatListItem } from '@buster/server-shared/chats';
// Mock the mainApi
vi.mock('../instances', () => ({
@ -17,7 +17,7 @@ describe('Chat API Requests', () => {
describe('getListChats', () => {
it('should fetch list of chats with default pagination parameters', async () => {
// Mock data
const mockChats: BusterChatListItem[] = [
const mockChats: ChatListItem[] = [
{
id: 'test-chat-1',
title: 'Test Chat 1',

View File

@ -3,8 +3,8 @@
import type { Chart } from 'chart.js';
import isEmpty from 'lodash/isEmpty';
import React, { useMemo } from 'react';
import { type BusterChartProps, type ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_CHART_CONFIG } from '@/api/asset_interfaces/metric/defaults';
import { type BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_CHART_CONFIG, type ChartEncodes } from '@buster/server-shared/metrics';
import { useMemoizedFn } from '@/hooks';
import { BusterChartComponent } from './BusterChartComponent';
import { BusterChartErrorWrapper } from './BusterChartErrorWrapper';

View File

@ -4,7 +4,7 @@ import './ChartJSTheme';
import type React from 'react';
import { useCallback, useRef, useState } from 'react';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_METADATA } from '@/api/asset_interfaces/metric';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_METADATA } from '@buster/server-shared/metrics';
import { useMemoizedFn } from '@/hooks';
import type { BusterChartComponentProps } from '../interfaces';
import { BusterChartJSComponent } from './BusterChartJSComponent';

View File

@ -2,7 +2,7 @@
import type { ChartType as ChartJSChartType, ChartOptions, Plugin, UpdateMode } from 'chart.js';
import React, { useMemo, useState } from 'react';
import type { ScatterAxis } from '@/api/asset_interfaces/metric/charts';
import type { ScatterAxis } from '@buster/server-shared/metrics';
import { useMemoizedFn, useMount, usePreviousRef } from '@/hooks';
import { useColors } from '../chartHooks';
import type { BusterChartTypeComponentProps } from '../interfaces/chartComponentInterfaces';

View File

@ -1,9 +1,10 @@
import React from 'react';
import type { BusterChartProps, ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { BusterChartLegendWrapper } from '../BusterChartLegend/BusterChartLegendWrapper';
import type { DatasetOptionsWithTicks } from '../chartHooks';
import type { ChartJSOrUndefined } from './core/types';
import { useBusterChartJSLegend } from './hooks';
import type { ChartEncodes } from '@buster/server-shared/metrics';
interface BusterChartJSLegendWrapperProps {
children: React.ReactNode;

View File

@ -26,7 +26,7 @@ import {
import ChartJsAnnotationPlugin from 'chartjs-plugin-annotation';
import ChartDataLabels from 'chartjs-plugin-datalabels';
import ChartDeferred from 'chartjs-plugin-deferred';
import { DEFAULT_CHART_THEME } from '@/api/asset_interfaces/metric/charts/configColors';
import { DEFAULT_CHART_THEME } from '@buster/server-shared/metrics';
import { truncateText } from '@/lib/text';
import { ChartMountedPlugin } from './core/plugins';
import ChartTrendlinePlugin from './core/plugins/chartjs-plugin-trendlines';

View File

@ -1,8 +1,12 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { BusterChartProps, Trendline } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { isNumericColumnType } from '@/lib/messages';
import { canSupportTrendlineRecord } from './canSupportTrendline';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ColumnLabelFormat,
type Trendline
} from '@buster/server-shared/metrics';
// Mock the isNumericColumnType function
vi.mock('@/lib/messages', () => ({
@ -28,7 +32,7 @@ describe('canSupportTrendlineRecord', () => {
[columnId]: {
columnType: 'number',
style: 'number'
}
} as ColumnLabelFormat
};
beforeEach(() => {

View File

@ -1,5 +1,5 @@
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { BusterChartProps, Trendline } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_COLUMN_LABEL_FORMAT, type Trendline } from '@buster/server-shared/metrics';
import { isNumericColumnType } from '@/lib/messages';
export const canSupportTrendlineRecord: Record<

View File

@ -1,7 +1,7 @@
// chartjs-plugin-trendline.ts
import type { ChartDataset, ChartType, Plugin, Point, Scale } from 'chart.js';
import { DEFAULT_TRENDLINE_CONFIG } from '@/api/asset_interfaces/metric/defaults';
import { DEFAULT_TRENDLINE_CONFIG } from '@buster/server-shared/metrics';
import { defaultLabelOptionConfig } from '../../../hooks/useChartSpecificOptions/labelOptionConfig';
/** The three trendline modes we support */

View File

@ -1,4 +1,4 @@
import type { Trendline } from '@/api/asset_interfaces/metric/charts';
import type { Trendline } from '@buster/server-shared/metrics';
type TrendlineType = Trendline['type'];

View File

@ -1,6 +1,6 @@
import type { Context } from 'chartjs-plugin-datalabels';
import { describe, expect, it } from 'vitest';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
import { formatBarAndLineDataLabel } from './formatBarAndLineDataLabel';
describe('formatBarAndLineDataLabel', () => {
@ -12,7 +12,7 @@ describe('formatBarAndLineDataLabel', () => {
numberSeparatorStyle: ',',
minimumFractionDigits: 0,
maximumFractionDigits: 2
};
} as ColumnLabelFormat;
const mockContext = {
chart: {

View File

@ -1,12 +1,12 @@
import type { Context } from 'chartjs-plugin-datalabels';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric';
import { formatLabel } from '@/lib/columnFormatter';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
export const formatBarAndLineDataLabel = (
value: number,
context: Context,
percentageMode: false | 'stacked' | 'data-label',
columnLabelFormat: ColumnLabelFormat
columnLabelFormat: Partial<ColumnLabelFormat>
) => {
if (!percentageMode) {
return formatLabel(value, columnLabelFormat);

View File

@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatChartLabel } from './formatChartLabel';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
describe('formatChartLabel', () => {
const columnLabelFormats = {
@ -51,7 +52,7 @@ describe('formatChartLabel', () => {
minimumFractionDigits: 1,
maximumFractionDigits: 1,
makeLabelHumanReadable: true
},
} as ColumnLabelFormat,
text_field: {
style: 'string',
compactNumbers: false,
@ -61,7 +62,7 @@ describe('formatChartLabel', () => {
minimumFractionDigits: 0,
maximumFractionDigits: 2,
makeLabelHumanReadable: true
},
} as ColumnLabelFormat,
custom_field: {
style: 'number',
compactNumbers: true,
@ -73,7 +74,7 @@ describe('formatChartLabel', () => {
prefix: '(',
suffix: ')',
makeLabelHumanReadable: true
}
} as ColumnLabelFormat
} satisfies NonNullable<BusterChartProps['columnLabelFormats']>;
it('should format a date label correctly', () => {

View File

@ -1,8 +1,7 @@
import type { Chart } from 'chart.js';
import { describe, expect, it } from 'vitest';
import type { ColumnSettings } from '@/api/asset_interfaces/metric/charts/columnInterfaces';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts/columnLabelInterfaces';
import type { SimplifiedColumnType } from '@/api/asset_interfaces/metric/charts/enum';
import type { ColumnSettings } from '@buster/server-shared/metrics';
import type { ColumnLabelFormat, SimplifiedColumnType } from '@buster/server-shared/metrics';
import { getLegendItems } from './getLegendItems';
describe('getLegendItems', () => {
@ -11,15 +10,15 @@ describe('getLegendItems', () => {
value: { columnVisualization: 'bar' },
value2: { columnVisualization: 'line' }
};
const defaultColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const defaultColumnLabelFormats: Record<string, ColumnLabelFormat> = {
value: {
columnType: 'number' as SimplifiedColumnType,
style: 'number'
},
} as ColumnLabelFormat,
value2: {
columnType: 'number' as SimplifiedColumnType,
style: 'number'
}
} as ColumnLabelFormat
};
it('should return empty array when chart data is not available', () => {

View File

@ -1,9 +1,10 @@
import type { ChartDataset } from 'chart.js';
import type React from 'react';
import { type BusterChartProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import { type BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartLegendItem } from '../../../BusterChartLegend';
import { formatLabelForPieLegend } from '../../../commonHelpers';
import type { ChartJSOrUndefined } from '../../core/types';
import type { ChartType } from '@buster/server-shared/metrics';
export const getLegendItems = ({
chartRef,

View File

@ -2,12 +2,7 @@
import type React from 'react';
import { useEffect, useMemo, useState, useTransition } from 'react';
import type { BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type {
BusterChartProps,
ChartEncodes,
ChartType
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { useDebounceFn, useMemoizedFn, useUpdateDebounceEffect } from '@/hooks';
import { timeout } from '@/lib';
import {
@ -20,6 +15,7 @@ import type { DatasetOptionsWithTicks } from '../../../chartHooks';
import { LEGEND_ANIMATION_THRESHOLD } from '../../../config';
import type { ChartJSOrUndefined } from '../../core/types';
import { getLegendItems } from './getLegendItems';
import type { ChartEncodes, ChartType } from '@buster/server-shared/metrics';
interface UseBusterChartJSLegendProps {
chartRef: React.RefObject<ChartJSOrUndefined | null>;
@ -28,7 +24,7 @@ interface UseBusterChartJSLegendProps {
selectedChartType: ChartType;
chartMounted: boolean;
selectedAxis: ChartEncodes | undefined;
showLegendHeadline: BusterMetricChartConfig['showLegendHeadline'] | undefined;
showLegendHeadline: BusterChartProps['showLegendHeadline'] | undefined;
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>;
loading: boolean;
lineGroupType: BusterChartProps['lineGroupType'];

View File

@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
import { barOptionsHandler, barPluginsHandler } from './barChartOptions';
import type { ChartSpecificOptionsProps } from './interfaces';
import type { ColumnSettings } from '@/api/asset_interfaces';
import type { ColumnSettings } from '@buster/server-shared/metrics';
type BarGroupType = 'stack' | 'group' | 'percentage-stack' | null;

View File

@ -1,9 +1,6 @@
import type { ChartType as ChartJSChartType } from 'chart.js';
import type {
BusterChartProps,
ChartEncodes,
ChartType
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartEncodes, ChartType } from '@buster/server-shared/metrics';
import type { ChartProps } from '../../core';
export interface UseChartSpecificOptionsProps {

View File

@ -3,6 +3,7 @@ import { describe, expect, it, vi } from 'vitest';
import { determineFontColorContrast } from '@/lib/colors';
import type { ChartSpecificOptionsProps } from './interfaces';
import { pieOptionsHandler, piePluginsHandler } from './pieChartOptions';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
vi.mock('@/lib/colors');
@ -62,7 +63,7 @@ describe('piePluginsHandler', () => {
category: []
} as ChartSpecificOptionsProps['selectedAxis'],
columnLabelFormats: {
value: { columnType: 'number', style: 'number' }
value: { columnType: 'number', style: 'number' } as any
},
barShowTotalAtTop: false,
columnSettings: {},
@ -96,7 +97,7 @@ describe('piePluginsHandler', () => {
category: []
} as ChartSpecificOptionsProps['selectedAxis'],
columnLabelFormats: {
value: { columnType: 'number', style: 'number' }
value: { columnType: 'number', style: 'number' } as ColumnLabelFormat
},
barShowTotalAtTop: false,
columnSettings: {},

View File

@ -5,11 +5,12 @@ import type { ChartType as ChartJSChartType, PluginChartOptions } from 'chart.js
import type { AnnotationPluginOptions } from 'chartjs-plugin-annotation';
import type { Context } from 'chartjs-plugin-datalabels';
import type { DeepPartial } from 'utility-types';
import type {
BusterChartConfigProps,
BusterChartProps,
ColumnLabelFormat
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartConfigProps,
type ColumnLabelFormat
} from '@buster/server-shared/metrics';
import { determineFontColorContrast } from '@/lib/colors';
import { formatLabel } from '@/lib/columnFormatter';
import { ArrayOperations } from '@/lib/math';
@ -131,7 +132,7 @@ export const piePluginsHandler = ({
const getInnerLabelValue = (
chart: ChartJSOrUndefined,
firstDatasetData: number[],
pieInnerLabelAggregate: BusterChartConfigProps['pieInnerLabelAggregate'],
pieInnerLabelAggregate: ChartConfigProps['pieInnerLabelAggregate'],
selectedAxis: ChartSpecificOptionsProps['selectedAxis'],
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>
): string => {
@ -150,7 +151,7 @@ const getInnerLabelValue = (
}
const yColumn = selectedAxis.y[0] || 'defaultYColumn';
const yColumnLabel = columnLabelFormats[yColumn];
const yColumnLabel = columnLabelFormats[yColumn] || DEFAULT_COLUMN_LABEL_FORMAT;
const formattedLabel = formatLabel(result, {
...yColumnLabel,
@ -163,6 +164,7 @@ const getInnerLabelValue = (
};
const percentStyle: ColumnLabelFormat = {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
style: 'percent'
};

View File

@ -1,11 +1,11 @@
import type { ChartType as ChartJSChartType, PluginChartOptions } from 'chart.js';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartProps } from '../../core';
import { barOptionsHandler, barPluginsHandler } from './barChartOptions';
import type { ChartSpecificOptionsProps, UseChartSpecificOptionsProps } from './interfaces';
import { pieOptionsHandler, piePluginsHandler } from './pieChartOptions';
import type { ChartType } from '@buster/server-shared/metrics';
export const useChartSpecificOptions = ({
selectedChartType,

View File

@ -1,12 +1,12 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type {
BusterChartConfigProps,
ChartType,
GoalLine
} from '@/api/asset_interfaces/metric/charts';
import { useGoalLines } from './useGoalLines';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartConfigProps,
type ChartType,
type GoalLine
} from '@buster/server-shared/metrics';
describe('useGoalLines', () => {
const defaultParams = {
@ -15,9 +15,9 @@ describe('useGoalLines', () => {
columnLabelFormats: {},
yAxisKeys: ['metric1'],
y2AxisKeys: undefined,
lineGroupType: null as BusterChartConfigProps['lineGroupType'],
barLayout: 'vertical' as BusterChartConfigProps['barLayout'],
barGroupType: 'group' as BusterChartConfigProps['barGroupType']
lineGroupType: null as ChartConfigProps['lineGroupType'],
barLayout: 'vertical' as ChartConfigProps['barLayout'],
barGroupType: 'group' as ChartConfigProps['barGroupType']
};
const mockGoalLine: GoalLine = {
@ -37,7 +37,7 @@ describe('useGoalLines', () => {
const params = {
...defaultParams,
goalLines: [mockGoalLine],
barGroupType: 'percentage-stack' as BusterChartConfigProps['barGroupType']
barGroupType: 'percentage-stack' as ChartConfigProps['barGroupType']
};
const { result } = renderHook(() => useGoalLines(params));
expect(result.current).toEqual([]);
@ -73,7 +73,7 @@ describe('useGoalLines', () => {
it('should generate correct annotation for a horizontal bar chart', () => {
const params = {
...defaultParams,
barLayout: 'horizontal' as BusterChartConfigProps['barLayout'],
barLayout: 'horizontal' as ChartConfigProps['barLayout'],
goalLines: [mockGoalLine],
columnLabelFormats: {
metric1: DEFAULT_COLUMN_LABEL_FORMAT

View File

@ -12,9 +12,9 @@
import type { AnnotationOptions, AnnotationPluginOptions } from 'chartjs-plugin-annotation';
import { useMemo } from 'react';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
import type {
BusterChartConfigProps,
ChartConfigProps,
ChartType,
ColumnLabelFormat,
GoalLine
@ -30,17 +30,17 @@ interface UseGoalLinesParams {
/** The type of chart being rendered */
selectedChartType: ChartType;
/** Format configurations for column labels */
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
/** Array of keys for the y-axis */
yAxisKeys: string[];
/** Optional array of keys for the secondary y-axis */
y2AxisKeys: string[] | undefined;
/** Type of line grouping */
lineGroupType: BusterChartConfigProps['lineGroupType'];
lineGroupType: ChartConfigProps['lineGroupType'];
/** Layout configuration for bar charts */
barLayout: BusterChartConfigProps['barLayout'];
barLayout: ChartConfigProps['barLayout'];
/** Type of bar grouping */
barGroupType: BusterChartConfigProps['barGroupType'];
barGroupType: ChartConfigProps['barGroupType'];
}
/**

View File

@ -1,7 +1,11 @@
import { renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import type { ChartEncodes, IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import {
type ChartEncodes,
type ColumnLabelFormat,
type SimplifiedColumnType
} from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib/columnFormatter';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
import { useXAxisTitle } from './useXAxisTitle';
@ -22,16 +26,16 @@ describe('useXAxisTitle', () => {
date: {
columnType: 'date' as SimplifiedColumnType,
style: 'date' as const
},
} as ColumnLabelFormat,
category: {
columnType: 'string' as SimplifiedColumnType,
style: 'string' as const
},
} as ColumnLabelFormat,
value: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
} as Record<string, IColumnLabelFormat>,
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>,
isSupportedChartForAxisTitles: true,
xAxisShowAxisTitle: true,
xAxisAxisTitle: '',

View File

@ -1,15 +1,16 @@
import { useMemo } from 'react';
import type { BusterChartConfigProps, ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { AXIS_TITLE_SEPARATOR } from '../../../../commonHelpers/axisHelper';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
import type { ChartEncodes } from '@buster/server-shared/metrics';
interface UseXAxisTitleProps {
xAxis: string[];
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>;
isSupportedChartForAxisTitles: boolean;
xAxisAxisTitle: BusterChartConfigProps['xAxisAxisTitle'];
xAxisShowAxisTitle: BusterChartConfigProps['xAxisShowAxisTitle'];
xAxisAxisTitle: BusterChartProps['xAxisAxisTitle'];
xAxisShowAxisTitle: BusterChartProps['xAxisShowAxisTitle'];
selectedAxis: ChartEncodes;
}

View File

@ -1,10 +1,10 @@
import { renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
import { useY2AxisTitle } from './useY2AxisTitle';
import type { ColumnLabelFormat, SimplifiedColumnType } from '@buster/server-shared/metrics';
// Mock the dependencies
vi.mock('@/lib/columnFormatter', () => ({
@ -23,17 +23,17 @@ describe('useY2AxisTitle', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
profit: {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
count: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
} as Record<string, IColumnLabelFormat>,
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>,
isSupportedChartForAxisTitles: true,
y2AxisShowAxisTitle: true,
y2AxisAxisTitle: ''

View File

@ -1,10 +1,13 @@
import { renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import type { ChartEncodes, IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
import { useYAxisTitle } from './useYAxisTitle';
import type {
ChartEncodes,
ColumnLabelFormat,
SimplifiedColumnType
} from '@buster/server-shared/metrics';
// Mock the dependencies
vi.mock('@/lib/columnFormatter', () => ({
@ -22,20 +25,20 @@ describe('useYAxisTitle', () => {
date: {
columnType: 'date' as SimplifiedColumnType,
style: 'date' as const
},
} as ColumnLabelFormat,
category: {
columnType: 'string' as SimplifiedColumnType,
style: 'string' as const
},
} as ColumnLabelFormat,
value: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
},
} as ColumnLabelFormat,
count: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
} as Record<string, IColumnLabelFormat>,
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>,
isSupportedChartForAxisTitles: true,
yAxisShowAxisTitle: true,
yAxisAxisTitle: '',

View File

@ -1,15 +1,16 @@
import { useMemo } from 'react';
import type { BusterChartConfigProps, ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { AXIS_TITLE_SEPARATOR } from '../../../../commonHelpers/axisHelper';
import { truncateWithEllipsis } from '../../../../commonHelpers/titleHelpers';
import type { ChartEncodes } from '@buster/server-shared/metrics';
interface UseYAxisTitleProps {
yAxis: string[];
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>;
isSupportedChartForAxisTitles: boolean;
yAxisAxisTitle: BusterChartConfigProps['yAxisAxisTitle'];
yAxisShowAxisTitle: BusterChartConfigProps['yAxisShowAxisTitle'];
yAxisAxisTitle: BusterChartProps['yAxisAxisTitle'];
yAxisShowAxisTitle: BusterChartProps['yAxisShowAxisTitle'];
selectedAxis: ChartEncodes;
}

View File

@ -1,8 +1,9 @@
import type { AnimationOptions, ChartType as ChartTypeJS } from 'chart.js';
import { useMemo } from 'react';
import type { BusterChartProps, ChartType } from '@/api/asset_interfaces/metric';
import type { BusterChartProps } from '@/api/asset_interfaces/metric';
import { ANIMATION_DURATION, ANIMATION_THRESHOLD } from '../../../config';
import { barDelayAnimation } from '../../core/animations/barDelayAnimation';
import type { ChartType } from '@buster/server-shared/metrics';
export const useAnimations = ({
animate,

View File

@ -1,6 +1,6 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import type { BusterChartConfigProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import { useInteractions } from './useInteractions';
describe('useInteractions', () => {
@ -8,7 +8,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'scatter' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
})
);
@ -23,7 +23,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'bar' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
})
);
@ -38,7 +38,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'bar' as ChartType,
barLayout: 'horizontal' as BusterChartConfigProps['barLayout']
barLayout: 'horizontal' as ChartConfigProps['barLayout']
})
);
@ -53,7 +53,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'line' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
})
);
@ -68,7 +68,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'combo' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
})
);
@ -83,7 +83,7 @@ describe('useInteractions', () => {
const { result } = renderHook(() =>
useInteractions({
selectedChartType: 'pie' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
})
);
@ -92,7 +92,7 @@ describe('useInteractions', () => {
it('should memoize the result and not recalculate on rerenders with same props', () => {
const props = {
selectedChartType: 'bar' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
};
const { result, rerender } = renderHook(() => useInteractions(props));
@ -108,7 +108,7 @@ describe('useInteractions', () => {
const { result, rerender } = renderHook((props) => useInteractions(props), {
initialProps: {
selectedChartType: 'bar' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
}
});
@ -117,7 +117,7 @@ describe('useInteractions', () => {
// Rerender with different props
rerender({
selectedChartType: 'scatter' as ChartType,
barLayout: 'vertical' as BusterChartConfigProps['barLayout']
barLayout: 'vertical' as ChartConfigProps['barLayout']
});
// Result should be a different object

View File

@ -1,6 +1,5 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import { useIsStacked } from './useIsStacked';
describe('useIsStacked', () => {

View File

@ -1,5 +1,6 @@
import { useMemo } from 'react';
import { type BusterChartProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import { type BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
export const useIsStacked = ({
selectedChartType,

View File

@ -2,11 +2,7 @@ import type { ChartType as ChartJSChartType, PluginChartOptions } from 'chart.js
import type { AnnotationPluginOptions } from 'chartjs-plugin-annotation';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types';
import type {
BusterChartConfigProps,
BusterChartProps,
ChartEncodes
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { DatasetOptionsWithTicks } from '../../../chartHooks';
import {
LINE_DECIMATION_SAMPLES,
@ -22,11 +18,12 @@ import { useTooltipOptions } from './useTooltipOptions.ts/useTooltipOptions';
import { useXAxis } from './useXAxis';
import { useY2Axis } from './useY2Axis';
import { useYAxis } from './useYAxis';
import type { ChartConfigProps, ChartEncodes } from '@buster/server-shared/metrics';
interface UseOptionsProps {
colors: string[];
selectedChartType: BusterChartConfigProps['selectedChartType'];
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
selectedChartType: ChartConfigProps['selectedChartType'];
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
selectedAxis: ChartEncodes;
columnMetadata: NonNullable<BusterChartProps['columnMetadata']>;
barLayout: BusterChartProps['barLayout'];

View File

@ -1,7 +1,7 @@
import type { Chart, ChartType as ChartJSChartType, TooltipItem } from 'chart.js';
import type React from 'react';
import { useMemo } from 'react';
import { type BusterChartProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import { type BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { BusterChartTooltip } from '../../../../BusterChartTooltip';
import type { ITooltipItem } from '../../../../BusterChartTooltip/interfaces';

View File

@ -5,7 +5,7 @@ import type {
TooltipItem
} from 'chart.js';
import { describe, expect, it } from 'vitest';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts/columnLabelInterfaces';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
import { barAndLineTooltipHelper } from './barAndLineTooltipHelper';
type MockDataset = Partial<
@ -54,19 +54,19 @@ describe('barAndLineTooltipHelper', () => {
}
} as unknown as Chart;
const mockColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const mockColumnLabelFormats: Record<string, ColumnLabelFormat> = {
value: {
columnType: 'number',
style: 'number'
},
} as ColumnLabelFormat,
percentage: {
columnType: 'number',
style: 'percent'
},
} as ColumnLabelFormat,
label: {
columnType: 'text',
style: 'string'
}
} as ColumnLabelFormat
};
const createMockDataset = (overrides = {}): MockDataset => ({

View File

@ -2,6 +2,7 @@ import type { Chart } from 'chart.js';
import { describe, expect, it } from 'vitest';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { getPercentage, percentageFormatter } from './helpers';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
describe('getPercentage', () => {
const mockChart = {
@ -24,7 +25,7 @@ describe('getPercentage', () => {
'test.field': {
style: 'percent',
columnType: 'number'
}
} as ColumnLabelFormat
};
it('should calculate series percentage when hasMultipleShownDatasets is false', () => {
@ -79,7 +80,7 @@ describe('percentageFormatter', () => {
'test.field': {
style: 'percent',
columnType: 'number'
}
} as ColumnLabelFormat
};
const result = percentageFormatter(
@ -96,7 +97,7 @@ describe('percentageFormatter', () => {
'test.field': {
style: 'number',
columnType: 'number'
}
} as ColumnLabelFormat
};
const result = percentageFormatter(33.333, 'test.field', columnLabelFormats);
@ -109,7 +110,7 @@ describe('percentageFormatter', () => {
field: {
style: 'percent',
columnType: 'number'
}
} as ColumnLabelFormat
};
const result = percentageFormatter(50, 'nested.field', columnLabelFormats);

View File

@ -1,6 +1,7 @@
import type { Chart } from 'chart.js';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ColumnLabelFormat } from '@buster/server-shared/metrics';
export const getPercentage = (
rawValue: number,
@ -50,7 +51,8 @@ export const percentageFormatter = (
yAxisKey: string,
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>
) => {
let columnLabelFormat = columnLabelFormats[yAxisKey];
let columnLabelFormat: Partial<ColumnLabelFormat> =
columnLabelFormats[yAxisKey] || DEFAULT_COLUMN_LABEL_FORMAT;
const isPercentage = columnLabelFormat?.style === 'percent';
if (!isPercentage) {
columnLabelFormat = {

View File

@ -1,6 +1,6 @@
import type { Chart, TooltipItem } from 'chart.js';
import { describe, expect, it } from 'vitest';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts/columnLabelInterfaces';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric/charts/columnLabelInterfaces';
import { pieTooltipHelper } from './pieTooltipHelper';
describe('pieTooltipHelper', () => {
@ -31,7 +31,7 @@ describe('pieTooltipHelper', () => {
}
} as unknown as Chart;
const mockColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const mockColumnLabelFormats: Record<string, ColumnLabelFormat> = {
value: {
columnType: 'number',
style: 'number'

View File

@ -1,8 +1,5 @@
import type { Chart, ChartTypeRegistry, TooltipItem } from 'chart.js';
import type {
BusterChartConfigProps,
BusterChartProps
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib';
import type { ITooltipItem } from '../../../../BusterChartTooltip/interfaces';
import { percentageFormatter } from './helpers';
@ -10,7 +7,7 @@ import { percentageFormatter } from './helpers';
export const pieTooltipHelper = (
dataPoints: TooltipItem<keyof ChartTypeRegistry>[],
chart: Chart,
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>,
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>,
keyToUsePercentage: string[]
): ITooltipItem[] => {
const tooltipItems = dataPoints.flatMap<ITooltipItem>((dataPoint) => {

View File

@ -1,11 +1,11 @@
import { renderHook } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type {
BusterChartProps,
ChartEncodes,
ChartType
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartEncodes,
type ChartType
} from '@buster/server-shared/metrics';
import { useTooltipOptions } from './useTooltipOptions';
// Mock necessary hooks and dependencies

View File

@ -4,17 +4,17 @@ import type { TooltipOptions } from 'chart.js';
import { useEffect, useMemo, useRef } from 'react';
import { renderToString } from 'react-dom/server';
import type { DeepPartial } from 'utility-types';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type {
BusterChartProps,
ChartEncodes,
ComboChartAxis
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn, useUnmount } from '@/hooks';
import { cn } from '@/lib/classMerge';
import { isNumericColumnType } from '@/lib/messages';
import type { ChartJSOrUndefined } from '../../../core/types';
import { BusterChartJSTooltip } from './BusterChartJSTooltip';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartEncodes,
type ComboChartAxis
} from '@buster/server-shared/metrics';
type TooltipContext = Parameters<TooltipOptions['external']>[0];

View File

@ -2,13 +2,14 @@ import '../../../ChartJSTheme';
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import type { ColumnSettings, SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import { useXAxis } from './useXAxis';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS
} from '@/api/asset_interfaces/metric';
import type { ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import { useXAxis } from './useXAxis';
DEFAULT_COLUMN_SETTINGS,
type ChartEncodes,
type ColumnSettings,
type SimplifiedColumnType
} from '@buster/server-shared/metrics';
describe('useXAxis', () => {
const defaultProps = {

View File

@ -3,25 +3,23 @@ import { Chart as ChartJS } from 'chart.js';
import isDate from 'lodash/isDate';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS
} from '@/api/asset_interfaces/metric';
import {
type BusterChartConfigProps,
type BusterChartProps,
type ChartEncodes,
ChartType,
type ColumnSettings,
type ComboChartAxis,
type IColumnLabelFormat,
type XAxisConfig
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn } from '@/hooks';
import { formatLabel, isNumericColumnType, truncateText } from '@/lib';
import { useXAxisTitle } from '../axisHooks/useXAxisTitle';
import { useIsStacked } from '../useIsStacked';
import { AUTO_DATE_FORMATS } from './config';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS,
type ChartConfigProps,
type ChartEncodes,
type ChartType,
type ColumnLabelFormat,
type ColumnSettings,
type ComboChartAxis,
type XAxisConfig
} from '@buster/server-shared/metrics';
const DEFAULT_X_AXIS_TICK_CALLBACK = ChartJS.defaults.scales.category?.ticks?.callback;
@ -39,7 +37,7 @@ export const useXAxis = ({
barGroupType,
xAxisTimeInterval
}: {
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
selectedAxis: ChartEncodes;
selectedChartType: ChartType;
xAxisLabelRotation: NonNullable<BusterChartProps['xAxisLabelRotation']>;
@ -62,10 +60,10 @@ export const useXAxis = ({
return !isPieChart;
}, [isPieChart]);
const xAxisColumnFormats: Record<string, IColumnLabelFormat> = useMemo(() => {
const xAxisColumnFormats: Record<string, ColumnLabelFormat> = useMemo(() => {
if (!isSupportedType) return {};
return selectedAxis.x.reduce<Record<string, IColumnLabelFormat>>((acc, x) => {
return selectedAxis.x.reduce<Record<string, ColumnLabelFormat>>((acc, x) => {
acc[x] = columnLabelFormats[x] || DEFAULT_COLUMN_LABEL_FORMAT;
return acc;
}, {});

View File

@ -1,7 +1,6 @@
import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { ChartType, type ComboChartAxis } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ComboChartAxis } from '@buster/server-shared/metrics';
import { useY2Axis } from './useY2Axis';
describe('useY2Axis', () => {

View File

@ -1,8 +1,7 @@
import { renderHook } from '@testing-library/react';
import type { LinearScaleOptions } from 'chart.js';
import { describe, expect, it } from 'vitest';
import { ChartType, DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ChartEncodes } from '@buster/server-shared/metrics';
import { useYAxis } from './useYAxis';
describe('useYAxis', () => {

View File

@ -1,18 +1,18 @@
import type { GridLineOptions, Scale, ScaleChartOptions } from 'chart.js';
import { useMemo } from 'react';
import type { DeepPartial } from 'utility-types';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import {
type BusterChartConfigProps,
type BusterChartProps,
type ChartEncodes,
ChartType,
type IColumnLabelFormat
} from '@/api/asset_interfaces/metric/charts';
import { useMemoizedFn } from '@/hooks';
import { formatYAxisLabel, yAxisSimilar } from '../../../commonHelpers';
import { useYAxisTitle } from './axisHooks/useYAxisTitle';
import { useIsStacked } from './useIsStacked';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartConfigProps,
type ChartEncodes,
type ChartType,
type ColumnLabelFormat
} from '@buster/server-shared/metrics';
import type { BusterChartProps } from '@/api/asset_interfaces/metric';
export const useYAxis = ({
columnLabelFormats,
@ -28,7 +28,7 @@ export const useYAxis = ({
yAxisScaleType,
gridLines
}: {
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
selectedAxis: ChartEncodes;
selectedChartType: ChartType;
columnMetadata: NonNullable<BusterChartProps['columnMetadata']> | undefined;
@ -60,10 +60,10 @@ export const useYAxis = ({
return false;
}, [lineGroupType, selectedChartType, barGroupType, isSupportedType]);
const yAxisColumnFormats: Record<string, IColumnLabelFormat> = useMemo(() => {
const yAxisColumnFormats: Record<string, ColumnLabelFormat> = useMemo(() => {
if (!isSupportedType) return {};
return selectedAxis.y.reduce<Record<string, IColumnLabelFormat>>((acc, y) => {
return selectedAxis.y.reduce<Record<string, ColumnLabelFormat>>((acc, y) => {
acc[y] = columnLabelFormats[y] || DEFAULT_COLUMN_LABEL_FORMAT;
return acc;
}, {});

View File

@ -1,6 +1,10 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_SETTINGS, type BusterChartProps } from '@/api/asset_interfaces/metric';
import { ChartType } from '@/api/asset_interfaces/metric/charts/enum';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS,
type ColumnLabelFormat
} from '@buster/server-shared/metrics';
import type { DatasetOption } from '../../../chartHooks';
import type { DatasetOptionsWithTicks } from '../../../chartHooks/useDatasetOptions/interfaces';
import { barSeriesBuilder } from './barSeriesBuilder';
@ -46,7 +50,7 @@ describe('barSeriesBuilder', () => {
suffix: '',
replaceMissingDataWith: 0,
makeLabelHumanReadable: true
}
} as ColumnLabelFormat
},
barShowTotalAtTop: false,
barGroupType: 'group',
@ -127,7 +131,7 @@ describe('barSeriesBuilder', () => {
suffix: '',
replaceMissingDataWith: 0,
makeLabelHumanReadable: true
},
} as ColumnLabelFormat,
sales2023: {
columnType: 'number',
style: 'number',
@ -138,7 +142,7 @@ describe('barSeriesBuilder', () => {
suffix: '',
replaceMissingDataWith: 0,
makeLabelHumanReadable: true
}
} as ColumnLabelFormat
},
barShowTotalAtTop: false,
barGroupType: 'group',
@ -215,7 +219,7 @@ describe('barSeriesBuilder', () => {
suffix: '%',
replaceMissingDataWith: 0,
makeLabelHumanReadable: true
}
} as ColumnLabelFormat
},
barShowTotalAtTop: false,
barGroupType: 'group',

View File

@ -1,11 +1,8 @@
import type { BarElement } from 'chart.js';
import type { Context } from 'chartjs-plugin-datalabels';
import type { Options } from 'chartjs-plugin-datalabels/types/options';
import {
type BusterChartProps,
DEFAULT_COLUMN_LABEL_FORMAT,
type IColumnLabelFormat
} from '@/api/asset_interfaces/metric';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ColumnLabelFormat } from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib';
import type { DatasetOption } from '../../../chartHooks';
import {
@ -339,7 +336,7 @@ const getFormattedValueAndSetBarDataLabels = (
columnLabelFormat
}: {
percentageMode: false | 'stacked' | 'data-label';
columnLabelFormat: IColumnLabelFormat;
columnLabelFormat: ColumnLabelFormat;
}
) => {
const rawValue = context.dataset.data[context.dataIndex] as number;

View File

@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_SETTINGS } from '@/api/asset_interfaces/metric';
import { comboSeriesBuilder_data } from './comboSeriesBuilder';
import { DEFAULT_COLUMN_SETTINGS } from '@buster/server-shared/metrics';
describe('comboSeriesBuilder_data', () => {
const mockColors = ['#000000', '#111111'];

View File

@ -1,11 +1,14 @@
import { DEFAULT_COLUMN_SETTINGS, ENABLED_DOTS_ON_LINE_SIZE } from '@/api/asset_interfaces/metric';
import type { ColumnSettings } from '@/api/asset_interfaces/metric/charts';
import type { DatasetOption } from '../../../chartHooks';
import type { ChartProps } from '../../core';
import { barBuilder } from './barSeriesBuilder';
import type { SeriesBuilderProps } from './interfaces';
import { lineBuilder, lineSeriesBuilder_labels } from './lineSeriesBuilder';
import type { LabelBuilderProps } from './useSeriesOptions';
import {
DEFAULT_COLUMN_SETTINGS,
ENABLED_DOTS_ON_LINE_SIZE,
type ColumnSettings
} from '@buster/server-shared/metrics';
type ComboSeries = Array<
ChartProps<'bar'>['data']['datasets'][number] | ChartProps<'line'>['data']['datasets'][number]

View File

@ -1,8 +1,4 @@
import {
type BusterChartProps,
type ChartEncodes,
DEFAULT_TRENDLINE_CONFIG
} from '@/api/asset_interfaces/metric';
import { type BusterChartProps } from '@/api/asset_interfaces/metric';
import { formatLabel } from '@/lib/columnFormatter';
import type {
AggregateMultiple,
@ -11,6 +7,7 @@ import type {
} from '../../core/plugins/chartjs-plugin-trendlines';
import { canSupportTrendlineRecord } from '../../core/plugins/chartjs-plugin-trendlines/canSupportTrendline';
import { TypeToLabel } from '../../core/plugins/chartjs-plugin-trendlines/config';
import { DEFAULT_TRENDLINE_CONFIG, type ChartEncodes } from '@buster/server-shared/metrics';
export const createTrendlineOnSeries = ({
trendlines,

View File

@ -1,5 +1,6 @@
import type { BusterChartProps, ChartEncodes } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { DatasetOptionsWithTicks } from '../../../chartHooks';
import type { ChartEncodes } from '@buster/server-shared/metrics';
export interface SeriesBuilderProps {
datasetOptions: DatasetOptionsWithTicks;

View File

@ -1,16 +1,14 @@
import type { ChartDataset, ScriptableContext } from 'chart.js';
import { describe, expect, it, vi } from 'vitest';
import type {
BusterChartProps,
ChartEncodes,
ColumnSettings,
IColumnLabelFormat,
ScatterAxis
} from '@/api/asset_interfaces/metric';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS
} from '@/api/asset_interfaces/metric/defaults';
DEFAULT_COLUMN_SETTINGS,
type ChartEncodes,
type ColumnLabelFormat,
type ColumnSettings,
type ScatterAxis
} from '@buster/server-shared/metrics';
import { createDayjsDate, formatLabel } from '@/lib';
import type { DatasetOption, DatasetOptionsWithTicks, KV } from '../../../chartHooks';
import { formatBarAndLineDataLabel } from '../../helpers';
@ -105,18 +103,18 @@ describe('lineSeriesBuilder', () => {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
style: 'number'
} as IColumnLabelFormat,
} as ColumnLabelFormat,
metric2: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
style: 'currency',
currency: 'USD'
} as IColumnLabelFormat,
} as ColumnLabelFormat,
metric3: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
style: 'percent'
} as IColumnLabelFormat
} as ColumnLabelFormat
} as ColumnLabelFormatMap,
xAxisKeys: ['category'] as ChartEncodes['x'],
lineGroupType: null,
@ -284,12 +282,12 @@ describe('lineSeriesBuilder', () => {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'date',
style: 'date'
} as IColumnLabelFormat,
} as ColumnLabelFormat,
category: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'text',
style: 'string'
} as IColumnLabelFormat
} as ColumnLabelFormat
} as ColumnLabelFormatMap,
columnSettings: {} as ColumnSettingsMap,
sizeKey: [] as ScatterAxis['size'],

View File

@ -1,9 +1,4 @@
import { Chart, Filler, type ScriptableContext } from 'chart.js';
import type { ColumnSettings } from '@/api/asset_interfaces/metric/charts';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS
} from '@/api/asset_interfaces/metric/defaults';
import { addOpacityToColor, createDayjsDate, formatLabel } from '@/lib';
import type { DatasetOption } from '../../../chartHooks';
import { formatLabelForDataset, JOIN_CHARACTER } from '../../../commonHelpers';
@ -13,6 +8,11 @@ import { defaultLabelOptionConfig } from '../useChartSpecificOptions/labelOption
import { createTrendlineOnSeries } from './createTrendlines';
import type { SeriesBuilderProps } from './interfaces';
import type { LabelBuilderProps } from './useSeriesOptions';
import {
DEFAULT_COLUMN_LABEL_FORMAT,
DEFAULT_COLUMN_SETTINGS,
type ColumnSettings
} from '@buster/server-shared/metrics';
Chart.register(Filler);

View File

@ -1,6 +1,5 @@
import { describe, expect, it } from 'vitest';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ColumnLabelFormat } from '@buster/server-shared/metrics';
import { createDayjsDate } from '@/lib/date';
import type { DatasetOptionsWithTicks } from '../../../chartHooks/useDatasetOptions/interfaces';
import type { SeriesBuilderProps } from './interfaces';
@ -38,7 +37,7 @@ describe('scatterSeriesBuilder_data', () => {
ticksKey: [{ key: 'timestamp', value: 'Timestamp' }]
};
const baseColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const baseColumnLabelFormats: Record<string, Partial<ColumnLabelFormat>> = {
timestamp: {
columnType: 'date',
style: 'date'
@ -52,7 +51,7 @@ describe('scatterSeriesBuilder_data', () => {
const baseProps: SeriesBuilderProps = {
colors: mockColors,
scatterDotSize: mockScatterDotSize,
columnLabelFormats: baseColumnLabelFormats,
columnLabelFormats: baseColumnLabelFormats as Record<string, ColumnLabelFormat>,
xAxisKeys: mockXAxisKeys,
sizeOptions: null,
datasetOptions: baseDatasetOptions,

View File

@ -1,5 +1,4 @@
import type { BubbleDataPoint, ScriptableContext } from 'chart.js';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { addOpacityToColor } from '@/lib/colors';
import { createDayjsDate } from '@/lib/date';
import { isDateColumnType } from '@/lib/messages';
@ -8,6 +7,7 @@ import type { ChartProps } from '../../core';
import { createTrendlineOnSeries } from './createTrendlines';
import type { SeriesBuilderProps } from './interfaces';
import type { LabelBuilderProps } from './useSeriesOptions';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
declare module 'chart.js' {
interface BubbleDataPoint {

View File

@ -1,13 +1,6 @@
import type { ChartType as ChartJSChartType } from 'chart.js';
import { useMemo } from 'react';
import type {
BusterChartConfigProps,
BusterChartProps,
ChartEncodes,
ChartType,
ScatterAxis
} from '@/api/asset_interfaces/metric/charts';
import type { ColumnMetaData } from '@/api/asset_interfaces/metric/interfaces';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { isNumericColumnType } from '@/lib';
import type { DatasetOptionsWithTicks } from '../../../chartHooks';
import type { ChartProps } from '../../core';
@ -17,6 +10,13 @@ import type { SeriesBuilderProps } from './interfaces';
import { lineSeriesBuilder, lineSeriesBuilder_labels } from './lineSeriesBuilder';
import { pieSeriesBuilder_data, pieSeriesBuilder_labels } from './pieSeriesBuilder';
import { scatterSeriesBuilder_data, scatterSeriesBuilder_labels } from './scatterSeriesBuilder';
import type {
ChartConfigProps,
ChartEncodes,
ChartType,
ColumnMetaData,
ScatterAxis
} from '@buster/server-shared/metrics';
export interface UseSeriesOptionsProps {
selectedChartType: ChartType;
@ -24,8 +24,8 @@ export interface UseSeriesOptionsProps {
yAxisKeys: string[];
xAxisKeys: string[];
sizeKey: ScatterAxis['size'];
columnSettings: NonNullable<BusterChartConfigProps['columnSettings']>;
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnSettings: NonNullable<ChartConfigProps['columnSettings']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
colors: string[];
datasetOptions: DatasetOptionsWithTicks;
scatterDotSize: BusterChartProps['scatterDotSize'];

View File

@ -1,5 +1,4 @@
import React from 'react';
import type { ShowLegendHeadline } from '@/api/asset_interfaces/metric/charts';
import { cn } from '@/lib/classMerge';
import { CircleSpinnerLoader } from '../../loaders';
import {
@ -8,6 +7,7 @@ import {
} from '../chartHooks/useChartWrapperProvider';
import { BusterChartLegend, type BusterChartLegendItem } from '.';
import { DownsampleAlert } from './DownsampleAlert';
import type { ShowLegendHeadline } from '@buster/server-shared/metrics';
export type BusterChartLegendWrapper = {
children: React.ReactNode;

View File

@ -1,6 +1,6 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import { LegendItemDot } from './LegendDot';
describe('LegendItemDot', () => {

View File

@ -1,6 +1,6 @@
import { cva, type VariantProps } from 'class-variance-authority';
import React, { useMemo } from 'react';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import { useMemoizedFn } from '@/hooks';
import { cn } from '@/lib/classMerge';
import { Target } from '../../icons';

View File

@ -1,6 +1,6 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import type { BusterChartLegendItem } from './interfaces';
import { LegendItem } from './LegendItem';

View File

@ -1,6 +1,6 @@
import { useVirtualizer } from '@tanstack/react-virtual';
import React from 'react';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import { Popover } from '@/components/ui/popover/Popover';
import { cn } from '@/lib/classMerge';
import type { BusterChartLegendItem, BusterChartLegendProps } from './interfaces';

View File

@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import { computeHiddenShowItems } from './helpers';
import type { BusterChartLegendItem } from './interfaces';

View File

@ -1,5 +1,5 @@
import type { ChartDataset } from 'chart.js';
import type { ChartType, ShowLegendHeadline } from '@/api/asset_interfaces/metric/charts';
import type { ChartType, ShowLegendHeadline } from '@buster/server-shared/metrics';
export interface BusterChartLegendProps {
animateLegend: boolean;

View File

@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest';
import type { ColumnMetaData, SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import {
ChartType,
type IColumnLabelFormat,
type ColumnLabelFormat,
type ShowLegendHeadline
} from '@/api/asset_interfaces/metric/charts';
import type { DatasetOptionsWithTicks } from '../chartHooks/useDatasetOptions/interfaces';
@ -39,7 +39,7 @@ describe('legendHeadlineHelpers', () => {
}
];
const mockColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const mockColumnLabelFormats: Record<string, ColumnLabelFormat> = {
timestamp: {
columnType: 'timestamp' as SimplifiedColumnType,
style: 'date'
@ -237,7 +237,7 @@ describe('legendHeadlineHelpers', () => {
}
];
const currencyColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const currencyColumnLabelFormats: Record<string, ColumnLabelFormat> = {
...mockColumnLabelFormats,
revenue: {
columnType: 'number' as SimplifiedColumnType,
@ -274,7 +274,7 @@ describe('legendHeadlineHelpers', () => {
}
];
const prefixColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const prefixColumnLabelFormats: Record<string, ColumnLabelFormat> = {
...mockColumnLabelFormats,
users: {
columnType: 'number' as SimplifiedColumnType,

View File

@ -1,9 +1,9 @@
import type { BusterMetricChartConfig } from '@/api/asset_interfaces/metric';
import type { BusterChartProps, ShowLegendHeadline } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { ArrayOperations } from '@/lib/math';
import type { DatasetOptionsWithTicks } from '../chartHooks';
import type { BusterChartLegendItem } from './interfaces';
import type { ShowLegendHeadline, ChartConfigProps } from '@buster/server-shared/metrics';
export const addLegendHeadlines = (
legendItems: BusterChartLegendItem[],
@ -11,30 +11,13 @@ export const addLegendHeadlines = (
showLegendHeadline: ShowLegendHeadline,
columnMetadata: NonNullable<BusterChartProps['columnMetadata']>,
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>,
selectedChartType: BusterMetricChartConfig['selectedChartType'],
selectedChartType: ChartConfigProps['selectedChartType'],
xAxisKeys: string[]
) => {
const isScatterChart = selectedChartType === 'scatter';
if (!showLegendHeadline || isScatterChart) return legendItems;
// const hasMultipleXAxisDimensions = xAxisKeys.length > 1;
// const firstXAxisDimensionName = xAxisKeys[0];
// const xIsDate = isDateColumnType(columnLabelFormats[firstXAxisDimensionName]?.columnType);
// const canUseRange = !hasMultipleXAxisDimensions && xIsDate;
// let range: string;
// if (canUseRange) {
// const firstXAxisDimensionMetadata = columnMetadata.find(
// (metadata) => metadata.name === firstXAxisDimensionName
// );
// const { min_value, max_value } = firstXAxisDimensionMetadata || {};
// const minDate = createDayjsDate((min_value as string) || new Date());
// const maxDate = createDayjsDate((max_value as string) || new Date());
// const dateFormat = getBestDateFormat(minDate, maxDate);
// range = `${minDate.format(dateFormat)} - ${maxDate.format(dateFormat)}`;
// }
const isPieChart = selectedChartType === 'pie';
legendItems.forEach((item, index) => {

View File

@ -1,5 +1,4 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ChartType } from '../../../../../api/asset_interfaces/metric/charts';
import { BusterChartLegend } from '../BusterChartLegend';
import type { BusterChartLegendItem } from '../interfaces';

View File

@ -1,6 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { ChartType } from '../../../../../api/asset_interfaces/metric/charts';
import { LegendItemDot } from '../LegendDot';
const meta = {

View File

@ -1,6 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { ChartType } from '../../../../../api/asset_interfaces/metric/charts';
import { LegendItem } from '../LegendItem';
const meta = {

View File

@ -1,6 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { ChartType } from '../../../../../api/asset_interfaces/metric/charts';
import type { BusterChartLegendItem } from '../interfaces';
import { OverflowButton } from '../OverflowContainer';

View File

@ -1,10 +1,9 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { describe, expect, it } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric/charts/enum';
import type { BusterChartLegendItem } from './interfaces';
import { useBusterChartLegend } from './useBusterChartLegend';
import type { ChartEncodes } from '@/api/asset_interfaces';
import type { ChartEncodes } from '@buster/server-shared/metrics';
describe('useBusterChartLegend', () => {
const defaultProps = {

View File

@ -1,13 +1,7 @@
'use client';
import { useMemo, useState } from 'react';
import type {
BusterChartProps,
ChartEncodes,
ChartType,
ComboChartAxis,
ScatterAxis
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { useUpdateEffect } from '@/hooks';
import {
DEFAULT_CATEGORY_AXIS_COLUMN_NAMES,
@ -16,6 +10,12 @@ import {
} from './config';
import type { BusterChartLegendItem } from './interfaces';
import { useLegendAutoShow } from './useLegendAutoShow';
import type {
ChartType,
ChartEncodes,
ComboChartAxis,
ScatterAxis
} from '@buster/server-shared/metrics';
interface UseBusterChartLegendProps {
selectedChartType: ChartType;

View File

@ -1,5 +1,5 @@
import type React from 'react';
import type { ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartType } from '@buster/server-shared/metrics';
import { cn } from '@/lib/classMerge';
import { LegendItemDot } from '../BusterChartLegend/LegendDot';
import type { ITooltipItem, TooltipItemValueProps } from './interfaces';

View File

@ -1,5 +1,5 @@
import type React from 'react';
import type { ChartType } from '@/api/asset_interfaces/metric';
import type { ChartType } from '@buster/server-shared/metrics';
import { LegendItemDot } from '../BusterChartLegend';
export const TooltipTitle: React.FC<{

View File

@ -1,7 +1,8 @@
import type React from 'react';
import { useMemo } from 'react';
import type { BusterChartProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { useMount } from '@/hooks';
import type { ChartType } from '@buster/server-shared/metrics';
export const NoValidAxis: React.FC<{
type: ChartType;

View File

@ -1,11 +1,15 @@
import { AnimatePresence, motion, type MotionProps } from 'framer-motion';
import React, { useMemo } from 'react';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { ColumnLabelFormat, MetricChartProps } from '@/api/asset_interfaces/metric/charts';
import { Title } from '@/components/ui/typography';
import { useMount } from '@/hooks';
import { formatLabel, JsonDataFrameOperationsSingle, timeout } from '@/lib';
import type { BusterMetricChartProps } from './interfaces';
import {
DEFAULT_CHART_CONFIG,
DEFAULT_COLUMN_LABEL_FORMAT,
type ChartConfigProps,
type ColumnLabelFormat
} from '@buster/server-shared/metrics';
export const BusterMetricChart: React.FC<BusterMetricChartProps> = React.memo(
({
@ -23,7 +27,7 @@ export const BusterMetricChart: React.FC<BusterMetricChartProps> = React.memo(
}) => {
const firstRow = data?.[0];
const firstRowValue = firstRow?.[metricColumnId];
const yLabelFormat = columnLabelFormats[metricColumnId];
const yLabelFormat = columnLabelFormats[metricColumnId] || DEFAULT_COLUMN_LABEL_FORMAT;
const headerColumnLabelFormat: ColumnLabelFormat = useMemo(() => {
const isDerivedTitle = typeof metricHeader === 'object' && metricHeader?.columnId;
@ -218,9 +222,9 @@ const AnimatedTitleWrapper = ({ title, type }: { title: string; type: 'header' |
const fallbackAggregate = (
columnId: string,
aggregate: MetricChartProps['metricValueAggregate'],
aggregate: ChartConfigProps['metricValueAggregate'],
columnLabelFormats: BusterMetricChartProps['columnLabelFormats']
): NonNullable<MetricChartProps['metricValueAggregate']> => {
): NonNullable<ChartConfigProps['metricValueAggregate']> => {
const columnLabelFormat = columnLabelFormats[columnId] || DEFAULT_COLUMN_LABEL_FORMAT;
const isNumber =
columnLabelFormat.style === 'number' && columnLabelFormat.columnType === 'number';

View File

@ -1,9 +1,5 @@
import type {
BusterChartProps,
BusterChartPropsBase,
MetricChartProps
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps, BusterChartPropsBase } from '@/api/asset_interfaces/metric/charts';
import { MetricChartProps } from '@buster/server-shared/metrics';
export interface BusterMetricChartProps extends MetricChartProps, BusterChartPropsBase {
columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']>;
}

View File

@ -1,10 +1,10 @@
import isEmpty from 'lodash/isEmpty';
import React, { useCallback } from 'react';
import {
type BusterChartPropsBase,
DEFAULT_CHART_CONFIG,
type BusterMetricChartConfig
} from '@/api/asset_interfaces/metric';
type BusterChartPropsBase,
type ChartConfigProps
} from '@buster/server-shared/metrics';
import { AppDataGrid } from '@/components/ui/table/AppDataGrid';
import { useUpdateMetricChart } from '@/context/Metrics';
import { useMemoizedFn } from '@/hooks';
@ -30,7 +30,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
}) => {
const { onUpdateMetricChartConfig, onInitializeTableColumnWidths } = useUpdateMetricChart();
const onChangeConfig = useMemoizedFn((config: Partial<BusterMetricChartConfig>) => {
const onChangeConfig = useMemoizedFn((config: Partial<ChartConfigProps>) => {
if (readOnly) return;
onUpdateMetricChartConfig({ chartConfig: config });
if (
@ -42,7 +42,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
});
const onUpdateTableColumnOrder = useMemoizedFn((columns: string[]) => {
const config: Partial<BusterMetricChartConfig> = {
const config: Partial<ChartConfigProps> = {
tableColumnOrder: columns
};
@ -51,7 +51,7 @@ const BusterTableChartBase: React.FC<BusterTableChartProps> = ({
const onUpdateTableColumnSize = useMemoizedFn((columns: { key: string; size: number }[]) => {
if (readOnly) return;
const config: Partial<BusterMetricChartConfig> = {
const config: Partial<ChartConfigProps> = {
tableColumnWidths: columns.reduce<Record<string, number>>((acc, { key, size }) => {
acc[key] = Number(size.toFixed(1));
return acc;

View File

@ -1,11 +1,11 @@
import type { BusterChartConfigProps, ChartType } from '@/api/asset_interfaces/metric/charts';
import type { ChartConfigProps } from '@buster/server-shared/metrics';
export type BusterTableChartConfig = {
type: 'table';
tableColumnOrder?: BusterChartConfigProps['tableColumnOrder'];
tableColumnWidths?: BusterChartConfigProps['tableColumnWidths'];
tableColumnOrder?: ChartConfigProps['tableColumnOrder'];
tableColumnWidths?: ChartConfigProps['tableColumnWidths'];
tableHeaderBackgroundColor?: string | null;
tableHeaderFontColor?: string | null;
tableColumnFontColor?: string | null;
columnLabelFormats?: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats?: NonNullable<ChartConfigProps['columnLabelFormats']>;
};

View File

@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { ChartType } from '@/api/asset_interfaces/metric';
import type { ChartType } from '@buster/server-shared/metrics';
import type { DatasetOption } from './useDatasetOptions';
export const useColors = ({

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT, type IColumnLabelFormat } from '@/api/asset_interfaces';
import { DEFAULT_COLUMN_LABEL_FORMAT, type ColumnLabelFormat } from '@/api/asset_interfaces';
import { aggregateAndCreateDatasets } from './aggregateAndCreateDatasets';
describe('aggregateAndCreateDatasets', () => {
@ -45,7 +45,7 @@ describe('aggregateAndCreateDatasets', () => {
{ region: 'South', category: 'B', sales: 250, profit: 50 }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
sales: {
...DEFAULT_COLUMN_LABEL_FORMAT,
style: 'currency',
@ -97,7 +97,7 @@ describe('aggregateAndCreateDatasets', () => {
{ region: 'South', sales: 250 }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
sales: {
...DEFAULT_COLUMN_LABEL_FORMAT,
style: 'currency',
@ -177,7 +177,7 @@ describe('aggregateAndCreateDatasets', () => {
{ region: 'South', category: 'B', sales: 250, profit: 50 }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
sales: {
...DEFAULT_COLUMN_LABEL_FORMAT,
style: 'currency',
@ -229,7 +229,7 @@ describe('aggregateAndCreateDatasets', () => {
{ region: 'South', sales: 250 }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
sales: {
...DEFAULT_COLUMN_LABEL_FORMAT,
style: 'currency',
@ -764,7 +764,7 @@ describe('aggregateAndCreateDatasets', () => {
{ x: 3, y: undefined, size: null }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
y: {
...DEFAULT_COLUMN_LABEL_FORMAT,
replaceMissingDataWith: 0
@ -823,7 +823,7 @@ describe('aggregateAndCreateDatasets', () => {
{ id: 3, metric1: 120, metric2: null }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
metric1: {
...DEFAULT_COLUMN_LABEL_FORMAT,
replaceMissingDataWith: 0
@ -874,7 +874,7 @@ describe('aggregateAndCreateDatasets', () => {
{ x: 3, y: 200 }
];
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
y: {
...DEFAULT_COLUMN_LABEL_FORMAT,
replaceMissingDataWith: null

View File

@ -1,7 +1,7 @@
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
import type { DatasetOption, DatasetOptionsWithTicks, KV } from './interfaces';
type ColumnLabelFormatBase = Pick<ColumnLabelFormat, 'replaceMissingDataWith'>;
type ColumnLabelFormatBase = Pick<Partial<ColumnLabelFormat>, 'replaceMissingDataWith'>;
export function aggregateAndCreateDatasets<
T extends Record<string, string | number | null | Date | undefined>

View File

@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest';
import type { ColumnMetaData } from '@/api/asset_interfaces/metric';
import type { ColumnMetaData } from '@buster/server-shared/metrics';
import { sortLineBarData } from './datasetHelpers_BarLinePie';
describe('sortLineBarData', () => {

View File

@ -1,7 +1,7 @@
'use client';
import type { ColumnMetaData, SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import type { ColumnMetaData, SimplifiedColumnType } from '@buster/server-shared/metrics';
import { createDayjsDate } from '@/lib/date';
export const sortLineBarData = (

View File

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest';
import { ChartType } from '@/api/asset_interfaces/metric';
import type { DatasetOption, DatasetOptionsWithTicks } from './interfaces';
import { modifyDatasets } from './modifyDatasets';

View File

@ -1,12 +1,8 @@
import { sum as lodashSum } from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import {
type BarSortBy,
type BusterChartProps,
ChartType,
type PieSortBy
} from '@/api/asset_interfaces/metric';
import type { BarSortBy, ChartType, PieSortBy } from '@buster/server-shared/metrics';
import type { DatasetOption, DatasetOptionsWithTicks, KV } from './interfaces';
import type { BusterChartProps } from '@/api/asset_interfaces/metric';
// Helper: ensure pie slices meet minimum percentage
function handlePieThreshold(datasets: DatasetOption[], minPercent: number): DatasetOption[] {

View File

@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
import type { BusterChartProps, Trendline } from '@/api/asset_interfaces/metric/charts';
import { isNumericColumnType } from '@/lib/messages';
import { canSupportTrendlineRecord } from './canSupportTrendline';

View File

@ -1,6 +1,7 @@
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { BusterChartProps, Trendline } from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { isNumericColumnType } from '@/lib/messages';
import type { Trendline } from '@buster/server-shared/metrics';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
export const canSupportTrendlineRecord: Record<
Trendline['type'],

View File

@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import type { IColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
import type { ColumnLabelFormat } from '@/api/asset_interfaces/metric/charts';
import { dataMapper } from './dataMapper';
describe('dataMapper', () => {
@ -12,7 +12,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'xAxis', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
xAxis: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
@ -37,7 +37,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'date', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
date: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'date',
@ -69,7 +69,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'category', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
category: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'text',
@ -94,7 +94,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'xAxis', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
xAxis: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
@ -120,7 +120,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'xAxis', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
xAxis: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',
@ -140,7 +140,7 @@ describe('dataMapper', () => {
ticksKey: [{ key: 'xAxis', value: '' }]
};
const columnLabelFormats: Record<string, IColumnLabelFormat> = {
const columnLabelFormats: Record<string, ColumnLabelFormat> = {
xAxis: {
...DEFAULT_COLUMN_LABEL_FORMAT,
columnType: 'number',

View File

@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import type {
ChartType,
IColumnLabelFormat
ColumnLabelFormat
} from '../../../../../api/asset_interfaces/metric/charts';
import { useDatasetOptions } from './useDatasetOptions';
@ -13,7 +13,7 @@ describe('useDatasetOptions', () => {
{ month: 'Mar', sales: 300, profit: 150 }
];
const mockColumnLabelFormats: Record<string, IColumnLabelFormat> = {
const mockColumnLabelFormats: Record<string, ColumnLabelFormat> = {
sales: { columnType: 'number', style: 'number' },
profit: { columnType: 'number', style: 'number' },
month: { columnType: 'text', style: 'string' }

View File

@ -3,15 +3,15 @@
import isEmpty from 'lodash/isEmpty';
import uniq from 'lodash/uniq';
import { useMemo } from 'react';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@/api/asset_interfaces/metric';
import { DEFAULT_COLUMN_LABEL_FORMAT } from '@buster/server-shared/metrics';
import type {
BarSortBy,
BusterChartConfigProps,
ChartConfigProps,
BusterChartProps,
ChartEncodes,
ChartType,
ComboChartAxis,
IColumnLabelFormat,
ColumnLabelFormat,
PieSortBy,
ScatterAxis,
Trendline
@ -41,7 +41,7 @@ type DatasetHookParams = {
selectedAxis: ChartEncodes;
selectedChartType: ChartType;
pieMinimumSlicePercentage: NonNullable<BusterChartProps['pieMinimumSlicePercentage']> | undefined;
columnLabelFormats: NonNullable<BusterChartConfigProps['columnLabelFormats']>;
columnLabelFormats: NonNullable<ChartConfigProps['columnLabelFormats']>;
barGroupType: BusterChartProps['barGroupType'] | undefined;
lineGroupType: BusterChartProps['lineGroupType'];
trendlines: Trendline[] | undefined;
@ -87,7 +87,7 @@ export const useDatasetOptions = (params: DatasetHookParams): DatasetHookResult
const sizeFieldString = useMemo(() => sizeField?.join(','), [sizeField]);
const tooltipFieldsString = useMemo(() => tooltipFields.join(','), [tooltipFields]);
const xFieldColumnLabelFormatColumnTypes: IColumnLabelFormat['columnType'][] = useMemo(() => {
const xFieldColumnLabelFormatColumnTypes: ColumnLabelFormat['columnType'][] = useMemo(() => {
return xFields.map(
(field) => columnLabelFormats[field]?.columnType || DEFAULT_COLUMN_LABEL_FORMAT.columnType
);

View File

@ -1,5 +1,5 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import type { SimplifiedColumnType } from '@/api/asset_interfaces/metric';
import type { ColumnLabelFormat, SimplifiedColumnType } from '@buster/server-shared/metrics';
import { formatLabel } from '@/lib/columnFormatter';
import { formatYAxisLabel, yAxisSimilar } from './axisHelper';
@ -22,13 +22,13 @@ describe('formatYAxisLabel', () => {
growth: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
},
} as ColumnLabelFormat,
revenue: {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
const usePercentageModeAxis = true;
// Execute
@ -58,13 +58,13 @@ describe('formatYAxisLabel', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
cost: {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'EUR'
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
const usePercentageModeAxis = false;
const compactNumbers = true;
@ -101,12 +101,12 @@ describe('formatYAxisLabel', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
growth: {
columnType: 'number' as SimplifiedColumnType,
style: 'percent' as const
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
const usePercentageModeAxis = false;
const compactNumbers = true;
@ -141,8 +141,8 @@ describe('formatYAxisLabel', () => {
count: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
const usePercentageModeAxis = false;
const compactNumbers = false;
@ -177,8 +177,8 @@ describe('formatYAxisLabel', () => {
count: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
const usePercentageModeAxis = false;
// No compactNumbers parameter provided
@ -217,13 +217,13 @@ describe('yAxisSimilar', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
sales: {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
// Execute
const result = yAxisSimilar(yAxis, columnLabelFormats);
@ -240,12 +240,12 @@ describe('yAxisSimilar', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
percentage: {
columnType: 'number' as SimplifiedColumnType,
style: 'percent' as const
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
// Execute
const result = yAxisSimilar(yAxis, columnLabelFormats);
@ -262,13 +262,13 @@ describe('yAxisSimilar', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
},
} as ColumnLabelFormat,
eur_revenue: {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'EUR'
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
// Execute
const result = yAxisSimilar(yAxis, columnLabelFormats);
@ -285,8 +285,8 @@ describe('yAxisSimilar', () => {
columnType: 'number' as SimplifiedColumnType,
style: 'currency' as const,
currency: 'USD'
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
// Execute
const result = yAxisSimilar(yAxis, columnLabelFormats);
@ -302,12 +302,12 @@ describe('yAxisSimilar', () => {
value1: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
},
} as ColumnLabelFormat,
value2: {
columnType: 'number' as SimplifiedColumnType,
style: 'number' as const
}
};
} as ColumnLabelFormat
} as Record<string, ColumnLabelFormat>;
// Execute
const result = yAxisSimilar(yAxis, columnLabelFormats);

View File

@ -1,12 +1,9 @@
import isEqual from 'lodash/isEqual';
import pick from 'lodash/pick';
import type {
BarAndLineAxis,
BusterChartProps,
ScatterAxis
} from '@/api/asset_interfaces/metric/charts';
import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib/columnFormatter';
import { JOIN_CHARACTER } from './labelHelpers';
import type { BarAndLineAxis, ScatterAxis } from '@buster/server-shared/metrics';
export const AXIS_TITLE_SEPARATOR = JOIN_CHARACTER;

View File

@ -3,6 +3,7 @@ import type { BusterChartProps } from '@/api/asset_interfaces/metric/charts';
import { formatLabel } from '@/lib';
import type { DatasetOption } from '../chartHooks';
import { formatLabelForDataset, formatLabelForPieLegend, JOIN_CHARACTER } from './labelHelpers';
import type { ColumnLabelFormat } from '@buster/server-shared/metrics';
// Mock the formatLabel function
vi.mock('@/lib', () => ({
@ -31,8 +32,8 @@ describe('labelHelpers', () => {
};
const columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']> = {
key1: { columnType: 'text', style: 'string' },
key2: { columnType: 'text', style: 'string' }
key1: { columnType: 'text', style: 'string' } as ColumnLabelFormat,
key2: { columnType: 'text', style: 'string' } as ColumnLabelFormat
};
const result = formatLabelForDataset(dataset, columnLabelFormats);
@ -55,8 +56,8 @@ describe('labelHelpers', () => {
};
const columnLabelFormats: NonNullable<BusterChartProps['columnLabelFormats']> = {
key1: { columnType: 'text', style: 'string' },
key2: { columnType: 'text', style: 'string' }
key1: { columnType: 'text', style: 'string' } as ColumnLabelFormat,
key2: { columnType: 'text', style: 'string' } as ColumnLabelFormat
};
const result = formatLabelForDataset(dataset, columnLabelFormats);

Some files were not shown because too many files have changed in this diff Show More