@cdc/waffle-chart 1.0.2 → 4.22.11
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/LICENSE +201 -0
- package/README.md +4 -4
- package/dist/cdcwafflechart.js +2 -2
- package/examples/example-data.json +90 -90
- package/examples/gallery/avg-to-max.json +3162 -0
- package/examples/gallery/count.json +3162 -0
- package/package.json +3 -3
- package/src/CdcWaffleChart.tsx +132 -187
- package/src/ConfigContext.js +3 -3
- package/src/components/EditorPanel.js +210 -192
- package/src/data/initial-state.js +31 -31
- package/src/index.html +27 -8
- package/src/index.js +7 -7
- package/src/scss/main.scss +3 -4
- package/src/scss/waffle-chart.scss +47 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/waffle-chart",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.22.11",
|
|
4
4
|
"description": "React component for displaying a single piece of data in a card module",
|
|
5
5
|
"main": "dist/cdcwafflechart",
|
|
6
6
|
"scripts": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@cdc/core": "^
|
|
23
|
+
"@cdc/core": "^4.22.11",
|
|
24
24
|
"@visx/shape": "^2.1.1",
|
|
25
25
|
"chroma": "0.0.1",
|
|
26
26
|
"chroma-js": "^2.1.0",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"resolutions": {
|
|
38
38
|
"@types/react": "17.x"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "9768d1ea0e2383044977d988e33531bcdfe33ea6"
|
|
41
41
|
}
|
package/src/CdcWaffleChart.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useState } from 'react'
|
|
1
|
+
import React, { useCallback, useEffect, useState, FC } from 'react'
|
|
2
2
|
import parse from 'html-react-parser'
|
|
3
3
|
import { Group } from '@visx/group'
|
|
4
4
|
import { Circle, Bar } from '@visx/shape'
|
|
@@ -13,7 +13,9 @@ import ConfigContext from './ConfigContext'
|
|
|
13
13
|
import EditorPanel from './components/EditorPanel'
|
|
14
14
|
import defaults from './data/initial-state'
|
|
15
15
|
|
|
16
|
-
import { publish } from '@cdc/core/helpers/events'
|
|
16
|
+
import { publish } from '@cdc/core/helpers/events'
|
|
17
|
+
|
|
18
|
+
import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
|
|
17
19
|
|
|
18
20
|
import './scss/main.scss'
|
|
19
21
|
|
|
@@ -28,54 +30,36 @@ const themeColor = {
|
|
|
28
30
|
'theme-indigo': '#26418f',
|
|
29
31
|
'theme-cyan': '#006778',
|
|
30
32
|
'theme-green': '#4b830d',
|
|
31
|
-
'theme-amber': '#fbab18'
|
|
33
|
+
'theme-amber': '#fbab18'
|
|
34
|
+
}
|
|
35
|
+
interface Props {
|
|
36
|
+
config?: any
|
|
37
|
+
isEditor?: any
|
|
38
|
+
link?: any
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
const WaffleChart = ({ config, isEditor }) => {
|
|
35
|
-
let {
|
|
36
|
-
title,
|
|
37
|
-
theme,
|
|
38
|
-
shape,
|
|
39
|
-
nodeWidth,
|
|
40
|
-
nodeSpacer,
|
|
41
|
-
prefix,
|
|
42
|
-
suffix,
|
|
43
|
-
subtext,
|
|
44
|
-
content,
|
|
45
|
-
orientation,
|
|
46
|
-
filters,
|
|
47
|
-
dataColumn,
|
|
48
|
-
dataFunction,
|
|
49
|
-
dataConditionalColumn,
|
|
50
|
-
dataConditionalOperator,
|
|
51
|
-
dataConditionalComparate,
|
|
52
|
-
customDenom,
|
|
53
|
-
dataDenom,
|
|
54
|
-
dataDenomColumn,
|
|
55
|
-
dataDenomFunction,
|
|
56
|
-
roundToPlace
|
|
57
|
-
} = config
|
|
41
|
+
const WaffleChart: FC<Props> = ({ config, isEditor, link }) => {
|
|
42
|
+
let { title, theme, shape, nodeWidth, nodeSpacer, prefix, suffix, subtext, content, orientation, filters, dataColumn, dataFunction, dataConditionalColumn, dataConditionalOperator, dataConditionalComparate, customDenom, dataDenom, dataDenomColumn, dataDenomFunction, roundToPlace } = config
|
|
58
43
|
|
|
59
44
|
const calculateData = useCallback(() => {
|
|
60
|
-
|
|
61
45
|
//If either the column or function aren't set, do not calculate
|
|
62
46
|
if (!dataColumn || !dataFunction) {
|
|
63
47
|
return ''
|
|
64
48
|
}
|
|
65
49
|
|
|
66
|
-
const getColumnSum =
|
|
50
|
+
const getColumnSum = arr => {
|
|
67
51
|
if (Array.isArray(arr) && arr.length > 0) {
|
|
68
52
|
const sum = arr.reduce((sum, x) => sum + x)
|
|
69
53
|
return applyPrecision(sum)
|
|
70
54
|
}
|
|
71
55
|
}
|
|
72
56
|
|
|
73
|
-
const getColumnMean =
|
|
57
|
+
const getColumnMean = arr => {
|
|
74
58
|
const mean = arr.length > 1 ? arr.reduce((a, b) => a + b) / arr.length : arr[0]
|
|
75
59
|
return applyPrecision(mean)
|
|
76
60
|
}
|
|
77
61
|
|
|
78
|
-
const getMode =
|
|
62
|
+
const getMode = arr => {
|
|
79
63
|
let freq = {}
|
|
80
64
|
let max = -Infinity
|
|
81
65
|
|
|
@@ -102,12 +86,12 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
102
86
|
|
|
103
87
|
const getMedian = arr => {
|
|
104
88
|
const mid = Math.floor(arr.length / 2),
|
|
105
|
-
nums = [
|
|
89
|
+
nums = [...arr].sort((a, b) => a - b)
|
|
106
90
|
const value = arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2
|
|
107
91
|
return applyPrecision(value)
|
|
108
92
|
}
|
|
109
93
|
|
|
110
|
-
const applyPrecision =
|
|
94
|
+
const applyPrecision = value => {
|
|
111
95
|
if ('' !== roundToPlace && !isNaN(roundToPlace) && Number(roundToPlace) > -1) {
|
|
112
96
|
value = Number(value).toFixed(Number(roundToPlace))
|
|
113
97
|
}
|
|
@@ -117,7 +101,7 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
117
101
|
//Optionally filter the data based on the user's filter
|
|
118
102
|
let filteredData = config.data
|
|
119
103
|
|
|
120
|
-
filters.map(
|
|
104
|
+
filters.map(filter => {
|
|
121
105
|
if (filter.columnName && filter.columnValue) {
|
|
122
106
|
filteredData = filteredData.filter(function (e) {
|
|
123
107
|
return e[filter.columnName] === filter.columnValue
|
|
@@ -131,26 +115,26 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
131
115
|
|
|
132
116
|
if (dataConditionalColumn !== '' && dataConditionalOperator !== '' && dataConditionalComparate !== '') {
|
|
133
117
|
switch (dataConditionalOperator) {
|
|
134
|
-
case
|
|
118
|
+
case '<':
|
|
135
119
|
conditionalData = filteredData.filter(e => e[dataConditionalColumn] < dataConditionalComparate)
|
|
136
120
|
break
|
|
137
|
-
case
|
|
121
|
+
case '>':
|
|
138
122
|
conditionalData = filteredData.filter(e => e[dataConditionalColumn] > dataConditionalComparate)
|
|
139
123
|
break
|
|
140
|
-
case
|
|
124
|
+
case '<=':
|
|
141
125
|
conditionalData = filteredData.filter(e => e[dataConditionalColumn] <= dataConditionalComparate)
|
|
142
126
|
break
|
|
143
|
-
case
|
|
127
|
+
case '>=':
|
|
144
128
|
conditionalData = filteredData.filter(e => e[dataConditionalColumn] >= dataConditionalComparate)
|
|
145
129
|
break
|
|
146
|
-
case
|
|
130
|
+
case '=':
|
|
147
131
|
if (isNaN(Number(dataConditionalComparate))) {
|
|
148
132
|
conditionalData = filteredData.filter(e => String(e[dataConditionalColumn]) === dataConditionalComparate)
|
|
149
133
|
} else {
|
|
150
134
|
conditionalData = filteredData.filter(e => e[dataConditionalColumn] === dataConditionalComparate)
|
|
151
135
|
}
|
|
152
136
|
break
|
|
153
|
-
case
|
|
137
|
+
case '≠':
|
|
154
138
|
if (isNaN(Number(dataConditionalComparate))) {
|
|
155
139
|
conditionalData = filteredData.filter(e => String(e[dataConditionalColumn]) !== dataConditionalComparate)
|
|
156
140
|
} else {
|
|
@@ -167,21 +151,25 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
167
151
|
const denomColumnData = filteredData.map(a => a[dataDenomColumn])
|
|
168
152
|
|
|
169
153
|
//Filter the column's data for numerical values only
|
|
170
|
-
let numericalData = columnData
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
154
|
+
let numericalData = columnData
|
|
155
|
+
.filter(value => {
|
|
156
|
+
let include = false
|
|
157
|
+
if (Number(value) || Number.isFinite(Number(value))) {
|
|
158
|
+
include = true
|
|
159
|
+
}
|
|
160
|
+
return include
|
|
161
|
+
})
|
|
162
|
+
.map(Number)
|
|
163
|
+
|
|
164
|
+
let numericalDenomData = denomColumnData
|
|
165
|
+
.filter(value => {
|
|
166
|
+
let include = false
|
|
167
|
+
if (Number(value) || Number.isFinite(Number(value))) {
|
|
168
|
+
include = true
|
|
169
|
+
}
|
|
170
|
+
return include
|
|
171
|
+
})
|
|
172
|
+
.map(Number)
|
|
185
173
|
|
|
186
174
|
// Calculate numerator ------------------
|
|
187
175
|
let waffleNumerator = ''
|
|
@@ -208,7 +196,7 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
208
196
|
[DATA_FUNCTION_MEDIAN]: getMedian(numericalDenomData).toString(),
|
|
209
197
|
[DATA_FUNCTION_MAX]: Math.max(...numericalDenomData).toString(),
|
|
210
198
|
[DATA_FUNCTION_MIN]: Math.min(...numericalDenomData).toString(),
|
|
211
|
-
[DATA_FUNCTION_MODE]: getMode(numericalDenomData).join(', ')
|
|
199
|
+
[DATA_FUNCTION_MODE]: getMode(numericalDenomData).join(', ')
|
|
212
200
|
}
|
|
213
201
|
|
|
214
202
|
if (customDenom && dataDenomColumn && dataDenomFunction) {
|
|
@@ -219,20 +207,7 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
219
207
|
|
|
220
208
|
// @ts-ignore
|
|
221
209
|
return applyPrecision((waffleNumerator / waffleDenominator) * 100)
|
|
222
|
-
}, [
|
|
223
|
-
dataColumn,
|
|
224
|
-
dataFunction,
|
|
225
|
-
config.data,
|
|
226
|
-
filters,
|
|
227
|
-
dataConditionalColumn,
|
|
228
|
-
dataConditionalOperator,
|
|
229
|
-
dataConditionalComparate,
|
|
230
|
-
customDenom,
|
|
231
|
-
dataDenomColumn,
|
|
232
|
-
dataDenomFunction,
|
|
233
|
-
roundToPlace,
|
|
234
|
-
dataDenom
|
|
235
|
-
])
|
|
210
|
+
}, [dataColumn, dataFunction, config.data, filters, dataConditionalColumn, dataConditionalOperator, dataConditionalComparate, customDenom, dataDenomColumn, dataDenomFunction, roundToPlace, dataDenom])
|
|
236
211
|
|
|
237
212
|
const dataPercentage = calculateData()
|
|
238
213
|
|
|
@@ -243,7 +218,7 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
243
218
|
|
|
244
219
|
const calculatePos = (shape, axis, index, width, spacer) => {
|
|
245
220
|
let mod = axis === 'x' ? index % 10 : axis === 'y' ? Math.floor(index / 10) : null
|
|
246
|
-
return shape === 'circle' ?
|
|
221
|
+
return shape === 'circle' ? mod * (width + spacer) + width / 2 : mod * (width + spacer)
|
|
247
222
|
}
|
|
248
223
|
|
|
249
224
|
for (let i = 0; i < 100; i++) {
|
|
@@ -252,115 +227,101 @@ const WaffleChart = ({ config, isEditor }) => {
|
|
|
252
227
|
x: calculatePos(shape, 'x', i, nodeWidthNum, nodeSpacerNum),
|
|
253
228
|
y: calculatePos(shape, 'y', i, nodeWidthNum, nodeSpacerNum),
|
|
254
229
|
color: themeColor[theme],
|
|
255
|
-
opacity: i + 1 >
|
|
230
|
+
opacity: i + 1 > 100 - Math.round(dataPercentage) ? 1 : 0.35
|
|
256
231
|
}
|
|
257
232
|
waffleData.push(newNode)
|
|
258
233
|
}
|
|
259
234
|
|
|
260
|
-
return waffleData.map((node, key) =>
|
|
261
|
-
node.shape === 'square'
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
: node.shape === 'person' ?
|
|
235
|
+
return waffleData.map((node, key) =>
|
|
236
|
+
node.shape === 'square' ? (
|
|
237
|
+
<Bar className='cdc-waffle-chart__node' style={{ transitionDelay: `${0.1 * key}ms` }} x={node.x} y={node.y} width={nodeWidthNum} height={nodeWidthNum} fill={node.color} fillOpacity={node.opacity} key={key} />
|
|
238
|
+
) : node.shape === 'person' ? (
|
|
265
239
|
<path
|
|
266
240
|
style={{ transform: `translateX(${node.x + nodeWidthNum / 4}px) translateY(${node.y}px) scale(${nodeWidthNum / 20})` }}
|
|
267
|
-
fill={node.color}
|
|
268
|
-
|
|
241
|
+
fill={node.color}
|
|
242
|
+
fillOpacity={node.opacity}
|
|
243
|
+
key={key}
|
|
244
|
+
d='M3.75,0a2.5,2.5,0,1,1-2.5,2.5A2.5,2.5,0,0,1,3.75,0M5.625,5.625H5.18125a3.433,3.433,0,0,1-2.8625,0H1.875A1.875,1.875,
|
|
269
245
|
0,0,0,0,7.5v5.3125a.9375.9375,0,0,0,.9375.9375h.625v5.3125A.9375.9375,0,0,0,2.5,20H5a.9375.9375,0,0,0,
|
|
270
|
-
.9375-.9375V13.75h.625A.9375.9375,0,0,0,7.5,12.8125V7.5A1.875,1.875,0,0,0,5.625,5.625Z
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
<Circle className=
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
}, [
|
|
246
|
+
.9375-.9375V13.75h.625A.9375.9375,0,0,0,7.5,12.8125V7.5A1.875,1.875,0,0,0,5.625,5.625Z'
|
|
247
|
+
></path>
|
|
248
|
+
) : (
|
|
249
|
+
<Circle className='cdc-waffle-chart__node' style={{ transitionDelay: `${0.1 * key}ms` }} cx={node.x} cy={node.y} r={nodeWidthNum / 2} fill={node.color} fillOpacity={node.opacity} key={key} />
|
|
250
|
+
)
|
|
251
|
+
)
|
|
252
|
+
}, [theme, dataPercentage, shape, nodeWidth, nodeSpacer])
|
|
277
253
|
|
|
278
254
|
const setRatio = useCallback(() => {
|
|
279
|
-
return
|
|
280
|
-
}, [
|
|
255
|
+
return nodeWidth * 10 + nodeSpacer * 9
|
|
256
|
+
}, [nodeWidth, nodeSpacer])
|
|
281
257
|
|
|
282
258
|
let dataFontSize = config.fontSize ? { fontSize: config.fontSize + 'px' } : null
|
|
283
259
|
|
|
260
|
+
const { innerContainerClasses, contentClasses } = useDataVizClasses(config)
|
|
284
261
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
// ! these two will be retired.
|
|
299
|
-
config.shadow && innerContainerClasses.push('shadow')
|
|
300
|
-
config?.visual?.roundedBorders && innerContainerClasses.push('bite--has-rounded-borders')
|
|
262
|
+
const handleWaffleChartAriaLabel = (state, testing = false) => {
|
|
263
|
+
if (testing) console.log(`handleWaffleChartAriaLabels Testing On:`, state)
|
|
264
|
+
try {
|
|
265
|
+
let ariaLabel = 'Waffle chart'
|
|
266
|
+
if (state.title) {
|
|
267
|
+
ariaLabel += ` with the title: ${state.title}`
|
|
268
|
+
}
|
|
269
|
+
return ariaLabel
|
|
270
|
+
} catch (e) {
|
|
271
|
+
console.error(e.message)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
301
274
|
|
|
302
275
|
return (
|
|
303
276
|
<div className={innerContainerClasses.join(' ')}>
|
|
304
277
|
<>
|
|
305
|
-
{title &&
|
|
306
|
-
|
|
278
|
+
{title && (
|
|
279
|
+
<header className={`cove-component__header chart-title ${config.theme}`} aria-hidden='true'>
|
|
307
280
|
{parse(title)}
|
|
308
|
-
|
|
309
|
-
}
|
|
281
|
+
</header>
|
|
282
|
+
)}
|
|
310
283
|
<div className={contentClasses.join(' ')}>
|
|
311
|
-
<div className=
|
|
312
|
-
<div
|
|
313
|
-
className=
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
<Group>
|
|
317
|
-
{buildWaffle()}
|
|
318
|
-
</Group>
|
|
284
|
+
<div className='cove-component__content-wrap'>
|
|
285
|
+
<div className={`cove-waffle-chart${orientation === 'vertical' ? ' cove-waffle-chart--verical' : ''}${config.overallFontSize ? ' font-' + config.overallFontSize : ''}`}>
|
|
286
|
+
<div className='cove-waffle-chart__chart' style={{ width: setRatio() }}>
|
|
287
|
+
<svg width={setRatio()} height={setRatio()} role='img' aria-label={handleWaffleChartAriaLabel(config)} tabIndex={0}>
|
|
288
|
+
<Group>{buildWaffle()}</Group>
|
|
319
289
|
</svg>
|
|
320
290
|
</div>
|
|
321
|
-
{(dataPercentage || content) &&
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
291
|
+
{(dataPercentage || content) && (
|
|
292
|
+
<div className='cove-waffle-chart__data'>
|
|
293
|
+
{dataPercentage && (
|
|
294
|
+
<div className='cove-waffle-chart__data--primary' style={dataFontSize}>
|
|
295
|
+
{prefix ? prefix : null}
|
|
296
|
+
{dataPercentage}
|
|
297
|
+
{suffix ? suffix : null}
|
|
298
|
+
</div>
|
|
299
|
+
)}
|
|
300
|
+
<div className='cove-waffle-chart__data--text'>{parse(content)}</div>
|
|
301
|
+
|
|
302
|
+
{subtext && <div className='cove-waffle-chart__subtext'>{parse(subtext)}</div>}
|
|
326
303
|
</div>
|
|
327
|
-
|
|
328
|
-
<div className="cove-waffle-chart__data--text" >{parse(content)}</div>
|
|
329
|
-
</div>
|
|
330
|
-
}
|
|
331
|
-
</div>
|
|
332
|
-
{subtext &&
|
|
333
|
-
<div className="cove-waffle-chart__subtext">
|
|
334
|
-
{parse(subtext)}
|
|
304
|
+
)}
|
|
335
305
|
</div>
|
|
336
|
-
}
|
|
337
306
|
</div>
|
|
338
307
|
</div>
|
|
308
|
+
{link && link}
|
|
339
309
|
</>
|
|
340
310
|
</div>
|
|
341
311
|
)
|
|
342
312
|
}
|
|
343
313
|
|
|
344
|
-
const CdcWaffleChart = (
|
|
345
|
-
{
|
|
346
|
-
configUrl,
|
|
347
|
-
config: configObj,
|
|
348
|
-
isDashboard = false,
|
|
349
|
-
isEditor = false,
|
|
350
|
-
setConfig: setParentConfig
|
|
351
|
-
}
|
|
352
|
-
) => {
|
|
353
|
-
|
|
314
|
+
const CdcWaffleChart = ({ configUrl, config: configObj, isDashboard = false, isEditor = false, setConfig: setParentConfig }) => {
|
|
354
315
|
// Default States
|
|
355
|
-
const [
|
|
356
|
-
const [
|
|
316
|
+
const [config, setConfig] = useState({ ...defaults })
|
|
317
|
+
const [loading, setLoading] = useState(true)
|
|
357
318
|
|
|
358
|
-
const [
|
|
359
|
-
const [
|
|
360
|
-
const [
|
|
319
|
+
const [currentViewport, setCurrentViewport] = useState<String>('lg')
|
|
320
|
+
const [coveLoadedHasRan, setCoveLoadedHasRan] = useState(false)
|
|
321
|
+
const [container, setContainer] = useState()
|
|
361
322
|
|
|
362
323
|
// Default Functions
|
|
363
|
-
const updateConfig =
|
|
324
|
+
const updateConfig = newConfig => {
|
|
364
325
|
Object.keys(defaults).forEach(key => {
|
|
365
326
|
if (newConfig[key] && 'object' === typeof newConfig[key] && !Array.isArray(newConfig[key])) {
|
|
366
327
|
newConfig[key] = { ...defaults[key], ...newConfig[key] }
|
|
@@ -375,7 +336,7 @@ const CdcWaffleChart = (
|
|
|
375
336
|
}
|
|
376
337
|
|
|
377
338
|
const loadConfig = useCallback(async () => {
|
|
378
|
-
let response = configObj || await (await fetch(configUrl)).json()
|
|
339
|
+
let response = configObj || (await (await fetch(configUrl)).json())
|
|
379
340
|
let responseData = response.data ?? {}
|
|
380
341
|
|
|
381
342
|
if (response.dataUrl) {
|
|
@@ -409,31 +370,35 @@ const CdcWaffleChart = (
|
|
|
409
370
|
|
|
410
371
|
//Load initial config
|
|
411
372
|
useEffect(() => {
|
|
412
|
-
loadConfig().catch(
|
|
373
|
+
loadConfig().catch(err => console.log(err))
|
|
413
374
|
}, [])
|
|
414
375
|
|
|
415
376
|
useEffect(() => {
|
|
416
377
|
if (config && !coveLoadedHasRan && container) {
|
|
417
|
-
|
|
418
|
-
|
|
378
|
+
publish('cove_loaded', { config: config })
|
|
379
|
+
setCoveLoadedHasRan(true)
|
|
419
380
|
}
|
|
420
|
-
}, [config, container])
|
|
381
|
+
}, [config, container])
|
|
421
382
|
|
|
422
383
|
//Reload config if config object provided/updated
|
|
423
384
|
useEffect(() => {
|
|
424
|
-
loadConfig().catch(
|
|
425
|
-
}, [
|
|
385
|
+
loadConfig().catch(err => console.log(err))
|
|
386
|
+
}, [])
|
|
387
|
+
|
|
388
|
+
//Reload config if parent passes different config
|
|
389
|
+
if (configObj) {
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
console.log('changing')
|
|
392
|
+
if (!configObj.dataUrl) {
|
|
393
|
+
updateConfig({ ...defaults, ...configObj })
|
|
394
|
+
}
|
|
395
|
+
}, [configObj.data])
|
|
396
|
+
}
|
|
426
397
|
|
|
427
|
-
let content =
|
|
398
|
+
let content = <Loading />
|
|
428
399
|
|
|
429
400
|
if (loading === false) {
|
|
430
|
-
let classNames = [
|
|
431
|
-
'cdc-open-viz-module',
|
|
432
|
-
'type-waffle-chart',
|
|
433
|
-
currentViewport,
|
|
434
|
-
config.theme,
|
|
435
|
-
'font-' + config.overallFontSize
|
|
436
|
-
]
|
|
401
|
+
let classNames = ['cove', 'type-waffle-chart', currentViewport, config.theme, 'font-' + config.overallFontSize]
|
|
437
402
|
|
|
438
403
|
if (isEditor) {
|
|
439
404
|
classNames.push('is-editor')
|
|
@@ -441,16 +406,14 @@ const CdcWaffleChart = (
|
|
|
441
406
|
|
|
442
407
|
let bodyClasses = ['cove-component', 'waffle-chart']
|
|
443
408
|
|
|
444
|
-
|
|
445
|
-
|
|
446
409
|
let body = (
|
|
447
410
|
<div className={`${bodyClasses.join(' ')}`} ref={outerContainerRef}>
|
|
448
|
-
<WaffleChart config={config} isEditor={isEditor}/>
|
|
411
|
+
<WaffleChart config={config} isEditor={isEditor} />
|
|
449
412
|
</div>
|
|
450
413
|
)
|
|
451
414
|
|
|
452
415
|
content = (
|
|
453
|
-
<div className={
|
|
416
|
+
<div className={classNames.join(' ')}>
|
|
454
417
|
{isEditor && <EditorPanel>{body}</EditorPanel>}
|
|
455
418
|
{!isEditor && body}
|
|
456
419
|
</div>
|
|
@@ -458,11 +421,8 @@ const CdcWaffleChart = (
|
|
|
458
421
|
}
|
|
459
422
|
|
|
460
423
|
return (
|
|
461
|
-
<ErrorBoundary component=
|
|
462
|
-
<ConfigContext.Provider
|
|
463
|
-
value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard, outerContainerRef }}>
|
|
464
|
-
{content}
|
|
465
|
-
</ConfigContext.Provider>
|
|
424
|
+
<ErrorBoundary component='WaffleChart'>
|
|
425
|
+
<ConfigContext.Provider value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard, outerContainerRef }}>{content}</ConfigContext.Provider>
|
|
466
426
|
</ErrorBoundary>
|
|
467
427
|
)
|
|
468
428
|
}
|
|
@@ -477,15 +437,7 @@ export const DATA_FUNCTION_MIN = 'Min'
|
|
|
477
437
|
export const DATA_FUNCTION_MODE = 'Mode'
|
|
478
438
|
export const DATA_FUNCTION_SUM = 'Sum'
|
|
479
439
|
|
|
480
|
-
export const DATA_FUNCTIONS = [
|
|
481
|
-
DATA_FUNCTION_COUNT,
|
|
482
|
-
DATA_FUNCTION_MAX,
|
|
483
|
-
DATA_FUNCTION_MEAN,
|
|
484
|
-
DATA_FUNCTION_MEDIAN,
|
|
485
|
-
DATA_FUNCTION_MIN,
|
|
486
|
-
DATA_FUNCTION_MODE,
|
|
487
|
-
DATA_FUNCTION_SUM
|
|
488
|
-
]
|
|
440
|
+
export const DATA_FUNCTIONS = [DATA_FUNCTION_COUNT, DATA_FUNCTION_MAX, DATA_FUNCTION_MEAN, DATA_FUNCTION_MEDIAN, DATA_FUNCTION_MIN, DATA_FUNCTION_MODE, DATA_FUNCTION_SUM]
|
|
489
441
|
|
|
490
442
|
export const DATA_OPERATOR_LESS = '<'
|
|
491
443
|
export const DATA_OPERATOR_GREATER = '>'
|
|
@@ -494,11 +446,4 @@ export const DATA_OPERATOR_GREATEREQUAL = '>='
|
|
|
494
446
|
export const DATA_OPERATOR_EQUAL = '='
|
|
495
447
|
export const DATA_OPERATOR_NOTEQUAL = '≠'
|
|
496
448
|
|
|
497
|
-
export const DATA_OPERATORS = [
|
|
498
|
-
DATA_OPERATOR_LESS,
|
|
499
|
-
DATA_OPERATOR_GREATER,
|
|
500
|
-
DATA_OPERATOR_LESSEQUAL,
|
|
501
|
-
DATA_OPERATOR_GREATEREQUAL,
|
|
502
|
-
DATA_OPERATOR_EQUAL,
|
|
503
|
-
DATA_OPERATOR_NOTEQUAL
|
|
504
|
-
]
|
|
449
|
+
export const DATA_OPERATORS = [DATA_OPERATOR_LESS, DATA_OPERATOR_GREATER, DATA_OPERATOR_LESSEQUAL, DATA_OPERATOR_GREATEREQUAL, DATA_OPERATOR_EQUAL, DATA_OPERATOR_NOTEQUAL]
|
package/src/ConfigContext.js
CHANGED