@sis-cc/dotstatsuite-components 13.5.5 → 14.1.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 (52) 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/factories/refineLayoutSize.js +1 -1
  6. package/lib/rules/src/table/preparators/prepareData.js +30 -5
  7. package/lib/rules/src/v8-transformer.js +10 -25
  8. package/lib/rules2/src/duplicateObservations.js +51 -0
  9. package/lib/rules2/src/getDimensionValuesIndexes.js +19 -0
  10. package/lib/rules2/src/getDimensionsSimpleHierarchies.js +42 -0
  11. package/lib/rules2/src/getHCodelistsRefsInData.js +46 -0
  12. package/lib/rules2/src/hierarchiseDimension.js +47 -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 +22 -0
  16. package/package.json +2 -2
  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/factories/refineLayoutSize.js +1 -1
  22. package/src/rules/src/table/preparators/prepareData.js +20 -3
  23. package/src/rules/src/v8-transformer.js +11 -30
  24. package/src/rules2/src/duplicateObservations.js +45 -0
  25. package/src/rules2/src/getDimensionValuesIndexes.js +13 -0
  26. package/src/rules2/src/getDimensionsSimpleHierarchies.js +34 -0
  27. package/src/rules2/src/getHCodelistsRefsInData.js +23 -0
  28. package/src/rules2/src/hierarchiseDimension.js +38 -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 +14 -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/hierarchiseDimension.test.js +87 -0
  38. package/test/invertTime.test.js +75 -0
  39. package/test/mocks/h-codelist.json +2095 -0
  40. package/test/mocks/table-invert-time--data.json +80211 -0
  41. package/test/mocks/table-invert-time--inverted.json +80076 -0
  42. package/test/mocks/table-prep-multi-duplicate--duplicated.json +26938 -0
  43. package/test/mocks/table-prep-multi-duplicate--indexes.json +1417 -0
  44. package/test/mocks/table-prep-multi-duplicate--observations.json +20330 -0
  45. package/test/mocks/table-prep-simple-duplicate--duplicated.json +77502 -0
  46. package/test/mocks/table-prep-simple-duplicate--indexes.json +274 -0
  47. package/test/mocks/table-prep-simple-duplicate--observations.json +60002 -0
  48. package/test/parseHierarchicalCodelist.test.js +76 -0
  49. package/test/refineLayoutSize.test.js +84 -0
  50. package/test/table-invert-time-perf.test.js +11 -0
  51. package/test/table-prep-duplicate-perf.test.js +21 -0
  52. 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'] }),
