@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
267 lines • 11.3 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2007-2019 GoodData Corporation
var get = require("lodash/get");
var map = require("lodash/map");
var zip = require("lodash/zip");
var values = require("lodash/values");
var flatten = require("lodash/flatten");
var identity = require("lodash/identity");
var isEmpty = require("lodash/isEmpty");
var helpers_1 = require("../../helpers");
var dataLabelsHelpers_1 = require("../../dataLabelsHelpers");
var visualizationTypes_1 = require("../../../../../../constants/visualizationTypes");
var toggleNonStackedChartLabels = function (visiblePoints, axisRangeForAxes, shouldCheckShapeIntersection) {
if (shouldCheckShapeIntersection === void 0) { shouldCheckShapeIntersection = false; }
var foundIntersection = helpers_1.toNeighbors(
// some data labels may not be rendered (too many points)
visiblePoints.filter(function (point) {
return dataLabelsHelpers_1.hasDataLabel(point) && dataLabelsHelpers_1.hasShape(point);
})).some(function (pointPair) {
var _a = pointPair || [], firstPoint = _a[0], nextPoint = _a[1];
var firstDataLabelAttr = dataLabelsHelpers_1.getDataLabelAttributes(firstPoint);
var nextDataLabelAttr = dataLabelsHelpers_1.getDataLabelAttributes(nextPoint);
if (shouldCheckShapeIntersection) {
var firstShapeAttr = helpers_1.getShapeAttributes(firstPoint);
var nextShapeAttr = helpers_1.getShapeAttributes(nextPoint);
return (helpers_1.isIntersecting(firstDataLabelAttr, nextDataLabelAttr) ||
helpers_1.isIntersecting(firstDataLabelAttr, nextShapeAttr) ||
helpers_1.isIntersecting(firstShapeAttr, nextDataLabelAttr));
}
return helpers_1.isIntersecting(firstDataLabelAttr, nextDataLabelAttr);
});
if (foundIntersection) {
dataLabelsHelpers_1.hideDataLabels(visiblePoints);
}
else {
visiblePoints.forEach(function (point) { return dataLabelsHelpers_1.showDataLabelInAxisRange(point, point.y, axisRangeForAxes); });
}
};
var toggleStackedChartLabels = function (visiblePoints, axisRangeForAxes) {
var toggleLabel = function (point) {
var dataLabel = point.dataLabel, shapeArgs = point.shapeArgs, chart = point.series.chart;
if (dataLabel && shapeArgs) {
var labelHeight = dataLabel.height + (2 * dataLabel.padding || 0);
var shapeHeight = dataLabelsHelpers_1.getShapeVisiblePart(shapeArgs, chart, shapeArgs.height);
var isOverlappingHeight = labelHeight > shapeHeight;
return isOverlappingHeight
? dataLabelsHelpers_1.hideDataLabel(point)
: // fix for HCH bug for negative stack labels
dataLabelsHelpers_1.showStackLabelInAxisRange(point, axisRangeForAxes);
}
return null;
};
if (isOverlappingWidth(visiblePoints)) {
dataLabelsHelpers_1.hideDataLabels(visiblePoints);
}
else {
visiblePoints.forEach(toggleLabel);
}
};
function isOverlappingWidth(visiblePoints) {
return visiblePoints.filter(dataLabelsHelpers_1.hasDataLabel).some(function (point) {
var dataLabel = point.dataLabel, shapeArgs = point.shapeArgs;
if (dataLabel && shapeArgs) {
var labelWidth = dataLabel.width + 2 * dataLabel.padding;
return labelWidth > shapeArgs.width;
}
return false;
});
}
exports.isOverlappingWidth = isOverlappingWidth;
function areNeighborsOverlapping(neighbors) {
return neighbors.some(function (labelsPair) {
var _a = labelsPair || [], firstLabel = _a[0], nextLabel = _a[1];
if (!isEmpty(firstLabel) && !isEmpty(nextLabel)) {
var firstClientRect = firstLabel.element.getBoundingClientRect();
var nextClientRect = nextLabel.element.getBoundingClientRect();
if (firstClientRect && nextClientRect) {
var firstLabelRight = firstClientRect.right;
var nextLabelLeft = nextClientRect.left;
return firstLabelRight > nextLabelLeft;
}
}
return false;
});
}
exports.areNeighborsOverlapping = areNeighborsOverlapping;
// Check if Total label overlapping other columns
function areLabelsOverlappingColumns(labels, visiblePoints) {
return labels.some(function (label) {
if (isEmpty(label)) {
return false;
}
var _a = label.element.getBoundingClientRect(), x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var labelAttr = {
x: x,
y: y,
width: width,
height: height,
};
return visiblePoints.some(function (point) {
var seriesType = get(point, "series.options.type");
if (isEmpty(point) ||
isEmpty(point.graphic) ||
// supportedDualAxesChartTypes is including AREA and LINE
// won't hide the stacked label if it overlaps with points of AREA and LINE
seriesType === visualizationTypes_1.VisualizationTypes.AREA ||
seriesType === visualizationTypes_1.VisualizationTypes.LINE) {
return false;
}
var _a = point.graphic.element.getBoundingClientRect(), x = _a.x, y = _a.y, width = _a.width, height = _a.height;
var pointAttr = {
x: x,
y: y,
width: width,
height: height,
};
return helpers_1.isIntersecting(pointAttr, labelAttr);
});
});
}
exports.areLabelsOverlappingColumns = areLabelsOverlappingColumns;
function findColumnKey(key) {
return key.indexOf("column") === 0;
}
/**
* Merge stack label points from axes to one
* Primary axis: [pointP1, pointP2, pointP3]
* Secondary axis: [pointS1, pointS2, pointS3]
* @param stacks
* @return [pointP1, pointS1, pointP2, pointS2, pointP3, pointS3]
*/
function getStackLabelPointsForDualAxis(stacks) {
return flatten(
// 'column0' is primary axis and 'column1' is secondary axis
zip.apply(void 0, stacks.map(function (item) {
var columnKey = Object.keys(item).find(findColumnKey);
return values(item[columnKey]);
}))).filter(identity);
}
exports.getStackLabelPointsForDualAxis = getStackLabelPointsForDualAxis;
function getStackTotalGroups(yAxis) {
return flatten(yAxis.map(function (axis) {
if (!isEmpty(axis.stacks)) {
return axis.stackTotalGroup;
}
return axis.series.map(function (serie) { return serie.dataLabelsGroup; });
})).filter(identity);
}
exports.getStackTotalGroups = getStackTotalGroups;
function toggleStackedLabelsForDualAxis() {
var yAxis = this.yAxis;
var stackTotalGroups = getStackTotalGroups(yAxis);
var stacks = getStackItems(yAxis);
if (stacks && stackTotalGroups) {
var points = getStackLabelPointsForDualAxis(stacks);
var labels = getLabelOrDataLabelForPoints(points);
var neighbors = helpers_1.toNeighbors(labels);
var neighborsOverlapping = areNeighborsOverlapping(neighbors);
var areOverlapping = neighborsOverlapping
? true
: areLabelsOverlappingColumns(labels, helpers_1.getDataPointsOfVisibleSeries(this));
if (areOverlapping) {
this.userOptions.stackLabelsVisibility = "hidden";
stackTotalGroups.forEach(function (stackTotalGroup) { return stackTotalGroup.hide(); });
}
else {
this.userOptions.stackLabelsVisibility = "visible";
stackTotalGroups.forEach(function (stackTotalGroup) { return stackTotalGroup.show(); });
}
}
}
function toggleStackedLabelsForSingleAxis() {
var yAxis = this.yAxis;
var _a = yAxis[0] || {}, stackTotalGroup = _a.stackTotalGroup, stacks = _a.stacks;
if (stacks && stackTotalGroup) {
var columnKey = Object.keys(stacks).find(findColumnKey);
// We need to use Lodash map, because we are iterating through an object
var labels = map(stacks[columnKey], function (point) { return point.label; });
var neighbors = helpers_1.toNeighbors(labels);
var areOverlapping = areNeighborsOverlapping(neighbors);
if (areOverlapping) {
this.userOptions.stackLabelsVisibility = "hidden";
stackTotalGroup.hide();
}
else {
this.userOptions.stackLabelsVisibility = "visible";
stackTotalGroup.show();
}
}
}
function toggleStackedLabels() {
var yAxis = this.yAxis;
// CL-10676 - Return if yAxis is undefined
if (!yAxis || yAxis.length === 0) {
return;
}
if (yAxis.length === 2) {
return toggleStackedLabelsForDualAxis.call(this);
}
return toggleStackedLabelsForSingleAxis.call(this);
}
exports.autohideColumnLabels = function (chart) {
var isStackedChart = helpers_1.isStacked(chart);
var hasLabelsStacked = dataLabelsHelpers_1.areLabelsStacked(chart);
var visiblePoints = helpers_1.getDataPointsOfVisibleSeries(chart);
var axisRangeForAxes = helpers_1.getAxisRangeForAxes(chart);
// stack chart labels is displayed inside column
if (isStackedChart) {
toggleStackedChartLabels(visiblePoints.filter(dataLabelsHelpers_1.hasLabelInside), axisRangeForAxes);
}
else {
toggleNonStackedChartLabels(visiblePoints, axisRangeForAxes, true);
}
// stack labels are total values displayed on top of columns
if (hasLabelsStacked) {
toggleStackedLabels.call(chart);
}
};
exports.handleColumnLabelsOutsideChart = function (chart) {
var visiblePoints = helpers_1.getDataPointsOfVisibleSeries(chart);
var axisRangeForAxes = helpers_1.getAxisRangeForAxes(chart);
visiblePoints.forEach(function (point) {
if (!helpers_1.isStacked(chart)) {
dataLabelsHelpers_1.showDataLabelInAxisRange(point, point.y, axisRangeForAxes);
}
else {
// fix for HCH bug for negative stack labels
dataLabelsHelpers_1.showStackLabelInAxisRange(point, axisRangeForAxes);
}
});
};
function getLabelOrDataLabelForPoints(points) {
return points
.map(function (point) {
return point.label || point.dataLabel;
})
.filter(identity);
}
exports.getLabelOrDataLabelForPoints = getLabelOrDataLabelForPoints;
function getStackItems(yAxis) {
return flatten(yAxis.map(function (axis) {
if (!isEmpty(axis.stacks)) {
return axis.stacks;
}
var series = axis.series;
var dataLabels = series.map(function (serie) {
return {
column: __assign({}, serie.data),
};
});
return dataLabels;
}));
}
exports.getStackItems = getStackItems;
//# sourceMappingURL=autohideColumnLabels.js.map