@sis-cc/dotstatsuite-components 17.27.0 → 17.29.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
  });
@@ -23,7 +23,8 @@ var parseAttributes = exports.parseAttributes = function parseAttributes(attribu
23
23
  var indexedDimensions = R.indexBy(R.prop('id'), dimensions);
24
24
  return R.addIndex(R.map)(function (attr, index) {
25
25
  var res = R.assoc('index', index, attr);
26
- if (R.isEmpty(attr.values || []) || !R.propOr(true, 'display', attr) || attr.id === _constants.REPORTING_YEAR_START_DAY || attr.id === _constants.REPYEARSTART) {
26
+ var displayableValuesCount = R.pipe(R.filter(R.propOr(true, 'display')), R.length)(attr);
27
+ if (R.isEmpty(attr.values || []) || !R.propOr(true, 'display', attr) || displayableValuesCount < 1 || attr.id === _constants.REPORTING_YEAR_START_DAY || attr.id === _constants.REPYEARSTART) {
27
28
  return R.assoc('display', false, res);
28
29
  }
29
30
  if (R.propEq('id', customAttributes.prefscale, attr)) {
@@ -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
 
@@ -234,7 +241,6 @@ var getLayoutData = function getLayoutData(layoutIndexes, layout, _ref) {
234
241
  sections = layoutIndexes.sections,
235
242
  rest = (0, _objectWithoutProperties3.default)(layoutIndexes, ['header', 'sections']);
236
243
 
237
-
238
244
  var headerData = R.reduce(function (acc, serie) {
239
245
  var datas = getSerieDataWithMissingLines(serie, layout.header, topCoordinates, attributesSeries, customAttributes, metadataCoordinates);
240
246
  return R.concat(acc, datas);
@@ -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
  };
@@ -123,10 +123,9 @@ var injectCombinationsInLayout = exports.injectCombinationsInLayout = function i
123
123
  if (idsInRowsSet.has(id)) return R.over(R.lensIndex(1), R.append(id), _acc);
124
124
  return R.over(R.lensIndex(2), R.append(id), _acc);
125
125
  }, [[], [], []], rest),
126
- _R$reduce2 = (0, _slicedToArray3.default)(_R$reduce, 3),
126
+ _R$reduce2 = (0, _slicedToArray3.default)(_R$reduce, 2),
127
127
  idsInSections = _R$reduce2[0],
128
- idsInRows = _R$reduce2[1],
129
- nowhere = _R$reduce2[2];
128
+ idsInRows = _R$reduce2[1];
130
129
 
131
130
  if (!R.isEmpty(idsInHeader) && R.isEmpty(idsInSections) && R.isEmpty(idsInRows)) {
132
131
  layoutRelationships.header = R.concat(layoutRelationships.header, relationship);
@@ -141,9 +140,8 @@ var injectCombinationsInLayout = exports.injectCombinationsInLayout = function i
141
140
  var _ids2 = injectCombination(comb)(acc.sections);
142
141
  return R.assoc('sections', _ids2)(acc);
143
142
  }
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);
143
+ layoutRelationships.rows = R.concat(layoutRelationships.rows, relationship);
144
+ var ids = injectCombination(comb)(acc.rows);
147
145
  return R.assoc('rows', ids)(acc);
148
146
  }, layoutIds, notInLayoutCombs);
149
147
  };
@@ -179,7 +177,17 @@ var getLayoutCombinations = exports.getLayoutCombinations = function getLayoutCo
179
177
  }, [], combinations);
180
178
  };
181
179
 
