@sis-cc/dotstatsuite-components 17.27.0 → 17.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,23 +19,25 @@ var isTableLayoutCompatible = function isTableLayoutCompatible(data, layout) {
19
19
  var combinationsDefinitions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
20
20
  var dataquery = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
21
21
 
22
- var multiValuesDimensions = R.pipe(R.pathOr([], ['structure', 'dimensions', 'observation']), function (dimensions) {
22
+ var indexedCombinations = R.indexBy(R.prop('id'), combinationsDefinitions);
23
+ var indexedManyValuesDimensions = R.pipe(R.pathOr([], ['structure', 'dimensions', 'observation']), function (dimensions) {
23
24
  return (0, _src.refineDimensions)(dimensions, dataquery);
24
25
  }, R.reject(function (d) {
25
26
  return R.prop('header', d) || !R.length(d.values || []);
26
- }), R.pluck('id'), R.map(function (d) {
27
- var conceptId = R.find(function (comb) {
28
- return R.includes(d, R.propOr([], 'concepts', comb));
29
- })(combinationsDefinitions);
30
- return conceptId ? conceptId.id : d;
31
- }))(data);
32
- var dimensionsInLayout = R.pipe(R.values, R.unnest)(layout);
33
-
34
- var dimensionsLength = R.length(multiValuesDimensions);
35
- var layoutLength = R.length(dimensionsInLayout);
36
- var intersectionLength = R.length(R.intersection(multiValuesDimensions, dimensionsInLayout));
37
-
38
- return R.all(R.equals(dimensionsLength))([intersectionLength, layoutLength]);
27
+ }), R.indexBy(R.prop('id')))(data);
28
+ var remainings = indexedManyValuesDimensions;
29
+ var layoutIds = R.pipe(R.values, R.unnest)(layout);
30
+ var hasFoundIrrelevant = false;
31
+ R.forEach(function (id) {
32
+ if (R.has(id, indexedManyValuesDimensions)) {
33
+ remainings = R.dissoc(id, remainings);
34
+ } else if (R.has(id, indexedCombinations)) {
35
+ remainings = R.omit(R.pathOr([], [id, 'concepts'], indexedCombinations), remainings);
36
+ } else if (id !== 'OBS_ATTRIBUTES') {
37
+ hasFoundIrrelevant = true;
38
+ }
39
+ }, layoutIds);
40
+ return R.isEmpty(remainings) && !hasFoundIrrelevant;
39
41
  };
40
42
 
41
43
  var isScatterLayoutCompatible = function isScatterLayoutCompatible(data, chartDimension) {
@@ -80,7 +82,15 @@ var isSharedLayoutCompatible = exports.isSharedLayoutCompatible = function isSha
80
82
  var dataquery = R.path(['config', 'sdmxSource', 'dataquery'], sharedData);
81
83
  var annotations = R.pathOr({}, ['structure', 'annotations'], sdmxData);
82
84
  var locale = R.pathOr({}, ['config', 'table', 'locale'], sharedData);
83
- var combinationsDefinitions = (0, _src.getCombinationDefinitions)(annotations, locale);
85
+ var rawDefaultCombinationsDefinition = R.pathOr({}, ['config', 'defaultCombinations'], sharedData);
86
+ var _rawDefaultCombinatio = rawDefaultCombinationsDefinition.concepts,
87
+ concepts = _rawDefaultCombinatio === undefined ? '' : _rawDefaultCombinatio,
88
+ _rawDefaultCombinatio2 = rawDefaultCombinationsDefinition.names,
89
+ names = _rawDefaultCombinatio2 === undefined ? '' : _rawDefaultCombinatio2;
90
+
91
+ var defaultCombinationsDefinition = (0, _src.parseCombinationDefinition)(locale)(concepts, names);
92
+ var customCombinationsDefinitions = (0, _src.getCombinationDefinitions)(annotations, locale);
93
+ var combinationsDefinitions = R.isNil(customCombinationsDefinitions) || R.isEmpty(customCombinationsDefinitions) ? defaultCombinationsDefinition : customCombinationsDefinitions;
84
94
  return isTableLayoutCompatible(sdmxData, layoutIds, combinationsDefinitions, dataquery);
85
95
  }
86
96
  var chartDimension = R.pathOr({}, ['config', 'chart', 'chartDimension'], sharedData);
@@ -147,6 +147,12 @@ Object.defineProperty(exports, 'getCombinationDefinitions', {
147
147
  return _getCombinationDefinitions.getCombinationDefinitions;
148
148
  }
149
149
  });
150
+ Object.defineProperty(exports, 'parseCombinationDefinition', {
151
+ enumerable: true,
152
+ get: function get() {
153
+ return _getCombinationDefinitions.parseCombinationDefinition;
154
+ }
155
+ });
150
156
 
151
157
  var _refineDimensions = require('./refineDimensions');
152
158
 
