Compare commits

...

2 Commits

Author SHA1 Message Date
Albert Backenhof
c8cd78ae5f Merge pull request #37 from qlik-oss/DEB-156/OnlyTwoDims
Moved design dimension to Appearance->Table format
2019-04-10 12:14:20 +02:00
Albert Backenhof
a5bc3ecd1b Moved design dimension to Appearance->Table format
-According to the documentation it should only be
 possible to set two dimensions. Previously you
 were able to set three, where the third one was
 used for styling. This wasn't obvious to the user
 though. Now, the design field is set under
 Appearance -> Table format.

Issue: DEB-156
2019-04-10 12:12:08 +02:00
5 changed files with 88 additions and 79 deletions

View File

@@ -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();
});
}

View File

@@ -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',

View File

@@ -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,

View File

@@ -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 = (
<Root
editmodeClass={editmodeClass}
qlik={component}
state={state}
editmodeClass={editmodeClass}
/>
);

View File

@@ -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
});