All files / src/utils chart.ts

100% Statements 49/49
100% Branches 14/14
100% Functions 3/3
100% Lines 49/49

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69  1x                     1x 10x 10x 10x 10x 10x   7x 7x 7x 7x   1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x   5x 5x 21x 21x 21x 21x 21x 5x 5x   5x   5x   5x 5x 5x 5x   5x 5x 5x 5x 5x 5x 5x   1x 53x  
// Types
import { ChartMode, ChartRow, LineChartRow } from '@/types/chart';
 
type ChartConfigParams = {
  mode: ChartMode;
  chartWidth: number;
  data: (ChartRow | LineChartRow)[];
  minY?: number;
  tickCount?: number;
  isTotal?: boolean;
};
 
export const getStepFromMaxValue = (
  maxValue: number,
  minY = 30,
  tickCount = 3,
): number => {
  if (maxValue <= 0) return minY / tickCount;
 
  const safeMax = Math.max(minY, maxValue);
  const rawStep = safeMax / tickCount;
  return Math.ceil(rawStep / 10) * 10;
};
 
export const calculateChartConfig = ({
  mode,
  chartWidth,
  data,
  minY = 30,
  tickCount = 3,
  isTotal = false,
}: ChartConfigParams) => {
  const spacingConfig: Partial<Record<ChartMode, number>> = {
    [ChartMode.Week]: isTotal ? 0.25 : 0.3,
    [ChartMode.Quarter]: isTotal ? 0.3 : 0.35,
    [ChartMode.Year]: 0.15,
  };
  const spacing = !!spacingConfig[mode] ? chartWidth * spacingConfig[mode] : 30;
 
  const maxValue = Math.max(
    ...data.map((d) => {
      const row = d as Record<string, number | string | null>;
      const values = Object.values(row).filter(
        (v) => typeof v === 'number',
      ) as number[];
      return Math.max(...values, 0);
    }),
  );
 
  const step = getStepFromMaxValue(maxValue, minY, tickCount);
 
  const roundedMax = step * tickCount;
 
  const ticks = Array.from(
    { length: roundedMax / step + 1 },
    (_, i) => i * step,
  );
 
  return {
    spacing,
    roundedMax,
    ticks,
    step,
  };
};
 
export const isValidChartMode = (mode: string): mode is ChartMode =>
  Object.values(ChartMode).includes(mode as ChartMode);