@dhis2/analytics 26.2.0-cumulative-values-alpha.1 → 26.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/build/cjs/api/analytics/__tests__/AnalyticsTrackedEntities.spec.js +0 -44
- package/build/cjs/api/analytics/__tests__/__snapshots__/AnalyticsTrackedEntities.spec.js.snap +0 -3
- package/build/cjs/components/RichText/Editor.bk/Editor.js +0 -40
- package/build/cjs/components/RichText/Editor.bk/__tests__/Editor.spec.js +0 -29
- package/build/cjs/components/RichText/Editor.bk/__tests__/convertCtrlKey.spec.js +0 -205
- package/build/cjs/components/RichText/Editor.bk/convertCtrlKey.js +0 -87
- package/build/cjs/components/RichText/Parser.bk/MdParser.js +0 -107
- package/build/cjs/components/RichText/Parser.bk/Parser.js +0 -34
- package/build/cjs/components/RichText/Parser.bk/__tests__/MdParser.spec.js +0 -34
- package/build/cjs/components/RichText/Parser.bk/__tests__/Parser.spec.js +0 -41
- package/build/cjs/visualizations/config/generators/dhis/singleValue.js.xp1 +0 -478
- package/build/es/api/analytics/__tests__/AnalyticsTrackedEntities.spec.js +0 -41
- package/build/es/api/analytics/__tests__/__snapshots__/AnalyticsTrackedEntities.spec.js.snap +0 -3
- package/build/es/components/RichText/Editor.bk/Editor.js +0 -30
- package/build/es/components/RichText/Editor.bk/__tests__/Editor.spec.js +0 -26
- package/build/es/components/RichText/Editor.bk/__tests__/convertCtrlKey.spec.js +0 -202
- package/build/es/components/RichText/Editor.bk/convertCtrlKey.js +0 -80
- package/build/es/components/RichText/Parser.bk/MdParser.js +0 -99
- package/build/es/components/RichText/Parser.bk/Parser.js +0 -24
- package/build/es/components/RichText/Parser.bk/__tests__/MdParser.spec.js +0 -31
- package/build/es/components/RichText/Parser.bk/__tests__/Parser.spec.js +0 -38
- package/build/es/visualizations/config/generators/dhis/singleValue.js.xp1 +0 -478
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
import { colors, spacers } from '@dhis2/ui'
|
|
2
|
-
import {
|
|
3
|
-
FONT_STYLE_VISUALIZATION_TITLE,
|
|
4
|
-
FONT_STYLE_VISUALIZATION_SUBTITLE,
|
|
5
|
-
FONT_STYLE_OPTION_FONT_SIZE,
|
|
6
|
-
FONT_STYLE_OPTION_TEXT_COLOR,
|
|
7
|
-
FONT_STYLE_OPTION_TEXT_ALIGN,
|
|
8
|
-
FONT_STYLE_OPTION_ITALIC,
|
|
9
|
-
FONT_STYLE_OPTION_BOLD,
|
|
10
|
-
TEXT_ALIGN_LEFT,
|
|
11
|
-
TEXT_ALIGN_RIGHT,
|
|
12
|
-
TEXT_ALIGN_CENTER,
|
|
13
|
-
mergeFontStyleWithDefault,
|
|
14
|
-
defaultFontStyle,
|
|
15
|
-
} from '../../../../modules/fontStyle.js'
|
|
16
|
-
import {
|
|
17
|
-
getColorByValueFromLegendSet,
|
|
18
|
-
LEGEND_DISPLAY_STYLE_FILL,
|
|
19
|
-
} from '../../../../modules/legends.js'
|
|
20
|
-
|
|
21
|
-
const svgNS = 'http://www.w3.org/2000/svg'
|
|
22
|
-
|
|
23
|
-
const generateValueSVG = ({
|
|
24
|
-
formattedValue,
|
|
25
|
-
subText,
|
|
26
|
-
valueColor,
|
|
27
|
-
icon,
|
|
28
|
-
noData,
|
|
29
|
-
containerWidth,
|
|
30
|
-
containerHeight,
|
|
31
|
-
}) => {
|
|
32
|
-
const ratio = containerHeight / containerWidth
|
|
33
|
-
const iconSize = containerHeight * 0.8 //300
|
|
34
|
-
const iconPadding = 50
|
|
35
|
-
const textSize = iconSize * 0.85
|
|
36
|
-
const textWidth = textSize * 0.75 * formattedValue.length
|
|
37
|
-
|
|
38
|
-
const showIcon = icon && formattedValue !== noData.text
|
|
39
|
-
|
|
40
|
-
let viewBoxWidth = textWidth
|
|
41
|
-
|
|
42
|
-
if (showIcon) {
|
|
43
|
-
viewBoxWidth += iconSize + iconPadding
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const viewBoxHeight = viewBoxWidth * ratio
|
|
47
|
-
|
|
48
|
-
const svgValue = document.createElementNS(svgNS, 'svg')
|
|
49
|
-
svgValue.setAttribute('viewBox', `0 0 ${viewBoxWidth} ${viewBoxHeight}`)
|
|
50
|
-
svgValue.setAttribute('width', containerWidth * 0.98)
|
|
51
|
-
svgValue.setAttribute('height', containerHeight * 0.98)
|
|
52
|
-
svgValue.setAttribute('x', '50%')
|
|
53
|
-
svgValue.setAttribute('y', '50%')
|
|
54
|
-
svgValue.setAttribute('style', 'overflow: visible')
|
|
55
|
-
|
|
56
|
-
let fillColor = colors.grey900
|
|
57
|
-
|
|
58
|
-
if (valueColor) {
|
|
59
|
-
fillColor = valueColor
|
|
60
|
-
} else if (formattedValue === noData.text) {
|
|
61
|
-
fillColor = colors.grey600
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const group = document.createElementNS(svgNS, 'g')
|
|
65
|
-
//group.setAttribute('font-size', '4em') // XXX
|
|
66
|
-
group.setAttribute('style', `color: ${fillColor}`)
|
|
67
|
-
|
|
68
|
-
// show icon if configured in maintenance app
|
|
69
|
-
if (showIcon) {
|
|
70
|
-
const iconSvgNode = document.createElementNS(svgNS, 'svg')
|
|
71
|
-
iconSvgNode.setAttribute('width', iconSize)
|
|
72
|
-
iconSvgNode.setAttribute('height', iconSize)
|
|
73
|
-
iconSvgNode.setAttribute('viewBox', '0 0 48 48')
|
|
74
|
-
iconSvgNode.setAttribute('y', `-${iconSize / 2}`)
|
|
75
|
-
iconSvgNode.setAttribute('x', `-${(textWidth + iconPadding) / 2}`)
|
|
76
|
-
//iconSvgNode.setAttribute('style', `color: ${fillColor}`)
|
|
77
|
-
|
|
78
|
-
// embed icon to allow changing color
|
|
79
|
-
// (elements with fill need to use "currentColor" for this to work)
|
|
80
|
-
fetch(icon)
|
|
81
|
-
.then((res) => res.text())
|
|
82
|
-
.then((originalSvgIcon) =>
|
|
83
|
-
originalSvgIcon.replaceAll('#333333', 'currentColor')
|
|
84
|
-
)
|
|
85
|
-
.then((svgIcon) => {
|
|
86
|
-
const parser = new DOMParser()
|
|
87
|
-
const svgIconDocument = parser.parseFromString(
|
|
88
|
-
svgIcon,
|
|
89
|
-
'image/svg+xml'
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
Array.from(svgIconDocument.documentElement.children).forEach(
|
|
93
|
-
(node) => {
|
|
94
|
-
console.log('appending', node)
|
|
95
|
-
|
|
96
|
-
iconSvgNode.appendChild(node)
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
/*
|
|
100
|
-
Array.from(svgIconDocument.documentElement.childNodes).forEach((node) => {
|
|
101
|
-
console.log('appending', node)
|
|
102
|
-
iconSvgNode.appendChild(node)
|
|
103
|
-
})
|
|
104
|
-
*/
|
|
105
|
-
//iconSvgNode.insertAdjacentHTML('beforeend', svgIcon)
|
|
106
|
-
//group.insertAdjacentHTML('beforeend', svgIcon)
|
|
107
|
-
group.appendChild(iconSvgNode)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
//svgValue.appendChild(iconSvgNode)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const textNode = document.createElementNS(svgNS, 'text')
|
|
114
|
-
//textNode.setAttribute('font-size', textSize)
|
|
115
|
-
textNode.setAttribute('font-weight', '300')
|
|
116
|
-
textNode.setAttribute('letter-spacing', '-5')
|
|
117
|
-
textNode.setAttribute(
|
|
118
|
-
'x',
|
|
119
|
-
showIcon ? `-${(textWidth - iconPadding) / 2 - iconSize}` : 0
|
|
120
|
-
)
|
|
121
|
-
textNode.setAttribute('y', 0)
|
|
122
|
-
textNode.setAttribute('fill', fillColor)
|
|
123
|
-
textNode.setAttribute('alignment-baseline', 'central')
|
|
124
|
-
textNode.setAttribute('data-test', 'visualization-primary-value')
|
|
125
|
-
|
|
126
|
-
if (!showIcon) {
|
|
127
|
-
textNode.setAttribute('text-anchor', 'middle')
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
textNode.appendChild(document.createTextNode(formattedValue))
|
|
131
|
-
|
|
132
|
-
// svgValue.appendChild(textNode)
|
|
133
|
-
group.appendChild(textNode)
|
|
134
|
-
|
|
135
|
-
// XXX
|
|
136
|
-
svgValue.appendChild(group)
|
|
137
|
-
|
|
138
|
-
if (subText) {
|
|
139
|
-
const subTextSize = 40
|
|
140
|
-
|
|
141
|
-
const subTextNode = document.createElementNS(svgNS, 'text')
|
|
142
|
-
subTextNode.setAttribute('text-anchor', 'middle')
|
|
143
|
-
subTextNode.setAttribute('font-size', subTextSize)
|
|
144
|
-
subTextNode.setAttribute('y', iconSize / 2)
|
|
145
|
-
subTextNode.setAttribute('fill', colors.grey600)
|
|
146
|
-
subTextNode.setAttribute('alignment-baseline', 'hanging')
|
|
147
|
-
subTextNode.appendChild(document.createTextNode(subText))
|
|
148
|
-
|
|
149
|
-
svgValue.appendChild(subTextNode)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return svgValue
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const generateDashboardItem = (
|
|
156
|
-
config,
|
|
157
|
-
{
|
|
158
|
-
svgContainer,
|
|
159
|
-
width,
|
|
160
|
-
height,
|
|
161
|
-
valueColor,
|
|
162
|
-
titleColor,
|
|
163
|
-
backgroundColor,
|
|
164
|
-
noData,
|
|
165
|
-
}
|
|
166
|
-
) => {
|
|
167
|
-
svgContainer.appendChild(
|
|
168
|
-
generateValueSVG({
|
|
169
|
-
formattedValue: config.formattedValue,
|
|
170
|
-
icon: config.icon,
|
|
171
|
-
subText: config.subText,
|
|
172
|
-
valueColor,
|
|
173
|
-
noData,
|
|
174
|
-
containerWidth: width,
|
|
175
|
-
containerHeight: height,
|
|
176
|
-
})
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
const container = document.createElement('div')
|
|
180
|
-
container.setAttribute(
|
|
181
|
-
'style',
|
|
182
|
-
`display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 100%; background-color:${backgroundColor};`
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
const titleStyle = `font-size: 12px; color: ${
|
|
186
|
-
titleColor || '#666'
|
|
187
|
-
}; padding: 0 8px; text-align: center;`
|
|
188
|
-
|
|
189
|
-
const title = document.createElement('span')
|
|
190
|
-
title.setAttribute('style', titleStyle)
|
|
191
|
-
if (config.title) {
|
|
192
|
-
title.appendChild(document.createTextNode(config.title))
|
|
193
|
-
|
|
194
|
-
// container.appendChild(title)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (config.subtitle) {
|
|
198
|
-
const subtitle = document.createElement('span')
|
|
199
|
-
subtitle.setAttribute('style', titleStyle + ' margin-top: 4px;')
|
|
200
|
-
|
|
201
|
-
subtitle.appendChild(document.createTextNode(config.subtitle))
|
|
202
|
-
|
|
203
|
-
// container.appendChild(subtitle)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
container.appendChild(svgContainer)
|
|
207
|
-
/*container.appendChild(
|
|
208
|
-
generateValueSVG({
|
|
209
|
-
formattedValue: config.formattedValue,
|
|
210
|
-
icon: config.icon,
|
|
211
|
-
subText: config.subText,
|
|
212
|
-
valueColor,
|
|
213
|
-
noData,
|
|
214
|
-
containerWidth: width,
|
|
215
|
-
containerHeight: height,
|
|
216
|
-
})
|
|
217
|
-
)*/
|
|
218
|
-
|
|
219
|
-
return container
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const getTextAnchorFromTextAlign = (textAlign) => {
|
|
223
|
-
switch (textAlign) {
|
|
224
|
-
default:
|
|
225
|
-
case TEXT_ALIGN_LEFT:
|
|
226
|
-
return 'start'
|
|
227
|
-
case TEXT_ALIGN_CENTER:
|
|
228
|
-
return 'middle'
|
|
229
|
-
case TEXT_ALIGN_RIGHT:
|
|
230
|
-
return 'end'
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const getXFromTextAlign = (textAlign) => {
|
|
235
|
-
switch (textAlign) {
|
|
236
|
-
default:
|
|
237
|
-
case TEXT_ALIGN_LEFT:
|
|
238
|
-
return '1%'
|
|
239
|
-
case TEXT_ALIGN_CENTER:
|
|
240
|
-
return '50%'
|
|
241
|
-
case TEXT_ALIGN_RIGHT:
|
|
242
|
-
return '99%'
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const generateDVItem = (
|
|
247
|
-
config,
|
|
248
|
-
{
|
|
249
|
-
svgContainer,
|
|
250
|
-
width,
|
|
251
|
-
height,
|
|
252
|
-
valueColor,
|
|
253
|
-
noData,
|
|
254
|
-
backgroundColor,
|
|
255
|
-
titleColor,
|
|
256
|
-
fontStyle,
|
|
257
|
-
}
|
|
258
|
-
) => {
|
|
259
|
-
if (backgroundColor) {
|
|
260
|
-
svgContainer.setAttribute(
|
|
261
|
-
'style',
|
|
262
|
-
`background-color: ${backgroundColor};`
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
const background = document.createElementNS(svgNS, 'rect')
|
|
266
|
-
background.setAttribute('width', '100%')
|
|
267
|
-
background.setAttribute('height', '100%')
|
|
268
|
-
background.setAttribute('fill', backgroundColor)
|
|
269
|
-
svgContainer.appendChild(background)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const svgWrapper = document.createElementNS(svgNS, 'svg')
|
|
273
|
-
|
|
274
|
-
const title = document.createElementNS(svgNS, 'text')
|
|
275
|
-
const titleFontStyle = mergeFontStyleWithDefault(
|
|
276
|
-
fontStyle && fontStyle[FONT_STYLE_VISUALIZATION_TITLE],
|
|
277
|
-
FONT_STYLE_VISUALIZATION_TITLE
|
|
278
|
-
)
|
|
279
|
-
title.setAttribute(
|
|
280
|
-
'x',
|
|
281
|
-
getXFromTextAlign(titleFontStyle[FONT_STYLE_OPTION_TEXT_ALIGN])
|
|
282
|
-
)
|
|
283
|
-
title.setAttribute('y', 28)
|
|
284
|
-
title.setAttribute(
|
|
285
|
-
'text-anchor',
|
|
286
|
-
getTextAnchorFromTextAlign(titleFontStyle[FONT_STYLE_OPTION_TEXT_ALIGN])
|
|
287
|
-
)
|
|
288
|
-
title.setAttribute(
|
|
289
|
-
'font-size',
|
|
290
|
-
`${titleFontStyle[FONT_STYLE_OPTION_FONT_SIZE]}px`
|
|
291
|
-
)
|
|
292
|
-
title.setAttribute(
|
|
293
|
-
'font-weight',
|
|
294
|
-
titleFontStyle[FONT_STYLE_OPTION_BOLD]
|
|
295
|
-
? FONT_STYLE_OPTION_BOLD
|
|
296
|
-
: 'normal'
|
|
297
|
-
)
|
|
298
|
-
title.setAttribute(
|
|
299
|
-
'font-style',
|
|
300
|
-
titleFontStyle[FONT_STYLE_OPTION_ITALIC]
|
|
301
|
-
? FONT_STYLE_OPTION_ITALIC
|
|
302
|
-
: 'normal'
|
|
303
|
-
)
|
|
304
|
-
if (
|
|
305
|
-
titleColor &&
|
|
306
|
-
titleFontStyle[FONT_STYLE_OPTION_TEXT_COLOR] ===
|
|
307
|
-
defaultFontStyle[FONT_STYLE_VISUALIZATION_TITLE][
|
|
308
|
-
FONT_STYLE_OPTION_TEXT_COLOR
|
|
309
|
-
]
|
|
310
|
-
) {
|
|
311
|
-
title.setAttribute('fill', titleColor)
|
|
312
|
-
} else {
|
|
313
|
-
title.setAttribute('fill', titleFontStyle[FONT_STYLE_OPTION_TEXT_COLOR])
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
title.setAttribute('data-test', 'visualization-title')
|
|
317
|
-
|
|
318
|
-
if (config.title) {
|
|
319
|
-
title.appendChild(document.createTextNode(config.title))
|
|
320
|
-
|
|
321
|
-
svgWrapper.appendChild(title)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const subtitleFontStyle = mergeFontStyleWithDefault(
|
|
325
|
-
fontStyle && fontStyle[FONT_STYLE_VISUALIZATION_SUBTITLE],
|
|
326
|
-
FONT_STYLE_VISUALIZATION_SUBTITLE
|
|
327
|
-
)
|
|
328
|
-
const subtitle = document.createElementNS(svgNS, 'text')
|
|
329
|
-
subtitle.setAttribute(
|
|
330
|
-
'x',
|
|
331
|
-
getXFromTextAlign(subtitleFontStyle[FONT_STYLE_OPTION_TEXT_ALIGN])
|
|
332
|
-
)
|
|
333
|
-
subtitle.setAttribute('y', 28)
|
|
334
|
-
subtitle.setAttribute('dy', 22)
|
|
335
|
-
subtitle.setAttribute(
|
|
336
|
-
'text-anchor',
|
|
337
|
-
getTextAnchorFromTextAlign(
|
|
338
|
-
subtitleFontStyle[FONT_STYLE_OPTION_TEXT_ALIGN]
|
|
339
|
-
)
|
|
340
|
-
)
|
|
341
|
-
subtitle.setAttribute(
|
|
342
|
-
'font-size',
|
|
343
|
-
`${subtitleFontStyle[FONT_STYLE_OPTION_FONT_SIZE]}px`
|
|
344
|
-
)
|
|
345
|
-
subtitle.setAttribute(
|
|
346
|
-
'font-weight',
|
|
347
|
-
subtitleFontStyle[FONT_STYLE_OPTION_BOLD]
|
|
348
|
-
? FONT_STYLE_OPTION_BOLD
|
|
349
|
-
: 'normal'
|
|
350
|
-
)
|
|
351
|
-
subtitle.setAttribute(
|
|
352
|
-
'font-style',
|
|
353
|
-
subtitleFontStyle[FONT_STYLE_OPTION_ITALIC]
|
|
354
|
-
? FONT_STYLE_OPTION_ITALIC
|
|
355
|
-
: 'normal'
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
if (
|
|
359
|
-
titleColor &&
|
|
360
|
-
subtitleFontStyle[FONT_STYLE_OPTION_TEXT_COLOR] ===
|
|
361
|
-
defaultFontStyle[FONT_STYLE_VISUALIZATION_SUBTITLE][
|
|
362
|
-
FONT_STYLE_OPTION_TEXT_COLOR
|
|
363
|
-
]
|
|
364
|
-
) {
|
|
365
|
-
subtitle.setAttribute('fill', titleColor)
|
|
366
|
-
} else {
|
|
367
|
-
subtitle.setAttribute(
|
|
368
|
-
'fill',
|
|
369
|
-
subtitleFontStyle[FONT_STYLE_OPTION_TEXT_COLOR]
|
|
370
|
-
)
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
subtitle.setAttribute('data-test', 'visualization-subtitle')
|
|
374
|
-
|
|
375
|
-
if (config.subtitle) {
|
|
376
|
-
subtitle.appendChild(document.createTextNode(config.subtitle))
|
|
377
|
-
|
|
378
|
-
svgWrapper.appendChild(subtitle)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
svgContainer.appendChild(svgWrapper)
|
|
382
|
-
|
|
383
|
-
svgContainer.appendChild(
|
|
384
|
-
generateValueSVG({
|
|
385
|
-
formattedValue: config.formattedValue,
|
|
386
|
-
icon: config.icon,
|
|
387
|
-
subText: config.subText,
|
|
388
|
-
valueColor,
|
|
389
|
-
noData,
|
|
390
|
-
containerWidth: width,
|
|
391
|
-
containerHeight: height,
|
|
392
|
-
})
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
return svgContainer
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const shouldUseContrastColor = (inputColor = '') => {
|
|
399
|
-
// based on https://stackoverflow.com/questions/3942878/how-to-decide-font-color-in-white-or-black-depending-on-background-color
|
|
400
|
-
var color =
|
|
401
|
-
inputColor.charAt(0) === '#' ? inputColor.substring(1, 7) : inputColor
|
|
402
|
-
var r = parseInt(color.substring(0, 2), 16) // hexToR
|
|
403
|
-
var g = parseInt(color.substring(2, 4), 16) // hexToG
|
|
404
|
-
var b = parseInt(color.substring(4, 6), 16) // hexToB
|
|
405
|
-
var uicolors = [r / 255, g / 255, b / 255]
|
|
406
|
-
var c = uicolors.map((col) => {
|
|
407
|
-
if (col <= 0.03928) {
|
|
408
|
-
return col / 12.92
|
|
409
|
-
}
|
|
410
|
-
return Math.pow((col + 0.055) / 1.055, 2.4)
|
|
411
|
-
})
|
|
412
|
-
var L = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2]
|
|
413
|
-
return L <= 0.179
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
export default function (
|
|
417
|
-
config,
|
|
418
|
-
parentEl,
|
|
419
|
-
{ dashboard, legendSets, fontStyle, noData, legendOptions }
|
|
420
|
-
) {
|
|
421
|
-
const legendSet = legendOptions && legendSets[0]
|
|
422
|
-
const legendColor =
|
|
423
|
-
legendSet && getColorByValueFromLegendSet(legendSet, config.value)
|
|
424
|
-
let valueColor, titleColor, backgroundColor
|
|
425
|
-
if (legendColor) {
|
|
426
|
-
if (legendOptions.style === LEGEND_DISPLAY_STYLE_FILL) {
|
|
427
|
-
backgroundColor = legendColor
|
|
428
|
-
valueColor = titleColor =
|
|
429
|
-
shouldUseContrastColor(legendColor) && colors.white
|
|
430
|
-
} else {
|
|
431
|
-
valueColor = legendColor
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
parentEl.style.overflow = 'hidden'
|
|
436
|
-
parentEl.style.display = 'flex'
|
|
437
|
-
parentEl.style.justifyContent = 'center'
|
|
438
|
-
|
|
439
|
-
const parentElBBox = parentEl.getBoundingClientRect()
|
|
440
|
-
const width = parentElBBox.width
|
|
441
|
-
const height = parentElBBox.height
|
|
442
|
-
|
|
443
|
-
const svgContainer = document.createElementNS(svgNS, 'svg')
|
|
444
|
-
svgContainer.setAttribute('xmlns', svgNS)
|
|
445
|
-
svgContainer.setAttribute('viewBox', `0 0 ${width} ${height}`)
|
|
446
|
-
svgContainer.setAttribute('width', '100%')
|
|
447
|
-
svgContainer.setAttribute('height', '100%')
|
|
448
|
-
svgContainer.setAttribute('data-test', 'visualization-container')
|
|
449
|
-
|
|
450
|
-
if (dashboard) {
|
|
451
|
-
parentEl.style.borderRadius = spacers.dp8
|
|
452
|
-
|
|
453
|
-
return generateDashboardItem(config, {
|
|
454
|
-
svgContainer,
|
|
455
|
-
width,
|
|
456
|
-
height,
|
|
457
|
-
valueColor,
|
|
458
|
-
backgroundColor,
|
|
459
|
-
noData,
|
|
460
|
-
...(legendColor && shouldUseContrastColor(legendColor)
|
|
461
|
-
? { titleColor: colors.white }
|
|
462
|
-
: {}),
|
|
463
|
-
})
|
|
464
|
-
} else {
|
|
465
|
-
parentEl.style.height = `100%`
|
|
466
|
-
|
|
467
|
-
return generateDVItem(config, {
|
|
468
|
-
svgContainer,
|
|
469
|
-
width,
|
|
470
|
-
height,
|
|
471
|
-
valueColor,
|
|
472
|
-
backgroundColor,
|
|
473
|
-
titleColor,
|
|
474
|
-
noData,
|
|
475
|
-
fontStyle,
|
|
476
|
-
})
|
|
477
|
-
}
|
|
478
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import fixtures from '../../../__fixtures__/fixtures.js';
|
|
2
|
-
import DataEngineMock from '../__mocks__/DataEngine.js';
|
|
3
|
-
import AnalyticsRequest from '../AnalyticsRequest.js';
|
|
4
|
-
import AnalyticsTrackedEntities from '../AnalyticsTrackedEntities.js';
|
|
5
|
-
describe.skip('analytics.trackedEntity', () => {
|
|
6
|
-
let enrollments;
|
|
7
|
-
let request;
|
|
8
|
-
let dataEngineMock;
|
|
9
|
-
let fixture;
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
dataEngineMock = new DataEngineMock();
|
|
12
|
-
DataEngineMock.mockClear();
|
|
13
|
-
enrollments = new AnalyticsTrackedEntities();
|
|
14
|
-
});
|
|
15
|
-
it('should not be allowed to be called without new', () => {
|
|
16
|
-
expect(() => AnalyticsTrackedEntities()).toThrowErrorMatchingSnapshot();
|
|
17
|
-
});
|
|
18
|
-
it('should use the dataEngine object when it is passed', () => {
|
|
19
|
-
const dataEngineMockObject = {};
|
|
20
|
-
enrollments = new AnalyticsTrackedEntities(dataEngineMockObject);
|
|
21
|
-
expect(enrollments.dataEngine).toBe(dataEngineMockObject);
|
|
22
|
-
});
|
|
23
|
-
describe('.getQuery()', () => {
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
enrollments = new AnalyticsTrackedEntities(new DataEngineMock());
|
|
26
|
-
request = new AnalyticsRequest().addOrgUnitDimension('ImspTQPwCqd').addDimension('WZbXY0S00lP.de0FEHSIoxh').addDimension('WZbXY0S00lP.sWoqcoByYmD').addPeriodFilter('LAST_MONTH').withTrackedEntity('nEenWmSyUEp').withAsc('ENROLLMENTDATE').withOuMode('DESCENDANTS').withColumns('w75KJ2mc4zz').withPage(1).withPageSize(10);
|
|
27
|
-
fixture = fixtures.get('/api/analytics/enrollments'); // XXX
|
|
28
|
-
|
|
29
|
-
dataEngineMock.query.mockReturnValue(Promise.resolve({
|
|
30
|
-
data: fixture
|
|
31
|
-
}));
|
|
32
|
-
});
|
|
33
|
-
it('should be a function', () => {
|
|
34
|
-
expect(enrollments.getQuery).toBeInstanceOf(Function);
|
|
35
|
-
});
|
|
36
|
-
it('should resolve a promise with data', () => enrollments.getQuery(request).then(data => {
|
|
37
|
-
expect(data.width).toEqual(fixture.width);
|
|
38
|
-
expect(data.height).toEqual(fixture.height);
|
|
39
|
-
}));
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
|
-
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
3
|
-
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
import React, { Component } from 'react';
|
|
6
|
-
import convertCtrlKey from './convertCtrlKey.js';
|
|
7
|
-
class Editor extends Component {
|
|
8
|
-
constructor() {
|
|
9
|
-
super(...arguments);
|
|
10
|
-
_defineProperty(this, "onKeyDown", event => {
|
|
11
|
-
convertCtrlKey(event, this.props.onEdit);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
render() {
|
|
15
|
-
const {
|
|
16
|
-
children
|
|
17
|
-
} = this.props;
|
|
18
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
19
|
-
onKeyDown: this.onKeyDown
|
|
20
|
-
}, children);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
Editor.defaultProps = {
|
|
24
|
-
onEdit: null
|
|
25
|
-
};
|
|
26
|
-
Editor.propTypes = {
|
|
27
|
-
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
|
|
28
|
-
onEdit: PropTypes.func
|
|
29
|
-
};
|
|
30
|
-
export default Editor;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { shallow } from 'enzyme';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import convertCtrlKey from '../convertCtrlKey.js';
|
|
4
|
-
import Editor from '../Editor.js';
|
|
5
|
-
jest.mock('../convertCtrlKey');
|
|
6
|
-
describe('RichText: Editor component', () => {
|
|
7
|
-
let richTextEditor;
|
|
8
|
-
const componentProps = {
|
|
9
|
-
onEdit: jest.fn()
|
|
10
|
-
};
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
convertCtrlKey.mockClear();
|
|
13
|
-
});
|
|
14
|
-
const renderComponent = props => {
|
|
15
|
-
return shallow( /*#__PURE__*/React.createElement(Editor, props, /*#__PURE__*/React.createElement("input", null)));
|
|
16
|
-
};
|
|
17
|
-
it('renders a result', () => {
|
|
18
|
-
richTextEditor = renderComponent(componentProps);
|
|
19
|
-
expect(richTextEditor).toHaveLength(1);
|
|
20
|
-
});
|
|
21
|
-
it('calls convertCtrlKey on keydown', () => {
|
|
22
|
-
richTextEditor = renderComponent(componentProps);
|
|
23
|
-
richTextEditor.simulate('keyDown');
|
|
24
|
-
expect(convertCtrlKey).toHaveBeenCalled();
|
|
25
|
-
});
|
|
26
|
-
});
|