@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
497 lines • 21.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2007-2020 GoodData Corporation
var range = require("lodash/range");
var get = require("lodash/get");
var head = require("lodash/head");
var last = require("lodash/last");
var isEmpty = require("lodash/isEmpty");
var inRange = require("lodash/inRange");
var PositionTypes_1 = require("./PositionTypes");
var common_1 = require("../../utils/common");
var chartOptionsBuilder_1 = require("../chartOptionsBuilder");
var visualizationTypes_1 = require("../../../../constants/visualizationTypes");
exports.RESPONSIVE_ITEM_MIN_WIDTH = 200;
exports.RESPONSIVE_VISIBLE_ROWS = 2;
exports.FLUID_PAGING_WIDTH = 30;
exports.LEGEND_PADDING = 12;
exports.ITEM_HEIGHT = 20;
exports.SKIPPED_LABEL_TEXT = "...";
exports.UTF_NON_BREAKING_SPACE = "\u00A0";
var STATIC_PAGING_HEIGHT = 44;
function getEmptyBlock(style, index) {
return {
key: "empty-" + index,
label: exports.UTF_NON_BREAKING_SPACE,
style: style,
};
}
function getLabelStyle(width, textAlign) {
return { width: width, textAlign: textAlign };
}
var ALEFT = "left";
var ARIGHT = "right";
var ACENTER = "center";
var DOTS_WIDTH = 10;
function getSkippedLabelBlock(index) {
return {
key: "dots-" + index,
label: exports.SKIPPED_LABEL_TEXT,
style: getLabelStyle(DOTS_WIDTH, ACENTER),
};
}
var verticalHeatmapMiddleLabelStyle = { height: 30, textAlign: ALEFT, lineHeight: "30px" };
exports.verticalHeatmapConfig = [
{ type: "label", labelIndex: 0, style: { height: 15, textAlign: ALEFT, lineHeight: "11px" } },
{ type: "label", labelIndex: 1, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 2, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 3, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 4, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 5, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 6, style: verticalHeatmapMiddleLabelStyle },
{ type: "label", labelIndex: 7, style: { height: 15, textAlign: ALEFT, lineHeight: "20px" } },
];
var defaultHeatmapLegendLabelStyle = { width: 40, textAlign: ACENTER };
exports.heatmapLegendConfigMatrix = [
[
{ type: "label", labelIndex: 0, style: { width: 175, textAlign: ALEFT } },
{ type: "label", labelIndex: 7, style: { width: 175, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 145, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 145, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 95, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 95, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 55, textAlign: ALEFT } },
{ type: "label", labelIndex: 2, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 5, style: { width: 90, textAlign: ACENTER } },
{ type: "label", labelIndex: 7, style: { width: 55, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 45, textAlign: ALEFT } },
{ type: "dots" },
{ type: "label", labelIndex: 2, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 5, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 45, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 30, textAlign: ALEFT } },
{ type: "label", labelIndex: 1, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 2, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 3, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 4, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 5, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 6, style: defaultHeatmapLegendLabelStyle },
{ type: "label", labelIndex: 7, style: { width: 30, textAlign: ARIGHT } },
],
];
exports.colorLegendConfigMatrix = [
[
{ type: "label", labelIndex: 0, style: { width: 175, textAlign: ALEFT } },
{ type: "label", labelIndex: 6, style: { width: 175, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 145, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 6, style: { width: 145, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 95, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 6, style: { width: 95, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 55, textAlign: ALEFT } },
{ type: "label", labelIndex: 2, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 4, style: { width: 90, textAlign: ACENTER } },
{ type: "label", labelIndex: 6, style: { width: 55, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 45, textAlign: ALEFT } },
{ type: "dots" },
{ type: "label", labelIndex: 2, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 40 } },
{ type: "dots" },
{ type: "label", labelIndex: 4, style: { width: 90, textAlign: ACENTER } },
{ type: "dots" },
{ type: "label", labelIndex: 6, style: { width: 45, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 30, textAlign: ALEFT } },
{ type: "label", labelIndex: 1, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 2, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 3, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 4, style: defaultHeatmapLegendLabelStyle },
{ type: "space", style: { width: 10 } },
{ type: "label", labelIndex: 5, style: defaultHeatmapLegendLabelStyle },
{ type: "label", labelIndex: 6, style: { width: 30, textAlign: ARIGHT } },
],
];
var defaultHeatmapSmallLegendStyle = { width: 40, textAlign: ACENTER };
exports.heatmapSmallLegendConfigMatrix = [
[
{ type: "label", labelIndex: 0, style: { width: 138, textAlign: ALEFT } },
{ type: "label", labelIndex: 7, style: { width: 138, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 115, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 26 } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 115, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 75, textAlign: ALEFT } },
{ type: "dots" },
{ type: "space", style: { width: 30 } },
{ type: "dots" },
{ type: "space", style: { width: 26 } },
{ type: "dots" },
{ type: "space", style: { width: 30 } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 75, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 45, textAlign: ALEFT } },
{ type: "label", labelIndex: 2, style: { width: 70, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 26 } },
{ type: "dots" },
{ type: "label", labelIndex: 5, style: { width: 70, textAlign: ACENTER } },
{ type: "label", labelIndex: 7, style: { width: 45, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 35, textAlign: ALEFT } },
{ type: "dots" },
{ type: "label", labelIndex: 2, style: { width: 70, textAlign: ACENTER } },
{ type: "dots" },
{ type: "space", style: { width: 26 } },
{ type: "dots" },
{ type: "label", labelIndex: 5, style: { width: 70, textAlign: ACENTER } },
{ type: "dots" },
{ type: "label", labelIndex: 7, style: { width: 35, textAlign: ARIGHT } },
],
[
{ type: "label", labelIndex: 0, style: { width: 20, textAlign: ALEFT } },
{ type: "label", labelIndex: 1, style: defaultHeatmapSmallLegendStyle },
{ type: "label", labelIndex: 2, style: defaultHeatmapSmallLegendStyle },
{ type: "label", labelIndex: 3, style: { width: 38, textAlign: ACENTER } },
{ type: "label", labelIndex: 4, style: { width: 38, textAlign: ACENTER } },
{ type: "label", labelIndex: 5, style: defaultHeatmapSmallLegendStyle },
{ type: "label", labelIndex: 6, style: defaultHeatmapSmallLegendStyle },
{ type: "label", labelIndex: 7, style: { width: 20, textAlign: ARIGHT } },
],
];
function buildColorLabelsConfig(labels, config) {
return config.map(function (element, index) {
switch (element.type) {
case "label":
return {
label: labels[element.labelIndex],
style: element.style,
key: element.type + "-" + index,
};
case "space":
return getEmptyBlock(element.style, index);
case "dots":
return getSkippedLabelBlock(index);
}
});
}
exports.buildColorLabelsConfig = buildColorLabelsConfig;
var LABEL_LENGHT_THRESHOLDS = [5, 8, 10, 15, 18];
var SMALL_LABEL_LENGHT_THRESHOLDS = [4, 7, 9, 13, 15];
function getColorLegendLabelsConfiguration(legendLabels, isSmall, isVertical) {
var numberOfLabels = legendLabels.length;
var firstLabelLength = head(legendLabels).length;
var lastLabelLength = last(legendLabels).length;
var maxLabelLength = firstLabelLength > lastLabelLength ? firstLabelLength : lastLabelLength;
var labelLengths = isSmall ? SMALL_LABEL_LENGHT_THRESHOLDS : LABEL_LENGHT_THRESHOLDS;
var shorteningConfig = isVertical
? exports.verticalHeatmapConfig
: getHorizontalShorteningLabelConfig(labelLengths, maxLabelLength, isSmall, numberOfLabels);
return buildColorLabelsConfig(legendLabels, shorteningConfig);
}
function getHorizontalShorteningLabelConfig(labelLengths, maxLabelLength, isSmall, numberOfLabels) {
var shorteningLevel = getColorLabelShorteningLevel(labelLengths, maxLabelLength);
if (isSmall) {
return exports.heatmapSmallLegendConfigMatrix[shorteningLevel];
}
if (numberOfLabels === 8) {
return exports.heatmapLegendConfigMatrix[shorteningLevel];
}
return exports.colorLegendConfigMatrix[shorteningLevel];
}
function getColorLabelShorteningLevel(labelLengths, maxLabelLength) {
var shorteningLevel;
if (inRange(maxLabelLength, 0, labelLengths[0])) {
shorteningLevel = 5;
}
else if (inRange(maxLabelLength, labelLengths[0], labelLengths[1])) {
shorteningLevel = 4;
}
else if (inRange(maxLabelLength, labelLengths[1], labelLengths[2])) {
shorteningLevel = 3;
}
else if (inRange(maxLabelLength, labelLengths[2], labelLengths[3])) {
shorteningLevel = 2;
}
else if (inRange(maxLabelLength, labelLengths[3], labelLengths[4])) {
shorteningLevel = 1;
}
else {
shorteningLevel = 0;
}
return shorteningLevel;
}
function calculateFluidLegend(seriesCount, containerWidth) {
// -1 because flex dimensions provide rounded number and the real width can be float
var realWidth = containerWidth - 2 * exports.LEGEND_PADDING - 1;
if (seriesCount <= 2) {
return {
hasPaging: false,
itemWidth: realWidth / seriesCount,
visibleItemsCount: seriesCount,
};
}
var columnsCount = Math.floor(realWidth / exports.RESPONSIVE_ITEM_MIN_WIDTH);
var itemWidth = realWidth / columnsCount;
var hasPaging = false;
var rowsCount = Math.ceil(seriesCount / columnsCount);
// Recalculate with paging
if (rowsCount > exports.RESPONSIVE_VISIBLE_ROWS) {
var legendWidthWithPaging = realWidth - exports.FLUID_PAGING_WIDTH;
columnsCount = Math.floor(legendWidthWithPaging / exports.RESPONSIVE_ITEM_MIN_WIDTH);
itemWidth = legendWidthWithPaging / columnsCount;
hasPaging = true;
}
var visibleItemsCount = columnsCount * exports.RESPONSIVE_VISIBLE_ROWS;
return {
itemWidth: itemWidth,
hasPaging: hasPaging,
visibleItemsCount: visibleItemsCount,
};
}
exports.calculateFluidLegend = calculateFluidLegend;
function getStaticVisibleItemsCount(containerHeight, withPaging) {
if (withPaging === void 0) { withPaging = false; }
var pagingHeight = withPaging ? STATIC_PAGING_HEIGHT : 0;
return Math.floor((containerHeight - pagingHeight) / exports.ITEM_HEIGHT);
}
function calculateStaticLegend(seriesCount, containerHeight) {
var visibleItemsCount = getStaticVisibleItemsCount(containerHeight);
if (visibleItemsCount >= seriesCount) {
return {
hasPaging: false,
visibleItemsCount: visibleItemsCount,
};
}
return {
hasPaging: true,
visibleItemsCount: getStaticVisibleItemsCount(containerHeight, true),
};
}
exports.calculateStaticLegend = calculateStaticLegend;
function getColorLegendLabels(series, format, numericSymbols) {
var min = get(head(series), "range.from", 0);
var max = get(last(series), "range.to", 0);
var diff = max - min;
return range(series.length + 1).map(function (index) {
var value;
if (index === 0) {
value = get(series, "0.range.from", 0);
}
else if (index === series.length) {
value = get(series, index - 1 + ".range.to", 0);
}
else {
value = get(series, index + ".range.from", 0);
}
return common_1.formatLegendLabel(value, format, diff, numericSymbols);
});
}
var MIDDLE_LEGEND_BOX_INDEX = 3;
function getColorBoxes(series) {
var getBoxStyle = function (item) { return ({
backgroundColor: item.color,
border: item.color === "rgb(255,255,255)" ? "1px solid #ccc" : "none",
}); };
return series.map(function (item, index) {
var style = getBoxStyle(item);
var middle = index === MIDDLE_LEGEND_BOX_INDEX ? "middle" : null;
return {
class: middle,
key: "item-" + index,
style: style,
};
});
}
function getColorLegendConfiguration(series, format, numericSymbols, isSmall, position) {
var legendLabels = getColorLegendLabels(series, format, numericSymbols);
var small = isSmall ? "small" : null;
var finalPosition;
// tslint:disable-next-line:prefer-conditional-expression
if (isSmall) {
finalPosition = position === PositionTypes_1.TOP ? PositionTypes_1.TOP : PositionTypes_1.BOTTOM;
}
else {
finalPosition = position || PositionTypes_1.RIGHT;
}
var classes = ["viz-legend", "color-legend", "position-" + finalPosition, small];
var isVertical = finalPosition === PositionTypes_1.LEFT || finalPosition === PositionTypes_1.RIGHT;
var finalLabels = getColorLegendLabelsConfiguration(legendLabels, isSmall, isVertical);
var boxes = getColorBoxes(series);
return {
classes: classes,
labels: finalLabels,
boxes: boxes,
position: finalPosition,
};
}
exports.getColorLegendConfiguration = getColorLegendConfiguration;
var LEGEND_TEXT_KEYS = {
column: ["left", "right"],
line: ["left", "right"],
bar: ["bottom", "top"],
area: ["left", "right"],
combo: ["left", "right"],
combo2: ["left", "right"],
};
exports.LEGEND_AXIS_INDICATOR = "legendAxisIndicator";
exports.LEGEND_SEPARATOR = "legendSeparator";
function separateLegendItems(series) {
return series.reduce(function (result, item) {
// for now, it assumes that GDC chart only has 2 Y axes in maximum
// yAxis only takes 0 (left/bottom axis) or 1 (right/top axis)
var yAxis = item.yAxis;
if (!yAxis) {
// 0
result.itemsOnFirstAxis.push(item);
}
else {
result.itemsOnSecondAxis.push(item);
}
return result;
}, {
itemsOnFirstAxis: [],
itemsOnSecondAxis: [],
});
}
function groupSeriesItemsByType(series) {
var primaryType = get(head(series), "type");
return series.reduce(function (result, item) {
if (primaryType === item.type) {
result.primaryItems.push(item);
}
else {
result.secondaryItems.push(item);
}
return result;
}, {
primaryItems: [],
secondaryItems: [],
});
}
exports.groupSeriesItemsByType = groupSeriesItemsByType;
function getComboChartSeries(series) {
var _a = groupSeriesItemsByType(series), primaryItems = _a.primaryItems, secondaryItems = _a.secondaryItems;
var primaryItem = head(primaryItems) || {};
var secondaryItem = head(secondaryItems) || {};
var primaryType = primaryItem.type || visualizationTypes_1.VisualizationTypes.COLUMN;
var secondaryType = secondaryItem.type || visualizationTypes_1.VisualizationTypes.LINE;
var _b = LEGEND_TEXT_KEYS.combo, firstAxisKey = _b[0], secondAxisKey = _b[1];
// convert to dual axis series when there is only one chart type
if (isEmpty(secondaryItems)) {
return transformToDualAxesSeries(series, primaryType);
}
// all measures display on same axis
if (primaryItem.yAxis === secondaryItem.yAxis) {
return [
{ type: exports.LEGEND_AXIS_INDICATOR, labelKey: primaryType }
].concat(primaryItems, [
{ type: exports.LEGEND_SEPARATOR },
{ type: exports.LEGEND_AXIS_INDICATOR, labelKey: secondaryType }
], secondaryItems);
}
return [
{
type: exports.LEGEND_AXIS_INDICATOR,
labelKey: visualizationTypes_1.VisualizationTypes.COMBO,
data: [primaryType, firstAxisKey],
}
].concat(primaryItems, [
{ type: exports.LEGEND_SEPARATOR },
{
type: exports.LEGEND_AXIS_INDICATOR,
labelKey: visualizationTypes_1.VisualizationTypes.COMBO,
data: [secondaryType, secondAxisKey],
}
], secondaryItems);
}
exports.getComboChartSeries = getComboChartSeries;
function transformToDualAxesSeries(series, chartType) {
var _a = separateLegendItems(series), itemsOnFirstAxis = _a.itemsOnFirstAxis, itemsOnSecondAxis = _a.itemsOnSecondAxis;
if (!common_1.isOneOfTypes(chartType, chartOptionsBuilder_1.supportedDualAxesChartTypes) ||
!itemsOnFirstAxis.length ||
!itemsOnSecondAxis.length) {
return series;
}
var _b = LEGEND_TEXT_KEYS[chartType], firstAxisKey = _b[0], secondAxisKey = _b[1];
return [
{ type: exports.LEGEND_AXIS_INDICATOR, labelKey: firstAxisKey }
].concat(itemsOnFirstAxis, [
{ type: exports.LEGEND_SEPARATOR },
{ type: exports.LEGEND_AXIS_INDICATOR, labelKey: secondAxisKey }
], itemsOnSecondAxis);
}
exports.transformToDualAxesSeries = transformToDualAxesSeries;
function isStackedChart(chartOptions) {
var seriesLength = get(chartOptions, "data.series.length");
var type = chartOptions.type, stacking = chartOptions.stacking, hasStackByAttribute = chartOptions.hasStackByAttribute;
var hasMoreThanOneSeries = seriesLength > 1;
var isAreaChartWithOneSerie = common_1.isAreaChart(type) && !hasMoreThanOneSeries && !hasStackByAttribute;
return !isAreaChartWithOneSerie && !common_1.isTreemap(type) && Boolean(stacking);
}
exports.isStackedChart = isStackedChart;
//# sourceMappingURL=helpers.js.map