From 49981f6ae33e808db1eeb4afa64644ae944a6cdf Mon Sep 17 00:00:00 2001 From: Albert Backenhof Date: Thu, 9 May 2019 10:09:33 +0200 Subject: [PATCH] Fixed cell number formatting -Now will always use the built in Qlik value format. Issue: DEB-217, DEB-218, DEB-219, DEB-220 --- src/data-table/data-cell.jsx | 52 ++------------ src/masking.js | 132 ----------------------------------- src/utilities.js | 15 ---- 3 files changed, 4 insertions(+), 195 deletions(-) delete mode 100644 src/masking.js diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index 316eb2d..9240d27 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -1,7 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { ApplyPreMask } from '../masking'; -import { addSeparators } from '../utilities'; import Tooltip from '../tooltip/index.jsx'; class DataCell extends React.PureComponent { @@ -45,11 +43,9 @@ class DataCell extends React.PureComponent { const isEmptyCell = measurement.displayValue === ''; const isColumnPercentageBased = (/%/).test(measurement.format); let formattedMeasurementValue; - if (isEmptyCell) { + if (isEmptyCell || styleBuilder.hasComments()) { formattedMeasurementValue = ''; cellStyle.cursor = 'default'; - } else if (styleBuilder.hasComments()) { - formattedMeasurementValue = '.'; } else { formattedMeasurementValue = formatMeasurementValue(measurement, styling); } @@ -129,51 +125,11 @@ DataCell.propTypes = { export default DataCell; function formatMeasurementValue (measurement, styling) { - const isColumnPercentageBased = (/%/).test(measurement.format); - let formattedMeasurementValue = ''; - if (isColumnPercentageBased) { - if (isNaN(measurement.value)) { - formattedMeasurementValue = styling.symbolForNulls; - } else { - formattedMeasurementValue = ApplyPreMask('0,00%', measurement.value); - } + if (isNaN(measurement.value)) { + return styling.symbolForNulls; } else { - let magnitudeDivider; - switch (measurement.magnitude.toLowerCase()) { - case 'k': - magnitudeDivider = 1000; - break; - case 'm': - magnitudeDivider = 1000000; - break; - default: - magnitudeDivider = 1; - } - const formattingStringWithoutMagnitude = measurement.format.replace(/k|K|m|M/gi, ''); - if (isNaN(measurement.value)) { - formattedMeasurementValue = styling.symbolForNulls; - } else { - let preFormatValue = measurement.value; - if (isColumnPercentageBased) { - preFormatValue *= 100; - } - switch (formattingStringWithoutMagnitude) { - case '#.##0': - formattedMeasurementValue = addSeparators((preFormatValue / magnitudeDivider), '.', ',', 0); - break; - case '#,##0': - formattedMeasurementValue = addSeparators((preFormatValue / magnitudeDivider), ',', '.', 0); - break; - default: - formattedMeasurementValue = ApplyPreMask( - formattingStringWithoutMagnitude, - (preFormatValue / magnitudeDivider) - ); - break; - } - } + return measurement.displayValue; } - return formattedMeasurementValue; } function getConditionalColor (measurement, conditionalColoring) { diff --git a/src/masking.js b/src/masking.js deleted file mode 100644 index 5cda4af..0000000 --- a/src/masking.js +++ /dev/null @@ -1,132 +0,0 @@ -import { addSeparators } from './utilities'; - -export function ApplyPreMask (mask, value) { // aqui - if (mask.indexOf(';') >= 0) { - if (value >= 0) { - switch (mask.substring(0, mask.indexOf(';'))) { - case '#.##0': - return (addSeparators(value, '.', ',', 0)); - case '#,##0': - return (addSeparators(value, ',', '.', 0)); - case '+#.##0': - return (addSeparators(value, '.', ',', 0)); - case '+#,##0': - return (addSeparators(value, ',', '.', 0)); - default: - return (applyMask(mask.substring(0, mask.indexOf(';')), value)); - } - } else { - const vMyValue = value * -1; - let vMyMask = mask.substring(mask.indexOf(';') + 1, mask.length); - vMyMask = vMyMask.replace('(', ''); - vMyMask = vMyMask.replace(')', ''); - switch (vMyMask) { - case '#.##0': - return (`(${addSeparators(vMyValue, '.', ',', 0)})`); - case '#,##0': - return (`(${addSeparators(vMyValue, ',', '.', 0)})`); - case '-#.##0': - return (`(${addSeparators(vMyValue, '.', ',', 0)})`); - case '-#,##0': - return (`(${addSeparators(vMyValue, ',', '.', 0)})`); - default: - return (`(${applyMask(vMyMask, vMyValue)})`); - } - } - } else { - return (applyMask(mask, value)); - } -} - -function applyMask (originalMask, originalValue) { - if (!originalMask || isNaN(Number(originalValue))) { - return originalValue; - } - - let isNegative; - let result; - let integer; - // find prefix/suffix - let len = originalMask.length; - const start = originalMask.search(/[0-9\-\+#]/); - const prefix = start > 0 ? originalMask.substring(0, start) : ''; - // reverse string: not an ideal method if there are surrogate pairs - let str = originalMask.split('') - .reverse() - .join(''); - const end = str.search(/[0-9\-\+#]/); - let offset = len - end; - const substr = originalMask.substring(offset, offset + 1); - let index = offset + ((substr === '.' || (substr === ',')) ? 1 : 0); - const suffix = end > 0 ? originalMask.substring(index, len) : ''; - - // mask with prefix & suffix removed - let mask = originalMask.substring(start, index); - - // convert any string to number according to formation sign. - let value = mask.charAt(0) === '-' ? -originalValue : Number(originalValue); - isNegative = value < 0 ? value = -value : 0; // process only abs(), and turn on flag. - - // search for separator for grp & decimal, anything not digit, not +/- sign, not #. - result = mask.match(/[^\d\-\+#]/g); - const decimal = (result && result[result.length - 1]) || '.'; // treat the right most symbol as decimal - const group = (result && result[1] && result[0]) || ','; // treat the left most symbol as group separator - - // split the decimal for the format string if any. - mask = mask.split(decimal); - // Fix the decimal first, toFixed will auto fill trailing zero. - value = value.toFixed(mask[1] && mask[1].length); - value = String(Number(value)); // convert number to string to trim off *all* trailing decimal zero(es) - - // fill back any trailing zero according to format - const posTrailZero = mask[1] && mask[1].lastIndexOf('0'); // look for last zero in format - const part = value.split('.'); - // integer will get !part[1] - if (!part[1] || (part[1] && part[1].length <= posTrailZero)) { - value = (Number(value)).toFixed(posTrailZero + 1); - } - const szSep = mask[0].split(group); // look for separator - mask[0] = szSep.join(''); // join back without separator for counting the pos of any leading 0. - - const posLeadZero = mask[0] && mask[0].indexOf('0'); - if (posLeadZero > -1) { - while (part[0].length < (mask[0].length - posLeadZero)) { - part[0] = `0${part[0]}`; - } - } else if (Number(part[0]) === 0) { - part[0] = ''; - } - - value = value.split('.'); - value[0] = part[0]; - - // process the first group separator from decimal (.) only, the rest ignore. - // get the length of the last slice of split result. - const posSeparator = (szSep[1] && szSep[szSep.length - 1].length); - if (posSeparator) { - integer = value[0]; - str = ''; - offset = integer.length % posSeparator; - len = integer.length; - for (index = 0; index < len; index++) { - str += integer.charAt(index); // ie6 only support charAt for sz. - // -posSeparator so that won't trail separator on full length - // jshint -W018 - if (!((index - offset + 1) % posSeparator) && index < len - posSeparator) { - str += group; - } - } - value[0] = str; - } - value[1] = (mask[1] && value[1]) ? decimal + value[1] : ''; - - // remove negative sign if result is zero - result = value.join(''); - if (result === '0' || result === '') { - // remove negative sign if result is zero - isNegative = false; - } - - // put back any negation, combine integer and fraction, and add back prefix & suffix - return prefix + ((isNegative ? '-' : '') + result) + suffix; -} diff --git a/src/utilities.js b/src/utilities.js index ba1b069..407c511 100644 --- a/src/utilities.js +++ b/src/utilities.js @@ -9,21 +9,6 @@ export function distinctArray (array) { .map(entry => JSON.parse(entry)); } -export function addSeparators (number, thousandSeparator, decimalSeparator, numberOfDecimals) { - const numberString = number.toFixed(numberOfDecimals); - const numberStringParts = numberString.split('.'); - let [ - wholeNumber, - decimal - ] = numberStringParts; - decimal = numberStringParts.length > 1 ? decimalSeparator + decimal : ''; - const regexCheckForThousand = /(\d+)(\d{3})/; - while (regexCheckForThousand.test(wholeNumber)) { - wholeNumber = wholeNumber.replace(regexCheckForThousand, `$1${thousandSeparator}$2`); - } - return wholeNumber + decimal; -} - export function Deferred () { this.promise = new Promise((resolve, reject) => { this.resolve = resolve;