some refactoring to get rid of duplicated code in row-lists

This commit is contained in:
Kristoffer Lind
2019-01-25 18:43:02 +01:00
parent f0121b3a75
commit 2bf9259fdc
6 changed files with 451 additions and 199 deletions

View File

@@ -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 = (
<th class = "empty" style={seperatorStyle}>*</th>
);
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 = (
<td className={'grid-cells-small' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
} else {
cellElement = (
<td className={'grid-cells' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
}
} else {
const cellStyle = {
fontFamily: vFontFamily,
...styleBuilder.getStyle(),
textAlign: 'right',
paddingRight: '4px'
};
if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) {
cellElement = (
<td className={'grid-cells-small' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
} else {
cellElement = (
<td className={'grid-cells' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
}
}
measurementCells.push(cellElement);
}
return (
<React.Fragment>
{measurementCells}
</React.Fragment>
)
}
}
ElseDimensionMeasures.propTypes = {};
export default ElseDimensionMeasures;

View File

@@ -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 = (
<th class = "empty" style={seperatorStyle}>*</th>
);
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 = (
<td className={'grid-cells-small' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
} else {
cellElement = (
<td className={'grid-cells' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
}
} else {
const cellStyle = {
fontFamily: vFontFamily,
...styleBuilder.getStyle(),
textAlign: 'right',
paddingRight: '4px'
};
if (vSpecialF.substring(vSpecialF.length - 1) == '%' && vNumMeasures > 1) {
cellElement = (
<td className={'grid-cells-small' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
} else {
cellElement = (
<td className={'grid-cells' + sufixCells} style={cellStyle}>
{columnNumber}
</td>
);
}
}
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 = (
<tr>
<td class="fdim-cells" style={rowStyle}>
{paddingTextElement}{columnText}
</td>
{cells}
<ElseDimensionMeasures
{...this.props}
{...measurementsProps}
/>
</tr>
);

73
src/row-list.jsx Normal file
View File

@@ -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 (
<span style={paddingStyle}></span>
);
} else {
return null;
}
}
render () {
const {
vLetterSize,
vCustomFileBool,
vFontFamily,
tableData, //ConceptMatrix,
measuresComponent
} = this.props;
return (
<React.Fragment>
{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 (
<tr>
<td class="fdim-cells" style={rowStyle}>
{paddingTextElement}{rowHeaderText}
</td>
<measuresComponent
{...this.props}
{...measurementsProps}
/>
</tr>
);
})}
</React.Fragment>
);
}
}
RowList.propTypes = {
tableData: PropTypes.Array.isRequired
};
export default RowList;

View File

@@ -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 (
<SingleDimensionRowList {...this.props} />
);
} else {
return (
<ElseDimensionRowList {...this.props} />
);
}
}
render () {
const {
ConceptMatrix,
ConceptMatrixPivot
} = this.props;
let tableData, measurementsComponent;
if (this.props.vNumDims === 1) {
tableData = ConceptMatrix;
measurementsComponent = SingleDimensionMeasures;
} else {
tableData = ConceptMatrixPivot;
measurementsComponent = ElseDimensionMeasures;
}
return (
<div className='row-wrapper'>
<table>
{this.generateDimensionRowList()}
<RowList
tableData={tableData}
measurementsComponent={measurementsComponent}
{...this.props}
/>
</table>
</div>
);
@@ -30,7 +37,8 @@ class RowWrapper extends React.PureComponent {
}
RowWrapper.propTypes = {
ConceptMatrix: PropTypes.Array.isRequired,
ConceptMatrixPivot: PropTypes.Array.isRequired
};
async function prepareProps ({ state }) {

View File

@@ -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 = (
<td className="grid-cells' + sufixCells + '" style={cellStyle}>
{vColumnNum}
</td>
);
measurementCells.push(measurementCell);
}
return (
<React.Fragment>
{measurementCells}
</React.Fragment>
);
}
}
SingleDimensionMeasures.propTypes = {};
export default SingleDimensionMeasures;

View File

@@ -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;
}
}
// <SingleDimensionMeasures />
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 = (
<tr>
<td class="fdim-cells" style={rowStyle}>
{paddingTextElement}{columnText}
</td>
{cells}
<SingleDimensionMeasures
{...this.props}
{...measurementsProps}
/>
</tr>
);