@@ -422,4 +428,13 @@ Object.defineProperty(exports, 'injectCombinationsInLayout', {
422
428
  get: function get() {
423
429
  return _getTableLayoutIds.injectCombinationsInLayout;
424
430
  }
431
+ });
432
+
433
+ var _declineObservationsOverAttributes = require('./table/declineObservationsOverAttributes');
434
+
435
+ Object.defineProperty(exports, 'declineObservationsOverAttributes', {
436
+ enumerable: true,
437
+ get: function get() {
438
+ return _declineObservationsOverAttributes.declineObservationsOverAttributes;
439
+ }
425
440
  });
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.declineObservationsOverAttributes = undefined;
7
+
8
+ var _extends2 = require('babel-runtime/helpers/extends');
9
+
10
+ var _extends3 = _interopRequireDefault(_extends2);
11
+
12
+ var _ramda = require('ramda');
13
+
14
+ var R = _interopRequireWildcard(_ramda);
15
+
16
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
17
+
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+
20
+ var declineObservationsOverAttributes = exports.declineObservationsOverAttributes = function declineObservationsOverAttributes(attrsIds, observations) {
21
+ var obsKeys = R.keys(observations);
22
+ return R.reduce(function (acc, obsKey) {
23
+ var obs = R.prop(obsKey, observations);
24
+ var enhancedObs = R.pipe(R.over(R.lensProp('orderedDimIndexes'), R.append(0)), R.over(R.lensProp('attributes'), R.omit(attrsIds)), R.assocPath(['indexedDimValIds', 'OBS_ATTRIBUTES'], 'OBS_VALUE'))(obs);
25
+ return R.addIndex(R.reduce)(function (_acc, attrId, attrIndex) {
26
+ var attr = R.pathOr({}, ['attributes', attrId], obs);
27
+ if (R.isEmpty(attr) || R.isNil(R.prop('value', attr)) || !R.pathOr(true, ['value', 'display'], attr)) {
28
+ return _acc;
29
+ }
30
+ var declinedKey = obsKey + ':' + (attrIndex + 1);
31
+ var declined = (0, _extends3.default)({}, obs, {
32
+ attributes: {},
33
+ value: R.prop('value', attr),
34
+ formattedValue: R.prop('value', attr),
35
+ orderedDimIndexes: R.append(attrIndex + 1, obs.orderedDimIndexes),
36
+ indexedDimValIds: (0, _extends3.default)({}, obs.indexedDimValIds, {
37
+ OBS_ATTRIBUTES: attr.id
38
+ })
39
+ });
40
+ return R.assoc(declinedKey, declined, _acc);
41
+ }, R.assoc(obsKey + ':0', enhancedObs, acc), attrsIds);
42
+ }, {}, obsKeys);
43
+ };
@@ -65,12 +65,13 @@ var getCells = exports.getCells = function getCells(customAttributes, cellsAttri
65
65
  })(customAttributes);
66
66
 
67
67
  return R.mapObjIndexed(function (obs) {
68
- var relevantAttributes = getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
69
- var flagsAndNotes = (0, _getFlagsAndNotes.getFlagsAndNotes)(R.omit(attributesInCellsCombination, relevantAttributes), _customAttributes);
70
- var combinedSeries = getCellCombinedSeries(relevantAttributes, combinations.cells || []);
71
- var hasAdvancedAttributes = R.pipe(R.omit(R.unnest([_customAttributes.flags || [], _customAttributes.notes || [], attributesInCellsCombination])), R.isEmpty, R.not)(relevantAttributes);
68
+ var isAttrCell = R.pathOr('OBS_VAL', ['indexedDimValIds', 'OBS_ATTR'], obs) !== 'OBS_VAL';
69
+ var relevantAttributes = isAttrCell ? [] : getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
70
+ var flagsAndNotes = isAttrCell ? [] : (0, _getFlagsAndNotes.getFlagsAndNotes)(R.omit(attributesInCellsCombination, relevantAttributes), _customAttributes);
71
+ var combinedSeries = isAttrCell ? [] : getCellCombinedSeries(relevantAttributes, combinations.cells || []);
72
+ var hasAdvancedAttributes = isAttrCell ? false : R.pipe(R.omit(R.unnest([_customAttributes.flags || [], _customAttributes.notes || [], attributesInCellsCombination])), R.isEmpty, R.not)(relevantAttributes);
72
73
 
73
- var hasMetadata = (0, _hasCellMetadata.hasCellMetadata)(metadataCoordinates, obs.indexedDimValIds);
74
+ var hasMetadata = isAttrCell ? false : (0, _hasCellMetadata.hasCellMetadata)(metadataCoordinates, obs.indexedDimValIds);
74
75
 
75
76
  return (0, _extends3.default)({}, R.pick(['indexedDimValIds', 'key'], obs), {
76
77
  flags: R.concat(flagsAndNotes, combinedSeries),
@@ -121,7 +121,9 @@ var combineConcepts = function combineConcepts(combDimValues, definition, attrVa
121
121
  };
122
122
 
123
123
  var getSerieFlagsAndSideProps = function getSerieFlagsAndSideProps(coordinates, validator, attributesValues, customAttributes, metadataCoordinates) {
124
- var layoutAttrValues = R.reject(R.prop('isObs'), attributesValues);
124
+ var layoutAttrValues = R.reject(function (attr) {
125
+ return R.prop('isObs', attr) && !validator(attr.coordinates);
126
+ }, attributesValues);
125
127
  var flags = (0, _getFlagsAndNotes.getFlagsAndNotes)(layoutAttrValues, customAttributes);
126
128
  var hasMetadata = !R.isNil(R.find(validator, metadataCoordinates));
127
129
  var hasAdvancedAttributes = getHasAdvancedAttributes(layoutAttrValues, customAttributes);
@@ -188,7 +190,12 @@ var getSerieDataWithMissingLines = function getSerieDataWithMissingLines(serie,
188
190
  attributes = _getSerieDimensionsDa.attributes,
189
191
  serieData = (0, _objectWithoutProperties3.default)(_getSerieDimensionsDa, ['attributes']);
190
192
 
191
- var _getSerieFlagsAndSide = getSerieFlagsAndSideProps(serieCoordinates, coordinatesValidator, attributes, customAttributes, metadataCoordinates),
193
+ var topCoordinatesValidator = (0, _utils.getLayoutCoordinatesValidator)(topCoordinates);
194
+ var flagsValidator = function flagsValidator(coordinates) {
195
+ return coordinatesValidator(coordinates) && !topCoordinatesValidator(coordinates);
196
+ };
197
+
198
+ var _getSerieFlagsAndSide = getSerieFlagsAndSideProps(serieCoordinates, flagsValidator, attributes, customAttributes, metadataCoordinates),
192
199
  flags = _getSerieFlagsAndSide.flags,
193
200
  sideProps = _getSerieFlagsAndSide.sideProps;
194
201
 
@@ -45,6 +45,9 @@ var getLayoutPivots = function getLayoutPivots(layoutEntry) {
45
45
  return valIndexGetter(d)(indexes);
46
46
  }, R.prop('dimensions', c));
47
47
  }, function (d) {
48
+ if (d.id === 'OBS_ATTRIBUTES') {
49
+ return R.last(indexes);
50
+ }
48
51
  return valIndexGetter(d)(indexes);
49
52
  }), layoutEntry);
50
53
  };
@@ -141,9 +141,8 @@ var injectCombinationsInLayout = exports.injectCombinationsInLayout = function i
141
141
  var _ids2 = injectCombination(comb)(acc.sections);
142
142
  return R.assoc('sections', _ids2)(acc);
143
143
  }
