mirror of https://github.com/buster-so/buster.git
attempt to set max and min
This commit is contained in:
parent
2f035ec70d
commit
84a6af7730
|
@ -7,6 +7,7 @@ import {
|
|||
DEFAULT_CHART_CONFIG,
|
||||
DEFAULT_COLUMN_LABEL_FORMAT,
|
||||
} from '@buster/server-shared/metrics';
|
||||
import { fa } from '@faker-js/faker';
|
||||
import type {
|
||||
CartesianScaleTypeRegistry,
|
||||
Scale,
|
||||
|
@ -20,7 +21,7 @@ import type { BusterChartProps } from '../../../BusterChart.types';
|
|||
import { formatYAxisLabel, yAxisSimilar } from '../../../commonHelpers';
|
||||
import { useY2AxisTitle } from './axisHooks/useY2AxisTitle';
|
||||
|
||||
export const DEFAULT_Y2_AXIS_COUNT = 7;
|
||||
export const DEFAULT_Y2_AXIS_COUNT = 9;
|
||||
|
||||
export const useY2Axis = ({
|
||||
columnLabelFormats,
|
||||
|
@ -47,6 +48,7 @@ export const useY2Axis = ({
|
|||
const selectedAxis = selectedAxisProp as ComboChartAxis;
|
||||
const y2AxisKeys = selectedAxis.y2 || [];
|
||||
const yAxisMinValue = yAxis?.min;
|
||||
const yAxisMaxValue = yAxis?.max;
|
||||
|
||||
const y2AxisKeysString = useMemo(() => {
|
||||
return y2AxisKeys.join(',');
|
||||
|
@ -116,6 +118,7 @@ export const useY2Axis = ({
|
|||
includeBounds: true,
|
||||
},
|
||||
min: yAxisMinValue,
|
||||
max: yAxisMaxValue,
|
||||
grid: {
|
||||
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
||||
},
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
||||
|
||||
import round from 'lodash/round';
|
||||
import { useMemo } from 'react';
|
||||
import type { BusterChartProps } from '../../../BusterChart.types';
|
||||
|
||||
const MIN_PERCENT_DIFFERENCE = 1.5;
|
||||
const MIN_PERCENT_DIFFERENCE = 2;
|
||||
const MAX_PERCENT_DIFFERENCE = 2;
|
||||
const MIN_OFFSET = 1.1;
|
||||
const MAX_OFFSET = 1.1;
|
||||
const PERCENTAGE_STEP = 5;
|
||||
|
||||
export const useYTickValues = ({
|
||||
hasY2Axis,
|
||||
|
@ -25,23 +28,34 @@ export const useYTickValues = ({
|
|||
const shouldUseMinAndMaxValues = hasY2Axis && columnMetadata && selectedChartType === 'combo';
|
||||
|
||||
const checkValues = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return [];
|
||||
return [...yAxisKeys, ...y2AxisKeys];
|
||||
}, [yAxisKeys, y2AxisKeys]);
|
||||
}, [yAxisKeys, y2AxisKeys, shouldUseMinAndMaxValues]);
|
||||
|
||||
const hasOnePercentageValue = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return false;
|
||||
return checkValues.some((key) => {
|
||||
const columnFormat = columnLabelFormats[key];
|
||||
return columnFormat?.style === 'percent';
|
||||
});
|
||||
}, [checkValues, columnLabelFormats, shouldUseMinAndMaxValues]);
|
||||
|
||||
const allYValuesArePercentage = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return false;
|
||||
return checkValues.every((key) => {
|
||||
const columnFormat = columnLabelFormats[key];
|
||||
return columnFormat?.style === 'percent';
|
||||
});
|
||||
}, [checkValues, columnLabelFormats]);
|
||||
}, [checkValues, columnLabelFormats, shouldUseMinAndMaxValues]);
|
||||
|
||||
const columnMap = useMemo(() => {
|
||||
if (!columnMetadata) return new Map();
|
||||
if (!columnMetadata || !shouldUseMinAndMaxValues) return new Map();
|
||||
return new Map(columnMetadata.map((col) => [col.name, col]));
|
||||
}, [columnMetadata]);
|
||||
}, [columnMetadata, shouldUseMinAndMaxValues]);
|
||||
|
||||
// Calculate min/max ranges for y-axis columns
|
||||
const yAxisRange = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return { min: Infinity, max: -Infinity };
|
||||
return yAxisKeys.reduce(
|
||||
(acc, key) => {
|
||||
const column = columnMap.get(key);
|
||||
|
@ -55,10 +69,11 @@ export const useYTickValues = ({
|
|||
},
|
||||
{ min: Infinity, max: -Infinity }
|
||||
);
|
||||
}, [yAxisKeys, columnMap]);
|
||||
}, [yAxisKeys, columnMap, shouldUseMinAndMaxValues]);
|
||||
|
||||
// Calculate min/max ranges for y2-axis columns
|
||||
const y2AxisRange = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return { min: Infinity, max: -Infinity };
|
||||
return y2AxisKeys.reduce(
|
||||
(acc, key) => {
|
||||
const column = columnMap.get(key);
|
||||
|
@ -72,7 +87,7 @@ export const useYTickValues = ({
|
|||
},
|
||||
{ min: Infinity, max: -Infinity }
|
||||
);
|
||||
}, [y2AxisKeys, columnMap]);
|
||||
}, [y2AxisKeys, columnMap, shouldUseMinAndMaxValues]);
|
||||
|
||||
const minTickValue: number | undefined = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return undefined;
|
||||
|
@ -110,9 +125,16 @@ export const useYTickValues = ({
|
|||
|
||||
// If both min and max values are similar, use the lowest min value
|
||||
if (minValuesAreSimilar && maxValuesAreSimilar) {
|
||||
return Math.min(yAxisRange.min, y2AxisRange.min) * MIN_OFFSET;
|
||||
if (hasOnePercentageValue) {
|
||||
// If there's at least one percentage value, round the min to the nearest lower multiple of 5
|
||||
const min = Math.min(yAxisRange.min, y2AxisRange.min) * MIN_OFFSET;
|
||||
return Math.floor(min / PERCENTAGE_STEP) * PERCENTAGE_STEP;
|
||||
}
|
||||
|
||||
return round(Math.min(yAxisRange.min, y2AxisRange.min) * MIN_OFFSET, 0);
|
||||
}
|
||||
}, [
|
||||
hasOnePercentageValue,
|
||||
columnLabelFormats,
|
||||
yAxisRange,
|
||||
y2AxisRange,
|
||||
|
@ -122,7 +144,60 @@ export const useYTickValues = ({
|
|||
allYValuesArePercentage,
|
||||
]);
|
||||
|
||||
const maxTickValue: number | undefined = undefined;
|
||||
const maxTickValue: number | undefined = useMemo(() => {
|
||||
if (!shouldUseMinAndMaxValues) return undefined;
|
||||
|
||||
// If all Y values are percentages, return the highest value
|
||||
if (allYValuesArePercentage) {
|
||||
const highestValue = checkValues.reduce((max, key) => {
|
||||
const column = columnMap.get(key);
|
||||
return Math.max(max, Number(column?.max_value ?? 0));
|
||||
}, -Infinity);
|
||||
if (highestValue === -Infinity) return undefined;
|
||||
if (highestValue < 1) return 1;
|
||||
return highestValue;
|
||||
}
|
||||
|
||||
// Reset infinities if no valid data found
|
||||
if (yAxisRange.min === Infinity) yAxisRange.min = 0;
|
||||
if (yAxisRange.max === -Infinity) yAxisRange.max = 0;
|
||||
if (y2AxisRange.min === Infinity) y2AxisRange.min = 0;
|
||||
if (y2AxisRange.max === -Infinity) y2AxisRange.max = 0;
|
||||
|
||||
// Check if min values are within 150% of each other
|
||||
const minValuesAreSimilar =
|
||||
Math.abs(yAxisRange.min) > 0 && Math.abs(y2AxisRange.min) > 0
|
||||
? Math.max(yAxisRange.min, y2AxisRange.min) / Math.min(yAxisRange.min, y2AxisRange.min) <=
|
||||
MIN_PERCENT_DIFFERENCE
|
||||
: yAxisRange.min === y2AxisRange.min;
|
||||
|
||||
// Check if max values are within 200% of each other
|
||||
const maxValuesAreSimilar =
|
||||
Math.abs(yAxisRange.max) > 0 && Math.abs(y2AxisRange.max) > 0
|
||||
? Math.max(yAxisRange.max, y2AxisRange.max) / Math.min(yAxisRange.max, y2AxisRange.max) <=
|
||||
MAX_PERCENT_DIFFERENCE
|
||||
: yAxisRange.max === y2AxisRange.max;
|
||||
|
||||
// If both min and max values are similar, use the highest max value
|
||||
if (minValuesAreSimilar && maxValuesAreSimilar) {
|
||||
if (hasOnePercentageValue) {
|
||||
// If there's at least one percentage value, round the max to the nearest higher multiple of 5
|
||||
const max = Math.max(yAxisRange.max, y2AxisRange.max) * MAX_OFFSET;
|
||||
return Math.ceil(max / PERCENTAGE_STEP) * PERCENTAGE_STEP;
|
||||
}
|
||||
|
||||
return round(Math.max(yAxisRange.max, y2AxisRange.max) * MAX_OFFSET, 0);
|
||||
}
|
||||
}, [
|
||||
hasOnePercentageValue,
|
||||
columnLabelFormats,
|
||||
yAxisRange,
|
||||
y2AxisRange,
|
||||
shouldUseMinAndMaxValues,
|
||||
columnMap,
|
||||
checkValues,
|
||||
allYValuesArePercentage,
|
||||
]);
|
||||
|
||||
return {
|
||||
minTickValue,
|
||||
|
|
Loading…
Reference in New Issue