@sis-cc/dotstatsuite-components 14.0.0 → 14.2.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.
Files changed (53) hide show
  1. package/lib/rules/src/preparators/enhanceObservations.js +0 -7
  2. package/lib/rules/src/table/factories/getCells.js +1 -1
  3. package/lib/rules/src/table/factories/getCuratedCells.js +2 -3
  4. package/lib/rules/src/table/factories/getTableData.js +6 -11
  5. package/lib/rules/src/table/preparators/prepareData.js +33 -5
  6. package/lib/rules/src/table/units/getUnitsSeries.js +15 -4
  7. package/lib/rules/src/v8-transformer.js +4 -22
  8. package/lib/rules2/src/duplicateObservations.js +51 -0
  9. package/lib/rules2/src/getDimensionValuesIndexes.js +19 -0
  10. package/lib/rules2/src/getHCodelistsRefsInData.js +46 -0
  11. package/lib/rules2/src/hierarchiseDimensionWithAdvancedHierarchy.js +47 -0
  12. package/lib/rules2/src/hierarchiseDimensionWithNativeHierarchy.js +28 -0
  13. package/lib/rules2/src/index.js +24 -0
  14. package/lib/rules2/src/invertTime.js +33 -0
  15. package/lib/rules2/src/parseHierarchicalCodelist.js +57 -0
  16. package/package.json +1 -1
  17. package/src/rules/src/preparators/enhanceObservations.js +0 -6
  18. package/src/rules/src/table/factories/getCells.js +2 -1
  19. package/src/rules/src/table/factories/getCuratedCells.js +3 -4
  20. package/src/rules/src/table/factories/getTableData.js +3 -22
  21. package/src/rules/src/table/preparators/prepareData.js +23 -3
  22. package/src/rules/src/table/units/getUnitsSeries.js +18 -6
  23. package/src/rules/src/v8-transformer.js +4 -26
  24. package/src/rules2/src/duplicateObservations.js +45 -0
  25. package/src/rules2/src/getDimensionValuesIndexes.js +13 -0
  26. package/src/rules2/src/getHCodelistsRefsInData.js +23 -0
  27. package/src/rules2/src/hierarchiseDimensionWithAdvancedHierarchy.js +44 -0
  28. package/src/rules2/src/hierarchiseDimensionWithNativeHierarchy.js +24 -0
  29. package/src/rules2/src/index.js +2 -0
  30. package/src/rules2/src/invertTime.js +22 -0
  31. package/src/rules2/src/parseHierarchicalCodelist.js +48 -0
  32. package/test/duplicateObservations.test.js +108 -0
  33. package/test/enhanceObservations.test.js +13 -48
  34. package/test/getCells.test.js +4 -11
  35. package/test/getDimensionValuesIndexes.test.js +33 -0
  36. package/test/getHCodelistsRefs.test.js +20 -0
  37. package/test/getUnitsSeries.test.js +112 -47
  38. package/test/hierarchiseDimensionWithAdvancedHierarchy.test.js +87 -0
  39. package/test/hierarchiseDimensionWithNativeHierarchy.test.js +32 -0
  40. package/test/invertTime.test.js +77 -0
  41. package/test/mocks/h-codelist.json +2095 -0
  42. package/test/mocks/table-invert-time--data.json +80211 -0
  43. package/test/mocks/table-invert-time--inverted.json +80076 -0
  44. package/test/mocks/table-prep-multi-duplicate--duplicated.json +26938 -0
  45. package/test/mocks/table-prep-multi-duplicate--indexes.json +1417 -0
  46. package/test/mocks/table-prep-multi-duplicate--observations.json +20330 -0
  47. package/test/mocks/table-prep-simple-duplicate--duplicated.json +77502 -0
  48. package/test/mocks/table-prep-simple-duplicate--indexes.json +274 -0
  49. package/test/mocks/table-prep-simple-duplicate--observations.json +60002 -0
  50. package/test/parseHierarchicalCodelist.test.js +140 -0
  51. package/test/table-invert-time-perf.test.js +11 -0
  52. package/test/table-prep-duplicate-perf.test.js +21 -0
  53. package/test/table-prep-perf.test.js +5 -2
@@ -1,5 +1,4 @@
1
1
  import * as R from 'ramda';
