From 2bf9259fdcb95877c5f9c1331ad93aea0ff95fde Mon Sep 17 00:00:00 2001 From: Kristoffer Lind Date: Fri, 25 Jan 2019 18:43:02 +0100 Subject: [PATCH] some refactoring to get rid of duplicated code in row-lists --- src/else-dimension-measures.jsx | 195 ++++++++++++++++++++++++++++++ src/else-dimension-row-list.jsx | 190 ++--------------------------- src/row-list.jsx | 73 +++++++++++ src/row-wrapper.jsx | 38 +++--- src/single-dimension-measures.jsx | 138 +++++++++++++++++++++ src/single-dimension-row-list.jsx | 16 ++- 6 files changed, 451 insertions(+), 199 deletions(-) create mode 100644 src/else-dimension-measures.jsx create mode 100644 src/row-list.jsx create mode 100644 src/single-dimension-measures.jsx diff --git a/src/else-dimension-measures.jsx b/src/else-dimension-measures.jsx new file mode 100644 index 0000000..27186d2 --- /dev/null +++ b/src/else-dimension-measures.jsx @@ -0,0 +1,195 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { ApplyPreMask } from './masking'; +import { addSeparators } from './utilities'; + +class ElseDimensionMeasures extends React.PureComponent { + render () { + const { + vFontFamily, + vSeparatorCols, + measure_count, + sufixCells, + vSymbolForNulls, + vLetterSize, + vColorMetric1, + vColorMetric1Text, + vColorMetric2, + vColorMetric2Text, + vColorMetric3, + vColorMetric3Text, + vAllSemaphores, + ConceptMatrixPivot, + ConceptsAffectedMatrix, + vAllMetrics, + MetricsAffectedMatrix, + vCritic, + vMMedium, + vNumMeasures, + vNumMeasures2, + MeasuresFormat, + rowNumber, + columnText, + styleBuilder + } = this.props; + + // modified in here + let columnNumber, + vMaskNum, + vColorSemaphore, + vColorSemaphoreText, + vDivide + ; + + const measurementCells = []; + + var nMeasure7 = 0; + var nMeasure72 = -1; + var nMeasure72Semaphore = 0; + + for (var nMeasures22 = 1; nMeasures22 <= vNumMeasures2; nMeasures22++) { + nMeasure7++; + nMeasure72++; + if (columnText.substring(0, 1) == '%') { + columnNumber = ApplyPreMask('0,00%', ConceptMatrixPivot[rowNumber][nMeasures22]); + var vSpecialF = '0,00%'; + } else { + switch (MeasuresFormat[nMeasure72].substr(MeasuresFormat[nMeasure72].length - 1)) { + case 'k': + vDivide = 1000; + break; + + case 'K': + vDivide = 1000; + break; + + case 'm': + vDivide = 1000000; + break; + + case 'M': + vDivide = 1000000; + break; + + default: + vDivide = 1; + break; + } + var vSpecialF = MeasuresFormat[nMeasure72].replace(/k|K|m|M/gi, ''); + if (!isNaN(ConceptMatrixPivot[rowNumber][nMeasures22])) { + vMaskNum = ConceptMatrixPivot[rowNumber][nMeasures22]; + if (vSpecialF.substring(vSpecialF.length - 1) == '%') { + vMaskNum = vMaskNum * 100; + } + + switch (vSpecialF) { + case '#.##0': + columnNumber = addSeparators((vMaskNum / vDivide), '.', ',', 0); + break; + case '#,##0': + columnNumber = addSeparators((vMaskNum / vDivide), ',', '.', 0); + break; + default: + columnNumber = ApplyPreMask(vSpecialF, (vMaskNum / vDivide)); + break; + } + } else { + columnNumber = vSymbolForNulls; + } + } + + if (vSeparatorCols && nMeasure7 == (measure_count + 1)) { + const seperatorStyle = { + color: 'white', + fontFamily: vFontFamily, + fontSize: (12 + vLetterSize) + 'px' + }; + const seperatorElement = ( + * + ); + measurementCells.push(seperatorElement); + nMeasure7 = 1; + } + if (nMeasure72 == (measure_count - 1)) { + nMeasure72 = -1; + nMeasure72Semaphore = measure_count; + } else { + nMeasure72Semaphore = nMeasure72 + 1; + } + + // apply the semaphores where needed + if (styleBuilder.hasComments()) { + columnNumber = '.'; + } + + let cellElement; + if ((vAllSemaphores || ConceptsAffectedMatrix.indexOf(columnText) >= 0) && (vAllMetrics || MetricsAffectedMatrix.indexOf(nMeasure72Semaphore) >= 0) && !isNaN(ConceptMatrixPivot[rowNumber][nMeasures22]) && !styleBuilder.hasComments()) { + if (ConceptMatrixPivot[rowNumber][nMeasures22] < vCritic) { + vColorSemaphore = vColorMetric1; + vColorSemaphoreText = vColorMetric1Text; + } else { + if (ConceptMatrixPivot[rowNumber][nMeasures22] < vMMedium) { + vColorSemaphore = vColorMetric2; + vColorSemaphoreText = vColorMetric2Text; + } else { + vColorSemaphore = vColorMetric3; + vColorSemaphoreText = vColorMetric3Text; + } + } + + const cellStyle = { + fontFamily: vFontFamily, + fontSize: styleBuilder.getStyle().fontSize, + color: vColorSemaphoreText, + backgroundColor: vColorSemaphore, + textAlign: 'right', + paddingLeft: '4px' + }; + if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) { + cellElement = ( + + {columnNumber} + + ); + } else { + cellElement = ( + + {columnNumber} + + ); + } + } else { + const cellStyle = { + fontFamily: vFontFamily, + ...styleBuilder.getStyle(), + textAlign: 'right', + paddingRight: '4px' + }; + if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) { + cellElement = ( + + {columnNumber} + + ); + } else { + cellElement = ( + + {columnNumber} + + ); + } + } + measurementCells.push(cellElement); + } + + return ( + + {measurementCells} + + ) + } +} + +ElseDimensionMeasures.propTypes = {}; + +export default ElseDimensionMeasures; diff --git a/src/else-dimension-row-list.jsx b/src/else-dimension-row-list.jsx index 86c2a38..7fe9546 100644 --- a/src/else-dimension-row-list.jsx +++ b/src/else-dimension-row-list.jsx @@ -1,8 +1,12 @@ +/* + DO NOT USE + should use row-list component instead, this is just left in here until testing conversion +*/ + import React from 'react'; import PropTypes from 'prop-types'; -import { ApplyPreMask } from './masking'; -import { addSeparators } from './utilities'; import StyleBuilder from './style-builder'; +import ElseDimensionMeasures from './single-dimension-measures'; class ElseDimensionRowList extends React.PureComponent { generatePaddingTextElement (hasCustomFileStyle) { @@ -19,181 +23,6 @@ class ElseDimensionRowList extends React.PureComponent { return null; } } - generateCells (rowNumber, columnText, styleBuilder) { - const { - vFontFamily, - vSeparatorCols, - measure_count, - sufixCells, - vSymbolForNulls, - vLetterSize, - vColorMetric1, - vColorMetric1Text, - vColorMetric2, - vColorMetric2Text, - vColorMetric3, - vColorMetric3Text, - vAllSemaphores, - ConceptMatrixPivot, - ConceptsAffectedMatrix, - vAllMetrics, - MetricsAffectedMatrix, - vCritic, - vMMedium, - vNumMeasures, - vNumMeasures2, - MeasuresFormat - } = this.props; - - // modified in here - let columnNumber, - vMaskNum, - vColorSemaphore, - vColorSemaphoreText, - vDivide - ; - - const measurementCells = []; - - var nMeasure7 = 0; - var nMeasure72 = -1; - var nMeasure72Semaphore = 0; - - for (var nMeasures22 = 1; nMeasures22 <= vNumMeasures2; nMeasures22++) { - nMeasure7++; - nMeasure72++; - if (columnText.substring(0, 1) == '%') { - columnNumber = ApplyPreMask('0,00%', ConceptMatrixPivot[rowNumber][nMeasures22]); - var vSpecialF = '0,00%'; - } else { - switch (MeasuresFormat[nMeasure72].substr(MeasuresFormat[nMeasure72].length - 1)) { - case 'k': - vDivide = 1000; - break; - - case 'K': - vDivide = 1000; - break; - - case 'm': - vDivide = 1000000; - break; - - case 'M': - vDivide = 1000000; - break; - - default: - vDivide = 1; - break; - } - var vSpecialF = MeasuresFormat[nMeasure72].replace(/k|K|m|M/gi, ''); - if (!isNaN(ConceptMatrixPivot[rowNumber][nMeasures22])) { - vMaskNum = ConceptMatrixPivot[rowNumber][nMeasures22]; - if (vSpecialF.substring(vSpecialF.length - 1) == '%') { - vMaskNum = vMaskNum * 100; - } - - switch (vSpecialF) { - case '#.##0': - columnNumber = addSeparators((vMaskNum / vDivide), '.', ',', 0); - break; - case '#,##0': - columnNumber = addSeparators((vMaskNum / vDivide), ',', '.', 0); - break; - default: - columnNumber = ApplyPreMask(vSpecialF, (vMaskNum / vDivide)); - break; - } - } else { - columnNumber = vSymbolForNulls; - } - } - - if (vSeparatorCols && nMeasure7 == (measure_count + 1)) { - const seperatorStyle = { - color: 'white', - fontFamily: vFontFamily, - fontSize: (12 + vLetterSize) + 'px' - }; - const seperatorElement = ( - * - ); - measurementCells.push(seperatorElement); - nMeasure7 = 1; - } - if (nMeasure72 == (measure_count - 1)) { - nMeasure72 = -1; - nMeasure72Semaphore = measure_count; - } else { - nMeasure72Semaphore = nMeasure72 + 1; - } - - // apply the semaphores where needed - if (styleBuilder.hasComments()) { - columnNumber = '.'; - } - - let cellElement; - if ((vAllSemaphores || ConceptsAffectedMatrix.indexOf(columnText) >= 0) && (vAllMetrics || MetricsAffectedMatrix.indexOf(nMeasure72Semaphore) >= 0) && !isNaN(ConceptMatrixPivot[rowNumber][nMeasures22]) && !styleBuilder.hasComments()) { - if (ConceptMatrixPivot[rowNumber][nMeasures22] < vCritic) { - vColorSemaphore = vColorMetric1; - vColorSemaphoreText = vColorMetric1Text; - } else { - if (ConceptMatrixPivot[rowNumber][nMeasures22] < vMMedium) { - vColorSemaphore = vColorMetric2; - vColorSemaphoreText = vColorMetric2Text; - } else { - vColorSemaphore = vColorMetric3; - vColorSemaphoreText = vColorMetric3Text; - } - } - - const cellStyle = { - fontFamily: vFontFamily, - fontSize: styleBuilder.getStyle().fontSize, - color: vColorSemaphoreText, - backgroundColor: vColorSemaphore, - textAlign: 'right', - paddingLeft: '4px' - }; - if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) { - cellElement = ( - - {columnNumber} - - ); - } else { - cellElement = ( - - {columnNumber} - - ); - } - } else { - const cellStyle = { - fontFamily: vFontFamily, - ...styleBuilder.getStyle(), - textAlign: 'right', - paddingRight: '4px' - }; - if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) { - cellElement = ( - - {columnNumber} - - ); - } else { - cellElement = ( - - {columnNumber} - - ); - } - } - measurementCells.push(cellElement); - } - } generateRows () { const { vLetterSize, @@ -224,13 +53,16 @@ class ElseDimensionRowList extends React.PureComponent { ...styleBuilder.getStyle() }; const paddingTextElement = this.generatePaddingTextElement(styleBuilder.hasCustomFileStyle()); - const cells = this.generateCells(rowNumber, columnText, styleBuilder); + const measurementsProps = { rowNumber, columnText, styleBuilder }; const rowElement = ( {paddingTextElement}{columnText} - {cells} + ); diff --git a/src/row-list.jsx b/src/row-list.jsx new file mode 100644 index 0000000..e0d0f43 --- /dev/null +++ b/src/row-list.jsx @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import StyleBuilder from './style-builder'; + +// TODO: everything except cell rendering is pretty much identical to ElseDimensionRowList +class RowList extends React.PureComponent { + generatePaddingTextElement (hasCustomFileStyle) { + const { vPadding, vFontFamily } = this.props; + if (vPadding && !hasCustomFileStyle) { + const paddingStyle = { + marginLeft: '15px', + fontFamily: vFontFamily + }; + return ( + + ); + } else { + return null; + } + } + render () { + const { + vLetterSize, + vCustomFileBool, + vFontFamily, + tableData, //ConceptMatrix, + measuresComponent + } = this.props; + + return ( + + {tableData.map((row, rowNumber) => { + const rowHeaderText = row[0]; + if (rowHeaderText === '-') { + return null; + } + const styleBuilder = new StyleBuilder(this.props); + if (vCustomFileBool) { + styleBuilder.parseCustomFileStyle(rowHeaderText); // TODO: parseCSVStyle? + } else { + styleBuilder.applyStandardAttributes(rowNumber); + styleBuilder.applyCustomStyle({ fontSize: (14 + vLetterSize) + 'px' }); + } + + const rowStyle = { + fontFamily: vFontFamily, + width: '230px', + ...styleBuilder.getStyle() + }; + const paddingTextElement = this.generatePaddingTextElement(styleBuilder.hasCustomFileStyle()); + const measurementsProps = { rowNumber, rowHeaderText, styleBuilder }; + return ( + + + {paddingTextElement}{rowHeaderText} + + + + ); + })} + + ); + } +} + +RowList.propTypes = { + tableData: PropTypes.Array.isRequired +}; + +export default RowList; diff --git a/src/row-wrapper.jsx b/src/row-wrapper.jsx index 360e39b..ad4caf7 100644 --- a/src/row-wrapper.jsx +++ b/src/row-wrapper.jsx @@ -2,27 +2,34 @@ import React from 'react'; import PropTypes from 'prop-types'; import { renderToStaticMarkup } from 'react-dom/server'; import $ from 'jquery'; -import SingleDimensionRowList from './single-dimension-row-list'; -import ElseDimensionRowList from './single-dimension-row-list'; +import RowList from './row-list'; +import SingleDimensionMeasures from './single-dimension-measures'; +import ElseDimensionMeasures from './single-dimension-measures'; // TableBody? class RowWrapper extends React.PureComponent { - generateDimensionRowList () { - if (this.props.vNumDims === 1) { - return ( - - ); - } else { - return ( - - ); - } - } render () { + const { + ConceptMatrix, + ConceptMatrixPivot + } = this.props; + let tableData, measurementsComponent; + if (this.props.vNumDims === 1) { + tableData = ConceptMatrix; + measurementsComponent = SingleDimensionMeasures; + } else { + tableData = ConceptMatrixPivot; + measurementsComponent = ElseDimensionMeasures; + } + return (
- {this.generateDimensionRowList()} +
); @@ -30,7 +37,8 @@ class RowWrapper extends React.PureComponent { } RowWrapper.propTypes = { - + ConceptMatrix: PropTypes.Array.isRequired, + ConceptMatrixPivot: PropTypes.Array.isRequired }; async function prepareProps ({ state }) { diff --git a/src/single-dimension-measures.jsx b/src/single-dimension-measures.jsx new file mode 100644 index 0000000..f1ede88 --- /dev/null +++ b/src/single-dimension-measures.jsx @@ -0,0 +1,138 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { ApplyPreMask } from './masking'; +import { addSeparators } from './utilities'; + +class SingleDimensionMeasures extends React.PureComponent { + render () { + const { + vFontFamily, + vSymbolForNulls, + vColorMetric1, + vColorMetric1Text, + vColorMetric2, + vColorMetric2Text, + vColorMetric3, + vColorMetric3Text, + ConceptMatrix, + vAllSemaphores, + ConceptsAffectedMatrix, + vAllMetrics, + MetricsAffectedMatrix, + vCritic, + vMMedium, + vNumMeasures, + MeasuresFormat, + rowNumber, + columnText, + styleBuilder + } = this.props; + + // modified in here + let vColumnNum, + vMaskNum, + vColorSemaphore, + vColorSemaphoreText, + vDivide; + + const measurementCells = []; + + // TODO: map ConceptMatrix[rowNumber] into cells + for (var nMeasures2 = 1; nMeasures2 <= vNumMeasures; nMeasures2++) { + var vSpecialF = MeasuresFormat[nMeasures2 - 1].replace(/k|K|m|M/gi, ''); + if (columnText.substring(0, 1) == '%') { + vColumnNum = ApplyPreMask('0,00%', ConceptMatrix[rowNumber][nMeasures2]); + vSpecialF = '0,00%'; + } else { + const magnitude = MeasuresFormat[nMeasures2 - 1].substr(MeasuresFormat[nMeasures2 - 1].length - 1); + switch (magnitude.toLowerCase()) { + case 'k': + vDivide = 1000; + break; + + case 'm': + vDivide = 1000000; + break; + + default: + vDivide = 1; + break; + } + if (!isNaN(ConceptMatrix[rowNumber][nMeasures2])) { + vMaskNum = ConceptMatrix[rowNumber][nMeasures2]; + if (vSpecialF.substring(vSpecialF.length - 1) == '%') { + vMaskNum = vMaskNum * 100; + } + switch (vSpecialF) { + case '#.##0': + vColumnNum = addSeparators((vMaskNum / vDivide), '.', ',', 0); + break; + + case '#,##0': + vColumnNum = addSeparators((vMaskNum / vDivide), ',', '.', 0); + break; + + default: + vColumnNum = ApplyPreMask(vSpecialF, (vMaskNum / vDivide)); + break; + } + } else { + vColumnNum = vSymbolForNulls; + } + } + if (styleBuilder.hasComments()) { + vColumnNum = '.'; + } + // apply the semaphore styles where needed + let cellStyle; + if ((vAllSemaphores || ConceptsAffectedMatrix.indexOf(columnText) >= 0) && (vAllMetrics || MetricsAffectedMatrix.indexOf(nMeasures2) >= 0) && !isNaN(ConceptMatrix[rowNumber][nMeasures2]) && !styleBuilder.hasComments()) { + if (ConceptMatrix[rowNumber][nMeasures2] < vCritic) { + vColorSemaphore = vColorMetric1; + vColorSemaphoreText = vColorMetric1Text; + } else { + if (ConceptMatrix[rowNumber][nMeasures2] < vMMedium) { + vColorSemaphore = vColorMetric2; + vColorSemaphoreText = vColorMetric2Text; + } else { + vColorSemaphore = vColorMetric3; + vColorSemaphoreText = vColorMetric3Text; + } + } + + cellStyle = { + fontFamily: vFontFamily, + fontSize: styleBuilder.getStyle().fontSize, + color: vColorSemaphoreText, + backgroundColor: vColorSemaphore, + textAlign: 'right', + paddingLeft: '4px' + }; + } else { + cellStyle = { + fontFamily: vFontFamily, + textAlign: 'right', + paddingLeft: '4px', + ...styleBuilder.getStyle() // TODO: this will explode since styletags are currently a string + }; + } + + const measurementCell = ( + + {vColumnNum} + + ); + + measurementCells.push(measurementCell); + } + + return ( + + {measurementCells} + + ); + } +} + +SingleDimensionMeasures.propTypes = {}; + +export default SingleDimensionMeasures; diff --git a/src/single-dimension-row-list.jsx b/src/single-dimension-row-list.jsx index f8ef340..77cc770 100644 --- a/src/single-dimension-row-list.jsx +++ b/src/single-dimension-row-list.jsx @@ -1,8 +1,12 @@ +/* + DO NOT USE + should use row-list component instead, this is just left in here until testing conversion +*/ + import React from 'react'; import PropTypes from 'prop-types'; -import { ApplyPreMask } from './masking'; -import { addSeparators } from './utilities'; import StyleBuilder from './style-builder'; +import SingleDimensionMeasures from './single-dimension-measures'; // TODO: everything except cell rendering is pretty much identical to ElseDimensionRowList // extract cells into subcomponents and merge to generic rowlist @@ -21,7 +25,6 @@ class SingleDimensionRowList extends React.PureComponent { return null; } } - // generateRows () { const { vLetterSize, @@ -52,13 +55,16 @@ class SingleDimensionRowList extends React.PureComponent { ...styleBuilder.getStyle() }; const paddingTextElement = this.generatePaddingTextElement(styleBuilder.hasCustomFileStyle()); - const cells = this.generateCells(rowNumber, columnText, styleBuilder); + const measurementsProps = { rowNumber, columnText, styleBuilder }; const rowElement = ( {paddingTextElement}{columnText} - {cells} + );