Skip to content

Commit

Permalink
Change algorithm for auto interval
Browse files Browse the repository at this point in the history
  • Loading branch information
wylieconlon authored and alexwizp committed Sep 1, 2020
1 parent 0b3259d commit 4b2ae64
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ import {
CalculateHistogramIntervalParams,
} from './histogram_calculate_interval';

const getLargestPossibleInterval = (params: CalculateHistogramIntervalParams) => {
const diff = params.values!.max - params.values!.min;
return diff / params.maxBucketsUiSettings;
};

describe('calculateHistogramInterval', () => {
describe('auto calculating mode', () => {
let params: CalculateHistogramIntervalParams;
Expand Down Expand Up @@ -86,17 +81,15 @@ describe('calculateHistogramInterval', () => {

describe('maxBucketsUserInput is not defined', () => {
test('should not set interval which more than largest possible', () => {
const p = {
...params,
values: {
min: 0,
max: 100,
},
};
const expectedInterval = getLargestPossibleInterval(p);

expect(expectedInterval).toBe(1);
expect(calculateHistogramInterval(p)).toBe(expectedInterval);
expect(
calculateHistogramInterval({
...params,
values: {
min: 0,
max: 100,
},
})
).toEqual(1);
});

test('should set intervals for integer numbers (diff less than maxBucketsUiSettings)', () => {
Expand All @@ -108,11 +101,11 @@ describe('calculateHistogramInterval', () => {
max: 10,
},
})
).toBe(1);
).toEqual(0.1);
});

test('should set intervals for integer numbers (diff more than maxBucketsUiSettings)', () => {
// diff === 44445; interval === 2000; buckets === 22
// diff === 44445; interval === 500; buckets === 89
expect(
calculateHistogramInterval({
...params,
Expand All @@ -121,11 +114,12 @@ describe('calculateHistogramInterval', () => {
max: 90123,
},
})
).toBe(2000);
).toEqual(500);
});

test('should set intervals for float numbers (small numbers)', () => {
// diff === 1.655; interval === 0.03; buckets === 55
test('should set intervals the same for the same interval', () => {
// both diffs are the same
// diff === 1.655; interval === 0.02; buckets === 82
expect(
calculateHistogramInterval({
...params,
Expand All @@ -134,11 +128,7 @@ describe('calculateHistogramInterval', () => {
max: 2.9,
},
})
).toBe(0.03);
});

test('should set intervals for float numbers (small numbers #2)', () => {
// diff === 1.655; interval === 0.02; buckets === 82
).toEqual(0.02);
expect(
calculateHistogramInterval({
...params,
Expand All @@ -147,7 +137,7 @@ describe('calculateHistogramInterval', () => {
max: 2.3,
},
})
).toBe(0.02);
).toEqual(0.02);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,41 +64,27 @@ const calculateForGivenInterval = (

const calculateAutoInterval = (
diff: number,
values: IntervalValuesRange,
maxBucketsUiSettings: CalculateHistogramIntervalParams['maxBucketsUiSettings'],
maxBucketsUserInput: CalculateHistogramIntervalParams['maxBucketsUserInput']
) => {
const getMaxFractionalPart = (...numbers: number[]) => {
return numbers.reduce((acc, n) => {
const [, value] = n.toString().split('.');
return value && value.length > acc ? value.length : acc;
}, 0);
};
const maxBars = Math.min(maxBucketsUiSettings, maxBucketsUserInput ?? maxBucketsUiSettings);
const exactInterval = diff / maxBars;

let autoBuckets: number = 0;
const lowerPower = Math.pow(10, Math.floor(Math.log10(exactInterval)));

if (!maxBucketsUserInput) {
const fractalFactor = Math.pow(10, getMaxFractionalPart(values.min, values.max));
const autoBuckets = diff / lowerPower;

autoBuckets = diff * fractalFactor;

if (autoBuckets > maxBucketsUiSettings) {
autoBuckets =
(Math.log10(maxBucketsUiSettings) / Math.log10(autoBuckets)) * maxBucketsUiSettings;
}

// For float numbers we can try to increase interval
if (fractalFactor > 1 && autoBuckets < maxBucketsUiSettings / 2) {
autoBuckets = autoBuckets * 5;
if (autoBuckets > maxBucketsUiSettings) {
autoBuckets = autoBuckets * 2;
}
if (autoBuckets > maxBars) {
if (autoBuckets / 2 <= maxBars) {
return lowerPower * 2;
} else if (autoBuckets / 5 <= maxBars) {
return lowerPower * 5;
} else {
return lowerPower * 10;
}
}

const bars = Math.min(maxBucketsUiSettings, maxBucketsUserInput || autoBuckets || 1);

return roundInterval(diff / bars);
return lowerPower;
};

export const calculateHistogramInterval = ({
Expand All @@ -121,7 +107,7 @@ export const calculateHistogramInterval = ({

if (diff) {
calculatedInterval = isAuto
? calculateAutoInterval(diff, values, maxBucketsUiSettings, maxBucketsUserInput)
? calculateAutoInterval(diff, maxBucketsUiSettings, maxBucketsUserInput)
: calculateForGivenInterval(diff, calculatedInterval, maxBucketsUiSettings);
}
}
Expand Down

0 comments on commit 4b2ae64

Please sign in to comment.