@@ -88,7 +88,7 @@ export const truncateSectionRows = (n, sectionsData) => {
88
88
  const rowsLength = R.length(rows);
89
89
  const sectionKey = R.join(':', R.head(lastSection));
90
90
  if (rowsLength > _n) {
91
- const [rest, extracted] = R.splitAt(R.negate(n), rows);
91
+ const [rest, extracted] = R.splitAt(R.negate(_n), rows);
92
92
  const updatedSection = R.set(R.lensIndex(1), rest)(lastSection);
93
93
  truncated = R.set(R.lensIndex(-1), updatedSection)(truncated);
94
94
  extractedKeys = { ...extractedKeys, [sectionKey]: R.map(R.join(':'), extracted) };
@@ -24,8 +24,12 @@ import {
24
24
  getObservationsAdvancedAttributes,
25
25
  getSeriesAdvancedAttributes
26
26
  } from '../../../../rules2/src/getAdvancedAttributes';
27
+ import { getDimensionsSimpleHierarchies } from '../../../../rules2/src/getDimensionsSimpleHierarchies';
28
+ import { duplicateObservations } from '../../../../rules2/src/duplicateObservations';
29
+ import { hierarchiseDimension } from '../../../../rules2/src/hierarchiseDimension';
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,8 @@ 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 simpleHierarchies = getDimensionsSimpleHierarchies(dimensions);
45
+ const hierarchies = R.mergeRight(simpleHierarchies, _options.hierarchies || {});
40
46
  const dimensionsIndexedByIds = R.indexBy(R.prop('id'), dimensions);
41
47
 
42
48
  const parsedDimensionsIds = parseDimensionsIds(dimensions);
@@ -160,10 +166,21 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
160
166
  seriesAdvancedAttributesIds
161
167
  );
162
168
 
169
+ const hierarchisedDimensions = R.map(
170
+ dim => hierarchiseDimension(dim, R.propOr({}, dim.id, hierarchies))
171
+ )(manyValuesDimensions);
172
+ const valuesIndexes = R.reduce(
173
+ (acc, dim) => ({ ...acc, [dim.__index]: getDimensionValuesIndexes(dim.values) }),
174
+ {},
175
+ R.values(hierarchisedDimensions)
176
+ );
177
+
178
+ const duplicatedObservations = duplicateObservations(observations, valuesIndexes);
179
+
163
180
  return ({
164
181
  dimensions: {
165
182
  one: oneValueDimensions,
166
- many: manyValuesDimensions,
183
+ many: hierarchisedDimensions,
167
184
  length: R.length(dimensions)
168
185
  },
169
186
  units: {
@@ -175,7 +192,7 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
175
192
  },
176
193
  metadataCoordinates,
177
194
  advancedAttributes: { ...dataflowAdvancedAttributes, ...observationsAdvancedAttributes, ...seriesAdvancedAttributes },
178
- observations,
195
+ observations: duplicatedObservations,
179
196
  observationsType: getObservationsType(sdmxJson.data),
180
197
  dataflowAttributes,
181
198
  dataflowName: R.path(['data', 'structure', 'name'], sdmxJson),
@@ -1,12 +1,14 @@
1
1
  import * as R from 'ramda';
2
2
  import dateFns from 'date-fns';
3
- import { getCodeOrder, getRefinedName, isTimePeriodDimension } from '@sis-cc/dotstatsuite-sdmxjs';
3
+ import { getCodeOrder, getRefinedName, getTimePeriodObservation } from '@sis-cc/dotstatsuite-sdmxjs';
4
4
  import {
5
5
  getRelationnalAnnotations, setAnnotationsLayout, getIsHidden } from './sdmx-data';
6
6
  import { getReportedTimePeriodLabel, getReportedTimePeriodNote, getReportedTimePeriod } from './date';
7
7
  import { getReportingYearStart } from './preparators/getReportingYearStart';
8
8
  import { getNotDisplayedIds } from '../../rules2/src';
9
9
 
10
+ const TIME_PERIOD_ID = 'TIME_PERIOD';
11
+
10
12
  export const dataTransformer = (dataNew, options = {}) => {
11
13
  const { locale } = options;
12
14
  const reportYearStart = getReportingYearStart(dataNew);
@@ -79,7 +81,9 @@ export const dataTransformer = (dataNew, options = {}) => {
79
81
  R.ascend(R.prop('__indexPosition')),
80
82
  R.ascend(R.propOr(-1, 'order'))
81
83
  ]),
82
- 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'))
83
87
  );
84
88
 
85
89
  //--------------------------------------------------------------------------------------------Header
@@ -136,38 +140,15 @@ export const dataTransformer = (dataNew, options = {}) => {
136
140
 
137
141
  const getDimObservations = R.propOr([], 'observation');
138
142
  const dimObservations = getDimObservations(dimensions);
143
+ const timePeriodDimension = getTimePeriodObservation(dimObservations);
144
+ const timePeriodId = timePeriodDimension.id;
139
145
 
140
146
  const getObservations = locale => R.addIndex(R.reduce)((acc, observation, obsIndex) => {
141
147
  const id = R.prop('id')(observation);
142
148
  const dimAnnotations = getRelationnalAnnotations(R.propOr([],'annotations')(observation))(annotations)
143
149
  const isHidden = R.has(id, hiddenIds) || getIsHidden(dimAnnotations);
144
- const isTime = isTimePeriodDimension(observation);
145
-
150
+ const isTime = observation.id === timePeriodId;
146
151
  const values = getValuesEnhanced(locale, annotations, isTime, id)(R.propOr([],'values', observation));
147
- const ids = R.pipe(R.pluck('id'), R.indexBy(R.identity))(values);
148
- const groupedByParentsValues = R.groupBy(val => {
149
- const parentId = R.propOr('##ROOT', 'parent', val);
150
- if (parentId !== '##ROOT' && !R.has(parentId, ids)) {
151
- return '##ROOT';
152
- }
153
- return parentId;
154
- }, values);
155
- const sortedGroupedValues = R.mapObjIndexed(
156
- R.sortWith([R.ascend(R.prop('__indexPosition')), R.ascend(R.prop('__index'))]),
157
- groupedByParentsValues
158
- );
159
-
160
- const getReccursiveChildren = (parent) => {
161
- const children = R.propOr([], parent, sortedGroupedValues);
162
- return R.map(child => R.prepend(child, getReccursiveChildren(child.id)), children);
163
- };
164
-
165
- const sortedValues = R.pipe(
166
- getReccursiveChildren,
167
- R.flatten,
168
- R.addIndex(R.map)((value, index) => R.assoc('__indexPosition', index, value)),
169
- R.sortBy(R.prop('__index'))
170
- )('##ROOT');
171
152
 
172
153
  return ({
173
154
  observation: R.append({
@@ -175,8 +156,8 @@ export const dataTransformer = (dataNew, options = {}) => {
175
156
  display: !isHidden,
176
157
  __index: obsIndex,
177
158
  name: getRefinedName(observation),
178
- values: sortedValues,
179
- role: R.isNil(observation.roles) ? null : R.head(observation.roles),
159
+ values,
160
+ role: isTime ? TIME_PERIOD_ID : R.head(R.propOr([], 'roles', observation)),
180
161
  })(acc.observation),
181
162
  dimensionsLayout: setAnnotationsLayout(id, acc.dimensionsLayout)(dimAnnotations),
182
163
  });
@@ -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,34 @@
1
+ import * as R from 'ramda';
2
+
3
+ const getDimensionSimpleHierarchy = ({ values }) => {
4
+ const indexed = R.indexBy(R.prop('id'), values);
5
+ return R.pipe(
6
+ R.reduce(
7
+ (acc, value) => {
8
+ const { id, parent } = value;
9
+ const _parent = R.isNil(parent) || !R.has(parent, indexed)
10
+ ? '#ROOT'
11
+ : parent;
12
+ return R.over(
13
+ R.lensProp(_parent),
14
+ ids => R.isNil(ids) ? [id] : R.append(id, ids)
15
+ )(acc);
16
+ },
17
+ {}
18
+ ),
19
+ R.map(R.sortBy(id => R.pathOr(-1, [id, '__indexPosition'], indexed)))
20
+ )(values);
21
+ };
22
+
23
+ export const getDimensionsSimpleHierarchies = (dimensions) => R.reduce(
24
+ (acc, dim) => {
25
+ const { id, values } = dim;
26
+ if (R.length(values) < 2) {
27
+ return acc;
28
+ }
29
+ const hierarchy = getDimensionSimpleHierarchy(dim);
30
+ return R.assoc(id, hierarchy, acc);
31
+ },
32
+ {},
33
+ dimensions
34
+ );
@@ -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 || '';
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,38 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const hierarchiseDimension = (dimension, hierarchy) => {
4
+ const indexed = R.indexBy(R.prop('id'), dimension.values);
5
+ let _hierarchy = hierarchy;
6
+ if (!R.has('#ROOT', hierarchy)) {
7
+ const indexes = R.pluck('id', dimension.values);
8
+ const refinedHierarchy = R.pick(indexes, _hierarchy);
9
+ const childrenIds = R.pipe(R.values, R.unnest, R.indexBy(R.identity))(refinedHierarchy);
10
+ const rootIds = R.pipe(
11
+ R.reject(val => R.has(val.id, childrenIds)),
12
+ R.sortBy(R.prop('__indexPosition')),
13
+ R.pluck('id')
14
+ )(dimension.values);
15
+ _hierarchy = R.assoc('#ROOT', rootIds, hierarchy);
16
+ }
17
+
18
+ const getChildren = (parents) => R.pipe(
19
+ ids => R.props(ids, indexed),
20
+ R.filter(R.identity),
21
+ R.map(
22
+ (val) => {
23
+ const _val = {
24
+ ...val,
25
+ parent: R.last(parents),
26
+ parents
27
+ };
28
+ const children = getChildren(R.append(val.id, parents));
29
+ return R.prepend(_val, children);
30
+ },
31
+ )
32
+ )(R.propOr([], R.last(parents) || '#ROOT', _hierarchy));
33
+
34
+ return R.set(
35
+ R.lensProp('values'),
36
+ R.flatten(getChildren([]))
37
+ )(dimension);
38
+ };
@@ -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,14 @@
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
+ return R.pipe(
8
+ R.propOr([], 'hierarchicalCodes'),
9
+ R.reduce((acc, parentCode) => {
10
+ const children = R.pluck('id', parentCode.hierarchicalCodes || []);
11
+ return R.assoc(parentCode.id, children, acc);
12
+ }, {}),
13
+ )(hierarchy);
14
+ };
@@ -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' },