144
- var rowsConcepts = R.concat(idsInRows, nowhere);
145
- layoutRelationships.rows = R.concat(layoutRelationships.rows, rowsConcepts);
146
- var ids = injectCombination((0, _extends4.default)({}, comb, { concepts: rowsConcepts }))(acc.rows);
144
+ layoutRelationships.rows = R.concat(layoutRelationships.rows, relationship);
145
+ var ids = injectCombination(comb)(acc.rows);
147
146
  return R.assoc('rows', ids)(acc);
148
147
  }, layoutIds, notInLayoutCombs);
149
148
  };
@@ -241,8 +240,17 @@ var injectRemainingDimensionsInLayout = exports.injectRemainingDimensionsInLayou
241
240
  var getTableLayoutIds = exports.getTableLayoutIds = function getTableLayoutIds(defaultLayoutIds, dimensions, attributes, combinations) {
242
241
  var layoutDimsIds = getLayoutDimsIds(dimensions);
243
242
  var layoutCombinations = getLayoutCombinations(combinations, layoutDimsIds, attributes);
243
+ var combinationsConcepts = R.pipe(R.pluck('_concepts'), R.unnest, function (ids) {
244
+ return new _set2.default(ids);
245
+ })(combinations);
246
+ var obsAttributes = R.filter(function (a) {
247
+ return a.series && R.isEmpty(a.relationship || []) && a.display && !combinationsConcepts.has(a);
248
+ }, attributes);
244
249
  var indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
245
250
  var filteredLayoutIds = R.map(R.filter(function (id) {
251
+ if (id === 'OBS_ATTRIBUTES') {
252
+ return !R.isEmpty(obsAttributes);
253
+ }
246
254
  return R.has(id, indexedCombinations) || layoutDimsIds.has(id);
247
255
  }), defaultLayoutIds);
248
256
  var layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
@@ -9,6 +9,12 @@ var _extends2 = require('babel-runtime/helpers/extends');
9
9
 
10
10
  var _extends3 = _interopRequireDefault(_extends2);
11
11
 
12
+ var _ramda = require('ramda');
13
+
14
+ var R = _interopRequireWildcard(_ramda);
15
+
16
+ var _declineObservationsOverAttributes = require('./declineObservationsOverAttributes');
17
+
12
18
  var _getLayout = require('./getLayout');
13
19
 
14
20
  var _getSortedLayoutIndexes = require('./getSortedLayoutIndexes');
@@ -29,6 +35,10 @@ var _getCuratedCells = require('./getCuratedCells');
29
35
 
30
36
  var _getSeriesCombinations = require('../getSeriesCombinations');
31
37
 
38
+ var _getCellsMetadataCoordinates = require('./getCellsMetadataCoordinates');
39
+
40
+ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
41
+
32
42
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
43
 
34
44
  var getTableProps = exports.getTableProps = function getTableProps(_ref) {
@@ -47,18 +57,40 @@ var getTableProps = exports.getTableProps = function getTableProps(_ref) {
47
57
  header = data.header;
48
58
 
49
59
 
60
+ var obsAttributes = R.filter(function (a) {
61
+ return a.series && R.isEmpty(a.relationship) && a.display && !a.combined;
62
+ }, attributes);
63
+ var dupObs = observations;
64
+ var hasDuplicatedCells = R.pipe(R.values, R.unnest, R.find(R.equals('OBS_ATTRIBUTES')))(layoutIds);
65
+ if (hasDuplicatedCells) {
66
+ var attrsIds = R.pluck('id', obsAttributes);
67
+ dupObs = (0, _declineObservationsOverAttributes.declineObservationsOverAttributes)(attrsIds, observations);
68
+ }
50
69
  var seriesCombinations = (0, _getSeriesCombinations.getSeriesCombinations)(combinations, oneValueDimensions);
51
- var layout = (0, _getLayout.getLayout)(layoutIds, dimensions, seriesCombinations, isTimeInverted);
52
- var layoutIndexes = (0, _getSortedLayoutIndexes.getSortedLayoutIndexes)(layout, observations);
70
+ var _dims = R.append({
71
+ id: 'OBS_ATTRIBUTES',
72
+ values: R.prepend({ id: 'OBS_VALUE' }, obsAttributes)
73
+ }, dimensions);
74
+ var layout = (0, _getLayout.getLayout)(layoutIds, _dims, seriesCombinations, isTimeInverted);
75
+ var layoutDimsIds = R.map(R.reduce(function (acc, entry) {
76
+ if (R.has('dimensions', entry)) {
77
+ return R.concat(acc, R.pluck('id', entry.dimensions));
78
+ }
79
+ return R.append(entry.id, acc);
80
+ }, []), layout);
81
+ var layoutIndexes = (0, _getSortedLayoutIndexes.getSortedLayoutIndexes)(layout, dupObs);
53
82
  var enhancedLayoutIndexes = (0, _parseSeriesIndexesHierarchies.parseLayoutIndexesHierarchies)(layoutIndexes, layout);
54
- var refinedLayoutIndexes = (0, _refineLayoutSize.refineLayoutSize)({ layout: layout, observations: observations, limit: limit })(enhancedLayoutIndexes);
83
+ var refinedLayoutIndexes = (0, _refineLayoutSize.refineLayoutSize)({ layout: layout, observations: dupObs, limit: limit })(enhancedLayoutIndexes);
55
84
  var layoutData = (0, _getLayoutData.getLayoutData)(refinedLayoutIndexes, layout, { metadataCoordinates: metadataCoordinates, attributesSeries: attributesSeries, customAttributes: customAttributes, topCoordinates: header.coordinates });
56
85
 
57
- var cellsAttributesIds = (0, _getCellsAttributesIds.getCellsAttributesIds)(layoutIds, attributes);
86
+ var cellsAttributesIds = (0, _getCellsAttributesIds.getCellsAttributesIds)(layoutDimsIds, attributes);
58
87
  var indexedCombinations = (0, _getIndexedCombinationsByDisplay.getIndexedCombinationsByDisplay)(layout, seriesCombinations);
59
- var cells = (0, _getCells.getCells)(customAttributes, cellsAttributesIds, indexedCombinations, attributesSeries, metadataCoordinates)(observations);
88
+ var cellsMetadataCoordinates = (0, _getCellsMetadataCoordinates.getCellsMetadataCoordinates)(metadataCoordinates, oneValueDimensions, layoutDimsIds);
89
+ var cells = (0, _getCells.getCells)(customAttributes, cellsAttributesIds, indexedCombinations, attributesSeries, cellsMetadataCoordinates)(dupObs);
60
90
 
61
91
  return (0, _extends3.default)({}, layoutData, {
62
- cells: (0, _getCuratedCells.getCuratedCells)(cells, layout)
92
+ cells: (0, _getCuratedCells.getCuratedCells)(cells, layout),
93
+ layout: layout,
94
+ combinations: seriesCombinations
63
95
  });
64
96
  };
@@ -26,6 +26,12 @@ var getLayoutCoordinatesValidator = exports.getLayoutCoordinatesValidator = func
26
26
  if (R.isEmpty(coordinates)) {
27
27
  return false;
28
28
  }
29
+ if (R.has('OBS_ATTRIBUTES', layoutCoordinates) || R.has('OBS_ATTRIBUTES', topCoordinates)) {
30
+ var obsAttrCoord = R.prop('OBS_ATTRIBUTES', layoutCoordinates) || R.prop('OBS_ATTRIBUTES', topCoordinates);
31
+ if (obsAttrCoord !== 'OBS_VALUE') {
32
+ return false;
33
+ }
34
+ }
29
35
  var keys = R.keys(coordinates);
30
36
  var res = true;
31
37
  var notInTop = {};
@@ -37,6 +43,7 @@ var getLayoutCoordinatesValidator = exports.getLayoutCoordinatesValidator = func
37
43
  notInTop[key] = key;
38
44
  }
39
45
  }, keys);
