@sis-cc/dotstatsuite-components 17.8.0 → 17.9.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.
- package/lib/viewer/src/chart.js +5 -9
- package/lib/viewer/src/footer.js +4 -22
- package/lib/viewer/src/header.js +9 -11
- package/lib/viewer/src/index.js +87 -49
- package/lib/viewer/src/utils.js +4 -2
- package/package.json +2 -3
- package/src/viewer/src/chart.js +6 -9
- package/src/viewer/src/footer.js +2 -10
- package/src/viewer/src/header.js +3 -8
- package/src/viewer/src/index.js +70 -34
- package/src/viewer/src/utils.js +3 -1
package/lib/viewer/src/chart.js
CHANGED
|
@@ -59,17 +59,13 @@ var Chart = function Chart(_ref) {
|
|
|
59
59
|
var ChartWrapper = function ChartWrapper() {
|
|
60
60
|
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
61
61
|
|
|
62
|
-
var options = R.over(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}, R.when(R.gt(0), R.always(300))), // 2 = borders
|
|
66
|
-
props.options);
|
|
67
|
-
|
|
68
|
-
if ((0, _utils.isChartNoData)((0, _extends3.default)({}, props, { options: options }))) {
|
|
69
|
-
if (R.isNil(props.fixedHeight)) return _react2.default.createElement(_dotstatsuiteVisions.NoData, { message: props.noData || 'No Data' });
|
|
62
|
+
var options = R.over(R.lensPath(['base', 'height']), R.when(function (h) {
|
|
63
|
+
return h < 0;
|
|
64
|
+
}, R.always(300)))(props.options);
|
|
70
65
|
|
|
66
|
+
if ((0, _utils.isChartNoData)(props)) {
|
|
71
67
|
var height = R.path(['base', 'height'], options);
|
|
72
|
-
var style =
|
|
68
|
+
var style = { height: height };
|
|
73
69
|
return _react2.default.createElement(
|
|
74
70
|
'div',
|
|
75
71
|
{ style: style },
|
package/lib/viewer/src/footer.js
CHANGED
|
@@ -4,10 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
-
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
|
8
|
-
|
|
9
|
-
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
|
|
10
|
-
|
|
11
7
|
var _react = require('react');
|
|
12
8
|
|
|
13
9
|
var _react2 = _interopRequireDefault(_react);
|
|
@@ -16,10 +12,6 @@ var _ramda = require('ramda');
|
|
|
16
12
|
|
|
17
13
|
var R = _interopRequireWildcard(_ramda);
|
|
18
14
|
|
|
19
|
-
var _size = require('@react-hook/size');
|
|
20
|
-
|
|
21
|
-
var _size2 = _interopRequireDefault(_size);
|
|
22
|
-
|
|
23
15
|
var _dotstatsuiteVisions = require('@sis-cc/dotstatsuite-visions');
|
|
24
16
|
|
|
25
17
|
var _ChartLegends = require('./legends/ChartLegends');
|
|
@@ -38,27 +30,17 @@ var Footer = function Footer(_ref) {
|
|
|
38
30
|
source = _ref.source,
|
|
39
31
|
logo = _ref.logo,
|
|
40
32
|
copyright = _ref.copyright,
|
|
41
|
-
onSize = _ref.onSize,
|
|
42
33
|
chartOptions = _ref.chartOptions,
|
|
43
|
-
isSticky = _ref.isSticky
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var _useSize = (0, _size2.default)(target),
|
|
48
|
-
_useSize2 = (0, _slicedToArray3.default)(_useSize, 2),
|
|
49
|
-
width = _useSize2[0],
|
|
50
|
-
height = _useSize2[1];
|
|
51
|
-
|
|
52
|
-
_react2.default.useEffect(function () {
|
|
53
|
-
if (R.is(Function, onSize)) onSize({ width: width, height: height });
|
|
54
|
-
}, [height]);
|
|
34
|
+
isSticky = _ref.isSticky,
|
|
35
|
+
target = _ref.target,
|
|
36
|
+
width = _ref.width;
|
|
55
37
|
|
|
56
38
|
var hasNoLegend = type === 'table' || (0, _utils.isChartNoData)({ data: chartData, type: type });
|
|
57
39
|
var legend = hasNoLegend ? null : _react2.default.createElement(_ChartLegends2.default, { data: chartData, options: chartOptions, type: type, width: width });
|
|
58
40
|
|
|
59
41
|
return _react2.default.createElement(
|
|
60
42
|
'div',
|
|
61
|
-
{ ref: target },
|
|
43
|
+
target ? { ref: target } : {},
|
|
62
44
|
_react2.default.createElement(_dotstatsuiteVisions.DataFooter, {
|
|
63
45
|
source: source,
|
|
64
46
|
logo: logo,
|
package/lib/viewer/src/header.js
CHANGED
|
@@ -4,28 +4,26 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _react = require('react');
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _react2 = _interopRequireDefault(_react);
|
|
14
14
|
|
|
15
15
|
var _dotstatsuiteVisions = require('@sis-cc/dotstatsuite-visions');
|
|
16
16
|
|
|
17
17
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
18
|
|
|
19
|
-
var Header = function Header(
|
|
19
|
+
var Header = function Header(_ref) {
|
|
20
|
+
var target = _ref.target,
|
|
21
|
+
props = (0, _objectWithoutProperties3.default)(_ref, ['target']);
|
|
20
22
|
return _react2.default.createElement(
|
|
21
23
|
'div',
|
|
22
|
-
|
|
24
|
+
target ? { ref: target } : {},
|
|
23
25
|
_react2.default.createElement(_dotstatsuiteVisions.DataHeader, props)
|
|
24
26
|
);
|
|
25
27
|
};
|
|
26
|
-
/*
|
|
27
|
-
putting DataHeader under a div is necessary because sizeMe add a hidden DOM element that
|
|
28
|
-
mess up the Header layout
|
|
29
|
-
*/
|
|
30
28
|
|
|
31
|
-
exports.default =
|
|
29
|
+
exports.default = Header;
|
package/lib/viewer/src/index.js
CHANGED
|
@@ -32,9 +32,9 @@ var _classnames = require('classnames');
|
|
|
32
32
|
|
|
33
33
|
var _classnames2 = _interopRequireDefault(_classnames);
|
|
34
34
|
|
|
35
|
-
var
|
|
35
|
+
var _size = require('@react-hook/size');
|
|
36
36
|
|
|
37
|
-
var
|
|
37
|
+
var _size2 = _interopRequireDefault(_size);
|
|
38
38
|
|
|
39
39
|
var _dotstatsuiteVisions = require('@sis-cc/dotstatsuite-visions');
|
|
40
40
|
|
|
@@ -56,6 +56,8 @@ var _footer = require('./footer');
|
|
|
56
56
|
|
|
57
57
|
var _footer2 = _interopRequireDefault(_footer);
|
|
58
58
|
|
|
59
|
+
var _utils = require('./utils');
|
|
60
|
+
|
|
59
61
|
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; } }
|
|
60
62
|
|
|
61
63
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -86,7 +88,8 @@ var useStyles = (0, _styles.makeStyles)(function () {
|
|
|
86
88
|
var fixedHeight = _ref2.fixedHeight;
|
|
87
89
|
return fixedHeight || '100%';
|
|
88
90
|
},
|
|
89
|
-
overflow: 'hidden'
|
|
91
|
+
overflow: 'hidden',
|
|
92
|
+
position: 'relative'
|
|
90
93
|
}
|
|
91
94
|
};
|
|
92
95
|
});
|
|
@@ -101,7 +104,6 @@ var ViewContent = function ViewContent(_ref3) {
|
|
|
101
104
|
rest = (0, _objectWithoutProperties3.default)(_ref3, ['loading', 'loadingProps', 'type', 'width', 'errorMessage']);
|
|
102
105
|
|
|
103
106
|
if (loading) return _react2.default.createElement(_dotstatsuiteVisions.Loading, (0, _extends3.default)({ message: loading }, loadingProps));
|
|
104
|
-
if (!width) return _react2.default.createElement(_dotstatsuiteVisions.Loading, (0, _extends3.default)({ message: loading }, loadingProps));
|
|
105
107
|
if (errorMessage) return _react2.default.createElement(_dotstatsuiteVisions.NoData, { message: errorMessage });
|
|
106
108
|
|
|
107
109
|
if (type === 'table') {
|
|
@@ -111,9 +113,11 @@ var ViewContent = function ViewContent(_ref3) {
|
|
|
111
113
|
|
|
112
114
|
return _react2.default.createElement(_dotstatsuiteVisions.TableHtml5, (0, _extends3.default)({ isRtl: R.prop('isRtl', rest) }, tableProps));
|
|
113
115
|
}
|
|
116
|
+
if ((0, _utils.isChartDataNotReady)({ data: R.prop('chartData', rest) }) || !width) {
|
|
117
|
+
return _react2.default.createElement(_dotstatsuiteVisions.Loading, null);
|
|
118
|
+
}
|
|
114
119
|
return _react2.default.createElement(_chart2.default, {
|
|
115
120
|
data: R.prop('chartData', rest),
|
|
116
|
-
fixedHeight: R.prop('fixedHeight', rest),
|
|
117
121
|
getAxisOptions: R.prop('getAxisOptions', rest),
|
|
118
122
|
heightOffsets: R.prop('heightOffsets', rest),
|
|
119
123
|
options: R.prop('chartOptions', rest),
|
|
@@ -125,41 +129,29 @@ var ViewContent = function ViewContent(_ref3) {
|
|
|
125
129
|
var Viewer = function Viewer(_ref4) {
|
|
126
130
|
var _cx;
|
|
127
131
|
|
|
128
|
-
var
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
rest = (0, _objectWithoutProperties3.default)(_ref4, ['getResponsiveSize', 'setFooterOffset', 'setHeaderOffset', 'size', 'type']);
|
|
132
|
+
var type = _ref4.type,
|
|
133
|
+
_ref4$targets = _ref4.targets,
|
|
134
|
+
targets = _ref4$targets === undefined ? {} : _ref4$targets,
|
|
135
|
+
width = _ref4.width,
|
|
136
|
+
rest = (0, _objectWithoutProperties3.default)(_ref4, ['type', 'targets', 'width']);
|
|
134
137
|
|
|
135
138
|
var classes = useStyles({
|
|
136
139
|
fixedWidth: rest.fixedWidth,
|
|
137
140
|
fixedHeight: rest.fixedHeight
|
|
138
141
|
});
|
|
139
|
-
(0, _react.useEffect)(function () {
|
|
140
|
-
if (R.is(Function, getResponsiveSize)) {
|
|
141
|
-
getResponsiveSize({
|
|
142
|
-
responsiveWidth: size.width,
|
|
143
|
-
responsiveHeight: size.height
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
142
|
|
|
148
143
|
return _react2.default.createElement(
|
|
149
144
|
'div',
|
|
150
|
-
{
|
|
145
|
+
(0, _extends3.default)({}, targets.viewer ? { ref: targets.viewer } : {}, {
|
|
151
146
|
className: (0, _classnames2.default)(classes.container, (_cx = {}, (0, _defineProperty3.default)(_cx, classes.tableContainer, type === 'table'), (0, _defineProperty3.default)(_cx, classes.chartContainer, type !== 'table'), _cx))
|
|
152
|
-
},
|
|
147
|
+
}),
|
|
153
148
|
_react2.default.createElement(_header2.default, (0, _extends3.default)({
|
|
154
|
-
|
|
155
|
-
return setHeaderOffset(size.height);
|
|
156
|
-
}
|
|
149
|
+
target: targets.header
|
|
157
150
|
}, R.propOr({}, 'headerProps', rest))),
|
|
158
|
-
_react2.default.createElement(ViewContent, (0, _extends3.default)({ type: type, width:
|
|
151
|
+
_react2.default.createElement(ViewContent, (0, _extends3.default)({ type: type, width: width }, rest)),
|
|
159
152
|
_react2.default.createElement(_footer2.default, (0, _extends3.default)({
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
},
|
|
153
|
+
width: width,
|
|
154
|
+
target: targets.footer,
|
|
163
155
|
type: type,
|
|
164
156
|
chartData: R.prop('chartData', rest),
|
|
165
157
|
chartOptions: R.prop('chartOptions', rest)
|
|
@@ -167,38 +159,84 @@ var Viewer = function Viewer(_ref4) {
|
|
|
167
159
|
);
|
|
168
160
|
};
|
|
169
161
|
|
|
162
|
+
var defaultChartHeight = function defaultChartHeight(chartOptions) {
|
|
163
|
+
return R.pipe(R.path(['base', 'height']), function (h) {
|
|
164
|
+
return R.isNil(h) || isNaN(h) ? 0 : h;
|
|
165
|
+
})(chartOptions);
|
|
166
|
+
};
|
|
167
|
+
|
|
170
168
|
var ViewerWrapper = function ViewerWrapper(_ref5) {
|
|
171
169
|
var chartOptions = _ref5.chartOptions,
|
|
172
170
|
type = _ref5.type,
|
|
173
|
-
|
|
171
|
+
getResponsiveSize = _ref5.getResponsiveSize,
|
|
172
|
+
props = (0, _objectWithoutProperties3.default)(_ref5, ['chartOptions', 'type', 'getResponsiveSize']);
|
|
174
173
|
|
|
175
174
|
var theme = (0, _styles.useTheme)();
|
|
176
|
-
|
|
177
|
-
var
|
|
175
|
+
var viewerTarget = _react2.default.useRef(null);
|
|
176
|
+
var headerTarget = _react2.default.useRef(null);
|
|
177
|
+
var footerTarget = _react2.default.useRef(null);
|
|
178
|
+
|
|
179
|
+
var _useSize = (0, _size2.default)(viewerTarget),
|
|
180
|
+
_useSize2 = (0, _slicedToArray3.default)(_useSize, 2),
|
|
181
|
+
viewerWidth = _useSize2[0],
|
|
182
|
+
viewerHeight = _useSize2[1];
|
|
183
|
+
|
|
184
|
+
var _useSize3 = (0, _size2.default)(headerTarget, { initialHeight: -1 }),
|
|
185
|
+
_useSize4 = (0, _slicedToArray3.default)(_useSize3, 2),
|
|
186
|
+
_ = _useSize4[0],
|
|
187
|
+
headerHeight = _useSize4[1];
|
|
188
|
+
|
|
189
|
+
var _useSize5 = (0, _size2.default)(footerTarget, { initialHeight: -1 }),
|
|
190
|
+
_useSize6 = (0, _slicedToArray3.default)(_useSize5, 2),
|
|
191
|
+
___ = _useSize6[0],
|
|
192
|
+
footerHeight = _useSize6[1];
|
|
193
|
+
|
|
194
|
+
var _useState = (0, _react.useState)(0),
|
|
178
195
|
_useState2 = (0, _slicedToArray3.default)(_useState, 2),
|
|
179
|
-
|
|
180
|
-
|
|
196
|
+
chartSvgHeight = _useState2[0],
|
|
197
|
+
setChartSvgHeight = _useState2[1];
|
|
181
198
|
|
|
182
|
-
var
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
fixedHeight: R.path(['base', 'height'], chartOptions)
|
|
193
|
-
});
|
|
199
|
+
var defChartHeight = defaultChartHeight(chartOptions);
|
|
200
|
+
|
|
201
|
+
(0, _react.useEffect)(function () {
|
|
202
|
+
if (R.is(Function, getResponsiveSize) && viewerWidth && headerHeight !== -1 && footerHeight !== -1) {
|
|
203
|
+
getResponsiveSize({
|
|
204
|
+
responsiveWidth: viewerWidth,
|
|
205
|
+
responsiveHeight: viewerHeight
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}, [viewerWidth, viewerHeight]);
|
|
194
209
|
|
|
195
|
-
|
|
210
|
+
(0, _react.useEffect)(function () {
|
|
211
|
+
if (headerHeight !== -1 && footerHeight !== -1 && !isNaN(headerHeight) && !isNaN(footerHeight)) {
|
|
212
|
+
var nextHeight = defChartHeight - headerHeight - footerHeight - 2;
|
|
213
|
+
setChartSvgHeight(nextHeight);
|
|
214
|
+
}
|
|
215
|
+
}, [headerHeight, footerHeight, defChartHeight]);
|
|
216
|
+
|
|
217
|
+
if (type === 'table') {
|
|
218
|
+
return _react2.default.createElement(Viewer, (0, _extends3.default)({}, props, {
|
|
219
|
+
width: viewerWidth,
|
|
220
|
+
type: type
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
196
223
|
|
|
197
|
-
var preparedChartOptions = R.pipe(R.over(R.lensPath(['base', 'width']), R.when(R.anyPass([R.isNil, isNaN]), R.always(
|
|
224
|
+
var preparedChartOptions = R.pipe(R.over(R.lensPath(['base', 'width']), R.when(R.anyPass([R.isNil, isNaN]), R.always(viewerWidth || 0))), R.set(R.lensPath(['base', 'height']), chartSvgHeight), function (chartOptions) {
|
|
198
225
|
return (0, _options2.default)(chartOptions, props.chartData, type, theme, props.timeFormats, props.locale);
|
|
199
226
|
})(chartOptions);
|
|
200
227
|
|
|
201
|
-
return _react2.default.createElement(Viewer, (0, _extends3.default)({},
|
|
228
|
+
return _react2.default.createElement(Viewer, (0, _extends3.default)({}, props, {
|
|
229
|
+
type: type,
|
|
230
|
+
chartOptions: preparedChartOptions,
|
|
231
|
+
fixedWidth: R.path(['base', 'width'], chartOptions),
|
|
232
|
+
fixedHeight: defChartHeight,
|
|
233
|
+
targets: {
|
|
234
|
+
viewer: viewerTarget,
|
|
235
|
+
header: headerTarget,
|
|
236
|
+
footer: footerTarget
|
|
237
|
+
},
|
|
238
|
+
width: viewerWidth
|
|
239
|
+
}));
|
|
202
240
|
};
|
|
203
241
|
|
|
204
|
-
exports.default =
|
|
242
|
+
exports.default = ViewerWrapper;
|
package/lib/viewer/src/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getOptionsFromFont = exports.getFontFromTheme = exports.isChartNoData = undefined;
|
|
6
|
+
exports.getOptionsFromFont = exports.getFontFromTheme = exports.isChartDataNotReady = exports.isChartNoData = undefined;
|
|
7
7
|
|
|
8
8
|
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
|
9
9
|
|
|
@@ -17,7 +17,9 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
|
|
|
17
17
|
|
|
18
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
19
|
|
|
20
|
-
var isChartNoData = exports.isChartNoData = R.anyPass([R.pipe(R.path(['data', 'series']), R.
|
|
20
|
+
var isChartNoData = exports.isChartNoData = R.anyPass([R.pipe(R.path(['data', 'series']), R.isEmpty), R.allPass([R.pipe(R.prop('type'), R.equals('ChoroplethChart'), R.not), R.pipe(R.path(['data', 'series', 0, 'datapoints']), R.anyPass([R.isNil, R.isEmpty]))])]);
|
|
21
|
+
|
|
22
|
+
var isChartDataNotReady = exports.isChartDataNotReady = R.pipe(R.path(['data', 'series']), R.isNil);
|
|
21
23
|
|
|
22
24
|
var getFontFromTheme = exports.getFontFromTheme = function getFontFromTheme(customPath) {
|
|
23
25
|
return R.converge(R.mergeRight, [R.pathOr({}, ['mixins', 'chart', 'main']), R.pathOr({}, R.concat(['mixins', 'chart'], customPath))]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sis-cc/dotstatsuite-components",
|
|
3
3
|
"description": "Set components based on React.",
|
|
4
|
-
"version": "17.
|
|
4
|
+
"version": "17.9.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"author": "OECD",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,8 +31,7 @@
|
|
|
31
31
|
"memoizee": "^0.4.4",
|
|
32
32
|
"numeral": "^2.0.6",
|
|
33
33
|
"prop-types": "^15.6.2",
|
|
34
|
-
"ramda": "^0.26.1"
|
|
35
|
-
"react-sizeme": "^2.3.6"
|
|
34
|
+
"ramda": "^0.26.1"
|
|
36
35
|
},
|
|
37
36
|
"peerDependencies": {
|
|
38
37
|
"@material-ui/core": "^4",
|
package/src/viewer/src/chart.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as R from 'ramda';
|
|
3
|
-
import { NoData } from '@sis-cc/dotstatsuite-visions';
|
|
3
|
+
import { NoData, Loading } from '@sis-cc/dotstatsuite-visions';
|
|
4
4
|
import * as charts from '../../bridge-d3-react/src';
|
|
5
5
|
import filterSeriesRegardingDimensions from './chartUtils/series';
|
|
6
6
|
import AxisLegend from './legends/AxisLegend';
|
|
@@ -25,17 +25,14 @@ const Chart = ({ options, series, type, width, getAxisOptions }) => {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const ChartWrapper = (props = {}) => {
|
|
28
|
-
const options = R.over(
|
|
28
|
+
const options = R.over(
|
|
29
29
|
R.lensPath(['base', 'height']),
|
|
30
|
-
R.
|
|
31
|
-
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
if (isChartNoData({...props, options })) {
|
|
35
|
-
if (R.isNil(props.fixedHeight)) return <NoData message={props.noData || 'No Data'} />;
|
|
30
|
+
R.when(h => h < 0, R.always(300))
|
|
31
|
+
)(props.options);
|
|
36
32
|
|
|
33
|
+
if (isChartNoData(props)) {
|
|
37
34
|
const height = R.path(['base', 'height'], options);
|
|
38
|
-
const style =
|
|
35
|
+
const style = { height };
|
|
39
36
|
return (
|
|
40
37
|
<div style={style}>
|
|
41
38
|
<NoData message={props.noData || 'No Data'} />
|
package/src/viewer/src/footer.js
CHANGED
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as R from 'ramda';
|
|
3
|
-
import useSize from '@react-hook/size';
|
|
4
3
|
import { DataFooter } from '@sis-cc/dotstatsuite-visions';
|
|
5
4
|
import ChartLegends from './legends/ChartLegends';
|
|
6
5
|
import { isChartNoData } from './utils';
|
|
7
6
|
|
|
8
|
-
const Footer = ({ type, chartData, source, logo, copyright,
|
|
9
|
-
const target = React.useRef(null);
|
|
10
|
-
const [width, height] = useSize(target);
|
|
11
|
-
|
|
12
|
-
React.useEffect(() => {
|
|
13
|
-
if (R.is(Function, onSize)) onSize({width, height});
|
|
14
|
-
}, [height]);
|
|
15
|
-
|
|
7
|
+
const Footer = ({ type, chartData, source, logo, copyright, chartOptions, isSticky, target, width }) => {
|
|
16
8
|
const hasNoLegend = type === 'table' || isChartNoData({ data: chartData, type });
|
|
17
9
|
const legend = hasNoLegend ? null : <ChartLegends data={chartData} options={chartOptions} type={type} width={width} />;
|
|
18
10
|
|
|
19
11
|
return (
|
|
20
|
-
<div
|
|
12
|
+
<div {...(target ? { ref: target } : {})}>
|
|
21
13
|
<DataFooter
|
|
22
14
|
source={source}
|
|
23
15
|
logo={logo}
|
package/src/viewer/src/header.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import sizeMe from 'react-sizeme';
|
|
3
2
|
import { DataHeader } from '@sis-cc/dotstatsuite-visions';
|
|
4
3
|
|
|
5
|
-
const Header = (props) => (
|
|
6
|
-
<div>
|
|
4
|
+
const Header = ({ target, ...props }) => (
|
|
5
|
+
<div {...(target ? { ref: target } : {})}>
|
|
7
6
|
<DataHeader {...props} />
|
|
8
7
|
</div>
|
|
9
8
|
);
|
|
10
|
-
/*
|
|
11
|
-
putting DataHeader under a div is necessary because sizeMe add a hidden DOM element that
|
|
12
|
-
mess up the Header layout
|
|
13
|
-
*/
|
|
14
9
|
|
|
15
|
-
export default
|
|
10
|
+
export default Header;
|
package/src/viewer/src/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import * as R from 'ramda';
|
|
3
3
|
import cx from 'classnames';
|
|
4
|
-
import
|
|
4
|
+
import useSize from '@react-hook/size';
|
|
5
5
|
import { Loading, NoData, TableHtml5 } from '@sis-cc/dotstatsuite-visions';
|
|
6
6
|
import { useTheme, makeStyles } from '@material-ui/core/styles';
|
|
7
7
|
import getChartOptions from './chartUtils/options';
|
|
8
8
|
import Header from './header';
|
|
9
9
|
import Chart from './chart';
|
|
10
10
|
import Footer from './footer';
|
|
11
|
+
import { isChartDataNotReady } from './utils';
|
|
11
12
|
|
|
12
13
|
const useStyles = makeStyles(() => ({
|
|
13
14
|
container: {
|
|
@@ -28,14 +29,16 @@ const useStyles = makeStyles(() => ({
|
|
|
28
29
|
chartContainer: {
|
|
29
30
|
width: ({ fixedWidth }) => fixedWidth || '100%',
|
|
30
31
|
height: ({ fixedHeight }) => fixedHeight || '100%',
|
|
31
|
-
overflow: 'hidden'
|
|
32
|
+
overflow: 'hidden',
|
|
33
|
+
position: 'relative'
|
|
32
34
|
}
|
|
33
35
|
}));
|
|
34
36
|
|
|
35
37
|
const ViewContent = ({ loading, loadingProps={}, type, width, errorMessage, ...rest }) => {
|
|
36
|
-
if (loading)
|
|
37
|
-
|
|
38
|
-
if (errorMessage)
|
|
38
|
+
if (loading)
|
|
39
|
+
return <Loading message={loading} {...loadingProps} />;
|
|
40
|
+
if (errorMessage)
|
|
41
|
+
return <NoData message={errorMessage} />;
|
|
39
42
|
|
|
40
43
|
if (type === 'table') {
|
|
41
44
|
const tableProps = R.propOr({}, 'tableProps', rest);
|
|
@@ -44,10 +47,12 @@ const ViewContent = ({ loading, loadingProps={}, type, width, errorMessage, ...r
|
|
|
44
47
|
|
|
45
48
|
return <TableHtml5 isRtl={R.prop('isRtl', rest)} {...tableProps} />;
|
|
46
49
|
}
|
|
50
|
+
if (isChartDataNotReady({ data: R.prop('chartData', rest) }) || !width) {
|
|
51
|
+
return <Loading />;
|
|
52
|
+
}
|
|
47
53
|
return (
|
|
48
54
|
<Chart
|
|
49
55
|
data={R.prop('chartData', rest)}
|
|
50
|
-
fixedHeight={R.prop('fixedHeight', rest)}
|
|
51
56
|
getAxisOptions={R.prop('getAxisOptions', rest)}
|
|
52
57
|
heightOffsets={R.prop('heightOffsets', rest)}
|
|
53
58
|
options={R.prop('chartOptions', rest)}
|
|
@@ -57,34 +62,28 @@ const ViewContent = ({ loading, loadingProps={}, type, width, errorMessage, ...r
|
|
|
57
62
|
);
|
|
58
63
|
};
|
|
59
64
|
|
|
60
|
-
const Viewer = ({
|
|
65
|
+
const Viewer = ({ type, targets={}, width, ...rest }) => {
|
|
61
66
|
const classes = useStyles({
|
|
62
67
|
fixedWidth: rest.fixedWidth,
|
|
63
68
|
fixedHeight: rest.fixedHeight
|
|
64
69
|
});
|
|
65
|
-
useEffect(() => {
|
|
66
|
-
if (R.is(Function, getResponsiveSize)) {
|
|
67
|
-
getResponsiveSize({
|
|
68
|
-
responsiveWidth: size.width,
|
|
69
|
-
responsiveHeight: size.height
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
70
|
|
|
74
71
|
return (
|
|
75
72
|
<div
|
|
73
|
+
{...(targets.viewer ? { ref: targets.viewer } : {})}
|
|
76
74
|
className={cx(classes.container, {
|
|
77
75
|
[classes.tableContainer]: type === 'table',
|
|
78
76
|
[classes.chartContainer]: type !== 'table'
|
|
79
77
|
})}
|
|
80
78
|
>
|
|
81
79
|
<Header
|
|
82
|
-
|
|
80
|
+
target={targets.header}
|
|
83
81
|
{...R.propOr({}, 'headerProps', rest)}
|
|
84
82
|
/>
|
|
85
|
-
<ViewContent type={type} width={
|
|
83
|
+
<ViewContent type={type} width={width} {...rest} />
|
|
86
84
|
<Footer
|
|
87
|
-
|
|
85
|
+
width={width}
|
|
86
|
+
target={targets.footer}
|
|
88
87
|
type={type}
|
|
89
88
|
chartData={R.prop('chartData', rest)}
|
|
90
89
|
chartOptions={R.prop('chartOptions', rest)}
|
|
@@ -94,29 +93,66 @@ const Viewer = ({ getResponsiveSize, setFooterOffset, setHeaderOffset, size, typ
|
|
|
94
93
|
);
|
|
95
94
|
};
|
|
96
95
|
|
|
97
|
-
const
|
|
96
|
+
const defaultChartHeight = chartOptions => R.pipe(
|
|
97
|
+
R.path(['base', 'height']),
|
|
98
|
+
h => (R.isNil(h) || isNaN(h)) ? 0 : h
|
|
99
|
+
)(chartOptions);
|
|
100
|
+
|
|
101
|
+
const ViewerWrapper = ({ chartOptions, type, getResponsiveSize, ...props }) => {
|
|
98
102
|
const theme = useTheme();
|
|
99
|
-
const
|
|
103
|
+
const viewerTarget = React.useRef(null);
|
|
104
|
+
const headerTarget = React.useRef(null);
|
|
105
|
+
const footerTarget = React.useRef(null);
|
|
106
|
+
const [viewerWidth, viewerHeight] = useSize(viewerTarget);
|
|
107
|
+
const [_, headerHeight] = useSize(headerTarget, { initialHeight: -1 });
|
|
108
|
+
const [___, footerHeight] = useSize(footerTarget, { initialHeight: -1 });
|
|
109
|
+
const [chartSvgHeight, setChartSvgHeight] = useState(0);
|
|
110
|
+
const defChartHeight = defaultChartHeight(chartOptions);
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (R.is(Function, getResponsiveSize) && viewerWidth && headerHeight !== -1 && footerHeight !== -1) {
|
|
114
|
+
getResponsiveSize({
|
|
115
|
+
responsiveWidth: viewerWidth,
|
|
116
|
+
responsiveHeight: viewerHeight
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}, [viewerWidth, viewerHeight]);
|
|
100
120
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
fixedWidth: R.path(['base', 'width'], chartOptions),
|
|
108
|
-
fixedHeight: R.path(['base', 'height'], chartOptions),
|
|
109
|
-
};
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (headerHeight !== -1 && footerHeight !== -1 && !isNaN(headerHeight) && !isNaN(footerHeight)) {
|
|
123
|
+
const nextHeight = defChartHeight - headerHeight - footerHeight - 2;
|
|
124
|
+
setChartSvgHeight(nextHeight);
|
|
125
|
+
}
|
|
126
|
+
}, [headerHeight, footerHeight, defChartHeight]);
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
|
|
129
|
+
if (type === 'table') {
|
|
130
|
+
return <Viewer
|
|
131
|
+
{...props}
|
|
132
|
+
width={viewerWidth}
|
|
133
|
+
type={type}
|
|
134
|
+
/>;
|
|
135
|
+
}
|
|
112
136
|
|
|
113
137
|
const preparedChartOptions = R.pipe(
|
|
114
|
-
R.over(R.lensPath(['base', 'width']), R.when(R.anyPass([R.isNil, isNaN]), R.always(
|
|
115
|
-
R.
|
|
138
|
+
R.over(R.lensPath(['base', 'width']), R.when(R.anyPass([R.isNil, isNaN]), R.always(viewerWidth || 0))),
|
|
139
|
+
R.set(R.lensPath(['base', 'height']), chartSvgHeight),
|
|
116
140
|
chartOptions => getChartOptions(chartOptions, props.chartData, type, theme, props.timeFormats, props.locale),
|
|
117
141
|
)(chartOptions);
|
|
118
142
|
|
|
119
|
-
return <Viewer
|
|
143
|
+
return <Viewer
|
|
144
|
+
{...props}
|
|
145
|
+
type={type}
|
|
146
|
+
chartOptions={preparedChartOptions}
|
|
147
|
+
fixedWidth={R.path(['base', 'width'], chartOptions)}
|
|
148
|
+
fixedHeight={defChartHeight}
|
|
149
|
+
targets={{
|
|
150
|
+
viewer: viewerTarget,
|
|
151
|
+
header: headerTarget,
|
|
152
|
+
footer: footerTarget
|
|
153
|
+
}}
|
|
154
|
+
width={viewerWidth}
|
|
155
|
+
/>;
|
|
120
156
|
};
|
|
121
157
|
|
|
122
|
-
export default
|
|
158
|
+
export default ViewerWrapper;
|
package/src/viewer/src/utils.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as R from 'ramda';
|
|
2
2
|
|
|
3
3
|
export const isChartNoData = R.anyPass([
|
|
4
|
-
R.pipe(R.path(['data', 'series']), R.
|
|
4
|
+
R.pipe(R.path(['data', 'series']), R.isEmpty),
|
|
5
5
|
R.allPass([
|
|
6
6
|
R.pipe(R.prop('type'), R.equals('ChoroplethChart'), R.not),
|
|
7
7
|
R.pipe(R.path(['data', 'series', 0, 'datapoints']), R.anyPass([R.isNil, R.isEmpty]))
|
|
8
8
|
])
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
+
export const isChartDataNotReady = R.pipe(R.path(['data', 'series']), R.isNil);
|
|
12
|
+
|
|
11
13
|
export const getFontFromTheme = customPath => R.converge(
|
|
12
14
|
R.mergeRight,
|
|
13
15
|
[R.pathOr({}, ['mixins', 'chart', 'main']), R.pathOr({}, R.concat(['mixins', 'chart'], customPath))]
|