in src/label/dataLabelRectPositioner.ts [151:201]
export function isValidLabelOverflowing(labelRect: IRect, labelPoint: LabelDataPoint, hasMultipleDataSeries: boolean): boolean {
const parentRect = (<LabelParentRect>labelPoint.parentShape).rect;
if (!shapes.Rect.isIntersecting(labelRect, parentRect)) {
return false; // label isn't overflowing from within parent
}
const intersection = shapes.Rect.intersect(labelRect, parentRect);
const precision = LabelOverflowingConsts.equalityPrecision;
const isLabelContainedVertically =
double.equalWithPrecision(intersection.top, labelRect.top, precision) &&
double.equalWithPrecision(intersection.height, labelRect.height, precision);
const isLabelContainedHorizontally =
double.equalWithPrecision(intersection.left, labelRect.left, precision) &&
double.equalWithPrecision(intersection.width, labelRect.width, precision);
const isParentOrientVertically = [
NewRectOrientation.VerticalBottomBased,
NewRectOrientation.VerticalTopBased
].some((orientation) => orientation === (<LabelParentRect>labelPoint.parentShape).orientation);
if (!isLabelContainedHorizontally && !isLabelContainedVertically ||
(hasMultipleDataSeries &&
(isParentOrientVertically && !isLabelContainedVertically ||
!isParentOrientVertically && !isLabelContainedHorizontally)
)) {
// Our overflowing definition require that at least one label's rectangle dimension (width / height) to be contained in parent rectangle.
// Furthermore, if we have multiple data series the contained dimention should be respective with the parent's orientation.
// To avoid data labels collisions from one series to another which appears inside the same bar.
return false;
} else if (isLabelContainedHorizontally && isLabelContainedVertically) {
return true; // null-overflowing, label is fully contained.
}
// Our overflowing definition require that the label and parent "will touch each other enough", this is defined by the ratio of their intersection
// (touching) against each of them, we look at the maximal intersection ratio which means that at least one of them is 'touched' enought by the other.
const labelAndParentIntersectEnough = maximalIntersectionRatio(labelRect, parentRect) >= LabelOverflowingConsts.minIntersectionRatio;
// Our overflowing definition require that the overflowing dimensions will not be too big in comparison to the same dimension of parent.
// this is done to avoid situationion where the parent is barely visible or that label text is very long.
let labelOverflowIsValid = false;
const parentToLabelOverflowRatioThreshold = LabelOverflowingConsts.parentToLabelOverflowRatioThreshold;
if (isLabelContainedVertically) {
labelOverflowIsValid = parentRect.width === 0 || (parentRect.width / labelRect.width) > parentToLabelOverflowRatioThreshold;
} else if (isLabelContainedHorizontally) {
labelOverflowIsValid = parentRect.height === 0 || (parentRect.height / labelRect.height) > parentToLabelOverflowRatioThreshold;
}
return labelAndParentIntersectEnough && labelOverflowIsValid;
}