40
- return res && !R.isEmpty(notInTop);
46
+ return res;
47
+ //return res && !R.isEmpty(notInTop);
41
48
  };
42
49
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sis-cc/dotstatsuite-components",
3
3
  "description": "Set components based on React.",
4
- "version": "17.27.0",
4
+ "version": "17.28.0",
5
5
  "main": "lib/index.js",
6
6
  "author": "OECD",
7
7
  "license": "MIT",
@@ -6,26 +6,35 @@ import {
6
6
  STACKED_ROW,
7
7
  V_SYMBOL
8
8
  } from './constants';
9
- import { getCombinationDefinitions, refineDimensions } from '../../rules2/src';
9
+ import {
10
+ getCombinationDefinitions,
11
+ refineDimensions,
12
+ parseCombinationDefinition
13
+ } from '../../rules2/src';
10
14
 
11
15
  const isTableLayoutCompatible = (data, layout, combinationsDefinitions = [], dataquery = '') => {
12
- const multiValuesDimensions = R.pipe(
16
+ const indexedCombinations = R.indexBy(R.prop('id'), combinationsDefinitions);
17
+ const indexedManyValuesDimensions = R.pipe(
13
18
  R.pathOr([], ['structure', 'dimensions', 'observation']),
14
19
  dimensions => refineDimensions(dimensions, dataquery),
15
20
  R.reject(d => R.prop('header', d) || !R.length(d.values || [])),
16
- R.pluck('id'),
17
- R.map(d => {
18
- const conceptId = R.find(comb => R.includes(d, R.propOr([], 'concepts', comb)))(combinationsDefinitions)
19
- return conceptId ? conceptId.id : d
20
- }),
21
+ R.indexBy(R.prop('id'))
21
22
  )(data);
22
- const dimensionsInLayout = R.pipe(R.values, R.unnest)(layout);
23
-
24
- const dimensionsLength = R.length(multiValuesDimensions);
25
- const layoutLength = R.length(dimensionsInLayout);
26
- const intersectionLength = R.length(R.intersection(multiValuesDimensions, dimensionsInLayout));
27
-
28
- return R.all(R.equals(dimensionsLength))([intersectionLength, layoutLength]);
23
+ let remainings = indexedManyValuesDimensions;
24
+ const layoutIds = R.pipe(R.values, R.unnest)(layout);
25
+ let hasFoundIrrelevant = false;
26
+ R.forEach(id => {
27
+ if (R.has(id, indexedManyValuesDimensions)) {
28
+ remainings = R.dissoc(id, remainings);
29
+ }
30
+ else if (R.has(id, indexedCombinations)) {
31
+ remainings = R.omit(R.pathOr([], [id, 'concepts'], indexedCombinations), remainings);
32
+ }
33
+ else if (id !== 'OBS_ATTRIBUTES') {
34
+ hasFoundIrrelevant = true;
35
+ }
36
+ }, layoutIds);
37
+ return R.isEmpty(remainings) && !hasFoundIrrelevant;
29
38
  };
30
39
 
31
40
 
@@ -90,8 +99,13 @@ export const isSharedLayoutCompatible = (sdmxData, sharedData) => {
90
99
  const layoutIds = R.pathOr({}, ['config', 'table', 'layoutIds'], sharedData);
91
100
  const dataquery = R.path(['config', 'sdmxSource', 'dataquery'], sharedData);
92
101
  const annotations = R.pathOr({}, ['structure', 'annotations'], sdmxData)
93
- const locale = R.pathOr({}, ['config', 'table', 'locale'], sharedData)
94
- const combinationsDefinitions = getCombinationDefinitions(annotations, locale)
102
+ const locale = R.pathOr({}, ['config', 'table', 'locale'], sharedData);
103
+ const rawDefaultCombinationsDefinition = R.pathOr({}, ['config', 'defaultCombinations'], sharedData);
104
+ const { concepts='', names='' } = rawDefaultCombinationsDefinition;
105
+ const defaultCombinationsDefinition = parseCombinationDefinition(locale)(concepts, names);
106
+ const customCombinationsDefinitions = getCombinationDefinitions(annotations, locale);
107
+ const combinationsDefinitions = R.isNil(customCombinationsDefinitions) || R.isEmpty(customCombinationsDefinitions)
108
+ ? defaultCombinationsDefinition : customCombinationsDefinitions;
95
109
  return isTableLayoutCompatible(sdmxData, layoutIds, combinationsDefinitions, dataquery);
96
110
  }
97
111
  const chartDimension = R.pathOr({}, ['config', 'chart', 'chartDimension'], sharedData);
@@ -15,7 +15,7 @@ export { duplicateObs } from './duplicateObservations';
15
15
  export { refinePartialHierarchy, hierarchiseDimensionWithAdvancedHierarchy } from './hierarchiseDimensionWithAdvancedHierarchy2';
16
16
  export { hierarchiseDimensionWithNativeHierarchy } from './hierarchiseDimensionWithNativeHierarchy2';
17
17
  export { getDimensionValuesIndexes } from './getDimensionValuesIndexes';
18
- export { getCombinationDefinitions } from './getCombinationDefinitions';
18
+ export { getCombinationDefinitions, parseCombinationDefinition } from './getCombinationDefinitions';
19
19
  export { refineDimensions } from './refineDimensions';
20
20
  export { parseAttributes } from './parseAttributes';
21
21
  export { parseCombinations } from './parseCombinations';
@@ -46,3 +46,4 @@ export { getTableLabelAccessor } from './table/getTableLabelAccessor';
46
46
  export { parseValueHierarchy } from './table/parseValueHierarchy';
47
47
  export { parseLayoutIndexesHierarchies } from './table/parseSeriesIndexesHierarchies';
48
48
  export { getTableLayoutIds, injectCombinationsInLayout } from './table/getTableLayoutIds';
49
+ export { declineObservationsOverAttributes } from './table/declineObservationsOverAttributes';
@@ -0,0 +1,32 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const declineObservationsOverAttributes = (attrsIds, observations) => {
4
+ const obsKeys = R.keys(observations);
5
+ return R.reduce((acc, obsKey) => {
6
+ const obs = R.prop(obsKey, observations);
7
+ const enhancedObs = R.pipe(
8
+ R.over(R.lensProp('orderedDimIndexes'), R.append(0)),
9
+ R.over(R.lensProp('attributes'), R.omit(attrsIds)),
10
+ R.assocPath(['indexedDimValIds', 'OBS_ATTRIBUTES'], 'OBS_VALUE')
11
+ )(obs);
12
+ return R.addIndex(R.reduce)((_acc, attrId, attrIndex) => {
13
+ const attr = R.pathOr({}, ['attributes', attrId], obs);
14
+ if (R.isEmpty(attr) || R.isNil(R.prop('value', attr)) || !R.pathOr(true, ['value', 'display'], attr)) {
15
+ return _acc;
16
+ }
17
+ const declinedKey = `${obsKey}:${attrIndex+1}`;
18
+ const declined = {
19
+ ...obs,
20
+ attributes: {},
21
+ value: R.prop('value', attr),
22
+ formattedValue: R.prop('value', attr),
23
+ orderedDimIndexes: R.append(attrIndex+1, obs.orderedDimIndexes),
24
+ indexedDimValIds: {
25
+ ...obs.indexedDimValIds,
26
+ OBS_ATTRIBUTES: attr.id
27
+ }
28
+ };
29
+ return R.assoc(declinedKey, declined, _acc);
30
+ }, R.assoc(`${obsKey}:0`, enhancedObs, acc), attrsIds);
31
+ }, {}, obsKeys);
32
+ };
@@ -62,16 +62,17 @@ export const getCells = (customAttributes, cellsAttributesId, combinations, attr
62
62
 
63
63
  return R.mapObjIndexed(
64
64
  obs => {
65
- const relevantAttributes = getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
66
- const flagsAndNotes = getFlagsAndNotes(R.omit(attributesInCellsCombination, relevantAttributes), _customAttributes);
67
- const combinedSeries = getCellCombinedSeries(relevantAttributes, combinations.cells || []);
68
- const hasAdvancedAttributes = R.pipe(
65
+ const isAttrCell = R.pathOr('OBS_VAL', ['indexedDimValIds', 'OBS_ATTR'], obs) !== 'OBS_VAL';
66
+ const relevantAttributes = isAttrCell ? [] : getCellRelevantAttributes(obs.attributes, attributesSeries, cellsAttributesId);
67
+ const flagsAndNotes = isAttrCell ? [] : getFlagsAndNotes(R.omit(attributesInCellsCombination, relevantAttributes), _customAttributes);
68
+ const combinedSeries = isAttrCell ? [] : getCellCombinedSeries(relevantAttributes, combinations.cells || []);
69
+ const hasAdvancedAttributes = isAttrCell ? false : R.pipe(
69
70
  R.omit(R.unnest([_customAttributes.flags || [], _customAttributes.notes || [], attributesInCellsCombination])),
70
71
  R.isEmpty,
71
72
  R.not
72
73
  )(relevantAttributes);
73
74
 
74
- const hasMetadata = hasCellMetadata(metadataCoordinates, obs.indexedDimValIds);
75
+ const hasMetadata = isAttrCell ? false : hasCellMetadata(metadataCoordinates, obs.indexedDimValIds);
75
76
 
76
77
  return ({
77
78
  ...R.pick(['indexedDimValIds', 'key'], obs),
@@ -80,7 +80,7 @@ const combineConcepts = (combDimValues, definition, attrValues) => R.over(
80
80
  })));
81
81
 
82
82
  const getSerieFlagsAndSideProps = (coordinates, validator, attributesValues, customAttributes, metadataCoordinates) => {
83
- const layoutAttrValues = R.reject(R.prop('isObs'), attributesValues);
83
+ const layoutAttrValues = R.reject(attr => R.prop('isObs', attr) && !validator(attr.coordinates), attributesValues);
84
84
  const flags = getFlagsAndNotes(layoutAttrValues, customAttributes);
85
85
  const hasMetadata = !R.isNil(R.find(validator, metadataCoordinates));
86
86
  const hasAdvancedAttributes = getHasAdvancedAttributes(layoutAttrValues, customAttributes);
@@ -142,7 +142,9 @@ export const getSerieDataWithMissingLines = (serie, definition, topCoordinates,
142
142
  { parentsIndexes: _parentsIndexes, missingParents: [] }, missingParentsIndexes);
143
143
 
144
144
  const { attributes, ...serieData } = getSerieDimensionsData(serie, definition, attributesValues, getMissingParents);
145
- const { flags, sideProps } = getSerieFlagsAndSideProps(serieCoordinates, coordinatesValidator, attributes, customAttributes, metadataCoordinates);
145
+ const topCoordinatesValidator = getLayoutCoordinatesValidator(topCoordinates);
146
+ const flagsValidator = coordinates => coordinatesValidator(coordinates) && !topCoordinatesValidator(coordinates);
147
+ const { flags, sideProps } = getSerieFlagsAndSideProps(serieCoordinates, flagsValidator, attributes, customAttributes, metadataCoordinates);
146
148
  return R.append({ ...serieData, flags, sideProps, coordinates: serieCoordinates }, lines);
147
149
  };
148
150
 
@@ -21,7 +21,12 @@ const getLayoutPivots = layoutEntry => {
21
21
  R.ifElse(
22
22
  R.has('dimensions'),
23
23
  c => R.map(d => valIndexGetter(d)(indexes), R.prop('dimensions', c)),
24
- d => valIndexGetter(d)(indexes)
24
+ d => {
25
+ if (d.id === 'OBS_ATTRIBUTES') {
26
+ return R.last(indexes);
27
+ }
28
+ return valIndexGetter(d)(indexes);
29
+ }
25
30
  ),
26
31
  layoutEntry
27
32
  );
@@ -77,9 +77,8 @@ export const injectCombinationsInLayout = (combinations, layoutIds) => {
77
77
  const ids = injectCombination(comb)(acc.sections);
78
78
  return R.assoc('sections', ids)(acc);
79
79
  }
80
- const rowsConcepts = R.concat(idsInRows, nowhere);
81
- layoutRelationships.rows = R.concat(layoutRelationships.rows, rowsConcepts);
82
- const ids = injectCombination({ ...comb, concepts: rowsConcepts })(acc.rows);
80
+ layoutRelationships.rows = R.concat(layoutRelationships.rows, relationship);
81
+ const ids = injectCombination(comb)(acc.rows);
83
82
  return R.assoc('rows', ids)(acc);
84
83
  }, layoutIds, notInLayoutCombs);
85
84
  };
@@ -187,9 +186,18 @@ export const getTableLayoutIds = (
187
186
  layoutDimsIds,
188
187
  attributes,
189
188
  );
189
+ const combinationsConcepts = R.pipe(R.pluck('_concepts'), R.unnest, ids => new Set(ids))(combinations);
190
+ const obsAttributes = R.filter(a =>
191
+ a.series && R.isEmpty(a.relationship || []) && a.display && !combinationsConcepts.has(a)
192
+ , attributes);
190
193
  const indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
191
194
  const filteredLayoutIds = R.map(
192
- R.filter(id => R.has(id, indexedCombinations) || layoutDimsIds.has(id)),
195
+ R.filter(id => {
196
+ if (id === 'OBS_ATTRIBUTES') {
197
+ return !R.isEmpty(obsAttributes);
198
+ }
199
+ return R.has(id, indexedCombinations) || layoutDimsIds.has(id);
200
+ }),
193
201
  defaultLayoutIds,
194
202
  );
195
203
  const layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
@@ -1,3 +1,5 @@
1
+ import * as R from 'ramda';
2
+ import { declineObservationsOverAttributes } from './declineObservationsOverAttributes';
1
3
  import { getLayout } from './getLayout';
2
4
  import { getSortedLayoutIndexes } from './getSortedLayoutIndexes';
3
5
  import { parseLayoutIndexesHierarchies } from './parseSeriesIndexesHierarchies';
@@ -8,6 +10,7 @@ import { getIndexedCombinationsByDisplay } from './getIndexedCombinationsByDispl
8
10
  import { getCells } from './getCells';
9
11
  import { getCuratedCells } from './getCuratedCells';
10
12
  import { getSeriesCombinations } from '../getSeriesCombinations';
13
+ import { getCellsMetadataCoordinates } from './getCellsMetadataCoordinates';
11
14
 
12
15
  export const getTableProps = ({ data, layoutIds, customAttributes, limit, isTimeInverted }) => {
13
16
  const {
@@ -21,22 +24,52 @@ export const getTableProps = ({ data, layoutIds, customAttributes, limit, isTime
21
24
  header
22
25
  } = data;
23
26
 
27
+ const obsAttributes = R.filter(
28
+ a => a.series && R.isEmpty(a.relationship) && a.display && !a.combined,
29
+ attributes
30
+ );
31
+ let dupObs = observations;
32
+ const hasDuplicatedCells = R.pipe(
33
+ R.values,
34
+ R.unnest,
35
+ R.find(R.equals('OBS_ATTRIBUTES')),
36
+ )(layoutIds);
37
+ if (hasDuplicatedCells) {
38
+ const attrsIds = R.pluck('id', obsAttributes);
39
+ dupObs = declineObservationsOverAttributes(attrsIds, observations);
40
+ }
24
41
  const seriesCombinations = getSeriesCombinations(combinations, oneValueDimensions);
25
- const layout = getLayout(layoutIds, dimensions, seriesCombinations, isTimeInverted);
26
- const layoutIndexes = getSortedLayoutIndexes(layout, observations);
42
+ const _dims = R.append(
43
+ {
44
+ id: 'OBS_ATTRIBUTES',
45
+ values: R.prepend({ id: 'OBS_VALUE' }, obsAttributes),
46
+ },
47
+ dimensions,
48
+ );
49
+ const layout = getLayout(layoutIds, _dims, seriesCombinations, isTimeInverted);
50
+ const layoutDimsIds = R.map(R.reduce((acc, entry) => {
51
+ if (R.has('dimensions', entry)) {
52
+ return R.concat(acc, R.pluck('id', entry.dimensions));
53
+ }
54
+ return R.append(entry.id, acc);
55
+ }, []), layout);
56
+ const layoutIndexes = getSortedLayoutIndexes(layout, dupObs);
27
57
  const enhancedLayoutIndexes = parseLayoutIndexesHierarchies(
28
58
  layoutIndexes,
29
59
  layout,
30
60
  );
31
- const refinedLayoutIndexes = refineLayoutSize({ layout, observations, limit })(enhancedLayoutIndexes);
61
+ const refinedLayoutIndexes = refineLayoutSize({ layout, observations: dupObs, limit })(enhancedLayoutIndexes);
32
62
  const layoutData = getLayoutData(refinedLayoutIndexes, layout, { metadataCoordinates, attributesSeries, customAttributes, topCoordinates: header.coordinates });
33
63
 
34
- const cellsAttributesIds = getCellsAttributesIds(layoutIds, attributes);
64
+ const cellsAttributesIds = getCellsAttributesIds(layoutDimsIds, attributes);
35
65
  const indexedCombinations = getIndexedCombinationsByDisplay(layout, seriesCombinations);
36
- const cells = getCells(customAttributes, cellsAttributesIds, indexedCombinations, attributesSeries, metadataCoordinates)(observations);
66
+ const cellsMetadataCoordinates = getCellsMetadataCoordinates(metadataCoordinates, oneValueDimensions, layoutDimsIds);
67
+ const cells = getCells(customAttributes, cellsAttributesIds, indexedCombinations, attributesSeries, cellsMetadataCoordinates)(dupObs);
37
68
 
38
69
  return ({
39
70
  ...layoutData,
40
- cells: getCuratedCells(cells, layout)
71
+ cells: getCuratedCells(cells, layout),
72
+ layout,
73
+ combinations: seriesCombinations
41
74
  });
42
75
  };
@@ -15,6 +15,13 @@ export const getLayoutCoordinatesValidator = (layoutCoordinates, topCoordinates=
15
15
  if (R.isEmpty(coordinates)) {
16
16
  return false;
17
17
  }
18
+ if (R.has('OBS_ATTRIBUTES', layoutCoordinates) || R.has('OBS_ATTRIBUTES', topCoordinates)) {
19
+ const obsAttrCoord = R.prop('OBS_ATTRIBUTES', layoutCoordinates)
20
+ || R.prop('OBS_ATTRIBUTES', topCoordinates);
21
+ if (obsAttrCoord !== 'OBS_VALUE') {
22
+ return false;
23
+ }
24
+ }
18
25
  const keys = R.keys(coordinates);
19
26
  let res = true;
20
27
  let notInTop = {};
@@ -26,5 +33,6 @@ export const getLayoutCoordinatesValidator = (layoutCoordinates, topCoordinates=
26
33
  notInTop[key] = key;
27
34
  }
28
35
  }, keys);
29
- return res && !R.isEmpty(notInTop);
36
+ return res;
37
+ //return res && !R.isEmpty(notInTop);
30
38
  };
@@ -1099,4 +1099,40 @@ describe('getSortedLayoutIndexes tests', () => {
1099
1099
 
1100
1100
  expect(getSortedLayoutIndexes(layout, observations)).to.deep.equal(expected);
1101
1101
  });
1102
+ it('OBS_ATTRIBUTES', () => {
1103
+ const layout = {
1104
+ header: [{ id: 'd1', __index: 0 }, { id: 'OBS_ATTRIBUTES' }],
1105
+ sections: [{ id: 'd2', __index: 1 }],
1106
+ rows: [{ id: 'd3', __index: 2 }],
1107
+ };
1108
+
1109
+ const observations = {
1110
+ '0:0:0:0': { orderedDimIndexes: [0, 0, 0, 0] },
1111
+ '0:0:0:1': { orderedDimIndexes: [0, 0, 0, 1] },
1112
+ '0:0:1:0': { orderedDimIndexes: [0, 0, 1, 0] },
1113
+ '0:0:1:1': { orderedDimIndexes: [0, 0, 1, 1] },
1114
+ '0:1:0:0': { orderedDimIndexes: [0, 1, 0, 0] },
1115
+ '0:1:0:1': { orderedDimIndexes: [0, 1, 0, 1] },
1116
+ '0:1:1:0': { orderedDimIndexes: [0, 1, 1, 0] },
1117
+ '0:1:1:1': { orderedDimIndexes: [0, 1, 1, 1] },
1118
+ '1:0:0:0': { orderedDimIndexes: [1, 0, 0, 0] },
1119
+ '1:0:0:1': { orderedDimIndexes: [1, 0, 0, 1] },
1120
+ '1:0:1:0': { orderedDimIndexes: [1, 0, 1, 0] },
1121
+ '1:0:1:1': { orderedDimIndexes: [1, 0, 1, 1] },
1122
+ '1:1:0:0': { orderedDimIndexes: [1, 1, 0, 0] },
1123
+ '1:1:0:1': { orderedDimIndexes: [1, 1, 0, 1] },
1124
+ '1:1:1:0': { orderedDimIndexes: [1, 1, 1, 0] },
1125
+ '1:1:1:1': { orderedDimIndexes: [1, 1, 1, 1] },
1126
+ };
1127
+
1128
+ const layoutIndexes = {
1129
+ header: [[0, 0], [0, 1], [1, 0], [1, 1]],
1130
+ sections: [
1131
+ [[0], [[0], [1]]],
1132
+ [[1], [[0], [1]]]
1133
+ ]
1134
+ };
1135
+
1136
+ expect(getSortedLayoutIndexes(layout, observations)).to.deep.equal(layoutIndexes);
1137
+ });
1102
1138
  });