UNPKG

@gooddata/react-components

Version:

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

100 lines (89 loc) 3.36 kB
// (C) 2007-2019 GoodData Corporation import { colors2Object, ISeparators, numberFormat } from "@gooddata/numberjs"; import isEmpty = require("lodash/isEmpty"); import isNaN = require("lodash/isNaN"); import { IFormattedHeadlineDataItem, IHeadlineDataItem } from "../../../../interfaces/Headlines"; import { IChartConfig } from "../../../../interfaces/Config"; const DEFAULT_VALUE_WHEN_EMPTY = "–"; const INVALID_VALUE = "NaN"; const PERCENTAGE_VALUE_LIMIT = 999; function processStringForNumberJs(value: string | null, format: string) { return value === null && !isEmpty(format) ? "" // return empty string for null value for number.js to apply [=null] format : parseFloat(value as string); } function formatValueToLabelWithColors(value: string | null, format: string, separators?: ISeparators) { const processedValue = processStringForNumberJs(value, format); const formattedValue = numberFormat(processedValue, format, undefined, separators); return colors2Object(formattedValue); } function buildCssStyle(color?: string, backgroundColor?: string) { const style: any = {}; if (color !== undefined) { style.color = color; } if (backgroundColor !== undefined) { style.backgroundColor = backgroundColor; } return style; } /** * Format {HeadlineData} value. * * The method processes the provided item and returns object with value that can be rendered as it is and 'cssStyle' * object that can be passed into the react element 'style' attribute. * * @param item * @returns {{cssStyle: {color, backgroundColor}, value: string, isValueEmpty: boolean}} */ export function formatItemValue( item: IHeadlineDataItem, config: IChartConfig = {}, ): IFormattedHeadlineDataItem { const { separators } = config; const { label, color, backgroundColor } = formatValueToLabelWithColors( item.value, item.format, separators, ); const isValueEmpty = label === INVALID_VALUE || label === ""; const value = isValueEmpty ? DEFAULT_VALUE_WHEN_EMPTY : label; return { cssStyle: buildCssStyle(color, backgroundColor), value, isValueEmpty, }; } /** * The method processes the provided IHeadlineDataItem and returns object with formatted value and isValueEmpty flag. * * Formatted value conditions: * - value is rounded to Integer * - shows '>999%' when value is above the limit * - shows '<-999%' when value is below the limit * - otherwise shows 'value%' * * @param item * @returns {{value: string, isValueEmpty: boolean}} */ export function formatPercentageValue(item: IHeadlineDataItem): IFormattedHeadlineDataItem { if (!item || item.value === null || isNaN(parseFloat(item.value))) { return { value: DEFAULT_VALUE_WHEN_EMPTY, isValueEmpty: true, }; } const roundedNumber = Math.round(parseFloat(item.value)); const isOverLimit = roundedNumber > PERCENTAGE_VALUE_LIMIT; const isUnderLimit = roundedNumber < -PERCENTAGE_VALUE_LIMIT; let formattedValue = `${roundedNumber}%`; if (isOverLimit) { formattedValue = `>${PERCENTAGE_VALUE_LIMIT}%`; } else if (isUnderLimit) { formattedValue = `<-${PERCENTAGE_VALUE_LIMIT}%`; } return { value: formattedValue, isValueEmpty: false, }; }