diff --git a/src/data-table/data-cell.jsx b/src/data-table/data-cell.jsx index 7178553..adde657 100644 --- a/src/data-table/data-cell.jsx +++ b/src/data-table/data-cell.jsx @@ -5,7 +5,7 @@ import { addSeparators } from '../utilities'; function formatMeasurementValue (measurement, styling) { // TODO: measurement.name is a horrible propertyname, it's actually the column header - const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; + const isColumnPercentageBased = measurement.parents.measurement.header.substring(0, 1) === '%'; let formattedMeasurementValue = ''; if (isColumnPercentageBased) { if (isNaN(measurement.value)) { @@ -62,50 +62,74 @@ function getSemaphoreColors (measurement, semaphoreColors) { return semaphoreColors.statusColors.normal; } -const DataCell = ({ data, general, measurement, styleBuilder, styling }) => { - const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; - let formattedMeasurementValue = formatMeasurementValue(measurement, styling); - if (styleBuilder.hasComments()) { - formattedMeasurementValue = '.'; +class DataCell extends React.PureComponent { + constructor (props) { + super(props); + + this.handleSelect = this.handleSelect.bind(this); } - let cellStyle = { - fontFamily: styling.options.fontFamily, - ...styleBuilder.getStyle(), - paddingRight: '4px', - textAlign: 'right' + handleSelect () { + const { data: { meta: { dimensionCount } }, general: { allowFilteringByClick }, measurement, qlik } = this.props; + const hasSecondDimension = dimensionCount > 1; + if (!allowFilteringByClick) { + return; + } - }; - const { semaphoreColors } = styling; - const isValidSemaphoreValue = !styleBuilder.hasComments() && !isNaN(measurement.value); - const shouldHaveSemaphoreColors = semaphoreColors.fieldsToApplyTo.applyToAll || semaphoreColors.fieldsToApplyTo.specificFields.indexOf(measurement.name) !== -1; - if (isValidSemaphoreValue && shouldHaveSemaphoreColors) { - const { backgroundColor, color } = getSemaphoreColors(measurement, semaphoreColors); - cellStyle = { - backgroundColor, - color, + qlik.backendApi.selectValues(0, [measurement.parents.dimension1.elementNumber], true); + + if (hasSecondDimension) { + qlik.backendApi.selectValues(1, [measurement.parents.dimension2.elementNumber], true); + } + } + + render () { + const { data, general, measurement, styleBuilder, styling } = this.props; + const isColumnPercentageBased = measurement.name.substring(0, 1) === '%'; + let formattedMeasurementValue = formatMeasurementValue(measurement, styling); + if (styleBuilder.hasComments()) { + formattedMeasurementValue = '.'; + } + + let cellStyle = { fontFamily: styling.options.fontFamily, - fontSize: styleBuilder.getStyle().fontSize, + ...styleBuilder.getStyle(), paddingLeft: '4px', textAlign: 'right' + }; - } + const { semaphoreColors } = styling; + const isValidSemaphoreValue = !styleBuilder.hasComments() && !isNaN(measurement.value); + const shouldHaveSemaphoreColors = semaphoreColors.fieldsToApplyTo.applyToAll || semaphoreColors.fieldsToApplyTo.specificFields.indexOf(measurement.parents.dimension1.header) !== -1; + if (isValidSemaphoreValue && shouldHaveSemaphoreColors) { + const { backgroundColor, color } = getSemaphoreColors(measurement, semaphoreColors); + cellStyle = { + backgroundColor, + color, + fontFamily: styling.options.fontFamily, + fontSize: styleBuilder.getStyle().fontSize, + paddingLeft: '4px', + textAlign: 'right' + }; + } - let cellClass = 'grid-cells'; - const shouldUseSmallCells = isColumnPercentageBased && data.headers.measurements.length > 1; - if (shouldUseSmallCells) { - cellClass = 'grid-cells-small'; - } + let cellClass = 'grid-cells'; + const shouldUseSmallCells = isColumnPercentageBased && data.headers.measurements.length > 1; + if (shouldUseSmallCells) { + cellClass = 'grid-cells-small'; + } - return ( - - {formattedMeasurementValue} - - ); -}; + return ( + + {formattedMeasurementValue} + + ); + } +} DataCell.propTypes = { data: PropTypes.shape({ @@ -121,6 +145,11 @@ DataCell.propTypes = { name: PropTypes.string, value: PropTypes.any }).isRequired, + qlik: PropTypes.shape({ + backendApi: PropTypes.shape({ + selectValues: PropTypes.func.isRequired + }).isRequired + }).isRequired, styleBuilder: PropTypes.shape({ hasComments: PropTypes.func.isRequired }).isRequired, diff --git a/src/data-table/index.jsx b/src/data-table/index.jsx index afe4aa5..5da451c 100644 --- a/src/data-table/index.jsx +++ b/src/data-table/index.jsx @@ -3,9 +3,10 @@ import PropTypes from 'prop-types'; import StyleBuilder from '../style-builder'; import DataCell from './data-cell.jsx'; import HeaderPadding from './header-padding.jsx'; +import RowHeader from './row-header.jsx'; import { injectSeparators } from '../utilities'; -const DataTable = ({ data, general, styling }) => { +const DataTable = ({ data, general, qlik, renderData, styling }) => { const { headers: { dimension1, @@ -17,79 +18,85 @@ const DataTable = ({ data, general, styling }) => { return (
- {dimension1.map((dimensionEntry, dimensionIndex) => { - const rowHeaderText = dimensionEntry.displayValue || ''; - if (rowHeaderText === '-') { - return null; - } - const styleBuilder = new StyleBuilder(styling); - if (styling.hasCustomFileStyle) { - styleBuilder.parseCustomFileStyle(rowHeaderText); - } else { - styleBuilder.applyStandardAttributes(dimensionIndex); - styleBuilder.applyCustomStyle({ - fontSize: `${14 + styling.options.fontSizeAdjustment}px` - }); - } - const rowStyle = { - fontFamily: styling.options.fontFamily, - width: '230px', - ...styleBuilder.getStyle() - }; + + {dimension1.map((dimensionEntry, dimensionIndex) => { + const rowHeaderText = dimensionEntry.displayValue || ''; + if (rowHeaderText === '-') { + return null; + } + const styleBuilder = new StyleBuilder(styling); + if (styling.hasCustomFileStyle) { + styleBuilder.parseCustomFileStyle(rowHeaderText); + } else { + styleBuilder.applyStandardAttributes(dimensionIndex); + styleBuilder.applyCustomStyle({ + fontSize: `${14 + styling.options.fontSizeAdjustment}px` + }); + } + const rowStyle = { + fontFamily: styling.options.fontFamily, + width: '230px', + ...styleBuilder.getStyle() + }; - return ( - - - {injectSeparators( - matrix[dimensionIndex], - styling.useSeparatorColumns, - { atEvery: measurements.length } - ).map(measurementData => { - if (measurementData.isSeparator) { - const separatorStyle = { - color: 'white', - fontFamily: styling.options.fontFamily, - fontSize: `${12 + styling.options.fontSizeAdjustment}px` - }; + {renderData && injectSeparators( + matrix[dimensionIndex], + styling.useSeparatorColumns, + { atEvery: measurements.length } + ).map((measurementData, index) => { + if (measurementData.isSeparator) { + const separatorStyle = { + color: 'white', + fontFamily: styling.options.fontFamily, + fontSize: `${12 + styling.options.fontSizeAdjustment}px` + }; + return ( + + ); + } + const { dimension1: dimension1Info, dimension2, measurement } = measurementData.parents; + const id = `${dimension1Info.elementNumber}-${dimension2 && dimension2.elementNumber}-${measurement.header}`; return ( - + ); - } - return ( - - ); - })} - - ); - })} + })} + + ); + })} +
- + - {dimensionEntry.displayValue} - + * + - * -
); }; +DataTable.defaultProps = { + renderData: true +}; + DataTable.propTypes = { data: PropTypes.shape({ headers: PropTypes.shape({ @@ -98,6 +105,8 @@ DataTable.propTypes = { matrix: PropTypes.arrayOf(PropTypes.array.isRequired).isRequired }).isRequired, general: PropTypes.shape({}).isRequired, + qlik: PropTypes.shape({}).isRequired, + renderData: PropTypes.bool, styling: PropTypes.shape({ hasCustomFileStyle: PropTypes.bool.isRequired }).isRequired diff --git a/src/data-table/row-header.jsx b/src/data-table/row-header.jsx new file mode 100644 index 0000000..06da248 --- /dev/null +++ b/src/data-table/row-header.jsx @@ -0,0 +1,49 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import HeaderPadding from './header-padding.jsx'; + +class RowHeader extends React.PureComponent { + constructor (props) { + super(props); + + this.handleSelect = this.handleSelect.bind(this); + } + + handleSelect () { + const { entry, qlik } = this.props; + qlik.backendApi.selectValues(0, [entry.elementNumber], true); + } + + render () { + const { entry, rowStyle, styleBuilder, styling } = this.props; + return ( + + + {entry.displayValue} + + ); + } +} + +RowHeader.propTypes = { + entry: PropTypes.shape({ + displayValue: PropTypes.string.isRequired + }).isRequired, + qlik: PropTypes.shape({ + backendApi: PropTypes.shape({ + selectValues: PropTypes.func.isRequired + }).isRequired + }).isRequired, + rowStyle: PropTypes.shape({}).isRequired, + styleBuilder: PropTypes.shape({}).isRequired, + styling: PropTypes.shape({}).isRequired +}; + +export default RowHeader; diff --git a/src/headers-table/column-header.jsx b/src/headers-table/column-header.jsx index 3c9f251..d50d666 100644 --- a/src/headers-table/column-header.jsx +++ b/src/headers-table/column-header.jsx @@ -1,24 +1,39 @@ import React from 'react'; import PropTypes from 'prop-types'; -const ColumnHeader = ({ baseCSS, cellSuffix, colSpan, styling, title }) => { - const style = { - ...baseCSS, - fontSize: `${14 + styling.headerOptions.fontSizeAdjustment} px`, - height: '45px', - verticalAlign: 'middle' - }; +class ColumnHeader extends React.PureComponent { + constructor (props) { + super(props); - return ( - - {title} - - ); -}; + this.handleSelect = this.handleSelect.bind(this); + } + + handleSelect () { + const { entry, qlik } = this.props; + qlik.backendApi.selectValues(1, [entry.elementNumber], true); + } + + render () { + const { baseCSS, cellSuffix, colSpan, entry, styling } = this.props; + const style = { + ...baseCSS, + fontSize: `${14 + styling.headerOptions.fontSizeAdjustment} px`, + height: '45px', + verticalAlign: 'middle' + }; + + return ( + + {entry.displayValue} + + ); + } +} ColumnHeader.defaultProps = { cellSuffix: '', @@ -29,12 +44,20 @@ ColumnHeader.propTypes = { baseCSS: PropTypes.shape({}).isRequired, cellSuffix: PropTypes.string, colSpan: PropTypes.number, + entry: PropTypes.shape({ + elementNumber: PropTypes.number.isRequired, + name: PropTypes.string.isRequired + }).isRequired, + qlik: PropTypes.shape({ + backendApi: PropTypes.shape({ + selectValues: PropTypes.func.isRequired + }).isRequired + }).isRequired, styling: PropTypes.shape({ headerOptions: PropTypes.shape({ fontSizeAdjustment: PropTypes.number.isRequired }).isRequired - }).isRequired, - title: PropTypes.string.isRequired + }).isRequired }; export default ColumnHeader; diff --git a/src/headers-table/index.jsx b/src/headers-table/index.jsx index c45fa48..019a0f1 100644 --- a/src/headers-table/index.jsx +++ b/src/headers-table/index.jsx @@ -5,7 +5,7 @@ import ColumnHeader from './column-header.jsx'; import MeasurementColumnHeader from './measurement-column-header.jsx'; import { injectSeparators } from '../utilities'; -const HeadersTable = ({ data, general, styling }) => { +const HeadersTable = ({ data, general, qlik, styling }) => { const baseCSS = { backgroundColor: styling.headerOptions.colorSchema, color: styling.headerOptions.textColor, @@ -43,7 +43,7 @@ const HeadersTable = ({ data, general, styling }) => { styling={styling} /> ))} - {hasSecondDimension && injectSeparators(dimension2, styling.useSeparatorColumns).map(entry => { + {hasSecondDimension && injectSeparators(dimension2, styling.useSeparatorColumns).map((entry, index) => { if (entry.isSeparator) { const separatorStyle = { color: 'white', @@ -54,6 +54,7 @@ const HeadersTable = ({ data, general, styling }) => { return ( * @@ -65,16 +66,17 @@ const HeadersTable = ({ data, general, styling }) => { baseCSS={baseCSS} cellSuffix={general.cellSuffix} colSpan={measurements.length} + entry={entry} key={entry.displayValue} + qlik={qlik} styling={styling} - title={entry.displayValue} /> ); })} {hasSecondDimension && ( - {injectSeparators(dimension2, styling.useSeparatorColumns).map(dimensionEntry => { + {injectSeparators(dimension2, styling.useSeparatorColumns).map((dimensionEntry, index) => { if (dimensionEntry.isSeparator) { const separatorStyle = { color: 'white', @@ -85,6 +87,7 @@ const HeadersTable = ({ data, general, styling }) => { return ( * @@ -120,6 +123,11 @@ HeadersTable.propTypes = { }) }).isRequired, general: PropTypes.shape({}).isRequired, + qlik: PropTypes.shape({ + backendApi: PropTypes.shape({ + selectValues: PropTypes.func.isRequired + }).isRequired + }).isRequired, styling: PropTypes.shape({ headerOptions: PropTypes.shape({}), options: PropTypes.shape({}) diff --git a/src/initialize-transformed.js b/src/initialize-transformed.js index b58f7ca..f5e9585 100644 --- a/src/initialize-transformed.js +++ b/src/initialize-transformed.js @@ -91,24 +91,41 @@ function generateMeasurements (information) { function generateDimensionEntry (information, data) { return { displayValue: data.qText, + elementNumber: data.qElemNumber, name: information.qFallbackTitle, value: data.qNum }; } -function generateMatrixCell (information, data) { - return { - displayValue: data.qText, - elementNumber: data.qElemNumber, - format: information.format, - magnitude: information.magnitudeLabelSuffix.substring( - information.magnitudeLabelSuffix.length - 2, - information.magnitudeLabelSuffix.length - 1 +function generateMatrixCell ({ cell, dimension1Information, dimension2Information, measurementInformation }) { + const matrixCell = { + displayValue: cell.qText, + format: measurementInformation.format, + magnitude: measurementInformation.magnitudeLabelSuffix.substring( + measurementInformation.magnitudeLabelSuffix.length - 2, + measurementInformation.magnitudeLabelSuffix.length - 1 ), - magnitudeLabelSuffix: information.magnitudeLabelSuffix, - name: information.name, - value: data.qNum + magnitudeLabelSuffix: measurementInformation.magnitudeLabelSuffix, + name: measurementInformation.name, + parents: { + dimension1: { + elementNumber: dimension1Information.qElemNumber, + header: dimension1Information.qText + }, + measurement: { + header: measurementInformation.name + } + }, + value: cell.qNum }; + + if (dimension2Information) { + matrixCell.parents.dimension2 = { + elementNumber: dimension2Information.qElemNumber + }; + } + + return matrixCell; } let lastRow = 0; @@ -135,7 +152,14 @@ function generateDataSet (component, dimensionsInformation, measurementsInformat .slice(firstDataCell, row.length) .map((cell, cellIndex) => { const measurementInformation = measurements[cellIndex]; - const generatedCell = generateMatrixCell(measurementInformation, cell); + const dimension1Information = row[0]; // eslint-disable-line prefer-destructuring + const dimension2Information = hasSecondDimension ? row[1] : null; + const generatedCell = generateMatrixCell({ + cell, + dimension1Information, + dimension2Information, + measurementInformation + }); return generatedCell; }); @@ -228,6 +252,7 @@ async function initializeTransformed ({ $element, layout, component }) { }, general: { allowExcelExport: layout.allowexportxls, + allowFilteringByClick: layout.filteroncellclick, cellSuffix: getCellSuffix(layout.columnwidthslider), // TOOD: move to matrix cells or is it headers.measurements? errorMessage: layout.errormessage, maxLoops diff --git a/src/paint.jsx b/src/paint.jsx index 2ed949d..f16a912 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -1,9 +1,7 @@ import $ from 'jquery'; -import { enableExcelExport } from './excel-export'; import initializeStore from './store'; import React from 'react'; -// import ReactDOM from 'react-dom'; -import { renderToStaticMarkup } from 'react-dom/server'; +import ReactDOM from 'react-dom'; import HeadersTable from './headers-table/index.jsx'; import DataTable from './data-table/index.jsx'; @@ -14,29 +12,20 @@ export default async function paint ($element, layout, component) { layout }); - const { - ConceptMatrixColElem, - ConceptMatrixColElemTable, - ConceptMatrixRowElem - } = state.properties; - - const { - data: { meta: { dimensionCount } }, - selection: { dimensionSelectionCounts }, - styling: { useSeparatorColumns } - } = state; - const jsx = (
@@ -44,159 +33,57 @@ export default async function paint ($element, layout, component) {
); - // TODO: switch to render when jquery interaction stuff in renderData is gone - const html = renderToStaticMarkup(jsx); - $element.html(html); - // ReactDOM.render(jsx, $element[0]); + ReactDOM.render(jsx, $element[0]); - RenderData(); - // TODO: move jquery interactions into their respective components - // Hook up interactions and some html mangling - function RenderData () { - $('.data-table .row-wrapper').on('scroll', function () { - $(`[tid="${layout.qInfo.qId}"] .kpi-table .row-wrapper`).scrollTop($(this).scrollTop()); + // TODO: skipped the following as they weren't blockers for letting react handle rendering, + // they are however the only reason we still depend on jQuery and should be removed as part of unnecessary dependencies issue + $(`[tid="${layout.qInfo.qId}"] .data-table .row-wrapper`).on('scroll', function () { + $(`[tid="${layout.qInfo.qId}"] .kpi-table .row-wrapper`).scrollTop($(this).scrollTop()); + }); + + // freeze first column + $(`[tid="${layout.qInfo.qId}"] .qv-object-content-container`).on('scroll', (t) => { + $(`[tid="${layout.qInfo.qId}"] .kpi-table`).css('left', `${Math.round(t.target.scrollLeft)}px`); + }); + + // TODO: fixing tooltips has a seperate issue, make sure to remove this as part of that issue + $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).hover(function () { + $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(500) + .show(0); + $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).children(`[tid="${layout.qInfo.qId}"] .tooltip`) + .remove(); + + const element = $(this); + const offset = element.offset(); + const toolTip = $('
'); + + toolTip.css({ + left: offset.left, + top: offset.top }); - // on hover popup with cell value, only in headers - $('.header-wrapper th').hover(function () { - $('.tooltip').delay(500) - .show(0); - $('.header-wrapper th').children('.tooltip') - .remove(); + toolTip.text(element.text()); + $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).append(toolTip); + }, () => { + $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(0) + .hide(0); + }); - const element = $(this); - const offset = element.offset(); - const toolTip = $("
"); - - toolTip.css({ - top: offset.top, - left: offset.left - }); - - toolTip.text(element.text()); - $('.header-wrapper th').append(toolTip); - }, () => { - $('.tooltip').delay(0) - .hide(0); - }); - - // allow making selections inside the table - $('.data-table td').on('click', function () { - if (layout.filteroncellclick == false) { - return; - } - const indextr = $(this).parent() - .parent() - .children() - .index($(this).parent()); // identifica la row - const indextd = $(this).parent() - .children() - .index($(this)); // identifica la col - - let SelectRow = 0; - let SelectCol = 0; - - SelectRow = ConceptMatrixRowElem[(indextr)]; - - // este if verifica primero si hay selecciones hechas en la dimensión, si las hay - // las reselecciona para poder borrar antes de poder seleccionar lo que quiero - // no es viable pedirle que seleccione a la vez elementos de 2 selecciones, se queda - // colgado el menú de confirm, por eso uso este sistema, que sí funciona. - // it can cause issues like error messages and wrong selections if there are null values - // and the check allow null values is active - if (dimensionCount > 1 && indextd > 0) { - if (dimensionSelectionCounts[1] > 0) { - const SelectB = JSON.parse(JSON.stringify(ConceptMatrixColElemTable)); - component.backendApi.selectValues(1, SelectB, true); - $(this).toggleClass('selected'); - } - SelectCol = ConceptMatrixColElemTable[(indextd)]; - - component.backendApi.selectValues(1, [SelectCol], true); - $(this).toggleClass('selected'); - } - - if (indextd > 0 && dimensionSelectionCounts[0] > 0) { - const SelectA = JSON.parse(JSON.stringify(ConceptMatrixRowElem)); - component.backendApi.selectValues(0, SelectA, true); - $(this).toggleClass('selected'); - } - - if (indextd > 0) { - component.backendApi.selectValues(0, [SelectRow], true); - $(this).toggleClass('selected'); - } - }); - // allow selections through the header of the second dimension - $('.header-wrapper th').on('click', function () { - const indextd = $(this).parent() - .children() - .index($(this)); // identifica la col - - let SelectCol = 0; - - if (dimensionCount > 1 && indextd > 0) { - if (dimensionSelectionCounts[1] > 0) { - const SelectB = JSON.parse(JSON.stringify(ConceptMatrixColElem)); - component.backendApi.selectValues(1, SelectB, true); - $(this).toggleClass('selected'); - } - if (useSeparatorColumns) { - SelectCol = ConceptMatrixColElem[(Math.round(indextd / 2) - 1)]; - } else { - SelectCol = ConceptMatrixColElem[(Math.round(indextd) - 1)]; - } - - component.backendApi.selectValues(1, [SelectCol], true); - $(this).toggleClass('selected'); - } - }); - // allow selections in desc dimension cells - $('.kpi-table td').on('click', function () { - const indextr = $(this).parent() - .parent() - .children() - .index($(this).parent()); // identifica la row - let SelectRow = 0; - SelectRow = ConceptMatrixRowElem[(indextr)]; - - if (dimensionSelectionCounts[0] > 0) { - const SelectA = JSON.parse(JSON.stringify(ConceptMatrixRowElem)); - component.backendApi.selectValues(0, SelectA, true); - $(this).toggleClass('selected'); - } - - component.backendApi.selectValues(0, [SelectRow], true); - $(this).toggleClass('selected'); - }); - - enableExcelExport(layout, html); - - // freeze first column - $('.qv-object-content-container').on('scroll', (t) => { - $('.kpi-table').css('left', `${Math.round(t.target.scrollLeft)}px`); - }); - $('.kpi-table .row-wrapper tr').each(function () { - $(this).find('th:not(.fdim-cells)') - .remove(); - $(this).find('td:not(.fdim-cells)') - .remove(); - }); - $('.kpi-table .header-wrapper tr').each(function () { - $(this).find('th:not(.fdim-cells)') - .remove(); - }); - } + // TODO: excel export is broken in most browsers, fixing it has an issue of it's own (leaving it disabled for now) + // import { enableExcelExport } from './excel-export'; + // enableExcelExport(layout, html); } diff --git a/src/store.js b/src/store.js index 7f4b3f3..6987015 100644 --- a/src/store.js +++ b/src/store.js @@ -1,4 +1,3 @@ -import { onlyUnique } from './utilities'; import initializeTransformed from './initialize-transformed'; async function initialize ({ $element, layout, component }) { @@ -8,137 +7,7 @@ async function initialize ({ $element, layout, component }) { layout }); - // TODO: remove everything from here to return statement once jquery parts in paint has been refactored - const vMaxLoops = layout.maxloops; - const vErrorMessage = layout.errormessage; - let vDimName = ''; - const ConceptMatrixFirst = new Array(); - const ConceptMatrixSecond = new Array(); - const LabelsArray = new Array(); - const ArrayGetSelectedCount = new Array(); - let vNumDims = 0; - let vNumMeasures = 0; - const MeasuresFormat = new Array(); - const dim_count = layout.qHyperCube.qDimensionInfo.length; - const measure_count = layout.qHyperCube.qMeasureInfo.length; - let vSeparatorCols = layout.separatorcols; - if (dim_count == 1) { - vSeparatorCols = false; - } - let lastrow = 0; - const ConceptMatrix = new Array(); - let ConceptMatrixRowElem = new Array(); - let ConceptMatrixColElem = new Array(); - const ConceptMatrixColElemTable = new Array(); - const ConceptMatrixPivot = new Array(); - let ConceptMatrixFirstClean = new Array(); - const nRows = component.backendApi.getRowCount(); - - const dimensionInfos = component.backendApi.getDimensionInfos(); - LabelsArray.push(dimensionInfos[0].qFallbackTitle); - ArrayGetSelectedCount.concat(dimensionInfos.map(dimensionInfo => dimensionInfo.qStateCounts.qSelected)); - vNumDims += dimensionInfos.length; - - const measureInfos = component.backendApi.getMeasureInfos(); - measureInfos.forEach(measureInfo => { - vDimName = measureInfo.qFallbackTitle; - LabelsArray.push(vDimName); - let mfor = ''; - - if (measureInfo.qNumFormat.qType == 'U' || measureInfo.qNumFormat.qFmt == '##############') { - mfor = '#.##0'; // in case of undefined - } else if (measureInfo.qNumFormat.qType == 'R') { - mfor = measureInfo.qNumFormat.qFmt; - mfor = mfor.replace(/(|)/gi, ''); - } else { - mfor = measureInfo.qNumFormat.qFmt; - } - - MeasuresFormat.push(mfor); - - vNumMeasures++; - }); - - component.backendApi.eachDataRow((t, a) => { - lastrow = t; - - const vNumMeasuresPlus = vNumMeasures + 1; - - ConceptMatrix[t] = new Array(); - ConceptMatrix[t][0] = a[0].qText; - - ConceptMatrixFirst[t] = a[0].qText; - ConceptMatrixRowElem[t] = a[0].qElemNumber; - let nMeasures = 0; - if (vNumDims == 1) { - for (nMeasures = 1; nMeasures <= vNumMeasures; nMeasures++) { - ConceptMatrix[t][nMeasures] = a[nMeasures].qNum; - } - } else { - ConceptMatrix[t][1] = a[1].qText; - ConceptMatrixColElem[t] = a[1].qElemNumber; - ConceptMatrixSecond[t] = a[1].qText; - // set the hipercube in a plain array without pivoting - for (nMeasures = 2; nMeasures <= vNumMeasuresPlus; nMeasures++) { - ConceptMatrix[t][nMeasures] = a[nMeasures].qNum; - } - } - }); - - ConceptMatrixFirstClean = ConceptMatrixFirst.filter(onlyUnique); - - if (nRows >= (vMaxLoops * 1000)) { - alert(vErrorMessage); - } - - if (vNumDims == 2) { - // new array with unique values for 2nd dim - var SecondHeader = ConceptMatrixSecond.filter(onlyUnique);// second dimension concepts - ConceptMatrixRowElem = ConceptMatrixRowElem.filter(onlyUnique);// first dimension concepts - ConceptMatrixColElem = ConceptMatrixColElem.filter(onlyUnique);// dimension code for further selections - const eo = ConceptMatrixColElem.length; - let vLoopColsMeasures = 1; - ConceptMatrixColElemTable[0] = ConceptMatrixColElem[0]; - for (let xx = 0; xx < eo; xx++) { - if (vSeparatorCols && xx > 0) { - ConceptMatrixColElemTable[vLoopColsMeasures] = ConceptMatrixColElem[xx]; - vLoopColsMeasures++; - } - - for (let xxx = 0; xxx < vNumMeasures; xxx++) { - ConceptMatrixColElemTable[vLoopColsMeasures] = ConceptMatrixColElem[xx]; - vLoopColsMeasures++; - } - } - - let ConceptPos = 0; - let nMeas3 = 0; - let vHeaderIndex = 0; - let MeasurePos = 0; - for (let nPivotElems = 0; nPivotElems <= lastrow; nPivotElems++) { - ConceptMatrixPivot[nPivotElems] = new Array(); - ConceptPos = ConceptMatrixFirstClean.indexOf(ConceptMatrix[nPivotElems][0]); - ConceptMatrixPivot[ConceptPos][0] = ConceptMatrix[nPivotElems][0]; - - for (let nMeas2 = 1; nMeas2 <= measure_count; nMeas2++) { - nMeas3 = nMeas2 + 1; - vHeaderIndex = (SecondHeader.indexOf(ConceptMatrix[nPivotElems][1]) + 1); - MeasurePos = (vHeaderIndex * measure_count) + (nMeas2 - measure_count); - ConceptMatrixPivot[ConceptPos][MeasurePos] = ConceptMatrix[nPivotElems][nMeas3]; - } - } - } - - const properties = { - ConceptMatrixColElem, - ConceptMatrixColElemTable, - ConceptMatrixRowElem - }; - - return { - properties, - ...transformedProperties - }; + return transformedProperties; } export default initialize;