@sis-cc/dotstatsuite-components 10.0.0 → 11.0.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/index.js +8 -3
  2. package/lib/rules/src/table/factories/getCells.js +22 -4
  3. package/lib/rules/src/table/factories/getLayoutWithFlags.js +32 -5
  4. package/lib/rules/src/table/factories/getTableData.js +9 -2
  5. package/lib/rules/src/table/preparators/prepareData.js +37 -2
  6. package/lib/rules/src/v8-transformer.js +5 -9
  7. package/lib/rules2/src/constants.js +7 -0
  8. package/lib/rules2/src/getAdvAttrSeriesAtCoordinates.js +39 -0
  9. package/lib/rules2/src/getAdvancedAttributes.js +126 -0
  10. package/lib/rules2/src/getMetadataCoordinates.js +38 -0
  11. package/lib/rules2/src/getMetadataStructureFromData.js +23 -0
  12. package/lib/rules2/src/getSidebarData.js +76 -0
  13. package/lib/rules2/src/hasCellMetadata.js +19 -0
  14. package/lib/rules2/src/hasLayoutEntryMetadata.js +18 -0
  15. package/lib/rules2/src/index.js +41 -0
  16. package/lib/rules2/src/json2.0DataFormatPatch.js +20 -0
  17. package/lib/rules2/src/parseMetadataSeries.js +83 -0
  18. package/lib/rules2/src/refineMetadataCoordinates.js +34 -0
  19. package/package.json +1 -1
  20. package/src/index.js +2 -0
  21. package/src/rules/src/table/factories/getCells.js +13 -4
  22. package/src/rules/src/table/factories/getLayoutWithFlags.js +36 -10
  23. package/src/rules/src/table/factories/getTableData.js +12 -3
  24. package/src/rules/src/table/preparators/prepareData.js +45 -4
  25. package/src/rules/src/v8-transformer.js +3 -8
  26. package/src/rules2/src/constants.js +2 -0
  27. package/src/rules2/src/getAdvAttrSeriesAtCoordinates.js +29 -0
  28. package/src/rules2/src/getAdvancedAttributes.js +113 -0
  29. package/src/rules2/src/getMetadataCoordinates.js +37 -0
  30. package/src/rules2/src/getMetadataStructureFromData.js +17 -0
  31. package/src/rules2/src/getSidebarData.js +73 -0
  32. package/src/rules2/src/hasCellMetadata.js +11 -0
  33. package/src/rules2/src/hasLayoutEntryMetadata.js +9 -0
  34. package/src/rules2/src/index.js +5 -0
  35. package/src/rules2/src/json2.0DataFormatPatch.js +9 -0
  36. package/src/rules2/src/parseMetadataSeries.js +80 -0
  37. package/src/rules2/src/refineMetadataCoordinates.js +27 -0
  38. package/test/advanced-attributes-parsing-perf.test.js +16 -0
  39. package/test/getCells.test.js +7 -5
  40. package/test/getDataflowAdvancedAttributes.test.js +32 -0
  41. package/test/getLayoutDataWithFlags.test.js +22 -12
  42. package/test/getMetadataCoordinates.test.js +0 -0
  43. package/test/getSeriesAdvancedAttributes.test.js +30 -0
  44. package/test/getSidebarData.test.js +116 -0
  45. package/test/getSubtitleFlags.test.js +1 -1
  46. package/test/getTableData.test.js +2 -1
  47. package/test/metadata-parsing-perf.test.js +487 -0
  48. package/test/mocks/OECD_SNA_TABLE1_1.0_-_AUS_V_metadata.json +152 -0
  49. package/test/mocks/large_metadata_series.json +701 -0
  50. package/test/mocks/observations-advanced-attributes.json +55382 -0
  51. package/test/parseMetadataSeries.test.js +55 -0
  52. package/test/prepareData.test.js +2 -0
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _constants = require('./constants');
8
+
9
+ Object.defineProperty(exports, 'SDMX_2_0_JSON_DATA_FORMAT', {
10
+ enumerable: true,
11
+ get: function get() {
12
+ return _constants.SDMX_2_0_JSON_DATA_FORMAT;
13
+ }
14
+ });
15
+
16
+ var _getSidebarData = require('./getSidebarData');
17
+
18
+ Object.defineProperty(exports, 'getSidebarData', {
19
+ enumerable: true,
20
+ get: function get() {
21
+ return _getSidebarData.getSidebarData;
22
+ }
23
+ });
24
+
25
+ var _parseMetadataSeries = require('./parseMetadataSeries');
26
+
27
+ Object.defineProperty(exports, 'parseMetadataSeries', {
28
+ enumerable: true,
29
+ get: function get() {
30
+ return _parseMetadataSeries.parseMetadataSeries;
31
+ }
32
+ });
33
+
34
+ var _json = require('./json2.0DataFormatPatch');
35
+
36
+ Object.defineProperty(exports, 'json_2_0_0_DataFormatPatch', {
37
+ enumerable: true,
38
+ get: function get() {
39
+ return _json.json_2_0_0_DataFormatPatch;
40
+ }
41
+ });
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.json_2_0_0_DataFormatPatch = undefined;
7
+
8
+ var _ramda = require('ramda');
9
+
10
+ var R = _interopRequireWildcard(_ramda);
11
+
12
+ 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; } }
13
+
14
+ var json_2_0_0_DataFormatPatch = exports.json_2_0_0_DataFormatPatch = function json_2_0_0_DataFormatPatch(sdmxJson) {
15
+ var dataSet = R.pipe(R.pathOr({}, ['data', 'dataSets']), R.head)(sdmxJson);
16
+ var structureIndex = R.prop('structure', dataSet);
17
+ var structure = R.pipe(R.pathOr([], ['data', 'structures']), R.nth(structureIndex))(sdmxJson);
18
+
19
+ return R.set(R.lensPath(['data', 'structure']), structure)(sdmxJson);
20
+ };
@@ -0,0 +1,83 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.parseMetadataSeries = undefined;
7
+
8
+ var _ramda = require('ramda');
9
+
10
+ var R = _interopRequireWildcard(_ramda);
11
+
12
+ var _dotstatsuiteSdmxjs = require('@sis-cc/dotstatsuite-sdmxjs');
13
+
14
+ 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; } }
15
+
16
+ var dimensionValueDisplay = function dimensionValueDisplay(locale, display) {
17
+ return function (data) {
18
+ if (display === 'code') {
19
+ return R.prop('id', data);
20
+ }
21
+ if (display === 'both') {
22
+ return R.prop('id', data) + ': ' + (0, _dotstatsuiteSdmxjs.getLocalisedName)(locale)(data);
23
+ }
24
+ return (0, _dotstatsuiteSdmxjs.getLocalisedName)(locale)(data);
25
+ };
26
+ };
27
+ // options = { locale, display, dimensions = [] };
28
+ var parseMetadataSeries = exports.parseMetadataSeries = function parseMetadataSeries(metadataJson, options) {
29
+ var metadataAttributes = R.pathOr([], ['data', 'structures', 0, 'attributes', 'dimensionGroup'], metadataJson);
30
+ var metaAttrLength = R.length(metadataAttributes);
31
+
32
+ if (!metaAttrLength) {
33
+ return {};
34
+ }
35
+
36
+ var dimensions = R.pipe(R.pathOr([], ['data', 'structures', 0, 'dimensions']), function (_ref) {
37
+ var _ref$series = _ref.series,
38
+ series = _ref$series === undefined ? [] : _ref$series,
39
+ _ref$observation = _ref.observation,
40
+ observation = _ref$observation === undefined ? [] : _ref$observation;
41
+ return R.concat(series, observation);
42
+ }, function (dims) {
43
+ return R.isEmpty(options.dimensions || []) ? dims : R.props(R.pluck('id', options.dimensions), R.indexBy(R.prop('id'), dims));
44
+ })(metadataJson);
45
+
46
+ var metadataSeries = R.pipe(R.pathOr({}, ['data', 'dataSets', 0, 'dimensionGroupAttributes']), function (series) {
47
+ return R.reduce(function (acc, serieKey) {
48
+ var indexes = series[serieKey];
49
+ var metaIndexes = R.take(metaAttrLength, indexes);
50
+
51
+ var evolvedKey = R.pipe(R.split(':'), R.addIndex(R.map)(function (vInd, dInd) {
52
+ if (R.isEmpty(vInd)) {
53
+ return vInd;
54
+ }
55
+ var dim = R.nth(dInd, dimensions);
56
+ var val = R.nth(Number(vInd), dim.values || []);
57
+
58
+ var originalVal = R.find(R.propEq('id', val.id))(R.propOr([], 'values', R.nth(dInd, options.dimensions)));
59
+ return R.propOr('', '__index', originalVal);
60
+ }), R.join(':'))(serieKey);
61
+
62
+ var attributes = R.addIndex(R.reduce)(function (acc, valueIndex, attrIndex) {
63
+ if (R.isNil(valueIndex)) {
64
+ return acc;
65
+ }
66
+ var attribute = R.nth(attrIndex, metadataAttributes);
67
+ var label = dimensionValueDisplay(options.locale, options.display)(attribute);
68
+
69
+ var value = R.prop('value', R.nth(valueIndex, attribute.values || []));
70
+
71
+ return R.append({
72
+ id: attribute.id,
73
+ label: label,
74
+ value: R.is(Object, value) ? R.prop(options.locale, value) : value
75
+ }, acc);
76
+ }, [], metaIndexes);
77
+
78
+ return R.assoc(evolvedKey, attributes, acc);
79
+ }, {}, R.keys(series));
80
+ })(metadataJson);
81
+
82
+ return metadataSeries;
83
+ };
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.refineMetadataCoordinates = undefined;
7
+
8
+ var _ramda = require('ramda');
9
+
10
+ var R = _interopRequireWildcard(_ramda);
11
+
12
+ 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; } }
13
+
14
+ var refineMetadataCoordinates = exports.refineMetadataCoordinates = function refineMetadataCoordinates(metadataCoordinates, layoutIds, headerDimensionsIds) {
15
+ return R.reduce(function (acc, coordinates) {
16
+ var refinedCoord = R.omit(headerDimensionsIds, coordinates);
17
+ if (R.isEmpty(refinedCoord)) {
18
+ return acc;
19
+ }
20
+ var removedHeaderCodes = R.omit(layoutIds.header, refinedCoord);
21
+ if (R.isEmpty(removedHeaderCodes)) {
22
+ return R.over(R.lensProp('layout'), R.append(refinedCoord))(acc);
23
+ }
24
+ var removedSectionCodes = R.omit(layoutIds.sections, refinedCoord);
25
+ if (R.isEmpty(removedSectionCodes)) {
26
+ return R.over(R.lensProp('layout'), R.append(refinedCoord))(acc);
27
+ }
28
+ var removedRowsCodes = R.omit(layoutIds.rows, removedSectionCodes);
29
+ if (R.isEmpty(removedRowsCodes)) {
30
+ return R.over(R.lensProp('layout'), R.append(refinedCoord))(acc);
31
+ }
32
+ return R.over(R.lensProp('cells'), R.append(refinedCoord))(acc);
33
+ }, { cells: [], layout: [] }, metadataCoordinates);
34
+ };
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": "10.0.0",
4
+ "version": "11.0.0",
5
5
  "main": "lib/index.js",