2
- import { withFlatHierarchy, isTimePeriodDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
2
  import { getCells } from './getCells';
4
3
  import { getConfirmedSeriesAttributesIds } from './getConfirmedSeriesAttributesIds';
5
4
  import { getCuratedCells } from './getCuratedCells';
@@ -14,6 +13,7 @@ import { getSortedLayoutIndexes } from './getSortedLayoutIndexes';
14
13
  import { refineLayoutSize } from './refineLayoutSize';
15
14
  import { getLayoutData } from './getLayoutData';
16
15
  import { refineMetadataCoordinates } from '../../../../rules2/src/refineMetadataCoordinates';
16
+ import { invertTime } from '../../../../rules2/src/invertTime';
17
17
 
18
18
  export const getTableProps = ({ data, layoutIds, display, customAttributes, limit, isTimeInverted }) => {
19
19
  const seriesAttributes = R.propOr({}, 'seriesAttributes', data);
@@ -56,26 +56,7 @@ export const getTableProps = ({ data, layoutIds, display, customAttributes, limi
56
56
  data.observationsType,
57
57
  );
58
58
 
59
- const dimensions = R.mapObjIndexed(
60
- R.pipe(
61
- R.when( // invert TimeDimension Values
62
- R.allPass([isTimePeriodDimension, R.always(isTimeInverted)]),
63
- (dim) => R.over(
64
- R.lensProp('values'),
65
- R.map(R.over(R.lensProp('__indexPosition'), R.negate))
66
- )(dim),
67
- ),
68
- (dim) => R.over( // sort values
69
- R.lensProp('values'),
70
- R.sortWith([R.ascend(R.prop('__indexPosition')), R.ascend(R.prop('order'))]),
71
- )(dim),
72
- R.when( // refine hierarchy on rows
73
- R.pipe(R.prop('id'), R.flip(R.includes)(R.propOr([], 'rows', layoutIds))),
74
- withFlatHierarchy
75
- )
76
- ),
77
- R.pathOr({}, ['dimensions', 'many'], data)
78
- );
59
+ const { dimensions, observations } = invertTime(data, isTimeInverted);
79
60
 
80
61
  const seriesAttributesValues = R.propOr({}, 'seriesAttributesValues', data);
81
62
  const layout = R.pipe(
@@ -99,7 +80,7 @@ export const getTableProps = ({ data, layoutIds, display, customAttributes, limi
99
80
  }),
100
81
  getLayoutDataWithFlags(seriesAttributesValues, display, customAttributes, refinedMetadataCoordinates, unitDimension.id),
101
82
  cleanUnitsInLayoutData({ unitsDisplay: unitsLevelDisplay, unitsLayoutIndexes: unitsIndexesInLayout }),
102
- )(layout, R.propOr({}, 'observations', data));
83
+ )(layout, observations);
103
84
 
104
85
  return ({
105
86
  cells: getCuratedCells({ layout, observations: cells, shape: ['header', 'sections', 'rows'] }),
@@ -24,8 +24,12 @@ import {
24
24
  getObservationsAdvancedAttributes,
25
25
  getSeriesAdvancedAttributes
26
26
  } from '../../../../rules2/src/getAdvancedAttributes';
27
+ import { duplicateObservations } from '../../../../rules2/src/duplicateObservations';
28
+ import { hierarchiseDimensionWithAdvancedHierarchy } from '../../../../rules2/src/hierarchiseDimensionWithAdvancedHierarchy';
29
+ import { hierarchiseDimensionWithNativeHierarchy } from '../../../../rules2/src/hierarchiseDimensionWithNativeHierarchy';
30
+ import { getDimensionValuesIndexes } from '../../../../rules2/src/getDimensionValuesIndexes';
27
31
 
28
- export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
32
+ export const prepareData = (sdmxJson, customAttributes, unitsProps={}, _options={}) => {
29
33
  const {
30
34
  defaultCodes=[],
31
35
  annotationsDefinitionCodes={},
@@ -37,6 +41,7 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
37
41
  const _customAttributes = R.assoc('units', unitsDefinitionCodes, customAttributes);
38
42
  const dimensions = R.pathOr([], ['data', 'structure', 'dimensions', 'observation'], sdmxJson);
39
43
 
44
+ const hierarchies = _options.hierarchies || {};
40
45
  const dimensionsIndexedByIds = R.indexBy(R.prop('id'), dimensions);
41
46
 
42
47
  const parsedDimensionsIds = parseDimensionsIds(dimensions);
@@ -160,10 +165,25 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
160
165
  seriesAdvancedAttributesIds
161
166
  );
162
167
 
168
+ const hierarchisedDimensions = R.map(dim => {
169
+ if (R.isEmpty(R.propOr({}, dim.id, hierarchies))) {
170
+ return hierarchiseDimensionWithNativeHierarchy(dim);
171
+ }
172
+ return hierarchiseDimensionWithAdvancedHierarchy(dim, R.prop(dim.id, hierarchies));
173
+ })(manyValuesDimensions);
174
+
175
+ const valuesIndexes = R.reduce(
176
+ (acc, dim) => ({ ...acc, [dim.__index]: getDimensionValuesIndexes(dim.values) }),
177
+ {},
178
+ R.values(hierarchisedDimensions)
179
+ );
180
+
181
+ const duplicatedObservations = duplicateObservations(observations, valuesIndexes);
182
+
163
183
  return ({
164
184
  dimensions: {
165
185
  one: oneValueDimensions,
166
- many: manyValuesDimensions,
186
+ many: hierarchisedDimensions,
167
187
  length: R.length(dimensions)
168
188
  },
169
189
  units: {
@@ -175,7 +195,7 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
175
195
  },
176
196
  metadataCoordinates,
177
197
  advancedAttributes: { ...dataflowAdvancedAttributes, ...observationsAdvancedAttributes, ...seriesAdvancedAttributes },
178
- observations,
198
+ observations: duplicatedObservations,
179
199
  observationsType: getObservationsType(sdmxJson.data),
180
200
  dataflowAttributes,
181
201
  dataflowName: R.path(['data', 'structure', 'name'], sdmxJson),
@@ -4,17 +4,29 @@ import * as R from 'ramda';
4
4
  observations = { [obsKey]: { units: { serieKey: '', [id]: { id, name, value } } } };
5
5
  */
6
6
 
7
+ const getIndex = R.path(['value', 'index']);
8
+ const getUnits = (keys, acc, units) => R.pick(keys, R.mergeWith((a, b) => getIndex(a) === getIndex(b) ? a : null, acc, units))
9
+
7
10
  export const getUnitsSeries = (observations) => {
8
11
  let series = {};
9
12
  R.map(obs => {
10
- series = R.over(R.lensProp(obs.units.serieKey), R.ifElse(R.isNil, R.always([obs.units]), R.append(obs.units)))(series);
13
+ series = R.over(
14
+ R.lensProp(obs.units.serieKey),
15
+ R.ifElse(R.isNil, R.always([obs.units]), R.append(obs.units))
16
+ )(series);
11
17
  }, observations);
12
18
 
13
19
  return R.map(
14
20
  serie => R.reduce(
15
- (acc, units) => R.mergeWith((a, b) => R.path(['value', 'index'], a) === R.path(['value', 'index'], b) ? a : null, acc, units),
16
- {},
17
- serie
18
- )
21
+ (acc, units) => {
22
+ const unitsKeys = R.keys(units);
23
+ if (R.isEmpty(acc.unitsKeys)) return { units: getUnits(unitsKeys, acc.units, units), unitsKeys }
24
+ const communKeys = R.intersection(acc.unitsKeys, unitsKeys);
25
+ return {
26
+ units: getUnits(communKeys, acc.units, units),
27
+ unitsKeys
28
+ }
29
+ ;
30
+ }, { unitsKeys: [], units: {} }, serie).units
19
31
  )(series);
20
- };
32
+ };
@@ -81,7 +81,9 @@ export const dataTransformer = (dataNew, options = {}) => {
81
81
  R.ascend(R.prop('__indexPosition')),
82
82
  R.ascend(R.propOr(-1, 'order'))
83
83
  ]),
84
- R.addIndex(R.map)((val, index) => R.assoc('__indexPosition', index, val))
84
+ R.addIndex(R.map)((val, index) => R.assoc('__indexPosition', index, val)),
85
+ /* NEW */
86
+ R.sortBy(R.prop('__index'))
85
87
  );
86
88
 
87
89
  //--------------------------------------------------------------------------------------------Header
@@ -147,30 +149,6 @@ export const dataTransformer = (dataNew, options = {}) => {
147
149
  const isHidden = R.has(id, hiddenIds) || getIsHidden(dimAnnotations);
148
150
  const isTime = observation.id === timePeriodId;
149
151
  const values = getValuesEnhanced(locale, annotations, isTime, id)(R.propOr([],'values', observation));
150
- const ids = R.pipe(R.pluck('id'), R.indexBy(R.identity))(values);
151
- const groupedByParentsValues = R.groupBy(val => {
152
- const parentId = R.propOr('##ROOT', 'parent', val);
153
- if (parentId !== '##ROOT' && !R.has(parentId, ids)) {
154
- return '##ROOT';
155
- }
156
- return parentId;
157
- }, values);
158
- const sortedGroupedValues = R.mapObjIndexed(
159
- R.sortWith([R.ascend(R.prop('__indexPosition')), R.ascend(R.prop('__index'))]),
160
- groupedByParentsValues
161
- );
162
-
163
- const getReccursiveChildren = (parent) => {
164
- const children = R.propOr([], parent, sortedGroupedValues);
165
- return R.map(child => R.prepend(child, getReccursiveChildren(child.id)), children);
166
- };
167
-
168
- const sortedValues = R.pipe(
169
- getReccursiveChildren,
170
- R.flatten,
171
- R.addIndex(R.map)((value, index) => R.assoc('__indexPosition', index, value)),
172
- R.sortBy(R.prop('__index'))
173
- )('##ROOT');
174
152
 
175
153
  return ({
176
154
  observation: R.append({
@@ -178,7 +156,7 @@ export const dataTransformer = (dataNew, options = {}) => {
178
156
  display: !isHidden,
179
157
  __index: obsIndex,
180
158
  name: getRefinedName(observation),
181
- values: sortedValues,
159
+ values,
182
160
  role: isTime ? TIME_PERIOD_ID : R.head(R.propOr([], 'roles', observation)),
183
161
  })(acc.observation),
184
162
  dimensionsLayout: setAnnotationsLayout(id, acc.dimensionsLayout)(dimAnnotations),
@@ -0,0 +1,45 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const duplicateObservations = (observations, indexes) => {
4
+ return R.addIndex(R.reduce)(
5
+ (acc, obs, i) => {
6
+
7
+ const orderedIndexes = R.addIndex(R.map)(
8
+ (valueIndex, dimIndex) => R.pathOr([Number(valueIndex)], [dimIndex, valueIndex], indexes),
9
+ R.propOr([], 'dimValuesIndexes', obs)
10
+ );
11
+
12
+ let cartesian;
13
+
14
+ if (R.any(is => R.length(is) > 1)(orderedIndexes)) {
15
+ cartesian = R.reduce(
16
+ (acc, oInds) => {
17
+ const r = R.map(
18
+ i => R.map(is => R.append(i, is), acc),
19
+ oInds
20
+ );
21
+ return R.unnest(r);
22
+ },
23
+ R.pipe(R.head, R.map(R.of))(orderedIndexes),
24
+ R.tail(orderedIndexes)
25
+ );
26
+ }
27
+ else {
28
+ cartesian = [R.unnest(orderedIndexes)];
29
+ }
30
+
31
+ const duplicatedObs = R.reduce(
32
+ (acc, orderedDimIndexes) => {
33
+ const key = R.join(':', orderedDimIndexes);
34
+ return R.assoc(key, { ...obs, orderedDimIndexes }, acc);
35
+ },
36
+ {},
37
+ cartesian
38
+ );
39
+
40
+ return R.mergeRight(acc, duplicatedObs);
41
+ },
42
+ {},
43
+ R.values(observations)
44
+ )
45
+ };
@@ -0,0 +1,13 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getDimensionValuesIndexes = (values) => R.addIndex(R.reduce)(
4
+ (acc, value, position) => {
5
+ const sdmxIndex = value.__index;
6
+ return R.over(
7
+ R.lensProp(String(sdmxIndex)),
8
+ R.ifElse(R.isNil, R.always([position]), R.append(position))
9
+ )(acc);
10
+ },
11
+ {},
12
+ values
13
+ );
@@ -0,0 +1,23 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getHCodelistsRefs = annotations => R.reduce(
4
+ (acc, annotation) => {
5
+ if (annotation.type !== 'HIER_CONTEXT') {
6
+ return acc;
7
+ }
8
+ const reference = annotation.text || annotation.title || '';
9
+ const match = reference.match(/([\w@_.]+):([\w@_.]+):([\w@_.]+)\(([\d.]+)\).([\w@_.]+)$/);
10
+ if (R.isNil(match)) {
11
+ return acc;
12
+ }
13
+ const [codelistId, agencyId, code, version, hierarchy] = R.tail(match);
14
+ return R.assoc(codelistId, { agencyId, code, version, hierarchy, codelistId }, acc);
15
+ },
16
+ {},
17
+ annotations,
18
+ );
19
+
20
+ export const getHCodelistsRefsInData = sdmxJson => {
21
+ const annotations = R.pathOr([], ['data', 'structure', 'annotations'], sdmxJson);
22
+ return getHCodelistsRefs(annotations);
23
+ };
@@ -0,0 +1,44 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const hierarchiseDimensionWithAdvancedHierarchy = (dimension, hierarchy) => {
4
+ const indexed = R.indexBy(R.prop('id'), dimension.values);
5
+
6
+ let rest = indexed;
7
+ const getChildren = (parents) => R.pipe(
8
+ ids => {
9
+ rest = R.omit(ids, rest);
10
+ return R.props(ids, indexed)
11
+ },
12
+ R.filter(R.identity),
13
+ R.map(
14
+ (val) => {
15
+ const _val = {
16
+ ...val,
17
+ parent: R.last(parents),
18
+ parents
19
+ };
20
+ const children = getChildren(R.append(val.id, parents));
21
+ return R.prepend(_val, children);
22
+ },
23
+ )
24
+ )(R.propOr([], R.isEmpty(parents) ? '#ROOT' : R.join('.', parents), hierarchy));
25
+
26
+ return R.set(
27
+ R.lensProp('values'),
28
+ R.pipe(
29
+ getChildren,
30
+ R.flatten,
31
+ values => {
32
+ if (R.isEmpty(rest)) {
33
+ return values;
34
+ }
35
+ const sortedRest = R.pipe(
36
+ R.values,
37
+ R.map(val => ({ ...val, parent: undefined, parents: [] })),
38
+ R.sortBy(R.prop('__indexPosition'))
39
+ )(rest);
40
+ return R.concat(sortedRest, values);
41
+ }
42
+ )([])
43
+ )(dimension);
44
+ };
@@ -0,0 +1,24 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const hierarchiseDimensionWithNativeHierarchy = (dimension) => {
4
+ const values = R.sortBy(R.prop('__indexPosition'), dimension.values || []);
5
+ const grouped = R.groupBy(R.propOr('#ROOT', 'parent'), values);
6
+
7
+ const getChildren = (parents) => {
8
+ const childs = R.propOr([], R.last(parents) || '#ROOT', grouped);
9
+ return R.reduce(
10
+ (acc, child) => {
11
+ const refined = R.assoc('parents', parents, child);
12
+ const children = getChildren(R.append(child.id, parents));
13
+ return R.concat(acc, R.prepend(refined, children));
14
+ },
15
+ [],
16
+ childs
17
+ );
18
+ }
19
+
20
+ return R.set(
21
+ R.lensProp('values'),
22
+ getChildren([])
23
+ )(dimension);
24
+ };
@@ -9,3 +9,5 @@ export { sdmx_3_0_DataFormatPatch } from './sdmx3.0DataFormatPatch';
9
9
  export { getDataflowTooltipAttributesIds } from './getDataflowTooltipAttributesIds';
10
10
  export { getMSDInformations } from './getMSDInformations';
11
11
  export { getNotDisplayedIds } from './getNotDisplayedIds';
12
+ export { getHCodelistsRefs, getHCodelistsRefsInData } from './getHCodelistsRefsInData';
13
+ export { parseHierarchicalCodelist } from './parseHierarchicalCodelist';
@@ -0,0 +1,22 @@
1
+ import * as R from 'ramda';
2
+ import { isTimePeriodDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
+
4
+ export const invertTime = (data, isTimeInverted) => {
5
+ const dimensions = R.pathOr([], ['dimensions', 'many'], data);
6
+ const observations = R.propOr({}, 'observations', data);
7
+ if (!isTimeInverted) {
8
+ return ({ dimensions, observations });
9
+ }
10
+ const timeD = R.find(isTimePeriodDimension, R.values(dimensions));
11
+ if (!timeD) {
12
+ return ({ dimensions, observations });
13
+ }
14
+ const timeLength = R.length(timeD.values);
15
+ const timeIndex = timeD.__index;
16
+ const invertTimeInObs = R.map(
17
+ R.over(R.lensProp('orderedDimIndexes'), R.over(R.lensIndex(timeIndex), i => timeLength - i - 1)),
18
+ observations
19
+ );
20
+ const invertedTimeInDims = R.over(R.lensProp(timeD.id), R.over(R.lensProp('values'), R.reverse))(dimensions);
21
+ return ({ dimensions: invertedTimeInDims, observations: invertTimeInObs });
22
+ };
@@ -0,0 +1,48 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const parseHierarchicalCodelist = (sdmxJson, hierarchyId) => {
4
+ const hCodelist = R.pathOr({}, ['data', 'hierarchicalCodelists', 0], sdmxJson);
5
+ const hierarchy = R.find(R.propEq('id', hierarchyId), hCodelist.hierarchies || []);
6
+
7
+ const getParentedCodes = (codes, parent) => {
8
+ const ids = R.pluck('codeID', codes);
9
+
10
+ const siblings = R.reduce(
11
+ (acc, code) => {
12
+ if (R.isEmpty(code.hierarchicalCodes || [])) {
13
+ return acc;
14
+ }
15
+ return R.mergeRight(acc, getParentedCodes(code.hierarchicalCodes, code.id));
16
+ },
17
+ {},
18
+ codes
19
+ );
20
+
21
+ return ({ ...siblings, [parent]: ids });
22
+ };
23
+
24
+ const getChildren = (codes, parents) => {
25
+ const ids = R.pluck('codeID', codes);
26
+
27
+ const children = R.reduce(
28
+ (acc, code) => {
29
+ if (R.isEmpty(code.hierarchicalCodes || [])) {
30
+ return acc;
31
+ }
32
+ return ({
33
+ ...acc,
34
+ ...getChildren(code.hierarchicalCodes, R.append(code.codeID, parents))
35
+ });
36
+ },
37
+ {},
38
+ codes
39
+ );
40
+ const key = R.isEmpty(parents) ? '#ROOT' : R.join('.', parents);
41
+ return ({ ...children, [key]: ids });
42
+ }
43
+
44
+ return R.pipe(
45
+ R.propOr([], 'hierarchicalCodes'),
46
+ codes => getChildren(codes, []),
47
+ )(hierarchy);
48
+ };
@@ -0,0 +1,108 @@
1
+ import { expect } from 'chai';
2
+ import { duplicateObservations } from '../src/rules2/src/duplicateObservations';
3
+
4
+ describe('duplicateObservations tests', () => {
5
+ it('simple case', () => {
6
+ const observations = {
7
+ '0:0:0': { dimValuesIndexes: [0, 0, 0] },
8
+ '0:0:1': { dimValuesIndexes: [0, 0, 1] },
9
+ '0:0:2': { dimValuesIndexes: [0, 0, 2] },
10
+ '1:0:0': { dimValuesIndexes: [1, 0, 0] },
11
+ '1:0:1': { dimValuesIndexes: [1, 0, 1] },
12
+ '1:0:2': { dimValuesIndexes: [1, 0, 2] },
13
+ };
14
+
15
+ const indexes = {
16
+ '0': {
17
+ '0': [0],
18
+ '1': [1]
19
+ },
20
+ '2': {
21
+ '0': [4],
22
+ '1': [0, 2],
23
+ '2': [1, 3]
24
+ }
25
+ };
26
+
27
+ const expected = {
28
+ '0:0:0': { dimValuesIndexes: [0, 0, 1], orderedDimIndexes: [0, 0, 0] },
29
+ '0:0:1': { dimValuesIndexes: [0, 0, 2], orderedDimIndexes: [0, 0, 1] },
30
+ '0:0:2': { dimValuesIndexes: [0, 0, 1], orderedDimIndexes: [0, 0, 2] },
31
+ '0:0:3': { dimValuesIndexes: [0, 0, 2], orderedDimIndexes: [0, 0, 3] },
32
+ '0:0:4': { dimValuesIndexes: [0, 0, 0], orderedDimIndexes: [0, 0, 4] },
33
+ '1:0:0': { dimValuesIndexes: [1, 0, 1], orderedDimIndexes: [1, 0, 0] },
34
+ '1:0:1': { dimValuesIndexes: [1, 0, 2], orderedDimIndexes: [1, 0, 1] },
35
+ '1:0:2': { dimValuesIndexes: [1, 0, 1], orderedDimIndexes: [1, 0, 2] },
36
+ '1:0:3': { dimValuesIndexes: [1, 0, 2], orderedDimIndexes: [1, 0, 3] },
37
+ '1:0:4': { dimValuesIndexes: [1, 0, 0], orderedDimIndexes: [1, 0, 4] },
38
+ };
39
+
40
+ expect(duplicateObservations(observations, indexes)).to.deep.equal(expected);
41
+ });
42
+ it('complex cartesian duplicate test', () => {
43
+ const observations = {
44
+ '0:0:0:0': { dimValuesIndexes: [0, 0, 0, 0] },
45
+ '0:0:0:1': { dimValuesIndexes: [0, 0, 0, 1] },
46
+ };
47
+
48
+ const indexes = {
49
+ '0': { '0': [1, 5] },
50
+ '1': { '0': [0, 4, 6] },
51
+ '2': { '0': [8, 9] },
52
+ '3': { '0': [3, 7], '1': [0, 13] },
53
+ };
54
+
55
+ const expected = {
56
+ '1:0:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 0, 8, 3] },
57
+ '1:0:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 0, 8, 7] },
58
+ '1:0:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 0, 9, 3] },
59
+ '1:0:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 0, 9, 7] },
60
+ '1:4:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 4, 8, 3] },
61
+ '1:4:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 4, 8, 7] },
62
+ '1:4:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 4, 9, 3] },
63
+ '1:4:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 4, 9, 7] },
64
+ '1:6:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 6, 8, 3] },
65
+ '1:6:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 6, 8, 7] },
66
+ '1:6:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 6, 9, 3] },
67
+ '1:6:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [1, 6, 9, 7] },
68
+ '5:0:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 0, 8, 3] },
69
+ '5:0:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 0, 8, 7] },
70
+ '5:0:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 0, 9, 3] },
71
+ '5:0:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 0, 9, 7] },
72
+ '5:4:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 4, 8, 3] },
73
+ '5:4:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 4, 8, 7] },
74
+ '5:4:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 4, 9, 3] },
75
+ '5:4:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 4, 9, 7] },
76
+ '5:6:8:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 6, 8, 3] },
77
+ '5:6:8:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 6, 8, 7] },
78
+ '5:6:9:3': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 6, 9, 3] },
79
+ '5:6:9:7': { dimValuesIndexes: [0, 0, 0, 0], orderedDimIndexes: [5, 6, 9, 7] },
80
+ '1:0:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 0, 8, 0] },
81
+ '1:0:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 0, 8, 13] },
82
+ '1:0:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 0, 9, 0] },
83
+ '1:0:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 0, 9, 13] },
84
+ '1:4:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 4, 8, 0] },
85
+ '1:4:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 4, 8, 13] },
86
+ '1:4:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 4, 9, 0] },
87
+ '1:4:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 4, 9, 13] },
88
+ '1:6:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 6, 8, 0] },
89
+ '1:6:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 6, 8, 13] },
90
+ '1:6:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 6, 9, 0] },
91
+ '1:6:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [1, 6, 9, 13] },
92
+ '5:0:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 0, 8, 0] },
93
+ '5:0:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 0, 8, 13] },
94
+ '5:0:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 0, 9, 0] },
95
+ '5:0:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 0, 9, 13] },
96
+ '5:4:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 4, 8, 0] },
97
+ '5:4:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 4, 8, 13] },
98
+ '5:4:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 4, 9, 0] },
99
+ '5:4:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 4, 9, 13] },
100
+ '5:6:8:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 6, 8, 0] },
101
+ '5:6:8:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 6, 8, 13] },
102
+ '5:6:9:0': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 6, 9, 0] },
103
+ '5:6:9:13': { dimValuesIndexes: [0, 0, 0, 1], orderedDimIndexes: [5, 6, 9, 13] }
104
+ };
105
+
106
+ expect(duplicateObservations(observations, indexes)).to.deep.equal(expected);
107
+ });
108
+ });
@@ -7,36 +7,6 @@ describe('enhanceObservations tests', () => {
7
7
  it('blank test', () => {
8
8
  expect(enhanceObservations([], {}, [], {})).to.deep.equal({});
9
9
  });
10
- it('orderedDimIndexes test', () => {
11
- const dimensions = [
12
- { id: 'D1', values: [{ id: 'v1', __indexPosition: 2 }, { id: 'v2', __indexPosition: 0 }, { id: 'v3', __indexPosition: 1 }] },
13
- { id: 'D2', values: [{ id: 'v1', __indexPosition: 1 }, { id: 'v2', __indexPosition: 2 }, { id: 'v3', __indexPosition: 0 }] },
14
- { id: 'D3', values: [{ id: 'v1', __indexPosition: 0 }] }
15
- ];
16
- const observations = {
17
- a: { dimValuesIndexes: [0, 0, 0], value: '1' },
18
- b: { dimValuesIndexes: [0, 1, 0], value: '2' },
19
- c: { dimValuesIndexes: [0, 2, 0], value: '3' },
20
- d: { dimValuesIndexes: [1, 0, 0], value: '4' },
21
- e: { dimValuesIndexes: [1, 1, 0], value: '5' },
22
- f: { dimValuesIndexes: [1, 2, 0], value: '6' },
23
- g: { dimValuesIndexes: [2, 0, 0], value: '7' },
24
- h: { dimValuesIndexes: [2, 1, 0], value: '8' },
25
- i: { dimValuesIndexes: [2, 2, 0], value: '9' }
26
- };
27
- expect(enhanceObservations(dimensions, observations, [], {})).to.deep.equal({
28
- a: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [0, 0, 0], orderedDimIndexes: [2, 1, 0], value: '1', formattedValue: '1', indexedDimValIds: { D1: 'v1', D2: 'v1', D3: 'v1' } },
29
- b: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [0, 1, 0], orderedDimIndexes: [2, 2, 0], value: '2', formattedValue: '2', indexedDimValIds: { D1: 'v1', D2: 'v2', D3: 'v1' } },
30
- c: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [0, 2, 0], orderedDimIndexes: [2, 0, 0], value: '3', formattedValue: '3', indexedDimValIds: { D1: 'v1', D2: 'v3', D3: 'v1' } },
31
- d: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [1, 0, 0], orderedDimIndexes: [0, 1, 0], value: '4', formattedValue: '4', indexedDimValIds: { D1: 'v2', D2: 'v1', D3: 'v1' } },
32
- e: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [1, 1, 0], orderedDimIndexes: [0, 2, 0], value: '5', formattedValue: '5', indexedDimValIds: { D1: 'v2', D2: 'v2', D3: 'v1' } },
33
- f: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [1, 2, 0], orderedDimIndexes: [0, 0, 0], value: '6', formattedValue: '6', indexedDimValIds: { D1: 'v2', D2: 'v3', D3: 'v1' } },
34
- g: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [2, 0, 0], orderedDimIndexes: [1, 1, 0], value: '7', formattedValue: '7', indexedDimValIds: { D1: 'v3', D2: 'v1', D3: 'v1' } },
35
- h: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [2, 1, 0], orderedDimIndexes: [1, 2, 0], value: '8', formattedValue: '8', indexedDimValIds: { D1: 'v3', D2: 'v2', D3: 'v1' } },
36
- i: { attributes: {}, units: { serieKey: 'x:x:x' }, dimValuesIndexes: [2, 2, 0], orderedDimIndexes: [1, 0, 0], value: '9', formattedValue: '9', indexedDimValIds: { D1: 'v3', D2: 'v3', D3: 'v1' } }
37
- });
38
- });
39
-
40
10
  it('formatValue test', () => {
41
11
  numeral.locale('eObs');
42
12
  const attributes = [
@@ -64,19 +34,19 @@ describe('enhanceObservations tests', () => {
64
34
  };
65
35
 
66
36
  expect(enhanceObservations([], observations, attributes, { customAttributes })).to.deep.equal({
67
- a: { attributes: {}, units: { serieKey: '' }, value: 2, formattedValue: '2', attrValuesIndexes: [null, null, null], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
68
- c: { attributes: {}, units: { serieKey: '' }, value: 10, formattedValue: '10', attrValuesIndexes: [null, 4, null], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
69
- d: { attributes: {}, units: { serieKey: '' }, value: 5, formattedValue: '5', attrValuesIndexes: [null, 1, null], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
70
- e: { attributes: {}, units: { serieKey: '' }, value: 8.3, formattedValue: '83', attrValuesIndexes: [null, 0, null], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
71
- f: { attributes: {}, units: { serieKey: '' }, value: 25.62, formattedValue: '0.02562', attrValuesIndexes: [null, 3, null], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
72
- g: { attributes: {}, units: { serieKey: '' }, value: 3.7, formattedValue: '3.7', attrValuesIndexes: [null, null, 4], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
73
- h: { attributes: {}, units: { serieKey: '' }, value: 21.1234567, formattedValue: '21.123', attrValuesIndexes: [null, null, 2], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
74
- i: { attributes: {}, units: { serieKey: '' }, value: 20.1, formattedValue: '20.10000', attrValuesIndexes: [null, null, 3], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
75
- j: { attributes: {}, units: { serieKey: '' }, value: 19.9, formattedValue: '20', attrValuesIndexes: [null, null, 0], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
76
- k: { attributes: {}, units: { serieKey: '' }, value: 16.35, formattedValue: '1.64', attrValuesIndexes: [null, 2, 1], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
77
- l: { attributes: {}, units: { serieKey: '' }, value: 155062.56, formattedValue: '155,062.560', attrValuesIndexes: [null, null, 2], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
78
- m: { attributes: {}, units: { serieKey: '' }, value: 155062.56, formattedValue: '155,063', attrValuesIndexes: [null, null, 0], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
79
- n: { attributes: {}, units: { serieKey: '' }, value: null, formattedValue: '..', attrValuesIndexes: [null, null, 1], dimValuesIndexes: [], orderedDimIndexes: [], indexedDimValIds: {} },
37
+ a: { attributes: {}, units: { serieKey: '' }, value: 2, formattedValue: '2', attrValuesIndexes: [null, null, null], dimValuesIndexes: [], indexedDimValIds: {} },
38
+ c: { attributes: {}, units: { serieKey: '' }, value: 10, formattedValue: '10', attrValuesIndexes: [null, 4, null], dimValuesIndexes: [], indexedDimValIds: {} },
39
+ d: { attributes: {}, units: { serieKey: '' }, value: 5, formattedValue: '5', attrValuesIndexes: [null, 1, null], dimValuesIndexes: [], indexedDimValIds: {} },
40
+ e: { attributes: {}, units: { serieKey: '' }, value: 8.3, formattedValue: '83', attrValuesIndexes: [null, 0, null], dimValuesIndexes: [], indexedDimValIds: {} },
41
+ f: { attributes: {}, units: { serieKey: '' }, value: 25.62, formattedValue: '0.02562', attrValuesIndexes: [null, 3, null], dimValuesIndexes: [], indexedDimValIds: {} },
42
+ g: { attributes: {}, units: { serieKey: '' }, value: 3.7, formattedValue: '3.7', attrValuesIndexes: [null, null, 4], dimValuesIndexes: [], indexedDimValIds: {} },
43
+ h: { attributes: {}, units: { serieKey: '' }, value: 21.1234567, formattedValue: '21.123', attrValuesIndexes: [null, null, 2], dimValuesIndexes: [], indexedDimValIds: {} },
44
+ i: { attributes: {}, units: { serieKey: '' }, value: 20.1, formattedValue: '20.10000', attrValuesIndexes: [null, null, 3], dimValuesIndexes: [], indexedDimValIds: {} },
45
+ j: { attributes: {}, units: { serieKey: '' }, value: 19.9, formattedValue: '20', attrValuesIndexes: [null, null, 0], dimValuesIndexes: [], indexedDimValIds: {} },
46
+ k: { attributes: {}, units: { serieKey: '' }, value: 16.35, formattedValue: '1.64', attrValuesIndexes: [null, 2, 1], dimValuesIndexes: [], indexedDimValIds: {} },
47
+ l: { attributes: {}, units: { serieKey: '' }, value: 155062.56, formattedValue: '155,062.560', attrValuesIndexes: [null, null, 2], dimValuesIndexes: [], indexedDimValIds: {} },
48
+ m: { attributes: {}, units: { serieKey: '' }, value: 155062.56, formattedValue: '155,063', attrValuesIndexes: [null, null, 0], dimValuesIndexes: [], indexedDimValIds: {} },
49
+ n: { attributes: {}, units: { serieKey: '' }, value: null, formattedValue: '..', attrValuesIndexes: [null, null, 1], dimValuesIndexes: [], indexedDimValIds: {} },
80
50
  });
81
51
  });
82
52
 
@@ -189,7 +159,6 @@ describe('enhanceObservations tests', () => {
189
159
  a: {
190
160
  attrValuesIndexes: [0, 0, 0, 0, 0],
191
161
  dimValuesIndexes: [0, 0, 0, 0, 0],
192
- orderedDimIndexes: [0, 0, 0, 0, 0],
193
162
  value: 22,
194
163
  formattedValue: '22',
195
164
  units: {
@@ -206,7 +175,6 @@ describe('enhanceObservations tests', () => {
206
175
  b: {
207
176
  attrValuesIndexes: [1, 0, 1, 1, 0],
208
177
  dimValuesIndexes: [0, 0, 0, 1, 0],
209
- orderedDimIndexes: [0, 0, 0, 1, 0],
210
178
  value: 17,
211
179
  formattedValue: '17',
212
180
  units: {
@@ -223,7 +191,6 @@ describe('enhanceObservations tests', () => {
223
191
  c: {
224
192
  attrValuesIndexes: [2, 0, null, null, 0],
225
193
  dimValuesIndexes: [1, 0, 0, 0, 0],
226
- orderedDimIndexes: [1, 0, 0, 0, 0],
227
194
  value: 55,
228
195
  formattedValue: '55',
229
196
  units: {
@@ -240,7 +207,6 @@ describe('enhanceObservations tests', () => {
240
207
  d: {
241
208
  attrValuesIndexes: [2, 0, null, null, 1],
242
209
  dimValuesIndexes: [2, 0, 0, 0, 0],
243
- orderedDimIndexes: [2, 0, 0, 0, 0],
244
210
  value: 35,
245
211
  formattedValue: '35',
246
212
  units: {
@@ -256,7 +222,6 @@ describe('enhanceObservations tests', () => {
256
222
  e: {
257
223
  attrValuesIndexes: [2, null, null, null, null],
258
224
  dimValuesIndexes: [3, 0, 0, 0, 0],
259
- orderedDimIndexes: [3, 0, 0, 0, 0],
260
225
  value: 35,
261
226
  formattedValue: '35',
262
227
  units: { serieKey: 'x:x:x:x:x' },