@dhis2/analytics 24.5.0-alpha.1 → 24.6.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/CHANGELOG.md +6 -4
- package/build/cjs/components/PeriodDimension/PeriodTransfer.js +4 -17
- package/build/cjs/components/PeriodDimension/__tests__/PeriodSelector.spec.js +0 -5
- package/build/cjs/components/PeriodDimension/utils/fixedPeriods.js +478 -205
- package/build/cjs/locales/en/translations.json +14 -0
- package/build/cjs/visualizations/config/generators/dhis/singleValue.js +76 -23
- package/build/cjs/visualizations/config/index.js +2 -1
- package/build/es/components/PeriodDimension/PeriodTransfer.js +4 -15
- package/build/es/components/PeriodDimension/__tests__/PeriodSelector.spec.js +0 -5
- package/build/es/components/PeriodDimension/utils/fixedPeriods.js +477 -203
- package/build/es/locales/en/translations.json +14 -0
- package/build/es/visualizations/config/generators/dhis/singleValue.js +79 -26
- package/build/es/visualizations/config/index.js +2 -1
- package/package.json +1 -7
|
@@ -182,6 +182,20 @@
|
|
|
182
182
|
"Fixed periods": "Fixed periods",
|
|
183
183
|
"Selected Periods": "Selected Periods",
|
|
184
184
|
"No periods selected": "No periods selected",
|
|
185
|
+
"January": "January",
|
|
186
|
+
"February": "February",
|
|
187
|
+
"March": "March",
|
|
188
|
+
"April": "April",
|
|
189
|
+
"May": "May",
|
|
190
|
+
"June": "June",
|
|
191
|
+
"July": "July",
|
|
192
|
+
"August": "August",
|
|
193
|
+
"September": "September",
|
|
194
|
+
"October": "October",
|
|
195
|
+
"November": "November",
|
|
196
|
+
"December": "December",
|
|
197
|
+
"Week {{weekNumber}}": "Week {{weekNumber}}",
|
|
198
|
+
"Bi-Week {{biWeekNumber}}": "Bi-Week {{biWeekNumber}}",
|
|
185
199
|
"Daily": "Daily",
|
|
186
200
|
"Weekly": "Weekly",
|
|
187
201
|
"Weekly (Start Wednesday)": "Weekly (Start Wednesday)",
|
|
@@ -15,10 +15,9 @@ const svgNS = 'http://www.w3.org/2000/svg';
|
|
|
15
15
|
|
|
16
16
|
const generateValueSVG = _ref => {
|
|
17
17
|
let {
|
|
18
|
-
value,
|
|
19
18
|
formattedValue,
|
|
20
19
|
subText,
|
|
21
|
-
|
|
20
|
+
valueColor,
|
|
22
21
|
noData,
|
|
23
22
|
y
|
|
24
23
|
} = _ref;
|
|
@@ -33,8 +32,8 @@ const generateValueSVG = _ref => {
|
|
|
33
32
|
|
|
34
33
|
let fillColor = _ui.colors.grey900;
|
|
35
34
|
|
|
36
|
-
if (
|
|
37
|
-
fillColor =
|
|
35
|
+
if (valueColor) {
|
|
36
|
+
fillColor = valueColor;
|
|
38
37
|
} else if (formattedValue === noData.text) {
|
|
39
38
|
fillColor = _ui.colors.grey600;
|
|
40
39
|
}
|
|
@@ -75,7 +74,7 @@ const generateValueSVG = _ref => {
|
|
|
75
74
|
|
|
76
75
|
const generateDashboardItem = (config, _ref2) => {
|
|
77
76
|
let {
|
|
78
|
-
|
|
77
|
+
valueColor,
|
|
79
78
|
noData
|
|
80
79
|
} = _ref2;
|
|
81
80
|
const container = document.createElement('div');
|
|
@@ -98,10 +97,9 @@ const generateDashboardItem = (config, _ref2) => {
|
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
container.appendChild(generateValueSVG({
|
|
101
|
-
value: config.value,
|
|
102
100
|
formattedValue: config.formattedValue,
|
|
103
101
|
subText: config.subText,
|
|
104
|
-
|
|
102
|
+
valueColor,
|
|
105
103
|
noData,
|
|
106
104
|
y: 40
|
|
107
105
|
}));
|
|
@@ -138,7 +136,8 @@ const getXFromTextAlign = textAlign => {
|
|
|
138
136
|
|
|
139
137
|
const generateDVItem = (config, _ref3) => {
|
|
140
138
|
let {
|
|
141
|
-
|
|
139
|
+
valueColor,
|
|
140
|
+
titleColor,
|
|
142
141
|
parentEl,
|
|
143
142
|
fontStyle,
|
|
144
143
|
noData
|
|
@@ -161,7 +160,13 @@ const generateDVItem = (config, _ref3) => {
|
|
|
161
160
|
title.setAttribute('font-size', "".concat(titleFontStyle[_fontStyle.FONT_STYLE_OPTION_FONT_SIZE], "px"));
|
|
162
161
|
title.setAttribute('font-weight', titleFontStyle[_fontStyle.FONT_STYLE_OPTION_BOLD] ? _fontStyle.FONT_STYLE_OPTION_BOLD : 'normal');
|
|
163
162
|
title.setAttribute('font-style', titleFontStyle[_fontStyle.FONT_STYLE_OPTION_ITALIC] ? _fontStyle.FONT_STYLE_OPTION_ITALIC : 'normal');
|
|
164
|
-
|
|
163
|
+
|
|
164
|
+
if (titleColor && titleFontStyle[_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR] === _fontStyle.defaultFontStyle[_fontStyle.FONT_STYLE_VISUALIZATION_TITLE][_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR]) {
|
|
165
|
+
title.setAttribute('fill', titleColor);
|
|
166
|
+
} else {
|
|
167
|
+
title.setAttribute('fill', titleFontStyle[_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR]);
|
|
168
|
+
}
|
|
169
|
+
|
|
165
170
|
title.setAttribute('data-test', 'visualization-title');
|
|
166
171
|
|
|
167
172
|
if (config.title) {
|
|
@@ -178,7 +183,13 @@ const generateDVItem = (config, _ref3) => {
|
|
|
178
183
|
subtitle.setAttribute('font-size', "".concat(subtitleFontStyle[_fontStyle.FONT_STYLE_OPTION_FONT_SIZE], "px"));
|
|
179
184
|
subtitle.setAttribute('font-weight', subtitleFontStyle[_fontStyle.FONT_STYLE_OPTION_BOLD] ? _fontStyle.FONT_STYLE_OPTION_BOLD : 'normal');
|
|
180
185
|
subtitle.setAttribute('font-style', subtitleFontStyle[_fontStyle.FONT_STYLE_OPTION_ITALIC] ? _fontStyle.FONT_STYLE_OPTION_ITALIC : 'normal');
|
|
181
|
-
|
|
186
|
+
|
|
187
|
+
if (titleColor && subtitleFontStyle[_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR] === _fontStyle.defaultFontStyle[_fontStyle.FONT_STYLE_VISUALIZATION_SUBTITLE][_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR]) {
|
|
188
|
+
subtitle.setAttribute('fill', titleColor);
|
|
189
|
+
} else {
|
|
190
|
+
subtitle.setAttribute('fill', subtitleFontStyle[_fontStyle.FONT_STYLE_OPTION_TEXT_COLOR]);
|
|
191
|
+
}
|
|
192
|
+
|
|
182
193
|
subtitle.setAttribute('data-test', 'visualization-subtitle');
|
|
183
194
|
|
|
184
195
|
if (config.subtitle) {
|
|
@@ -187,34 +198,76 @@ const generateDVItem = (config, _ref3) => {
|
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
svg.appendChild(generateValueSVG({
|
|
190
|
-
value: config.value,
|
|
191
201
|
formattedValue: config.formattedValue,
|
|
192
202
|
subText: config.subText,
|
|
193
|
-
|
|
203
|
+
valueColor,
|
|
194
204
|
noData,
|
|
195
205
|
y: 20
|
|
196
206
|
}));
|
|
197
207
|
return svg;
|
|
198
208
|
};
|
|
199
209
|
|
|
210
|
+
const shouldUseContrastColor = inputColor => {
|
|
211
|
+
// based on https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
|
212
|
+
var color = inputColor.charAt(0) === '#' ? inputColor.substring(1, 7) : inputColor;
|
|
213
|
+
var r = parseInt(color.substring(0, 2), 16); // hexToR
|
|
214
|
+
|
|
215
|
+
var g = parseInt(color.substring(2, 4), 16); // hexToG
|
|
216
|
+
|
|
217
|
+
var b = parseInt(color.substring(4, 6), 16); // hexToB
|
|
218
|
+
|
|
219
|
+
var uicolors = [r / 255, g / 255, b / 255];
|
|
220
|
+
var c = uicolors.map(col => {
|
|
221
|
+
if (col <= 0.03928) {
|
|
222
|
+
return col / 12.92;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return Math.pow((col + 0.055) / 1.055, 2.4);
|
|
226
|
+
});
|
|
227
|
+
var L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
|
228
|
+
return L <= 0.179;
|
|
229
|
+
};
|
|
230
|
+
|
|
200
231
|
function _default(config, parentEl, _ref4) {
|
|
201
232
|
let {
|
|
202
233
|
dashboard,
|
|
203
234
|
legendSets,
|
|
204
235
|
fontStyle,
|
|
205
|
-
noData
|
|
236
|
+
noData,
|
|
237
|
+
legendOptions
|
|
206
238
|
} = _ref4;
|
|
207
|
-
const legendSet = legendSets[0];
|
|
239
|
+
const legendSet = legendOptions && legendSets[0];
|
|
240
|
+
const legendColor = legendSet && (0, _legends.getColorByValueFromLegendSet)(legendSet, config.value);
|
|
241
|
+
let valueColor, titleColor;
|
|
242
|
+
|
|
243
|
+
if (legendColor) {
|
|
244
|
+
if (legendOptions.style === _legends.LEGEND_DISPLAY_STYLE_FILL) {
|
|
245
|
+
parentEl.style.background = legendColor;
|
|
246
|
+
valueColor = titleColor = shouldUseContrastColor(legendColor) && _ui.colors.white;
|
|
247
|
+
} else {
|
|
248
|
+
valueColor = legendColor;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
208
252
|
parentEl.style.overflow = 'hidden';
|
|
209
253
|
parentEl.style.display = 'flex';
|
|
210
254
|
parentEl.style.justifyContent = 'center';
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
255
|
+
parentEl.style.borderRadius = _ui.spacers.dp8;
|
|
256
|
+
|
|
257
|
+
if (dashboard) {
|
|
258
|
+
return generateDashboardItem(config, {
|
|
259
|
+
valueColor,
|
|
260
|
+
noData
|
|
261
|
+
});
|
|
262
|
+
} else {
|
|
263
|
+
parentEl.style.margin = _ui.spacers.dp8;
|
|
264
|
+
parentEl.style.height = "calc(100% - (".concat(_ui.spacers.dp8, " * 2))");
|
|
265
|
+
return generateDVItem(config, {
|
|
266
|
+
valueColor,
|
|
267
|
+
titleColor,
|
|
268
|
+
parentEl,
|
|
269
|
+
fontStyle,
|
|
270
|
+
noData
|
|
271
|
+
});
|
|
272
|
+
}
|
|
220
273
|
}
|
|
@@ -80,6 +80,7 @@ function _default(_ref) {
|
|
|
80
80
|
|
|
81
81
|
this.createVisualization = () => _generator(this.getConfig(), el, { ...extraOptions,
|
|
82
82
|
noData: DEFAULT_EXTRA_OPTIONS.noData,
|
|
83
|
-
fontStyle: layout.fontStyle
|
|
83
|
+
fontStyle: layout.fontStyle,
|
|
84
|
+
legendOptions: layout.legend
|
|
84
85
|
});
|
|
85
86
|
}
|
|
@@ -2,8 +2,6 @@ import _JSXStyle from "styled-jsx/style";
|
|
|
2
2
|
|
|
3
3
|
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
4
|
|
|
5
|
-
import { useConfig } from '@dhis2/app-runtime';
|
|
6
|
-
import { getNowInCalendar } from '@dhis2/multi-calendar-dates';
|
|
7
5
|
import { TabBar, Tab, Transfer } from '@dhis2/ui';
|
|
8
6
|
import PropTypes from 'prop-types';
|
|
9
7
|
import React, { useState } from 'react';
|
|
@@ -27,18 +25,9 @@ const PeriodTransfer = _ref => {
|
|
|
27
25
|
rightFooter,
|
|
28
26
|
excludedPeriodTypes
|
|
29
27
|
} = _ref;
|
|
30
|
-
const {
|
|
31
|
-
systemInfo
|
|
32
|
-
} = useConfig();
|
|
33
|
-
const {
|
|
34
|
-
calendar = 'gregory'
|
|
35
|
-
} = systemInfo;
|
|
36
28
|
const defaultRelativePeriodType = excludedPeriodTypes.includes(MONTHLY) ? getRelativePeriodsOptionsById(QUARTERLY) : getRelativePeriodsOptionsById(MONTHLY);
|
|
37
|
-
const defaultFixedPeriodType = excludedPeriodTypes.includes(MONTHLY) ? getFixedPeriodsOptionsById(QUARTERLY
|
|
38
|
-
const
|
|
39
|
-
// there is still a pending decision in Temporal regarding which era to use by default: https://github.com/js-temporal/temporal-polyfill/blob/9350ee7dd0d29f329fc097debf923a517c32f813/lib/calendar.ts#L1964
|
|
40
|
-
|
|
41
|
-
const defaultFixedPeriodYear = now.eraYear || now.year;
|
|
29
|
+
const defaultFixedPeriodType = excludedPeriodTypes.includes(MONTHLY) ? getFixedPeriodsOptionsById(QUARTERLY) : getFixedPeriodsOptionsById(MONTHLY);
|
|
30
|
+
const defaultFixedPeriodYear = new Date().getFullYear();
|
|
42
31
|
|
|
43
32
|
const fixedPeriodConfig = year => ({
|
|
44
33
|
offset: year - defaultFixedPeriodYear,
|
|
@@ -60,7 +49,7 @@ const PeriodTransfer = _ref => {
|
|
|
60
49
|
const onIsRelativeClick = state => {
|
|
61
50
|
if (state !== isRelative) {
|
|
62
51
|
setIsRelative(state);
|
|
63
|
-
setAllPeriods(state ? getRelativePeriodsOptionsById(relativeFilter.periodType).getPeriods() : getFixedPeriodsOptionsById(fixedFilter.periodType
|
|
52
|
+
setAllPeriods(state ? getRelativePeriodsOptionsById(relativeFilter.periodType).getPeriods() : getFixedPeriodsOptionsById(fixedFilter.periodType).getPeriods(fixedPeriodConfig(Number(fixedFilter.year))));
|
|
64
53
|
}
|
|
65
54
|
};
|
|
66
55
|
|
|
@@ -113,7 +102,7 @@ const PeriodTransfer = _ref => {
|
|
|
113
102
|
|
|
114
103
|
const onSelectFixedPeriods = filter => {
|
|
115
104
|
setFixedFilter(filter);
|
|
116
|
-
setAllPeriods(getFixedPeriodsOptionsById(filter.periodType
|
|
105
|
+
setAllPeriods(getFixedPeriodsOptionsById(filter.periodType).getPeriods(fixedPeriodConfig(Number(filter.year))));
|
|
117
106
|
};
|
|
118
107
|
|
|
119
108
|
const renderEmptySelection = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", {
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import PeriodTransfer from '../PeriodTransfer.js';
|
|
4
|
-
jest.mock('@dhis2/app-runtime', () => ({
|
|
5
|
-
useConfig: () => ({
|
|
6
|
-
systemInfo: {}
|
|
7
|
-
})
|
|
8
|
-
}));
|
|
9
4
|
describe('The Period Selector component', () => {
|
|
10
5
|
let props;
|
|
11
6
|
let shallowPeriodTransfer;
|