UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

267 lines • 11.3 kB
"use strict"; 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