in src/XAxisLabels.js [25:99]
function resolveXLabelsForValues(
scale,
values,
formats = [],
style,
force = true,
) {
// given a set of values to label, and a list of formatters to try,
// find the first formatter that produces a set of labels
// which are A) distinct and B) fit on the axis without colliding with each other
// returns the formatter and the generated labels
let labels;
const attempts = [];
const goodFormat = formats.find(format => {
const testLabels = values.map((value, i) => {
return MeasuredValueLabel.getLabel({
value,
format,
style: defaults(
getValue(style.labelStyle, { value }, i),
style.defaultStyle,
),
});
});
const areLabelsDistinct = checkLabelsDistinct(testLabels);
if (!areLabelsDistinct) {
attempts.push({ labels: testLabels, format, areLabelsDistinct });
return false;
}
const labelXRanges = testLabels.map(label =>
getLabelXRange(scale, label, style.textAnchor || 'middle'),
);
const collisionCount = countRangeOverlaps(labelXRanges);
if (collisionCount) {
// console.log(`labels do not fit on X axis, ${collisionCount} collisions`, _.map(testLabels, 'text'));
attempts.push({
labels: testLabels,
format,
areLabelsDistinct,
collisionCount,
});
return false;
}
labels = testLabels;
return true;
});
if (!isUndefined(goodFormat)) {
// found labels which work, return them
return {
labels,
format: goodFormat,
areLabelsDistinct: true,
collisionCount: 0,
};
}
// none of the sets of labels are good
if (!force)
// if we're not forced to decide, return all the labels we tried (let someone else decide)
return { attempts };
// forced to decide, choose the least bad option
// todo warn that we couldn't find good labels
const distinctAttempts = attempts.filter(
attempt => attempt.areLabelsDistinct,
);
return distinctAttempts.length === 0
? last(attempts)
: minBy(distinctAttempts, 'collisionCount');
}