@dhis2/analytics 26.2.0-alpha.2 → 26.2.0-cumulative-values-alpha.1
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/build/cjs/__demo__/PivotTable.stories.js +69 -29
- package/build/cjs/api/analytics/Analytics.js +0 -7
- package/build/cjs/api/analytics/AnalyticsBase.js +6 -24
- package/build/cjs/api/analytics/AnalyticsRequest.js +10 -33
- package/build/cjs/api/analytics/AnalyticsRequestBase.js +1 -3
- package/build/cjs/api/analytics/AnalyticsRequestPropertiesMixin.js +0 -19
- package/build/cjs/api/analytics/__tests__/AnalyticsTrackedEntities.spec.js +44 -0
- package/build/cjs/api/analytics/__tests__/__snapshots__/AnalyticsTrackedEntities.spec.js.snap +3 -0
- package/build/cjs/api/analytics/utils.js +2 -23
- package/build/cjs/components/Options/VisualizationOptions.js +1 -1
- package/build/cjs/components/Options/styles/VisualizationOptions.style.js +8 -1
- package/build/cjs/components/RichText/Editor.bk/Editor.js +40 -0
- package/build/cjs/components/RichText/Editor.bk/__tests__/Editor.spec.js +29 -0
- package/build/cjs/components/RichText/Editor.bk/__tests__/convertCtrlKey.spec.js +205 -0
- package/build/cjs/components/RichText/Editor.bk/convertCtrlKey.js +87 -0
- package/build/cjs/components/RichText/Parser.bk/MdParser.js +107 -0
- package/build/cjs/components/RichText/Parser.bk/Parser.js +34 -0
- package/build/cjs/components/RichText/Parser.bk/__tests__/MdParser.spec.js +34 -0
- package/build/cjs/components/RichText/Parser.bk/__tests__/Parser.spec.js +41 -0
- package/build/cjs/modules/layout/dimension.js +2 -9
- package/build/cjs/modules/layout/dimensionCreate.js +0 -3
- package/build/cjs/modules/pivotTable/PivotTableEngine.js +119 -57
- package/build/cjs/visualizations/config/generators/dhis/singleValue.js.xp1 +478 -0
- package/build/es/__demo__/PivotTable.stories.js +69 -29
- package/build/es/api/analytics/Analytics.js +0 -7
- package/build/es/api/analytics/AnalyticsBase.js +6 -24
- package/build/es/api/analytics/AnalyticsRequest.js +10 -33
- package/build/es/api/analytics/AnalyticsRequestBase.js +1 -3
- package/build/es/api/analytics/AnalyticsRequestPropertiesMixin.js +0 -19
- package/build/es/api/analytics/__tests__/AnalyticsTrackedEntities.spec.js +41 -0
- package/build/es/api/analytics/__tests__/__snapshots__/AnalyticsTrackedEntities.spec.js.snap +3 -0
- package/build/es/api/analytics/utils.js +1 -20
- package/build/es/components/Options/VisualizationOptions.js +2 -2
- package/build/es/components/Options/styles/VisualizationOptions.style.js +6 -0
- package/build/es/components/RichText/Editor.bk/Editor.js +30 -0
- package/build/es/components/RichText/Editor.bk/__tests__/Editor.spec.js +26 -0
- package/build/es/components/RichText/Editor.bk/__tests__/convertCtrlKey.spec.js +202 -0
- package/build/es/components/RichText/Editor.bk/convertCtrlKey.js +80 -0
- package/build/es/components/RichText/Parser.bk/MdParser.js +99 -0
- package/build/es/components/RichText/Parser.bk/Parser.js +24 -0
- package/build/es/components/RichText/Parser.bk/__tests__/MdParser.spec.js +31 -0
- package/build/es/components/RichText/Parser.bk/__tests__/Parser.spec.js +38 -0
- package/build/es/modules/layout/dimension.js +1 -7
- package/build/es/modules/layout/dimensionCreate.js +1 -4
- package/build/es/modules/pivotTable/PivotTableEngine.js +119 -57
- package/build/es/visualizations/config/generators/dhis/singleValue.js.xp1 +478 -0
- package/package.json +1 -1
- package/build/cjs/api/analytics/AnalyticsTrackedEntities.js +0 -31
- package/build/es/api/analytics/AnalyticsTrackedEntities.js +0 -24
|
@@ -0,0 +1,478 @@
|
|
|
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
|
+
}
|
|
@@ -825,14 +825,15 @@ storiesOf('PivotTable', module).add('empty columns (weekly) - shown', (_, _ref35
|
|
|
825
825
|
visualization: visualization
|
|
826
826
|
}));
|
|
827
827
|
});
|
|
828
|
-
storiesOf('PivotTable', module).add('empty columns (weekly) -
|
|
828
|
+
storiesOf('PivotTable', module).add('cumulative + empty columns (weekly) - shown', (_, _ref36) => {
|
|
829
829
|
let {
|
|
830
830
|
pivotTableOptions
|
|
831
831
|
} = _ref36;
|
|
832
832
|
const visualization = {
|
|
833
833
|
...weeklyColumnsVisualization,
|
|
834
834
|
...pivotTableOptions,
|
|
835
|
-
hideEmptyColumns:
|
|
835
|
+
hideEmptyColumns: false,
|
|
836
|
+
cumulativeValues: true
|
|
836
837
|
};
|
|
837
838
|
return /*#__PURE__*/React.createElement("div", {
|
|
838
839
|
style: {
|
|
@@ -844,10 +845,49 @@ storiesOf('PivotTable', module).add('empty columns (weekly) - hidden', (_, _ref3
|
|
|
844
845
|
visualization: visualization
|
|
845
846
|
}));
|
|
846
847
|
});
|
|
847
|
-
storiesOf('PivotTable', module).add('empty columns
|
|
848
|
+
storiesOf('PivotTable', module).add('empty columns (weekly) - hidden', (_, _ref37) => {
|
|
848
849
|
let {
|
|
849
850
|
pivotTableOptions
|
|
850
851
|
} = _ref37;
|
|
852
|
+
const visualization = {
|
|
853
|
+
...weeklyColumnsVisualization,
|
|
854
|
+
...pivotTableOptions,
|
|
855
|
+
hideEmptyColumns: true
|
|
856
|
+
};
|
|
857
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
858
|
+
style: {
|
|
859
|
+
width: 800,
|
|
860
|
+
height: 600
|
|
861
|
+
}
|
|
862
|
+
}, /*#__PURE__*/React.createElement(PivotTable, {
|
|
863
|
+
data: weeklyColumnsData,
|
|
864
|
+
visualization: visualization
|
|
865
|
+
}));
|
|
866
|
+
});
|
|
867
|
+
storiesOf('PivotTable', module).add('cumulative + empty columns (weekly) - hidden', (_, _ref38) => {
|
|
868
|
+
let {
|
|
869
|
+
pivotTableOptions
|
|
870
|
+
} = _ref38;
|
|
871
|
+
const visualization = {
|
|
872
|
+
...weeklyColumnsVisualization,
|
|
873
|
+
...pivotTableOptions,
|
|
874
|
+
hideEmptyColumns: true,
|
|
875
|
+
cumulativeValues: true
|
|
876
|
+
};
|
|
877
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
878
|
+
style: {
|
|
879
|
+
width: 800,
|
|
880
|
+
height: 600
|
|
881
|
+
}
|
|
882
|
+
}, /*#__PURE__*/React.createElement(PivotTable, {
|
|
883
|
+
data: weeklyColumnsData,
|
|
884
|
+
visualization: visualization
|
|
885
|
+
}));
|
|
886
|
+
});
|
|
887
|
+
storiesOf('PivotTable', module).add('empty columns + assigned cats (shown)', (_, _ref39) => {
|
|
888
|
+
let {
|
|
889
|
+
pivotTableOptions
|
|
890
|
+
} = _ref39;
|
|
851
891
|
const visualization = {
|
|
852
892
|
...emptyColumnsVisualization,
|
|
853
893
|
...visualizationReset,
|
|
@@ -864,10 +904,10 @@ storiesOf('PivotTable', module).add('empty columns + assigned cats (shown)', (_,
|
|
|
864
904
|
visualization: visualization
|
|
865
905
|
}));
|
|
866
906
|
});
|
|
867
|
-
storiesOf('PivotTable', module).add('empty columns + assigned cats (hidden)', (_,
|
|
907
|
+
storiesOf('PivotTable', module).add('empty columns + assigned cats (hidden)', (_, _ref40) => {
|
|
868
908
|
let {
|
|
869
909
|
pivotTableOptions
|
|
870
|
-
} =
|
|
910
|
+
} = _ref40;
|
|
871
911
|
const visualization = {
|
|
872
912
|
...emptyColumnsVisualization,
|
|
873
913
|
...visualizationReset,
|
|
@@ -884,10 +924,10 @@ storiesOf('PivotTable', module).add('empty columns + assigned cats (hidden)', (_
|
|
|
884
924
|
visualization: visualization
|
|
885
925
|
}));
|
|
886
926
|
});
|
|
887
|
-
storiesOf('PivotTable', module).add('legend - fixed (light fill)', (_,
|
|
927
|
+
storiesOf('PivotTable', module).add('legend - fixed (light fill)', (_, _ref41) => {
|
|
888
928
|
let {
|
|
889
929
|
pivotTableOptions
|
|
890
|
-
} =
|
|
930
|
+
} = _ref41;
|
|
891
931
|
const visualization = {
|
|
892
932
|
...targetVisualization,
|
|
893
933
|
...visualizationReset,
|
|
@@ -912,10 +952,10 @@ storiesOf('PivotTable', module).add('legend - fixed (light fill)', (_, _ref39) =
|
|
|
912
952
|
legendSets: [underAbove100LegendSet]
|
|
913
953
|
}));
|
|
914
954
|
});
|
|
915
|
-
storiesOf('PivotTable', module).add('legend - fixed (dark fill)', (_,
|
|
955
|
+
storiesOf('PivotTable', module).add('legend - fixed (dark fill)', (_, _ref42) => {
|
|
916
956
|
let {
|
|
917
957
|
pivotTableOptions
|
|
918
|
-
} =
|
|
958
|
+
} = _ref42;
|
|
919
959
|
const visualization = {
|
|
920
960
|
...targetVisualization,
|
|
921
961
|
...visualizationReset,
|
|
@@ -941,10 +981,10 @@ storiesOf('PivotTable', module).add('legend - fixed (dark fill)', (_, _ref40) =>
|
|
|
941
981
|
legendSets: [legendSet]
|
|
942
982
|
}));
|
|
943
983
|
});
|
|
944
|
-
storiesOf('PivotTable', module).add('legend - fixed (text)', (_,
|
|
984
|
+
storiesOf('PivotTable', module).add('legend - fixed (text)', (_, _ref43) => {
|
|
945
985
|
let {
|
|
946
986
|
pivotTableOptions
|
|
947
|
-
} =
|
|
987
|
+
} = _ref43;
|
|
948
988
|
const visualization = {
|
|
949
989
|
...targetVisualization,
|
|
950
990
|
...visualizationReset,
|
|
@@ -965,10 +1005,10 @@ storiesOf('PivotTable', module).add('legend - fixed (text)', (_, _ref41) => {
|
|
|
965
1005
|
legendSets: [underAbove100LegendSet]
|
|
966
1006
|
}));
|
|
967
1007
|
});
|
|
968
|
-
storiesOf('PivotTable', module).add('legend - fixed (% row)', (_,
|
|
1008
|
+
storiesOf('PivotTable', module).add('legend - fixed (% row)', (_, _ref44) => {
|
|
969
1009
|
let {
|
|
970
1010
|
pivotTableOptions
|
|
971
|
-
} =
|
|
1011
|
+
} = _ref44;
|
|
972
1012
|
const visualization = {
|
|
973
1013
|
...targetVisualization,
|
|
974
1014
|
...visualizationReset,
|
|
@@ -992,10 +1032,10 @@ storiesOf('PivotTable', module).add('legend - fixed (% row)', (_, _ref42) => {
|
|
|
992
1032
|
legendSets: [underAbove100LegendSet]
|
|
993
1033
|
}));
|
|
994
1034
|
});
|
|
995
|
-
storiesOf('PivotTable', module).add('legend - by data item', (_,
|
|
1035
|
+
storiesOf('PivotTable', module).add('legend - by data item', (_, _ref45) => {
|
|
996
1036
|
let {
|
|
997
1037
|
pivotTableOptions
|
|
998
|
-
} =
|
|
1038
|
+
} = _ref45;
|
|
999
1039
|
const visualization = {
|
|
1000
1040
|
...targetVisualization,
|
|
1001
1041
|
...visualizationReset,
|
|
@@ -1023,10 +1063,10 @@ storiesOf('PivotTable', module).add('legend - by data item', (_, _ref43) => {
|
|
|
1023
1063
|
legendSets: [underAbove100LegendSet, customLegendSet]
|
|
1024
1064
|
}));
|
|
1025
1065
|
});
|
|
1026
|
-
storiesOf('PivotTable', module).add('hierarchy - none', (_,
|
|
1066
|
+
storiesOf('PivotTable', module).add('hierarchy - none', (_, _ref46) => {
|
|
1027
1067
|
let {
|
|
1028
1068
|
pivotTableOptions
|
|
1029
|
-
} =
|
|
1069
|
+
} = _ref46;
|
|
1030
1070
|
const visualization = {
|
|
1031
1071
|
...hierarchyVisualization,
|
|
1032
1072
|
...visualizationReset,
|
|
@@ -1047,10 +1087,10 @@ storiesOf('PivotTable', module).add('hierarchy - none', (_, _ref44) => {
|
|
|
1047
1087
|
visualization: visualization
|
|
1048
1088
|
}));
|
|
1049
1089
|
});
|
|
1050
|
-
storiesOf('PivotTable', module).add('hierarchy - rows', (_,
|
|
1090
|
+
storiesOf('PivotTable', module).add('hierarchy - rows', (_, _ref47) => {
|
|
1051
1091
|
let {
|
|
1052
1092
|
pivotTableOptions
|
|
1053
|
-
} =
|
|
1093
|
+
} = _ref47;
|
|
1054
1094
|
const visualization = {
|
|
1055
1095
|
...hierarchyVisualization,
|
|
1056
1096
|
...visualizationReset,
|
|
@@ -1070,10 +1110,10 @@ storiesOf('PivotTable', module).add('hierarchy - rows', (_, _ref45) => {
|
|
|
1070
1110
|
visualization: visualization
|
|
1071
1111
|
}));
|
|
1072
1112
|
});
|
|
1073
|
-
storiesOf('PivotTable', module).add('hierarchy - columns', (_,
|
|
1113
|
+
storiesOf('PivotTable', module).add('hierarchy - columns', (_, _ref48) => {
|
|
1074
1114
|
let {
|
|
1075
1115
|
pivotTableOptions
|
|
1076
|
-
} =
|
|
1116
|
+
} = _ref48;
|
|
1077
1117
|
const visualization = {
|
|
1078
1118
|
...hierarchyVisualization,
|
|
1079
1119
|
...visualizationReset,
|
|
@@ -1095,10 +1135,10 @@ storiesOf('PivotTable', module).add('hierarchy - columns', (_, _ref46) => {
|
|
|
1095
1135
|
visualization: visualization
|
|
1096
1136
|
}));
|
|
1097
1137
|
});
|
|
1098
|
-
storiesOf('PivotTable', module).add('narrative', (_,
|
|
1138
|
+
storiesOf('PivotTable', module).add('narrative', (_, _ref49) => {
|
|
1099
1139
|
let {
|
|
1100
1140
|
pivotTableOptions
|
|
1101
|
-
} =
|
|
1141
|
+
} = _ref49;
|
|
1102
1142
|
const visualization = {
|
|
1103
1143
|
...narrativeVisualization,
|
|
1104
1144
|
...visualizationReset,
|
|
@@ -1116,10 +1156,10 @@ storiesOf('PivotTable', module).add('narrative', (_, _ref47) => {
|
|
|
1116
1156
|
visualization: visualization
|
|
1117
1157
|
}));
|
|
1118
1158
|
});
|
|
1119
|
-
storiesOf('PivotTable', module).add('narrative - data as filter', (_,
|
|
1159
|
+
storiesOf('PivotTable', module).add('narrative - data as filter', (_, _ref50) => {
|
|
1120
1160
|
let {
|
|
1121
1161
|
pivotTableOptions
|
|
1122
|
-
} =
|
|
1162
|
+
} = _ref50;
|
|
1123
1163
|
const visualization = {
|
|
1124
1164
|
...narrativeVisualization,
|
|
1125
1165
|
...visualizationReset,
|
|
@@ -1143,10 +1183,10 @@ storiesOf('PivotTable', module).add('narrative - data as filter', (_, _ref48) =>
|
|
|
1143
1183
|
visualization: visualization
|
|
1144
1184
|
}));
|
|
1145
1185
|
});
|
|
1146
|
-
storiesOf('PivotTable', module).add('DEGS', (_,
|
|
1186
|
+
storiesOf('PivotTable', module).add('DEGS', (_, _ref51) => {
|
|
1147
1187
|
let {
|
|
1148
1188
|
pivotTableOptions
|
|
1149
|
-
} =
|
|
1189
|
+
} = _ref51;
|
|
1150
1190
|
const visualization = {
|
|
1151
1191
|
...degsVisualization,
|
|
1152
1192
|
...visualizationReset,
|
|
@@ -1162,10 +1202,10 @@ storiesOf('PivotTable', module).add('DEGS', (_, _ref49) => {
|
|
|
1162
1202
|
visualization: visualization
|
|
1163
1203
|
}));
|
|
1164
1204
|
});
|
|
1165
|
-
storiesOf('PivotTable', module).add('Truncated header cell', (_,
|
|
1205
|
+
storiesOf('PivotTable', module).add('Truncated header cell', (_, _ref52) => {
|
|
1166
1206
|
let {
|
|
1167
1207
|
pivotTableOptions
|
|
1168
|
-
} =
|
|
1208
|
+
} = _ref52;
|
|
1169
1209
|
const widths = [250, 200, 500];
|
|
1170
1210
|
const [width, setWidth] = useState(250);
|
|
1171
1211
|
const toggleWidth = () => setWidth(currentWidth => {
|