6
6
  "author": "OECD",
7
7
  "license": "MIT",
package/src/index.js CHANGED
@@ -2,9 +2,11 @@ import meta from '../package.json';
2
2
  console.info(`${meta.name}@${meta.version}`);
3
3
 
4
4
  import * as rules from './rules/src';
5
+ import * as rules2 from './rules2/src';
5
6
  import * as bridgeD3React from './bridge-d3-react/src';
6
7
 
7
8
  export { rules };
9
+ export { rules2 };
8
10
  export { bridgeD3React };
9
11
 
10
12
  export { default as RulesDriver } from './rules-driver/src';
@@ -1,12 +1,13 @@
1
1
  import * as R from 'ramda';
2
2
  import { dimensionValueDisplay } from '../../dimension-utils';
3
+ import { hasCellMetadata } from '../../../../rules2/src/hasCellMetadata';
3
4
 
4
5
  const getAttrLabel = (display) => (attribute) => `${display(attribute)}: ${display(R.propOr({}, 'value', attribute))}`;
5
6
 
6
7
  export const getFlags = (customAttributesIds, display, unitsProps) => ({ attributes={}, units={} }) => {
7
8
  const refinedAttributes = R.omit(R.propOr([], 'rejected', customAttributesIds), attributes);
8
9
  const flags = R.pipe(R.pick(R.propOr([], 'flags', customAttributesIds)), R.values)(refinedAttributes);
9
- const footnotes = R.pipe(R.omit(R.propOr([], 'flags', customAttributesIds)), R.values)(refinedAttributes);
10
+ const footnotes = R.pipe(R.pick(R.propOr([], 'footnotes', customAttributesIds)), R.values)(refinedAttributes);
10
11
 
11
12
  const unitsDisplay = R.prop('unitsDisplay', unitsProps);
12
13
  const rejectedUnitsValueIds = R.propOr([], 'rejectedValueIds', unitsProps);
@@ -73,9 +74,16 @@ export const getFlags = (customAttributesIds, display, unitsProps) => ({ attribu
73
74
  )(flags, footnotes);
74
75
  };
75
76
 
76
- const isValidNumber = R.both(R.is(Number), R.complement(R.equals(NaN)));
77
+ const getSideProps = ({ attributes, indexedDimValIds }, customAttributes, metadataCoordinates) => {
78
+ const rejected = [...customAttributes.flags || [], ...customAttributes.footnotes || [], ...customAttributes.rejected || []];
79
+ const advancedAttributes = R.omit(rejected, attributes);
80
+ const hasAdvancedAttributes = !R.isEmpty(advancedAttributes);
81
+ const hasMetadata = hasCellMetadata(metadataCoordinates, indexedDimValIds);
77
82
 
78
- export const getCells = (data, display, customAttributes, unitsProps) => R.mapObjIndexed(
83
+ return hasAdvancedAttributes || hasMetadata ? { hasAdvancedAttributes, hasMetadata, coordinates: indexedDimValIds } : null;
84
+ }
85
+
86
+ export const getCells = (data, display, customAttributes, unitsProps, metadataCoordinates) => R.mapObjIndexed(
79
87
  (observation) => R.pipe(
80
88
  R.set(
81
89
  R.lensProp('flags'),
@@ -85,7 +93,8 @@ export const getCells = (data, display, customAttributes, unitsProps) => R.mapOb
85
93
  ),
86
94
  R.set(R.lensProp('intValue'), R.prop('value', observation)),
87
95
  R.set(R.lensProp('value'), R.prop('formattedValue', observation)),
88
- R.assoc('indexedDimValIds', R.prop('indexedDimValIds', observation))
96
+ R.assoc('indexedDimValIds', R.prop('indexedDimValIds', observation)),
97
+ R.assoc('sideProps', getSideProps(observation, customAttributes, metadataCoordinates))
89
98
  )({}),
90
99
  R.propOr({}, 'observations', data)
91
100
  );
@@ -1,6 +1,7 @@
1
1
  import * as R from 'ramda';
2
2
  import { getFlags } from './getCells';
3
3
  import { dimensionValueDisplay } from '../../dimension-utils';
4
+ import { hasCellMetadata } from '../../../../rules2/src/hasCellMetadata';
4
5
 
5
6
  export const getLayoutSerieAttributes = (layoutSerie, seriesAttributes) => {
6
7
  const length = R.length(layoutSerie);
@@ -72,15 +73,39 @@ const getSerieKey = R.pipe(R.reduce(
72
73
  []
73
74
  ), R.join(':'));
74
75
 
75
- export const getLayoutDataWithFlags = (seriesAttributes, display, customAttributes) => {
76
- const formatSublayout = getAttributes => R.converge(
77
- (data, key, flags) => ({ data, key, flags }),
78
- [
79
- getSublayoutDataCells(display, customAttributes),
80
- getSerieKey,
81
- R.pipe(getAttributes, getFlagsFromSeriesAttributes(display, customAttributes))
82
- ]
83
- );
76
+ const getCoordinates = (data, unitsId) => R.reduce(
77
+ (acc, entry) => {
78
+ const dimId = R.path(['dimension', 'id'], entry);
79
+ const valId = R.path(['value', 'id'], entry);
80
+ if (dimId === unitsId) {
81
+ return acc;
82
+ }
83
+ return R.assoc(dimId, valId, acc);
84
+ },
85
+ {},
86
+ data
87
+ );
88
+
89
+ export const getLayoutDataWithFlags = (seriesAttributes, display, customAttributes, metadataCoordinates, unitsId) => {
90
+ const regularAttrsIds = R.concat(customAttributes.flags || [], customAttributes.footnotes || []);
91
+ const formatSublayout = (getAttributes, supplData = []) => data => {
92
+ const attributes = getAttributes(data);
93
+ const key = getSerieKey(data);
94
+ const cells = getSublayoutDataCells(display, customAttributes)(data);
95
+ const flags = getFlagsFromSeriesAttributes(display, customAttributes)(attributes);
96
+ const coordinates = getCoordinates(R.concat(supplData, data), unitsId);
97
+ const hasMetadata = hasCellMetadata(metadataCoordinates, coordinates);
98
+ const advancedAttributesSeries = R.isNil(attributes)
99
+ ? {}
100
+ : R.filter(
101
+ serie => !R.isEmpty(R.omit(regularAttrsIds, R.propOr({}, 'attributes', serie))),
102
+ attributes
103
+ );
104
+ const hasAdvancedAttributes = !R.isEmpty(advancedAttributesSeries);
105
+ const sideProps = hasMetadata || hasAdvancedAttributes ? { hasAdvancedAttributes, hasMetadata, coordinates } : null;
106
+
107
+ return ({ data: cells, key, flags, sideProps });
108
+ };
84
109
 
85
110
  return R.evolve({
86
111
  headerData: R.map(formatSublayout(data => getLayoutSerieAttributes(data, seriesAttributes))),
@@ -91,7 +116,8 @@ export const getLayoutDataWithFlags = (seriesAttributes, display, customAttribut
91
116
  return ([
92
117
  formatSublayout(() => sectionAttributes)(sectionSerie),
93
118
  R.map(
94
- formatSublayout(rowData => getLayoutSerieAttributes(R.concat(sectionSerie, rowData), R.omit(R.keys(sectionAttributes), seriesAttributes)))
119
+ formatSublayout(rowData => getLayoutSerieAttributes(R.concat(sectionSerie, rowData), R.omit(R.keys(sectionAttributes), seriesAttributes)),
120
+ sectionSerie)
95
121
  )(R.last(sectionData))
96
122
  ]);
97
123
  }
@@ -13,6 +13,7 @@ import { cleanUnitsInLayoutData } from '../units/cleanUnitsInLayoutData';
13
13
  import { getSortedLayoutIndexes } from './getSortedLayoutIndexes';
14
14
  import { refineLayoutSize } from './refineLayoutSize';
15
15
  import { getLayoutData } from './getLayoutData';
16
+ import { refineMetadataCoordinates } from '../../../../rules2/src/refineMetadataCoordinates';
16
17
 
17
18
  export const getTableProps = ({ data, layoutIds, display, customAttributes, limit, isTimeInverted }) => {
18
19
  const seriesAttributes = R.propOr({}, 'seriesAttributes', data);
@@ -22,6 +23,12 @@ export const getTableProps = ({ data, layoutIds, display, customAttributes, limi
22
23
  layoutIds
23
24
  );
24
25
 
26
+ const headerDimensionsIds = R.pluck('id',
27
+ R.concat(R.pathOr([], ['units', 'headerUnits'], data), R.values(R.pathOr({}, ['dimensions', 'one'], data)))
28
+ );
29
+
30
+ const refinedMetadataCoordinates = refineMetadataCoordinates(data.metadataCoordinates, layoutIds, headerDimensionsIds);
31
+
25
32
  const {
26
33
  rejectedValueIds,
27
34
  unitDimension,
@@ -45,7 +52,8 @@ export const getTableProps = ({ data, layoutIds, display, customAttributes, limi
45
52
  unitsDefinitionCodes, unitsSeries, unitsDisplay: unitsLevelDisplay,
46
53
  unitDimension, rejectedValueIds, layoutDimsIds
47
54
  },
48
- data.observationsType
55
+ refinedMetadataCoordinates.cells,
56
+ data.observationsType,
49
57
  );
50
58
 
51
59
  const dimensions = R.mapObjIndexed(
@@ -89,9 +97,10 @@ export const getTableProps = ({ data, layoutIds, display, customAttributes, limi
89
97
  unitsDefinitionCodes, unitsIndexes: unitsAttachmentIndexesInLayout,
90
98
  partialUnitSerieIndexes, rejectedValueIds, layoutIds
91
99
  }),
92
- getLayoutDataWithFlags(seriesAttributesValues, display, customAttributes),
93
- cleanUnitsInLayoutData({ unitsDisplay: unitsLevelDisplay, unitsLayoutIndexes: unitsIndexesInLayout })
100
+ getLayoutDataWithFlags(seriesAttributesValues, display, customAttributes, refinedMetadataCoordinates.layout, unitDimension.id),
101
+ cleanUnitsInLayoutData({ unitsDisplay: unitsLevelDisplay, unitsLayoutIndexes: unitsIndexesInLayout }),
94
102
  )(layout, R.propOr({}, 'observations', data));
103
+
95
104
  return ({
96
105
  cells: getCuratedCells({ layout, observations: cells, shape: ['header', 'sections', 'rows'] }),
97
106
  layout,
@@ -21,6 +21,13 @@ import { getDisplay } from '../../preparators/getDisplay';
21
21
  import { getObservations } from '../../preparators/getObservations';
22
22
  import { enhanceObservations } from '../../preparators/enhanceObservations';
23
23
 
24
+ import { getMetadataCoordinates } from '../../../../rules2/src/getMetadataCoordinates';
25
+ import {
26
+ getDataflowAdvancedAttributes,
27
+ getObservationsAdvancedAttributes,
28
+ getSeriesAdvancedAttributes
29
+ } from '../../../../rules2/src/getAdvancedAttributes';
30
+
24
31
  export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
25
32
  const {
26
33
  defaultCodes=[],
@@ -127,10 +134,42 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
127
134
  attributesIndexedByIds,
128
135
  );
129
136
 
130
- const seriesAttributesValues = refineSeriesAttributesValues(
131
- dimensionsAttributesValues.series,
132
- attributesIndexedByIds,
137
+ const seriesAttributesValues = R.map(
138
+ series => refineSeriesAttributesValues(series, attributesIndexedByIds),
139
+ dimensionsAttributesValues
140
+ );
141
+
142
+ const metadataCoordinates = getMetadataCoordinates(sdmxJson);
143
+ const headerAttributesIds = R.concat(attributesIdsIndexedByTargets.dataflow || [], attributesIdsIndexedByTargets.oneValueDimensions || []);
144
+ const headerAttributes = R.pick(headerAttributesIds, attributesIndexedByIds);
145
+ const headerAdvancedAttrIds = R.pipe(
146
+ R.filter(id => !R.includes(id, customAttributes.flags || []) && !R.includes(id, customAttributes.footnotes || [])),
147
+ )(headerAttributesIds);
148
+
149
+ const dataflowAdvancedAttributes = getDataflowAdvancedAttributes(
150
+ headerAttributes,
151
+ oneValueDimensions,
152
+ headerAdvancedAttrIds,
153
+ R.length(dimensions)
154
+ );
155
+
156
+ const observationsAdvancedAttributesIds = R.filter(
157
+ id => !R.includes(id, customAttributes.flags || []) && !R.includes(id, customAttributes.footnotes || []),
158
+ attributesIdsIndexedByTargets.observations || []
133
159
  );
160
+ const observationsAdvancedAttributes = getObservationsAdvancedAttributes(observations, observationsAdvancedAttributesIds);
161
+
162
+ const seriesAdvancedAttributesIds = R.filter(
163
+ id => !R.includes(id, customAttributes.flags || []) && !R.includes(id, customAttributes.footnotes || []),
164
+ R.concat(attributesIdsIndexedByTargets.series || [], attributesIdsIndexedByTargets.manyValuesDimensions || [])
165
+ );
166
+
167
+ const seriesAdvancedAttributes = getSeriesAdvancedAttributes(
168
+ seriesAttributesValues,
169
+ dimensions,
170
+ seriesAdvancedAttributesIds
171
+ );
172
+
134
173
  return ({
135
174
  dimensions: {
136
175
  one: oneValueDimensions,
@@ -144,11 +183,13 @@ export const prepareData = (sdmxJson, customAttributes, unitsProps={}) => {
144
183
  unitsAttachmentSeriesIds,
145
184
  unitsSeries,
146
185
  },
186
+ metadataCoordinates,
187
+ advancedAttributes: { ...dataflowAdvancedAttributes, ...observationsAdvancedAttributes, ...seriesAdvancedAttributes },
147
188
  observations,
148
189
  observationsType: getObservationsType(sdmxJson.data),
149
190
  dataflowAttributes,
150
191
  dataflowName: R.path(['data', 'structure', 'name'], sdmxJson),
151
192
  seriesAttributes: R.props(seriesAttributesIds, attributesIndexedByIds),
152
- seriesAttributesValues
193
+ seriesAttributesValues: seriesAttributesValues.series || {}
153
194
  });
154
195
  };
@@ -95,22 +95,17 @@ export const dataTransformer = (dataNew, options = {}) => {
95
95
  const getAttrObservations = R.propOr([], 'observation');
96
96
  const attrObservations = getAttrObservations(attributes);
97
97
 
98
- const getAttrDataset = R.propOr([], 'dataset')
99
- const attrDataset = getAttrDataset(attributes);
100
-
101
- const mergeAttr = R.concat(attrDataset, attrObservations);
102
-
103
98
  const resAttrObservations = R.map((observation) => ({
104
99
  ...observation,
105
100
  name: getLocalisedProp('names', observation),
106
- values: getValues(observation.values),
101
+ values: getValues(observation.values || []),
107
102
  roles: !R.isNil(observation.role) ? R.head(observation.role) : null,
108
- }), mergeAttr);
103
+ }), attrObservations);
109
104
 
110
105
  const resAttributes = {
111
106
  ...attributes,
112
107
  observation: resAttrObservations,
113
- }
108
+ };
114
109
 
115
110
  //----------------------------------------------------------------------------------------Dimensions
116
111
  const getDimensions = R.propOr({}, 'dimensions');
@@ -0,0 +1,2 @@
1
+ export const SDMX_2_0_JSON_DATA_FORMAT = 'application/vnd.sdmx.data+json;version=2.0.0';
2
+ export const SDMX_2_0_CSV_DATA_FORMAT = 'application/vnd.sdmx.data+csv;version=2.0.0';
@@ -0,0 +1,29 @@
1
+ import * as R from 'ramda';
2
+
3
+ const attribueValueDisplay = (display) => data => {
4
+ if (display === 'code') {
5
+ return R.prop('id', data);
6
+ }
7
+ if (display === 'both') {
8
+ return `${R.prop('id', data)}: ${R.prop('name', data)}`;
9
+ }
10
+ return R.prop('name', data);
11
+ };
12
+
13
+ export const getAdvAttrSeriesAtCoordinates = (coordinates, advancedAttributes, display) => R.pipe(
14
+ R.filter(serie => {
15
+ const mergedCoord = R.mergeLeft(serie.coordinates, coordinates);
16
+ return R.equals(mergedCoord, coordinates);
17
+ }),
18
+ R.map(serie => {
19
+ return R.pipe(
20
+ R.propOr({}, 'attributes'),
21
+ R.values,
22
+ R.map(attribute => ({
23
+ id: attribute.id,
24
+ label: attribueValueDisplay(display)(attribute),
25
+ value: attribueValueDisplay(display)(attribute.value)
26
+ }))
27
+ )(serie);
28
+ }),
29
+ )(advancedAttributes);
@@ -0,0 +1,113 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getObservationsAdvancedAttributes = (observations, advancedAttributesIds) => R.pipe(
4
+ R.map(obs => ({ attributes: R.pick(advancedAttributesIds, obs.attributes || {}), coordinates: obs.indexedDimValIds || {} })),
5
+ R.filter(entry => !R.isEmpty(entry.attributes))
6
+ )(observations);
7
+
8
+ export const getDataflowAdvancedAttributes = (attributes, dimensions, advancedAttributesIds, dimLength) => {
9
+ const advancedAttributes = R.pick(advancedAttributesIds, attributes);
10
+ const keyTemplate = R.times(R.always(''), dimLength);
11
+ return R.reduce(
12
+ (acc, attribute) => {
13
+ const value = R.head(attribute.values || []);
14
+ const attr = { ...R.pick(['id', 'name'], attribute), value };
15
+ let coordinates = {};
16
+ let key = keyTemplate;
17
+
18
+ if (!R.isEmpty(R.pathOr([], ['relationship', 'dimensions'], attribute))) {
19
+ const attrDimensionsIds = R.pathOr([], ['relationship', 'dimensions'], attribute);
20
+ const attrDimensions = R.props(attrDimensionsIds, dimensions);
21
+ R.forEach(
22
+ dim => {
23
+ const dId = dim.id;
24
+ const dIndex = dim.__index;
25
+ const vId = R.path(['values', 0, 'id'], dim);
26
+ coordinates = { ...coordinates, [dId]: vId };
27
+ key = R.set(R.lensIndex(dIndex), 0)(key);
28
+ },
29
+ attrDimensions
30
+ );
31
+ }
32
+
33
+ key = R.join(':', key);
34
+ return R.over(
35
+ R.lensProp(key),
36
+ entry => R.isNil(entry)
37
+ ? ({ attributes: { [attribute.id]: attr }, coordinates })
38
+ : R.over(R.lensProp('attributes'), R.assoc(attribute.id, attr))(entry)
39
+ )(acc);
40
+ },
41
+ {},
42
+ R.values(advancedAttributes)
43
+ )
44
+ };
45
+
46
+ /*
47
+ {
48
+ series: {
49
+ '0:0:x:x:x': { attributes: { a2: { id, value } } }
50
+ },
51
+ dimensions: {
52
+ '3:0': { attributes: { a1: { id, value } } },
53
+ }
54
+ }
55
+
56
+ */
57
+
58
+ export const getSeriesAdvancedAttributes = (seriesAttributes, dimensions, advancedAttributesIds) => {
59
+ const seriesAdvancedAttributes = R.pipe(
60
+ R.propOr({}, 'series'),
61
+ series => R.reduce(
62
+ (acc, key) => {
63
+ const serie = series[key];
64
+ const advancedAttributes = R.pick(advancedAttributesIds, serie.attributes);
65
+ if (R.isEmpty(advancedAttributes)) {
66
+ return acc;
67
+ }
68
+ const splitKey = R.split(':', key);
69
+ const { coordinates, refinedKey } = R.addIndex(R.reduce)(
70
+ (acc, vInd, dInd) => {
71
+ if (vInd === 'x') {
72
+ return ({ ...acc, refinedKey: R.append('', acc.refinedKey) });
73
+ }
74
+ const _refined = R.append(vInd, acc.refinedKey);
75
+ const dim = R.nth(dInd, dimensions);
76
+ const valId = R.path(['values', Number(vInd), 'id'], dim);
77
+ const _coordinates = R.assoc(dim.id, valId, acc.coordinates);
78
+ return ({ coordinates: _coordinates, refinedKey: _refined });
79
+ },
80
+ { coordinates: {}, refinedKey: [] },
81
+ splitKey
82
+ );
83
+ return R.assoc(R.join(':', refinedKey), { attributes: advancedAttributes, coordinates }, acc);
84
+ },
85
+ {},
86
+ R.keys(series)
87
+ )
88
+ )(seriesAttributes);
89
+ const keyTemplate = R.map(R.always(''), dimensions);
90
+ const dimensionsAdvancedAttributes = R.pipe(
91
+ R.propOr({}, 'dimensions'),
92
+ series => R.reduce(
93
+ (acc, key) => {
94
+ const serie = series[key];
95
+ const advancedAttributes = R.pick(advancedAttributesIds, serie.attributes);
96
+ if (R.isEmpty(advancedAttributes)) {
97
+ return acc;
98
+ }
99
+ const [dInd, vInd] = R.split(':', key);
100
+ const dim = R.nth(Number(dInd), dimensions);
101
+ const valId = R.path(['values', Number(vInd), 'id'], dim);
102
+ const coordinates = { [dim.id]: valId };
103
+ let refinedKey = keyTemplate;
104
+ refinedKey[Number(dInd)] = vInd;
105
+ return R.assoc(R.join(':', refinedKey), { attributes: advancedAttributes, coordinates }, acc);
106
+ },
107
+ {},
108
+ R.keys(series)
109
+ )
110
+ )(seriesAttributes);
111
+
112
+ return R.merge(seriesAdvancedAttributes, dimensionsAdvancedAttributes);
113
+ };
@@ -0,0 +1,37 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getMetadataCoordinates = (sdmxJson) => {
4
+ const dimensions = R.pathOr([], ['data', 'structure', 'dimensions', 'observation'], sdmxJson);
5
+ const annotations = R.pathOr([], ['data', 'structure', 'annotations'], sdmxJson);
6
+ const metadataAvailKeys = R.pipe(
7
+ R.pathOr([], ['data', 'dataSets', 0, 'dimensionGroupAttributes']),
8
+ R.map(indexes => R.props(indexes, annotations)),
9
+ R.filter(R.find(R.propEq('type', 'HAS_METADATA'))),
10
+ R.keys
11
+ )(sdmxJson);
12
+
13
+ return R.map(
14
+ key => {
15
+ const indexes = R.split(':', key);
16
+ return R.addIndex(R.reduce)(
17
+ (acc, vIndex, dimIndex) => {
18
+ if (R.isNil(vIndex) || R.isEmpty(vIndex)) {
19
+ return acc;
20
+ }
21
+ const dim = R.nth(dimIndex, dimensions);
22
+ if (R.isNil(dim)) {
23
+ return acc;
24
+ }
25
+ const val = R.path(['values', Number(vIndex)], dim);
26
+ if (R.isNil(val)) {
27
+ return acc;
28
+ }
29
+ return R.assoc(dim.id, val.id, acc);
30
+ },
31
+ {},
32
+ indexes
33
+ );
34
+ },
35
+ metadataAvailKeys
36
+ );
37
+ };
@@ -0,0 +1,17 @@
1
+ import * as R from 'ramda';
2
+
3
+ export const getDataflowMetadataStructure = sdmxJson => {
4
+ const annotations = R.pathOr([], ['data', 'stucture', 'annotations'], sdmxJson);
5
+ const dataSetAnnotIndexes = R.pathOr([], ['data', 'dataSets', 0, 'annotations'], sdmxJson);
6
+ const dataSetAnnotations = R.props(dataSetAnnotIndexes, annotations);
7
+ const metadataAnnotation = R.find(R.propEq('type', 'METADATA'), dataSetAnnotations);
8
+ if (!metadataAnnotation) {
9
+ return null;
10
+ }
11
+ return R.pipe(
12
+ R.propOr('', 'title'),
13
+ R.split('='),
14
+ R.last,
15
+
16
+ )(metadataAnnotation);
17
+ };