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_CHART_CONFIG,
|
||||||
DEFAULT_COLUMN_LABEL_FORMAT,
|
DEFAULT_COLUMN_LABEL_FORMAT,
|
||||||
} from '@buster/server-shared/metrics';
|
} from '@buster/server-shared/metrics';
|
||||||
|
import { fa } from '@faker-js/faker';
|
||||||
import type {
|
import type {
|
||||||
CartesianScaleTypeRegistry,
|
CartesianScaleTypeRegistry,
|
||||||
Scale,
|
Scale,
|
||||||
|
@ -20,7 +21,7 @@ import type { BusterChartProps } from '../../../BusterChart.types';
|
||||||
import { formatYAxisLabel, yAxisSimilar } from '../../../commonHelpers';
|
import { formatYAxisLabel, yAxisSimilar } from '../../../commonHelpers';
|
||||||
import { useY2AxisTitle } from './axisHooks/useY2AxisTitle';
|
import { useY2AxisTitle } from './axisHooks/useY2AxisTitle';
|
||||||
|
|
||||||
export const DEFAULT_Y2_AXIS_COUNT = 7;
|
export const DEFAULT_Y2_AXIS_COUNT = 9;
|
||||||
|
|
||||||
export const useY2Axis = ({
|
export const useY2Axis = ({
|
||||||
columnLabelFormats,
|
columnLabelFormats,
|
||||||
|
@ -47,6 +48,7 @@ export const useY2Axis = ({
|
||||||
const selectedAxis = selectedAxisProp as ComboChartAxis;
|
const selectedAxis = selectedAxisProp as ComboChartAxis;
|
||||||
const y2AxisKeys = selectedAxis.y2 || [];
|
const y2AxisKeys = selectedAxis.y2 || [];
|
||||||
const yAxisMinValue = yAxis?.min;
|
const yAxisMinValue = yAxis?.min;
|
||||||
|
const yAxisMaxValue = yAxis?.max;
|
||||||
|
|
||||||
const y2AxisKeysString = useMemo(() => {
|
const y2AxisKeysString = useMemo(() => {
|
||||||
return y2AxisKeys.join(',');
|
return y2AxisKeys.join(',');
|
||||||
|
@ -116,6 +118,7 @@ export const useY2Axis = ({
|
||||||
includeBounds: true,
|
includeBounds: true,
|
||||||
},
|
},
|
||||||
min: yAxisMinValue,
|
min: yAxisMinValue,
|
||||||
|
max: yAxisMaxValue,
|
||||||
grid: {
|
grid: {
|
||||||
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
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 */
|
/** biome-ignore-all lint/style/noNonNullAssertion: false positive */
|
||||||
|
|
||||||
|
import round from 'lodash/round';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { BusterChartProps } from '../../../BusterChart.types';
|
import type { BusterChartProps } from '../../../BusterChart.types';
|
||||||
|
|
||||||
const MIN_PERCENT_DIFFERENCE = 1.5;
|
const MIN_PERCENT_DIFFERENCE = 2;
|
||||||
const MAX_PERCENT_DIFFERENCE = 2;
|
const MAX_PERCENT_DIFFERENCE = 2;
|
||||||
const MIN_OFFSET = 1.1;
|
const MIN_OFFSET = 1.1;
|
||||||
const MAX_OFFSET = 1.1;
|
const MAX_OFFSET = 1.1;
|
||||||
|
const PERCENTAGE_STEP = 5;
|
||||||
|
|
||||||
export const useYTickValues = ({
|
export const useYTickValues = ({
|
||||||
hasY2Axis,
|
hasY2Axis,
|
||||||
|
@ -25,23 +28,34 @@ export const useYTickValues = ({
|
||||||
const shouldUseMinAndMaxValues = hasY2Axis && columnMetadata && selectedChartType === 'combo';
|
const shouldUseMinAndMaxValues = hasY2Axis && columnMetadata && selectedChartType === 'combo';
|
||||||
|
|
||||||
const checkValues = useMemo(() => {
|
const checkValues = useMemo(() => {
|
||||||
|
if (!shouldUseMinAndMaxValues) return [];
|
||||||
return [...yAxisKeys, ...y2AxisKeys];
|
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(() => {
|
const allYValuesArePercentage = useMemo(() => {
|
||||||
|
if (!shouldUseMinAndMaxValues) return false;
|
||||||
return checkValues.every((key) => {
|
return checkValues.every((key) => {
|
||||||
const columnFormat = columnLabelFormats[key];
|
const columnFormat = columnLabelFormats[key];
|
||||||
return columnFormat?.style === 'percent';
|
return columnFormat?.style === 'percent';
|
||||||
});
|
});
|
||||||
}, [checkValues, columnLabelFormats]);
|
}, [checkValues, columnLabelFormats, shouldUseMinAndMaxValues]);
|
||||||
|
|
||||||
const columnMap = useMemo(() => {
|
const columnMap = useMemo(() => {
|
||||||
if (!columnMetadata) return new Map();
|
if (!columnMetadata || !shouldUseMinAndMaxValues) return new Map();
|
||||||
return new Map(columnMetadata.map((col) => [col.name, col]));
|
return new Map(columnMetadata.map((col) => [col.name, col]));
|
||||||
}, [columnMetadata]);
|
}, [columnMetadata, shouldUseMinAndMaxValues]);
|
||||||
|
|
||||||
// Calculate min/max ranges for y-axis columns
|
// Calculate min/max ranges for y-axis columns
|
||||||
const yAxisRange = useMemo(() => {
|
const yAxisRange = useMemo(() => {
|
||||||
|
if (!shouldUseMinAndMaxValues) return { min: Infinity, max: -Infinity };
|
||||||
return yAxisKeys.reduce(
|
return yAxisKeys.reduce(
|
||||||
(acc, key) => {
|
(acc, key) => {
|
||||||
const column = columnMap.get(key);
|
const column = columnMap.get(key);
|
||||||
|
@ -55,10 +69,11 @@ export const useYTickValues = ({
|
||||||
},
|
},
|
||||||
{ min: Infinity, max: -Infinity }
|
{ min: Infinity, max: -Infinity }
|
||||||
);
|
);
|
||||||
}, [yAxisKeys, columnMap]);
|
}, [yAxisKeys, columnMap, shouldUseMinAndMaxValues]);
|
||||||
|
|
||||||
// Calculate min/max ranges for y2-axis columns
|
// Calculate min/max ranges for y2-axis columns
|
||||||
const y2AxisRange = useMemo(() => {
|
const y2AxisRange = useMemo(() => {
|
||||||
|
if (!shouldUseMinAndMaxValues) return { min: Infinity, max: -Infinity };
|
||||||
return y2AxisKeys.reduce(
|
return y2AxisKeys.reduce(
|
||||||
(acc, key) => {
|
(acc, key) => {
|
||||||
const column = columnMap.get(key);
|
const column = columnMap.get(key);
|
||||||
|
@ -72,7 +87,7 @@ export const useYTickValues = ({
|
||||||
},
|
},
|
||||||
{ min: Infinity, max: -Infinity }
|
{ min: Infinity, max: -Infinity }
|
||||||
);
|
);
|
||||||
}, [y2AxisKeys, columnMap]);
|
}, [y2AxisKeys, columnMap, shouldUseMinAndMaxValues]);
|
||||||
|
|
||||||
const minTickValue: number | undefined = useMemo(() => {
|
const minTickValue: number | undefined = useMemo(() => {
|
||||||
if (!shouldUseMinAndMaxValues) return undefined;
|
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 both min and max values are similar, use the lowest min value
|
||||||
if (minValuesAreSimilar && maxValuesAreSimilar) {
|
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,
|
columnLabelFormats,
|
||||||
yAxisRange,
|
yAxisRange,
|
||||||
y2AxisRange,
|
y2AxisRange,
|
||||||
|
@ -122,7 +144,60 @@ export const useYTickValues = ({
|
||||||
allYValuesArePercentage,
|
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 {
|
return {
|
||||||
minTickValue,
|
minTickValue,
|
||||||
|
|
Loading…
Reference in New Issue