182
- var extractConcepts = function extractConcepts(ids, indexedCombinations) {
180
+ var extractConcepts = function extractConcepts(ids, indexedCombinations, layoutDimsIds) {
181
+ var entry = R.find(function (id) {
182
+ if (R.has(id, indexedCombinations)) {
183
+ var dimId = R.find(function (i) {
184
+ return layoutDimsIds.has(i);
185
+ }, R.pathOr([], [id, 'concepts'], indexedCombinations));
186
+ return !R.isNil(dimId);
187
+ }
188
+ return true;
189
+ }, ids);
190
+
183
191
  var getRelationship = function getRelationship(id) {
184
192
  if (R.has(id, indexedCombinations)) {
185
193
  return R.append(id, R.path([id, 'relationship'], indexedCombinations));
@@ -190,7 +198,7 @@ var extractConcepts = function extractConcepts(ids, indexedCombinations) {
190
198
  return R.assoc(id, getRelationship(id), acc);
191
199
  }, {}, ids);
192
200
 
193
- var relationship = [R.head(ids)];
201
+ var relationship = [entry];
194
202
  while (!R.isEmpty(indexedRels)) {
195
203
  var related = R.pickBy(function (rels) {
196
204
  return !R.isEmpty(R.intersection(relationship, rels));
@@ -207,20 +215,31 @@ var extractConcepts = function extractConcepts(ids, indexedCombinations) {
207
215
  }, ids);
208
216
  };
209
217
 
210
- var injectRemainingDimensionsInLayout = exports.injectRemainingDimensionsInLayout = function injectRemainingDimensionsInLayout(layoutIds, remainingDims, indexedCombinations) {
218
+ var injectRemainingDimensionsInLayout = exports.injectRemainingDimensionsInLayout = function injectRemainingDimensionsInLayout(layoutIds, remainingDims, indexedCombinations, layoutDimsIds) {
211
219
  var _layout = layoutIds;
212
220
  var _remaining = remainingDims;
213
221
 
214
- if (R.isEmpty(_layout.rows)) {
222
+ var dimInRows = R.find(function (id) {
223
+ if (layoutDimsIds.has(id)) {
224
+ return true;
225
+ }
226
+ var dimId = R.find(function (i) {
227
+ return layoutDimsIds.has(i);
228
+ }, R.pathOr([], [id, 'concepts'], indexedCombinations));
229
+ return !R.isNil(dimId);
230
+ }, _layout.rows);
231
+
232
+ console.log({ dimInRows: dimInRows, layoutIds: layoutIds, indexedCombinations: indexedCombinations, layoutDimsIds: layoutDimsIds });
233
+ if (R.isNil(dimInRows)) {
215
234
  if (R.isEmpty(_remaining)) {
216
235
  var toTakeIn = R.isEmpty(_layout.sections) ? 'header' : 'sections';
217
236
 
218
- var _extractConcepts = extractConcepts(R.prop(toTakeIn, _layout), indexedCombinations),
237
+ var _extractConcepts = extractConcepts(R.prop(toTakeIn, _layout), indexedCombinations, layoutDimsIds),
219
238
  _extractConcepts2 = (0, _slicedToArray3.default)(_extractConcepts, 2),
220
239
  extracted = _extractConcepts2[0],
221
240
  remains = _extractConcepts2[1];
222
241
 
223
- _layout = (0, _extends4.default)({}, _layout, (0, _defineProperty3.default)({ rows: extracted }, toTakeIn, remains));
242
+ _layout = (0, _extends4.default)({}, _layout, (0, _defineProperty3.default)({ rows: R.concat(_layout.rows, extracted) }, toTakeIn, remains));
224
243
  } else {
225
244
  _layout = R.over(R.lensProp('rows'), R.append(R.head(_remaining)))(_layout);
226
245
  _remaining = R.tail(_remaining);
@@ -241,8 +260,18 @@ var injectRemainingDimensionsInLayout = exports.injectRemainingDimensionsInLayou
241
260
  var getTableLayoutIds = exports.getTableLayoutIds = function getTableLayoutIds(defaultLayoutIds, dimensions, attributes, combinations) {
242
261
  var layoutDimsIds = getLayoutDimsIds(dimensions);
243
262
  var layoutCombinations = getLayoutCombinations(combinations, layoutDimsIds, attributes);
263
+
264
+ var combinationsConcepts = R.pipe(R.pluck('_concepts'), R.unnest, function (ids) {
265
+ return new _set2.default(ids);
266
+ })(combinations);
267
+ var obsAttributes = R.filter(function (a) {
268
+ return a.series && R.isEmpty(a.relationship || []) && a.display && !combinationsConcepts.has(a);
269
+ }, attributes);
244
270
  var indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
245
271
  var filteredLayoutIds = R.map(R.filter(function (id) {
272
+ if (id === 'OBS_ATTRIBUTES') {
273
+ return !R.isEmpty(obsAttributes);
274
+ }
246
275
  return R.has(id, indexedCombinations) || layoutDimsIds.has(id);
247
276
  }), defaultLayoutIds);
248
277
  var layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
@@ -284,5 +313,5 @@ var getTableLayoutIds = exports.getTableLayoutIds = function getTableLayoutIds(d
284
313
  nextLayout = _R$reduce4.nextLayout,
285
314
  remaining = _R$reduce4.remaining;
286
315
 
287
- return injectRemainingDimensionsInLayout(nextLayout, remaining, indexedCombinations);
316
+ return injectRemainingDimensionsInLayout(nextLayout, remaining, indexedCombinations, layoutDimsIds);
288
317
  };
@@ -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
  };
@@ -276,8 +276,12 @@ var refineLayoutSize = exports.refineLayoutSize = function refineLayoutSize(_ref
276
276
  truncated = _truncateLayout.truncated,
277
277
  extractedKeys = _truncateLayout.extractedKeys;
278
278
 
279
+ var dimsLength = R.pipe(R.values, R.head, R.propOr([], 'orderedDimIndexes'), R.length)(observations);
280
+ var _layout = R.map(R.map(function (entry) {
281
+ return entry.id === 'OBS_ATTRIBUTES' ? R.assoc('__index', dimsLength - 1, entry) : entry;
282
+ }), layout);
279
283
  var curatedObs = R.pipe(getShape, function (shape) {
280
- return getCuratedCells({ layout: layout, observations: observations, shape: shape });
284
+ return getCuratedCells({ layout: _layout, observations: observations, shape: shape });
281
285
  })(isVertical);
282
286
 
283
287
  var refined = refineLayout(isVertical)(toRefine, extractedKeys, curatedObs);
@@ -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.29.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';
@@ -5,8 +5,13 @@ export const parseAttributes = (attributes, dimensions, customAttributes) => {
5
5
  const indexedDimensions = R.indexBy(R.prop('id'), dimensions);
6
6
  return R.addIndex(R.map)((attr, index) => {
7
7
  let res = R.assoc('index', index, attr);
8
+ const displayableValuesCount = R.pipe(
9
+ R.filter(R.propOr(true, 'display')),
10
+ R.length,
11
+ )(attr);
8
12
  if (R.isEmpty(attr.values || []) || !R.propOr(true, 'display', attr)
9
- || attr.id === REPORTING_YEAR_START_DAY || attr.id === REPYEARSTART) {
13
+ || displayableValuesCount < 1 || attr.id === REPORTING_YEAR_START_DAY
14
+ || attr.id === REPYEARSTART) {
10
15
  return R.assoc('display', false, res);
11
16
  }
12
17
  if (R.propEq('id', customAttributes.prefscale, attr)) {
@@ -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
 
@@ -165,7 +167,6 @@ export const getSerieDataWithoutMissingLines = (serie, definition, topCoordinate
165
167
 
166
168
  export const getLayoutData = (layoutIndexes, layout, { metadataCoordinates, attributesSeries, customAttributes, topCoordinates={} }) => {
167
169
  const { header, sections, ...rest } = layoutIndexes;
168
-
169
170
  const headerData = R.reduce((acc, serie) => {
170
171
  const datas = getSerieDataWithMissingLines(serie, layout.header, topCoordinates, attributesSeries, customAttributes, metadataCoordinates);
171
172
  return R.concat(acc, datas);
@@ -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
  );
@@ -57,7 +57,7 @@ export const injectCombinationsInLayout = (combinations, layoutIds) => {
57
57
  i => idsInHeaderSet.has(i),
58
58
  relationship
59
59
  );
60
- const [idsInSections, idsInRows, nowhere] = R.reduce((_acc, id) => {
60
+ const [idsInSections, idsInRows] = R.reduce((_acc, id) => {
61
61
  if (idsInSectionsSet.has(id))
62
62
  return R.over(R.lensIndex(0), R.append(id), _acc);
63
63
  if (idsInRowsSet.has(id))
@@ -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
  };
@@ -123,7 +122,15 @@ export const getLayoutCombinations = (combinations, layoutDimsIds, attributes) =
123
122
  );
124
123
  };
125
124
 
126
- const extractConcepts = (ids, indexedCombinations) => {
125
+ const extractConcepts = (ids, indexedCombinations, layoutDimsIds) => {
126
+ const entry = R.find(id => {
127
+ if (R.has(id, indexedCombinations)) {
128
+ const dimId = R.find(i => layoutDimsIds.has(i), R.pathOr([], [id, 'concepts'], indexedCombinations));
129
+ return !R.isNil(dimId);
130
+ }
131
+ return true;
132
+ }, ids);
133
+
127
134
  const getRelationship = id => {
128
135
  if (R.has(id, indexedCombinations)) {
129
136
  return R.append(id, R.path([id, 'relationship'], indexedCombinations));
@@ -134,7 +141,7 @@ const extractConcepts = (ids, indexedCombinations) => {
134
141
  R.assoc(id, getRelationship(id), acc)
135
142
  , {}, ids);
136
143
 
137
- let relationship = [R.head(ids)];
144
+ let relationship = [entry];
138
145
  while (!R.isEmpty(indexedRels)) {
139
146
  const related = R.pickBy(rels => !R.isEmpty(R.intersection(relationship, rels)), indexedRels);
140
147
  if (R.isEmpty(related)) {
@@ -147,15 +154,24 @@ const extractConcepts = (ids, indexedCombinations) => {
147
154
  return R.partition(id => set.has(id), ids);
148
155
  }
149
156
 
150
- export const injectRemainingDimensionsInLayout = (layoutIds, remainingDims, indexedCombinations) => {
157
+ export const injectRemainingDimensionsInLayout = (layoutIds, remainingDims, indexedCombinations, layoutDimsIds) => {
151
158
  let _layout = layoutIds;
152
159
  let _remaining = remainingDims;
153
160
 
154
- if (R.isEmpty(_layout.rows)) {
161
+ const dimInRows = R.find(id => {
162
+ if (layoutDimsIds.has(id)) {
163
+ return true;
164
+ }
165
+ const dimId = R.find(i => layoutDimsIds.has(i), R.pathOr([], [id, 'concepts'], indexedCombinations));
166
+ return !R.isNil(dimId);
167
+ }, _layout.rows);
168
+
169
+ console.log({ dimInRows, layoutIds, indexedCombinations, layoutDimsIds });
170
+ if (R.isNil(dimInRows)) {
155
171
  if (R.isEmpty(_remaining)) {
156
172
  const toTakeIn = R.isEmpty(_layout.sections) ? 'header' : 'sections';
157
- const [extracted, remains] = extractConcepts(R.prop(toTakeIn, _layout), indexedCombinations);
158
- _layout = ({ ..._layout, rows: extracted, [toTakeIn]: remains });
173
+ const [extracted, remains] = extractConcepts(R.prop(toTakeIn, _layout), indexedCombinations, layoutDimsIds);
174
+ _layout = ({ ..._layout, rows: R.concat(_layout.rows, extracted), [toTakeIn]: remains });
159
175
  }
160
176
  else {
161
177
  _layout = R.over(R.lensProp('rows'), R.append(R.head(_remaining)))(_layout);
@@ -187,9 +203,19 @@ export const getTableLayoutIds = (
187
203
  layoutDimsIds,
188
204
  attributes,
189
205
  );
206
+
207
+ const combinationsConcepts = R.pipe(R.pluck('_concepts'), R.unnest, ids => new Set(ids))(combinations);
208
+ const obsAttributes = R.filter(a =>
209
+ a.series && R.isEmpty(a.relationship || []) && a.display && !combinationsConcepts.has(a)
210
+ , attributes);
190
211
  const indexedCombinations = R.indexBy(R.prop('id'), layoutCombinations);
191
212
  const filteredLayoutIds = R.map(
192
- R.filter(id => R.has(id, indexedCombinations) || layoutDimsIds.has(id)),
213
+ R.filter(id => {
214
+ if (id === 'OBS_ATTRIBUTES') {
215
+ return !R.isEmpty(obsAttributes);
216
+ }
217
+ return R.has(id, indexedCombinations) || layoutDimsIds.has(id);
218
+ }),
193
219
  defaultLayoutIds,
194
220
  );
195
221
  const layoutWithCombs = injectCombinationsInLayout(layoutCombinations, filteredLayoutIds);
@@ -236,5 +262,5 @@ export const getTableLayoutIds = (
236
262
  return R.over(R.lensProp('remaining'), R.append(dim.id))(acc);
237
263
  }, { nextLayout: layoutWithCombs, remaining: [] }, dimensions);
238
264
 
239
- return injectRemainingDimensionsInLayout(nextLayout, remaining, indexedCombinations);
265
+ return injectRemainingDimensionsInLayout(nextLayout, remaining, indexedCombinations, layoutDimsIds);
240
266
  };
@@ -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
  };
@@ -299,9 +299,14 @@ export const refineLayoutSize = ({ layout, observations, limit }) => layoutIndex
299
299
 
300
300
  const { truncated, extractedKeys } = truncateLayout(isVertical)(cutLength, toTruncate);
301
301
 
302
+ const dimsLength = R.pipe(R.values, R.head, R.propOr([], 'orderedDimIndexes'), R.length)(observations);
303
+ const _layout = R.map(
304
+ R.map(entry => entry.id === 'OBS_ATTRIBUTES' ? R.assoc('__index', dimsLength - 1, entry) : entry),
305
+ layout
306
+ );
302
307
  const curatedObs = R.pipe(
303
308
  getShape,
304
- (shape) => getCuratedCells({ layout, observations, shape })
309
+ (shape) => getCuratedCells({ layout: _layout, observations, shape })
305
310
  )(isVertical);
306
311
 
307
312
 
@@ -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
  });
@@ -224,4 +224,28 @@ describe('getTableLayoutIds tests', () => {
224
224
  rows: ['D4']
225
225
  });
226
226
  });
227
+ it('nothing in rows with combination without dimensions', () => {
228
+ const combinations = [{
229
+ id: 'COMB',
230
+ concepts: ['A1', 'A2']
231
+ }];
232
+ const attributes = [
233
+ { id: 'A1', series: true, relationship: ['D1'] },
234
+ { id: 'A2', series: true, relationship: ['D1'] },
235
+ ]
236
+ const dimensions = [
237
+ { id: 'D1' },
238
+ { id: 'D2' },
239
+ ];
240
+ const layoutIds = {
241
+ header: ['D2'],
242
+ sections: ['COMB', 'D1'],
243
+ rows: ['D3']
244
+ };
245
+ expect(getTableLayoutIds(layoutIds, dimensions, attributes, combinations)).to.deep.equal({
246
+ header: ['D2'],
247
+ sections: [],
248
+ rows: ['COMB', 'D1']
249
+ });
250
+ });
227
251
  });
@@ -403,6 +403,109 @@ describe('refineLayoutSize 2 tests', () => {
403
403
  })(layoutIndexes)
404
404
  ).to.deep.equal(expected);
405
405
  });
406
+ it('truncation with OBS_ATTRIBUTES in layout', () => {
407
+ const layout = {
408
+ header: [{ __index: 1 }, { id: 'OBS_ATTRIBUTES' }],
409
+ rows: [{ __index: 0 }],
410
+ sections: [],
411
+ };
412
+
413
+ const layoutIndexes = {
414
+ header: [
415
+ { indexes: [0, 0], parentsIndexes: [[]], missingIndexes: [[]] },
416
+ { indexes: [0, 1], parentsIndexes: [[]], missingIndexes: [[]] },
417
+ { indexes: [1, 0], parentsIndexes: [[]], missingIndexes: [[]] },
418
+ { indexes: [1, 1], parentsIndexes: [[]], missingIndexes: [[]] },
419
+ ],
420
+ sections: [
421
+ [
422
+ { indexes: [] },
423
+ [
424
+ { indexes: [0], parentsIndexes: [[]], missingIndexes: [[]] },
425
+ { indexes: [1], parentsIndexes: [[]], missingIndexes: [[]] },
426
+ { indexes: [2], parentsIndexes: [[]], missingIndexes: [[]] },
427
+ { indexes: [3], parentsIndexes: [[]], missingIndexes: [[]] },
428
+ { indexes: [4], parentsIndexes: [[]], missingIndexes: [[]] },
429
+ { indexes: [5], parentsIndexes: [[]], missingIndexes: [[]] },
430
+ { indexes: [6], parentsIndexes: [[]], missingIndexes: [[]] },
431
+ { indexes: [7], parentsIndexes: [[]], missingIndexes: [[]] },
432
+ { indexes: [8], parentsIndexes: [[]], missingIndexes: [[]] },
433
+ ]
434
+ ]
435
+ ]
436
+ };
437
+
438
+ const observations = {
439
+ '0:0:0': { orderedDimIndexes: [0, 0, 0] },
440
+ '0:0:1': { orderedDimIndexes: [0, 0, 1] },
441
+ '0:1:0': { orderedDimIndexes: [0, 1, 0] },
442
+ '0:1:1': { orderedDimIndexes: [0, 1, 1] },
443
+ '1:0:0': { orderedDimIndexes: [1, 0, 0] },
444
+ '1:0:1': { orderedDimIndexes: [1, 0, 1] },
445
+ '1:1:0': { orderedDimIndexes: [1, 1, 0] },
446
+ '1:1:1': { orderedDimIndexes: [1, 1, 1] },
447
+ '2:0:0': { orderedDimIndexes: [2, 0, 0] },
448
+ '2:0:1': { orderedDimIndexes: [2, 0, 1] },
449
+ '2:1:0': { orderedDimIndexes: [2, 1, 0] },
450
+ '2:1:1': { orderedDimIndexes: [2, 1, 1] },
451
+ '3:0:0': { orderedDimIndexes: [3, 0, 0] },
452
+ '3:0:1': { orderedDimIndexes: [3, 0, 1] },
453
+ '3:1:0': { orderedDimIndexes: [3, 1, 0] },
454
+ '3:1:1': { orderedDimIndexes: [3, 1, 1] },
455
+ '4:0:0': { orderedDimIndexes: [4, 0, 0] },
456
+ '4:0:1': { orderedDimIndexes: [4, 0, 1] },
457
+ '4:1:0': { orderedDimIndexes: [4, 1, 0] },
458
+ '4:1:1': { orderedDimIndexes: [4, 1, 1] },
459
+ '5:0:0': { orderedDimIndexes: [5, 0, 0] },
460
+ '5:0:1': { orderedDimIndexes: [5, 0, 1] },
461
+ '5:1:0': { orderedDimIndexes: [5, 1, 0] },
462
+ '5:1:1': { orderedDimIndexes: [5, 1, 1] },
463
+ '6:0:0': { orderedDimIndexes: [6, 0, 0] },
464
+ '6:0:1': { orderedDimIndexes: [6, 0, 1] },
465
+ '6:1:0': { orderedDimIndexes: [6, 1, 0] },
466
+ '6:1:1': { orderedDimIndexes: [6, 1, 1] },
467
+ '7:0:0': { orderedDimIndexes: [7, 0, 0] },
468
+ '7:0:1': { orderedDimIndexes: [7, 0, 1] },
469
+ '7:1:0': { orderedDimIndexes: [7, 1, 0] },
470
+ '7:1:1': { orderedDimIndexes: [7, 1, 1] },
471
+ '8:0:0': { orderedDimIndexes: [8, 0, 0] },
472
+ '8:0:1': { orderedDimIndexes: [8, 0, 1] },
473
+ '8:1:0': { orderedDimIndexes: [8, 1, 0] },
474
+ '8:1:1': { orderedDimIndexes: [8, 1, 1] },
475
+ };
476
+
477
+ const expected = {
478
+ header: [
479
+ { indexes: [0, 0], parentsIndexes: [[]], missingIndexes: [[]] },
480
+ { indexes: [0, 1], parentsIndexes: [[]], missingIndexes: [[]] },
481
+ { indexes: [1, 0], parentsIndexes: [[]], missingIndexes: [[]] },
482
+ { indexes: [1, 1], parentsIndexes: [[]], missingIndexes: [[]] },
483
+ ],
484
+ sections: [
485
+ [
486
+ { indexes: [] },
487
+ [
488
+ { indexes: [0], parentsIndexes: [[]], missingIndexes: [[]] },
489
+ { indexes: [1], parentsIndexes: [[]], missingIndexes: [[]] },
490
+ { indexes: [2], parentsIndexes: [[]], missingIndexes: [[]] },
491
+ { indexes: [3], parentsIndexes: [[]], missingIndexes: [[]] },
492
+ { indexes: [4], parentsIndexes: [[]], missingIndexes: [[]] },
493
+ { indexes: [5], parentsIndexes: [[]], missingIndexes: [[]] },
494
+ ]
495
+ ]
496
+ ],
497
+ truncated: true,
498
+ totalCells: 70
499
+ };
500
+
501
+ expect(
502
+ refineLayoutSize({
503
+ layout,
504
+ observations,
505
+ limit: 52
506
+ })(layoutIndexes)
507
+ ).to.deep.equal(expected);
508
+ });
406
509
  /*it('no rows', () => {
407
510
 
408
511
  const layout = {