function histogram(
tableColumn,
bucketWidth,
bucketCount,
fixedTicks,
maxBucketCount
) {
const [absMin, absMax] = [form.absMin, form.absMax];
let regularMin, regularMax
regularMin = Math.max(absMin, form.regularMin);
regularMax = Math.min(absMax, form.regularMax);
let regMinWithRequired = regularMin;
let regMaxWithRequired = regularMax;
if(fixedTicks) {
const smallestFixedTick = Math.min(...fixedTicks);
const biggestFixedTick = Math.max(...fixedTicks);
regMinWithRequired = Math.min(smallestFixedTick, Math.max(absMin, form.regularMin));
regMaxWithRequired = Math.max(biggestFixedTick, Math.min(absMax, form.regularMax));
}
const distance = regMaxWithRequired - regMinWithRequired;
const MAX_PRECISION = 5
if (distance === 0) {
let power = getPower(regularMin, MAX_PRECISION);
const intValue = Math.floor(regularMin * Math.pow(10, power));
const lowerBound = intValue / Math.pow(10, power);
const upperBound = (intValue + 1) / Math.pow(10, power);
const boundaries = [absMin, lowerBound, upperBound,absMax];
const step = +Math.pow(10, -power).toFixed(countDecimals(upperBound));
return boundaries;
}
let suggestedStep;
if (bucketWidth) {
suggestedStep = bucketWidth;
} else {
const count = Math.ceil(Math.log2(2)) + 1;
suggestedStep = distance / count;
}
let step;
let ticks = [];
let power;
let firstTick;
let indexDiff;
step = tickIncrement(suggestedStep, fixedTicks);
const minStepAllowed = minTickIncrement(distance / (maxBucketCount - 2))
if (step < minStepAllowed) {
step = minStepAllowed
}
if (step <= Math.pow(10, -MAX_PRECISION)) {
step = +Math.pow(10, -MAX_PRECISION).toFixed(MAX_PRECISION);
}
const precision = getPrecision(step, fixedTicks, MAX_PRECISION);
if (fixedTicks) {
firstTick = fixedTicks[0];
} else {
firstTick = 0;
}
indexDiff = Math.ceil((firstTick - regMinWithRequired) / step);
firstTick = firstTick - (indexDiff * step)
let index = 0;
let currentTick = firstTick;
while (currentTick <= regularMax || currentTick < regMaxWithRequired) {
currentTick = (firstTick + index * step);
ticks.push(+currentTick.toFixed(precision))
index++
}
const newAbsMin = Math.min(absMin, Math.min(...ticks));
const newAbsMax = Math.max(absMax, Math.max(...ticks));
const bucketBoundaries = [newAbsMin, ...ticks, newAbsMax];
return { boundaries: bucketBoundaries, step: step };
}