diff --git a/src/dataset.js b/src/dataset.js index 4ca5bff..6bddb44 100644 --- a/src/dataset.js +++ b/src/dataset.js @@ -6,7 +6,7 @@ function createCube (definition, app) { }); } -async function buildDataCube (originCubeDefinition, dimensionIndexes, app) { +async function buildDataCube (originCubeDefinition, hasTwoDimensions, app) { const cubeDefinition = { ...originCubeDefinition, qInitialDataFetch: [ @@ -15,62 +15,18 @@ async function buildDataCube (originCubeDefinition, dimensionIndexes, app) { qWidth: 10 } ], - qDimensions: [originCubeDefinition.qDimensions[dimensionIndexes.dimension1]], + qDimensions: [originCubeDefinition.qDimensions[0]], qMeasures: originCubeDefinition.qMeasures }; - if (dimensionIndexes.dimension2) { - cubeDefinition.qDimensions.push(originCubeDefinition.qDimensions[dimensionIndexes.dimension2]); + if (hasTwoDimensions) { + cubeDefinition.qDimensions.push(originCubeDefinition.qDimensions[1]); } const cube = await createCube(cubeDefinition, app); - return cube.qHyperCube.qDataPages[0].qMatrix; } -async function buildDesignCube (originCubeDefinition, dimensionIndexes, app) { - if (!dimensionIndexes.design) { - return null; - } - const cube = await createCube({ - qInitialDataFetch: [ - { - qHeight: 1000, - qWidth: 1 - } - ], - qDimensions: [originCubeDefinition.qDimensions[dimensionIndexes.design]] - }, app); - - return cube.qHyperCube.qDataPages[0].qMatrix; -} - -const STYLE_SEPARATOR_COUNT = 7; -function findDesignDimension (qMatrix) { - return qMatrix[0].map(entry => (entry.qText.match(/;/g) || []).length).indexOf(STYLE_SEPARATOR_COUNT); -} - -function getDimensionIndexes (dimensionsInformation, designDimensionIndex) { - const hasDesign = designDimensionIndex !== -1; - const nonDesignDimensionCount = hasDesign ? dimensionsInformation.length - 1 : dimensionsInformation.length; - const dimension1 = designDimensionIndex === 0 ? 1 : 0; - let dimension2 = false; - if (nonDesignDimensionCount === 2) { - dimension2 = hasDesign && designDimensionIndex < 2 ? 2 : 1; - } - const design = hasDesign && designDimensionIndex; - const firstMeasurementIndex = dimensionsInformation.length; - return { - design, - dimension1, - dimension2, - firstMeasurementIndex - }; -} - -export async function initializeCubes ({ component, layout }) { +export async function initializeDataCube (component, layout) { const app = qlik.currApp(component); - const designDimensionIndex = findDesignDimension(layout.qHyperCube.qDataPages[0].qMatrix); - const dimensionsInformation = layout.qHyperCube.qDimensionInfo; - const dimensionIndexes = getDimensionIndexes(dimensionsInformation, designDimensionIndex); let properties; if (component.backendApi.isSnapshot) { @@ -80,12 +36,24 @@ export async function initializeCubes ({ component, layout }) { properties = await component.backendApi.getProperties(); } - const originCubeDefinition = properties.qHyperCubeDef; - const designCube = await buildDesignCube(originCubeDefinition, dimensionIndexes, app); - const dataCube = await buildDataCube(originCubeDefinition, dimensionIndexes, app); - - return { - design: designCube, - data: dataCube - }; + return buildDataCube( + properties.qHyperCubeDef, layout.qHyperCube.qDimensionInfo.length === 2, app); +} + +export function initializeDesignList (component, layout) { + if (!layout.stylingfield) { + return null; + } + + return new Promise(resolve => { + const app = qlik.currApp(component); + const stylingField = app.field(layout.stylingfield); + const listener = function () { + const data = stylingField.rows.map(row => row.qText); + stylingField.OnData.unbind(listener); + resolve(data); + }; + stylingField.OnData.bind(listener); + stylingField.getData(); + }); } diff --git a/src/definition/table-format.js b/src/definition/table-format.js index bd04b11..d6cca5f 100644 --- a/src/definition/table-format.js +++ b/src/definition/table-format.js @@ -1,12 +1,53 @@ +const qlik = window.require('qlik'); + // fixes case for when there are 3 dimensions, missies the case with 1 design dimension and 1 data dimension function hasDesignDimension (data) { return data.qHyperCubeDef.qDimensions.length > 2; } +function getFieldList () { + return new Promise(function (resolve) { + const app = qlik.currApp(); + app.getList('FieldList').then(function (model) { + // Close the model to prevent any updates. + app.destroySessionObject(model.layout.qInfo.qId); + + // This is a bit iffy, might be smarter to reject and handle empty lists on the props instead. + if (!model.layout.qFieldList.qItems) { + return resolve([]); + } + // Resolve an array with master objects. + return resolve(model.layout.qFieldList.qItems.map(function (item) { + return { + value: item.qName, + label: item.qName + }; + })); + }); + }); +} + const tableFormat = { type: 'items', label: 'Table Format', items: { + StylingField: { + ref: 'stylingfield', + disabledRef: '', + type: 'string', + component: 'dropdown', + label: 'Style with field', + options: function () { + return getFieldList().then(function (items) { + items.unshift( + { + value: '', + label: 'None' + }); + return items; + }); + } + }, IndentBool: { ref: 'indentbool', type: 'boolean', diff --git a/src/initialize-transformed.js b/src/initialize-transformed.js index b008a33..8169a0e 100644 --- a/src/initialize-transformed.js +++ b/src/initialize-transformed.js @@ -107,15 +107,16 @@ function generateMatrixCell ({ cell, dimension1Information, dimension2Informatio } let lastRow = 0; -function generateDataSet (component, dimensionsInformation, measurementsInformation, cubes) { +function generateDataSet ( + component, dimensionsInformation, measurementsInformation, dataCube) { + + const measurements = generateMeasurements(measurementsInformation); let dimension1 = []; let dimension2 = []; - const measurements = generateMeasurements(measurementsInformation); let matrix = []; - const hasDesignDimension = cubes.design; - const hasSecondDimension = hasDesignDimension ? dimensionsInformation.length > 2 : dimensionsInformation.length > 1; - cubes.data.forEach(row => { + const hasSecondDimension = dimensionsInformation.length > 1; + dataCube.forEach(row => { lastRow += 1; const dimension1Entry = generateDimensionEntry(dimensionsInformation[0], row[0]); dimension1.push(dimension1Entry); @@ -200,7 +201,7 @@ function generateDataSet (component, dimensionsInformation, measurementsInformat }; } -function initializeTransformed ({ $element, component, cubes, layout }) { +function initializeTransformed ({ $element, component, dataCube, designList, layout }) { const dimensionsInformation = component.backendApi.getDimensionInfos(); const measurementsInformation = component.backendApi.getMeasureInfos(); const dimensionCount = layout.qHyperCube.qDimensionInfo.length; @@ -211,19 +212,18 @@ function initializeTransformed ({ $element, component, cubes, layout }) { dimension2, measurements, matrix - } = generateDataSet(component, dimensionsInformation, measurementsInformation, cubes); + } = generateDataSet(component, dimensionsInformation, measurementsInformation, dataCube); const customSchemaBasic = []; const customSchemaFull = []; let customHeadersCount = 0; - if (cubes.design) { - const allTextLines = cubes.design.map(entry => entry[0].qText); - const headers = allTextLines[0].split(';'); + if (designList && designList.length > 0) { + const headers = designList[0].split(';'); customHeadersCount = headers.length; - for (let lineNumber = 0; lineNumber < allTextLines.length; lineNumber += 1) { + for (let lineNumber = 0; lineNumber < designList.length; lineNumber += 1) { customSchemaFull[lineNumber] = new Array(headers.length); - const data = allTextLines[lineNumber].split(';'); + const data = designList[lineNumber].split(';'); if (data.length === headers.length) { for (let headerIndex = 0; headerIndex < headers.length; headerIndex += 1) { @@ -267,7 +267,7 @@ function initializeTransformed ({ $element, component, cubes, layout }) { count: customHeadersCount, full: customSchemaFull }, - hasCustomFileStyle: Boolean(cubes.design), + hasCustomFileStyle: Boolean(designList), headerOptions: { alignment: getAlignment(layout.HeaderAlign), colorSchema: layout.HeaderColorSchema.color, diff --git a/src/paint.jsx b/src/paint.jsx index 9d4bc9a..5791a3a 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -2,25 +2,24 @@ import initializeStore from './store'; import React from 'react'; import ReactDOM from 'react-dom'; import Root from './root.jsx'; -import { initializeCubes } from './dataset'; +import { initializeDataCube, initializeDesignList } from './dataset'; export default async function paint ($element, layout, component) { - const cubes = await initializeCubes({ - component, - layout - }); + const dataCube = await initializeDataCube(component, layout); + const designList = await initializeDesignList(component, layout); const state = await initializeStore({ $element, component, - cubes, + dataCube, + designList, layout }); const editmodeClass = component.inAnalysisState() ? '' : 'edit-mode'; const jsx = ( ); diff --git a/src/store.js b/src/store.js index 89d8199..7b301aa 100644 --- a/src/store.js +++ b/src/store.js @@ -1,10 +1,11 @@ import initializeTransformed from './initialize-transformed'; -async function initialize ({ $element, layout, component, cubes }) { +async function initialize ({ $element, layout, component, dataCube, designList }) { const transformedProperties = await initializeTransformed({ $element, component, - cubes, + dataCube, + designList, layout });