UNPKG

@gooddata/react-components

Version:

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

263 lines • 11.5 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-2020 GoodData Corporation var partial = require("lodash/partial"); var merge = require("lodash/merge"); var includes = require("lodash/includes"); var isNil = require("lodash/isNil"); var set = require("lodash/set"); var get = require("lodash/get"); var chartOptionsBuilder_1 = require("../chartOptionsBuilder"); var dataLabelsHelpers_1 = require("./dataLabelsHelpers"); var common_1 = require("../../utils/common"); var comboChartOptions_1 = require("../chartOptions/comboChartOptions"); exports.NORMAL_STACK = "normal"; exports.PERCENT_STACK = "percent"; /** * Set 'normal' stacking config to single series which will overwrite config in 'plotOptions.series' * @param stackMeasures * @param seriesItem */ function handleStackMeasure(stackMeasures, seriesItem) { return stackMeasures ? __assign({}, seriesItem, { stacking: exports.NORMAL_STACK, stack: seriesItem.yAxis }) : seriesItem; } /** * Set 'percent' stacking config to single series which will overwrite config in 'plotOptions.series' * @param stackMeasuresToPercent * @param seriesItem */ function handleStackMeasuresToPercent(stackMeasuresToPercent, seriesItem) { return stackMeasuresToPercent ? __assign({}, seriesItem, { stacking: exports.PERCENT_STACK, stack: seriesItem.yAxis }) : seriesItem; } function getStackingValue(chartOptions, seriesItem) { var yAxes = chartOptions.yAxes, type = chartOptions.type; var stacking = seriesItem.stacking, yAxis = seriesItem.yAxis; var seriesChartType = seriesItem.type || type; var defaultStackingValue = common_1.isComboChart(type) ? null : exports.NORMAL_STACK; return common_1.isPrimaryYAxis(yAxes[yAxis]) && !common_1.isLineChart(seriesChartType) ? stacking : defaultStackingValue; } function handleDualAxis(chartOptions, seriesItem) { var yAxes = chartOptions.yAxes, type = chartOptions.type; var isDualAxis = yAxes.length === 2; if (!isDualAxis && !common_1.isComboChart(type)) { return seriesItem; } var stacking = seriesItem.stacking; // highcharts stack config // percent stack is only applied to primary Y axis var hcStackingConfig = stacking ? { stacking: getStackingValue(chartOptions, seriesItem) } : {}; return __assign({}, seriesItem, hcStackingConfig); } function handleLabelStyle(chartOptions, seriesItem) { if (!common_1.isComboChart(chartOptions.type)) { return seriesItem; } var type = seriesItem.type, stacking = seriesItem.stacking; return __assign({}, seriesItem, { dataLabels: { style: dataLabelsHelpers_1.getLabelStyle(type, stacking), } }); } function countMeasuresInSeries(series) { return series.reduce(function (result, seriesItem) { result[seriesItem.yAxis] += 1; return result; }, [0, 0]); } /** * For y axis having one series, this series should be removed stacking config * @param series */ function getSanitizedStackingForSeries(series) { var _a = countMeasuresInSeries(series), primaryMeasuresNum = _a[0], secondaryMeasuresNum = _a[1]; /** * stackMeasures is applied for both measures in each axis * stackMeasuresToPercent is applied for * - [measures on primary y-axis only] or * - [measures on secondary y-axis only] or * - [applied for measures on primary y-axis + ignore for measures on secondary y-axis] */ // has measures on both [primary y-axis] and [secondary y-axis] if (primaryMeasuresNum > 0 && secondaryMeasuresNum > 0) { return series.map(function (seriesItem) { // seriesItem is on [secondary y-axis] if (seriesItem.yAxis === 1) { return __assign({}, seriesItem, { stack: null, // reset stackMeasuresToPercent in this case (stacking: PERCENT_STACK) stacking: seriesItem.stacking ? exports.NORMAL_STACK : null }); } else { return seriesItem; } }); } // has [measures on primary y-axis only] or [measures on secondary y-axis only] return series; } exports.getSanitizedStackingForSeries = getSanitizedStackingForSeries; function getSeriesConfiguration(chartOptions, config, stackMeasures, stackMeasuresToPercent) { var series = config.series; var handlers = [ partial(handleStackMeasure, stackMeasures), partial(handleStackMeasuresToPercent, stackMeasuresToPercent), partial(handleDualAxis, chartOptions), partial(handleLabelStyle, chartOptions), ]; // get series with stacking config var seriesWithStackingConfig = series.map(function (seriesItem) { return handlers.reduce(function (result, handler) { return handler(result); }, seriesItem); }); return { series: getSanitizedStackingForSeries(seriesWithStackingConfig), }; } function getYAxisConfiguration(chartOptions, config, chartConfig) { var type = common_1.getPrimaryChartType(chartOptions); var yAxis = config.yAxis; var _a = chartConfig.stackMeasuresToPercent, stackMeasuresToPercent = _a === void 0 ? false : _a; // only support column char // bar chart disables stack labels by default if (!common_1.isColumnChart(type)) { return {}; } var labelsVisible = get(chartConfig, "dataLabels.visible"); var dataLabelEnabled = dataLabelsHelpers_1.getLabelsVisibilityConfig(labelsVisible).enabled; // enable by default or follow dataLabels.visible config var stackLabelConfig = isNil(dataLabelEnabled) || dataLabelEnabled; var yAxisWithStackLabel = yAxis.map(function (axis, index) { // disable stack labels for primary Y axis when there is 'Stack to 100%' on var stackLabelEnabled = (index !== 0 || !stackMeasuresToPercent) && stackLabelConfig; return __assign({}, axis, { stackLabels: { enabled: stackLabelEnabled, } }); }); return { yAxis: yAxisWithStackLabel }; } exports.getYAxisConfiguration = getYAxisConfiguration; /** * Set config to highchart for 'Stack Measures' and 'Stack to 100%' * @param chartOptions * @param config * @param chartConfig */ function getStackMeasuresConfiguration(chartOptions, config, chartConfig) { var _a = chartConfig.stackMeasures, stackMeasures = _a === void 0 ? false : _a, _b = chartConfig.stackMeasuresToPercent, stackMeasuresToPercent = _b === void 0 ? false : _b; var canStackInPercent = comboChartOptions_1.canComboChartBeStackedInPercent(config.series); if (!stackMeasures && !stackMeasuresToPercent) { return {}; } return __assign({}, getSeriesConfiguration(chartOptions, config, stackMeasures, stackMeasuresToPercent && canStackInPercent), getYAxisConfiguration(chartOptions, config, chartConfig)); } exports.getStackMeasuresConfiguration = getStackMeasuresConfiguration; /** * Add style to X axis in case of 'grouped-categories' * @param chartOptions * @param config */ function getParentAttributeConfiguration(chartOptions, config) { var type = chartOptions.type; var xAxis = config.xAxis; var xAxisItem = xAxis[0]; // expect only one X axis // parent attribute in X axis var parentAttributeOptions = {}; // only apply font-weight to parent label set(parentAttributeOptions, "style", { fontWeight: "bold", }); if (common_1.isInvertedChartType(type)) { // distance more 5px for two groups of attributes for bar chart set(parentAttributeOptions, "x", -5); } // 'groupedOptions' is custom property in 'grouped-categories' plugin set(xAxisItem, "labels.groupedOptions", [parentAttributeOptions]); return { xAxis: [xAxisItem] }; } exports.getParentAttributeConfiguration = getParentAttributeConfiguration; function setDrillConfigToXAxis(drillConfig) { return { xAxis: [{ drillConfig: drillConfig }] }; } exports.setDrillConfigToXAxis = setDrillConfigToXAxis; /** * Format labels in Y axis from '0 - 100' to '0% - 100%' * Only applied when measure/series in Y axis more than one * @param chartOptions * @param _config * @param chartConfig */ function getShowInPercentConfiguration(chartOptions, config, chartConfig) { if (config === void 0) { config = {}; } var _a = chartConfig.stackMeasuresToPercent, stackMeasuresToPercent = _a === void 0 ? false : _a, primaryChartType = chartConfig.primaryChartType; var canStackInPercent = comboChartOptions_1.canComboChartBeStackedInPercent(config.series); if (!canStackInPercent || !stackMeasuresToPercent || common_1.isLineChart(primaryChartType)) { return {}; } var _b = chartOptions.yAxes, yAxes = _b === void 0 ? [] : _b, type = chartOptions.type; var percentageFormatter = partial(dataLabelsHelpers_1.formatAsPercent, 1); // suppose that max number of y axes is 2 // percentage format only supports primary axis var yAxis = yAxes.map(function (axis, index) { if (index !== 0 || (common_1.isComboChart(type) && !common_1.isPrimaryYAxis(axis))) { return {}; } return { labels: { formatter: percentageFormatter, }, }; }); return { yAxis: yAxis }; } exports.getShowInPercentConfiguration = getShowInPercentConfiguration; /** * Convert [0, 1] to [0, 100], it's needed by highchart * Only applied to primary Y axis * @param _chartOptions * @param config * @param chartConfig */ function convertMinMaxFromPercentToNumber(_chartOptions, config, chartConfig) { var _a = chartConfig.stackMeasuresToPercent, stackMeasuresToPercent = _a === void 0 ? false : _a; if (!stackMeasuresToPercent) { return {}; } var _b = config.yAxis, yAxes = _b === void 0 ? [] : _b; var yAxis = yAxes.map(function (axis, _, axes) { var min = axis.min, max = axis.max; var newAxis = {}; if (!isNil(min)) { set(newAxis, "min", min * 100); } if (!isNil(max)) { set(newAxis, "max", max * 100); } var numberOfAxes = axes.length; if (numberOfAxes === 1) { return newAxis; } var _a = axis.opposite, opposite = _a === void 0 ? false : _a; return opposite ? {} : newAxis; }); return { yAxis: yAxis }; } exports.convertMinMaxFromPercentToNumber = convertMinMaxFromPercentToNumber; function getOptionalStackingConfiguration(chartOptions, config, chartConfig, drillConfig) { if (chartConfig === void 0) { chartConfig = {}; } var type = chartOptions.type; return includes(chartOptionsBuilder_1.supportedStackingAttributesChartTypes, type) ? merge({}, setDrillConfigToXAxis(drillConfig), getParentAttributeConfiguration(chartOptions, config), getStackMeasuresConfiguration(chartOptions, config, chartConfig), getShowInPercentConfiguration(chartOptions, config, chartConfig), convertMinMaxFromPercentToNumber(chartOptions, config, chartConfig)) : {}; } exports.default = getOptionalStackingConfiguration; //# sourceMappingURL=getOptionalStackingConfiguration.js.map