@cdc/waffle-chart 4.25.11 → 4.26.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/dist/cdcwafflechart.js +6603 -6234
- package/examples/tp5-style-white.json +72 -0
- package/examples/tp5-style.json +72 -0
- package/examples/tp5-waffle.json +123 -0
- package/index.html +3 -6
- package/package.json +6 -5
- package/src/CdcWaffleChart.tsx +156 -96
- package/src/_stories/WaffleChart.Editor.stories.tsx +17 -30
- package/src/_stories/WaffleChart.stories.tsx +28 -0
- package/src/components/EditorPanel.jsx +110 -199
- package/src/images/callout-flag.svg +7 -0
- package/src/scss/waffle-chart.scss +86 -4
- package/src/test/CdcWaffleChart.test.jsx +1 -1
- package/src/types/Config.ts +4 -2
- package/LICENSE +0 -201
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "waffle-chart",
|
|
3
|
+
"shape": "person",
|
|
4
|
+
"title": "Overdose Mortality Rate",
|
|
5
|
+
"content": "of overdoses resulted in death.",
|
|
6
|
+
"subtext": "This data is an example and does not reflect actual averages",
|
|
7
|
+
"orientation": "horizontal",
|
|
8
|
+
"visualizationType": "TP5 Waffle",
|
|
9
|
+
"data": [
|
|
10
|
+
{
|
|
11
|
+
"Resulted in Death": 250,
|
|
12
|
+
"Number of Overdoses": 600,
|
|
13
|
+
"state": "Alabama",
|
|
14
|
+
"Year": "2010"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"Resulted in Death": 16,
|
|
18
|
+
"Number of Overdoses": 80,
|
|
19
|
+
"state": "Alaska",
|
|
20
|
+
"Year": "2008"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"Resulted in Death": 19,
|
|
24
|
+
"Number of Overdoses": 100,
|
|
25
|
+
"state": "Alaska",
|
|
26
|
+
"Year": "2010"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"Resulted in Death": 93,
|
|
30
|
+
"Number of Overdoses": 400,
|
|
31
|
+
"state": "Alaska",
|
|
32
|
+
"Year": "2012"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"Resulted in Death": 82,
|
|
36
|
+
"Number of Overdoses": 400,
|
|
37
|
+
"state": "Arizona",
|
|
38
|
+
"Year": "2010"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"filters": [],
|
|
42
|
+
"fontSize": null,
|
|
43
|
+
"overallFontSize": "medium",
|
|
44
|
+
"dataColumn": "Resulted in Death",
|
|
45
|
+
"dataFunction": "Sum",
|
|
46
|
+
"dataConditionalColumn": "",
|
|
47
|
+
"dataConditionalOperator": null,
|
|
48
|
+
"dataConditionalComparate": "",
|
|
49
|
+
"customDenom": true,
|
|
50
|
+
"dataDenom": null,
|
|
51
|
+
"dataDenomColumn": "Number of Overdoses",
|
|
52
|
+
"dataDenomFunction": "Sum",
|
|
53
|
+
"prefix": "",
|
|
54
|
+
"suffix": "%",
|
|
55
|
+
"roundToPlace": 0,
|
|
56
|
+
"nodeWidth": 10,
|
|
57
|
+
"nodeSpacer": 2,
|
|
58
|
+
"theme": "theme-blue",
|
|
59
|
+
"visualizationSubType": "",
|
|
60
|
+
"invalidComparate": false,
|
|
61
|
+
"showDenominator": false,
|
|
62
|
+
"showPercent": true,
|
|
63
|
+
"valueDescription": "Overdose mortality percentage",
|
|
64
|
+
"visual": {
|
|
65
|
+
"border": false,
|
|
66
|
+
"accent": false,
|
|
67
|
+
"background": false,
|
|
68
|
+
"hideBackgroundColor": false,
|
|
69
|
+
"borderColorTheme": false,
|
|
70
|
+
"whiteBackground": true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "waffle-chart",
|
|
3
|
+
"shape": "person",
|
|
4
|
+
"title": "Overdose Mortality Rate",
|
|
5
|
+
"content": "of overdoses resulted in death.",
|
|
6
|
+
"subtext": "This data is an example and does not reflect actual averages",
|
|
7
|
+
"orientation": "horizontal",
|
|
8
|
+
"visualizationType": "TP5 Waffle",
|
|
9
|
+
"data": [
|
|
10
|
+
{
|
|
11
|
+
"Resulted in Death": 250,
|
|
12
|
+
"Number of Overdoses": 600,
|
|
13
|
+
"state": "Alabama",
|
|
14
|
+
"Year": "2010"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"Resulted in Death": 16,
|
|
18
|
+
"Number of Overdoses": 80,
|
|
19
|
+
"state": "Alaska",
|
|
20
|
+
"Year": "2008"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"Resulted in Death": 19,
|
|
24
|
+
"Number of Overdoses": 100,
|
|
25
|
+
"state": "Alaska",
|
|
26
|
+
"Year": "2010"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"Resulted in Death": 93,
|
|
30
|
+
"Number of Overdoses": 400,
|
|
31
|
+
"state": "Alaska",
|
|
32
|
+
"Year": "2012"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"Resulted in Death": 82,
|
|
36
|
+
"Number of Overdoses": 400,
|
|
37
|
+
"state": "Arizona",
|
|
38
|
+
"Year": "2010"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"filters": [],
|
|
42
|
+
"fontSize": null,
|
|
43
|
+
"overallFontSize": "medium",
|
|
44
|
+
"dataColumn": "Resulted in Death",
|
|
45
|
+
"dataFunction": "Sum",
|
|
46
|
+
"dataConditionalColumn": "",
|
|
47
|
+
"dataConditionalOperator": null,
|
|
48
|
+
"dataConditionalComparate": "",
|
|
49
|
+
"customDenom": true,
|
|
50
|
+
"dataDenom": null,
|
|
51
|
+
"dataDenomColumn": "Number of Overdoses",
|
|
52
|
+
"dataDenomFunction": "Sum",
|
|
53
|
+
"prefix": "",
|
|
54
|
+
"suffix": "%",
|
|
55
|
+
"roundToPlace": 0,
|
|
56
|
+
"nodeWidth": 10,
|
|
57
|
+
"nodeSpacer": 2,
|
|
58
|
+
"theme": "theme-blue",
|
|
59
|
+
"visualizationSubType": "",
|
|
60
|
+
"invalidComparate": false,
|
|
61
|
+
"showDenominator": false,
|
|
62
|
+
"showPercent": true,
|
|
63
|
+
"valueDescription": "Overdose mortality percentage",
|
|
64
|
+
"visual": {
|
|
65
|
+
"border": false,
|
|
66
|
+
"accent": false,
|
|
67
|
+
"background": false,
|
|
68
|
+
"hideBackgroundColor": false,
|
|
69
|
+
"borderColorTheme": false,
|
|
70
|
+
"whiteBackground": false
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "A Waffle Chart - Person",
|
|
3
|
+
"titleStyle": "small",
|
|
4
|
+
"showTitle": true,
|
|
5
|
+
"visualizationSubType": "linear",
|
|
6
|
+
"showPercent": true,
|
|
7
|
+
"showDenominator": true,
|
|
8
|
+
"valueDescription": "out of",
|
|
9
|
+
"content": "Highlight a piece of data in relationship to a data set.",
|
|
10
|
+
"subtext": "",
|
|
11
|
+
"orientation": null,
|
|
12
|
+
"filters": [],
|
|
13
|
+
"fontSize": "",
|
|
14
|
+
"overallFontSize": "medium",
|
|
15
|
+
"dataColumn": "Age-adjusted rate",
|
|
16
|
+
"dataFunction": "Count",
|
|
17
|
+
"dataConditionalColumn": "",
|
|
18
|
+
"dataConditionalOperator": "",
|
|
19
|
+
"dataConditionalComparate": "",
|
|
20
|
+
"invalidComparate": false,
|
|
21
|
+
"customDenom": false,
|
|
22
|
+
"dataDenom": "100",
|
|
23
|
+
"dataDenomColumn": "",
|
|
24
|
+
"dataDenomFunction": "",
|
|
25
|
+
"suffix": "%",
|
|
26
|
+
"roundToPlace": "0",
|
|
27
|
+
"shape": "person",
|
|
28
|
+
"nodeWidth": "10",
|
|
29
|
+
"nodeSpacer": "2",
|
|
30
|
+
"theme": "theme-blue",
|
|
31
|
+
"type": "waffle-chart",
|
|
32
|
+
"visualizationType": "TP5 Waffle",
|
|
33
|
+
"gauge": {
|
|
34
|
+
"height": 35,
|
|
35
|
+
"width": "100%"
|
|
36
|
+
},
|
|
37
|
+
"visual": {
|
|
38
|
+
"border": true,
|
|
39
|
+
"accent": false,
|
|
40
|
+
"background": false,
|
|
41
|
+
"hideBackgroundColor": false,
|
|
42
|
+
"borderColorTheme": false,
|
|
43
|
+
"colors": {
|
|
44
|
+
"theme-blue": "#005eaa",
|
|
45
|
+
"theme-purple": "#712177",
|
|
46
|
+
"theme-brown": "#705043",
|
|
47
|
+
"theme-teal": "#00695c",
|
|
48
|
+
"theme-pink": "#af4448",
|
|
49
|
+
"theme-orange": "#bb4d00",
|
|
50
|
+
"theme-slate": "#29434e",
|
|
51
|
+
"theme-indigo": "#26418f",
|
|
52
|
+
"theme-cyan": "#006778",
|
|
53
|
+
"theme-green": "#4b830d",
|
|
54
|
+
"theme-amber": "#fbab18"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"errors": [],
|
|
58
|
+
"currentViewport": "lg",
|
|
59
|
+
"id": 17,
|
|
60
|
+
"category": "General",
|
|
61
|
+
"label": "Waffle Chart",
|
|
62
|
+
"subType": "Waffle",
|
|
63
|
+
"icon": {
|
|
64
|
+
"type": {},
|
|
65
|
+
"key": null,
|
|
66
|
+
"ref": null,
|
|
67
|
+
"props": {},
|
|
68
|
+
"_owner": null,
|
|
69
|
+
"_store": {}
|
|
70
|
+
},
|
|
71
|
+
"activeVizButtonID": 17,
|
|
72
|
+
"dataFileName": "valid-data-chart.csv",
|
|
73
|
+
"dataFileSourceType": "file",
|
|
74
|
+
"dataDescription": {
|
|
75
|
+
"horizontal": false,
|
|
76
|
+
"series": false
|
|
77
|
+
},
|
|
78
|
+
"data": [
|
|
79
|
+
{
|
|
80
|
+
"Race": "Hispanic or Latino",
|
|
81
|
+
"Age-adjusted rate": "644.2"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"Race": "Non-Hispanic American Indian",
|
|
85
|
+
"Age-adjusted rate": "636.1"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"Race": "Non-Hispanic Black",
|
|
89
|
+
"Age-adjusted rate": "563.7"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"Race": "Non-Hispanic Asian or Pacific Islander",
|
|
93
|
+
"Age-adjusted rate": "202.5"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"Race": "Non-Hispanic White",
|
|
97
|
+
"Age-adjusted rate": "183.6"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"formattedData": [
|
|
101
|
+
{
|
|
102
|
+
"Race": "Hispanic or Latino",
|
|
103
|
+
"Age-adjusted rate": "644.2"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"Race": "Non-Hispanic American Indian",
|
|
107
|
+
"Age-adjusted rate": "636.1"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"Race": "Non-Hispanic Black",
|
|
111
|
+
"Age-adjusted rate": "563.7"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"Race": "Non-Hispanic Asian or Pacific Islander",
|
|
115
|
+
"Age-adjusted rate": "202.5"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"Race": "Non-Hispanic White",
|
|
119
|
+
"Age-adjusted rate": "183.6"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"datasets": {}
|
|
123
|
+
}
|
package/index.html
CHANGED
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
6
6
|
<style>
|
|
7
|
-
.type-waffle-chart {
|
|
8
|
-
min-height: 100vh;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
7
|
body {
|
|
12
8
|
/* max-width: 1000px; */
|
|
13
9
|
margin: 0 auto !important;
|
|
@@ -17,8 +13,9 @@
|
|
|
17
13
|
border-top: none !important;
|
|
18
14
|
}
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
/* Add 1rem padding to mimic DFE when editor is not visible */
|
|
17
|
+
.cdc-open-viz-module:not(.isEditor) {
|
|
18
|
+
padding: 1rem;
|
|
22
19
|
}
|
|
23
20
|
</style>
|
|
24
21
|
<link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/5.0/css/app.min.css?_=71669" />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/waffle-chart",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.26.1",
|
|
4
4
|
"description": "React component for displaying a single piece of data in a card module",
|
|
5
5
|
"moduleName": "CdcWaffleChart",
|
|
6
6
|
"main": "dist/cdcwafflechart",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@cdc/core": "^4.
|
|
30
|
+
"@cdc/core": "^4.26.1",
|
|
31
31
|
"@visx/shape": "^3.12.0",
|
|
32
32
|
"@visx/text": "^3.12.0",
|
|
33
33
|
"chroma": "0.0.1",
|
|
@@ -40,10 +40,11 @@
|
|
|
40
40
|
"react-dom": "^18.2.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
+
"@rollup/plugin-dsv": "^3.0.2",
|
|
43
44
|
"@vitejs/plugin-react": "^4.3.4",
|
|
44
|
-
"
|
|
45
|
+
"sass": "^1.89.2",
|
|
45
46
|
"vite-plugin-css-injected-by-js": "^2.4.0",
|
|
46
|
-
"vite-plugin-svgr": "^2.
|
|
47
|
+
"vite-plugin-svgr": "^4.2.0"
|
|
47
48
|
},
|
|
48
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "7e3b27098c4eb7a24bc9c3654ad53f88d6419f16"
|
|
49
50
|
}
|
package/src/CdcWaffleChart.tsx
CHANGED
|
@@ -30,6 +30,13 @@ import './scss/main.scss'
|
|
|
30
30
|
import Title from '@cdc/core/components/ui/Title'
|
|
31
31
|
import Layout from '@cdc/core/components/Layout'
|
|
32
32
|
|
|
33
|
+
// images
|
|
34
|
+
import CalloutFlag from './images/callout-flag.svg?url'
|
|
35
|
+
|
|
36
|
+
// TP5 Style Constants
|
|
37
|
+
const TP5_NODE_WIDTH = 13
|
|
38
|
+
const TP5_NODE_SPACER = 3
|
|
39
|
+
|
|
33
40
|
type CdcWaffleChartProps = {
|
|
34
41
|
configUrl?: string
|
|
35
42
|
config?: Config
|
|
@@ -256,8 +263,10 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
|
|
|
256
263
|
|
|
257
264
|
const buildWaffle = useCallback(() => {
|
|
258
265
|
let waffleData = []
|
|
259
|
-
|
|
260
|
-
|
|
266
|
+
// Use standardized values for TP5 style
|
|
267
|
+
const isTP5 = config.visualizationType === 'TP5 Waffle'
|
|
268
|
+
let nodeWidthNum = isTP5 ? TP5_NODE_WIDTH : parseInt(nodeWidth, 10)
|
|
269
|
+
let nodeSpacerNum = isTP5 ? TP5_NODE_SPACER : parseInt(nodeSpacer, 10)
|
|
261
270
|
|
|
262
271
|
const calculatePos = (shape, axis, index, width, spacer) => {
|
|
263
272
|
let mod = axis === 'x' ? index % 10 : axis === 'y' ? Math.floor(index / 10) : null
|
|
@@ -270,7 +279,8 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
|
|
|
270
279
|
x: calculatePos(shape, 'x', i, nodeWidthNum, nodeSpacerNum),
|
|
271
280
|
y: calculatePos(shape, 'y', i, nodeWidthNum, nodeSpacerNum),
|
|
272
281
|
color: config.visual.colors[theme],
|
|
273
|
-
opacity: i + 1 > 100 - Math.round(dataPercentage) ? 1 : 0.
|
|
282
|
+
opacity: i + 1 > 100 - Math.round(dataPercentage) ? 1 : 0.2,
|
|
283
|
+
isFilled: i + 1 > 100 - Math.round(dataPercentage)
|
|
274
284
|
}
|
|
275
285
|
waffleData.push(newNode)
|
|
276
286
|
}
|
|
@@ -280,25 +290,37 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
|
|
|
280
290
|
<Bar
|
|
281
291
|
className='cdc-waffle-chart__node'
|
|
282
292
|
style={{ transitionDelay: `${0.1 * key}ms` }}
|
|
283
|
-
x={node.x}
|
|
284
|
-
y={node.y}
|
|
285
|
-
width={nodeWidthNum}
|
|
286
|
-
height={nodeWidthNum}
|
|
287
|
-
fill={node.color}
|
|
288
|
-
fillOpacity={node.opacity}
|
|
293
|
+
x={isTP5 && !node.isFilled ? node.x + 1 : node.x}
|
|
294
|
+
y={isTP5 && !node.isFilled ? node.y + 1 : node.y}
|
|
295
|
+
width={isTP5 && !node.isFilled ? nodeWidthNum - 2 : nodeWidthNum}
|
|
296
|
+
height={isTP5 && !node.isFilled ? nodeWidthNum - 2 : nodeWidthNum}
|
|
297
|
+
fill={isTP5 ? (node.isFilled ? '#009EC1' : '#DFF2F6') : node.color}
|
|
298
|
+
fillOpacity={isTP5 ? 1 : node.opacity}
|
|
299
|
+
stroke={isTP5 ? (!node.isFilled ? '#009EC1' : undefined) : undefined}
|
|
300
|
+
strokeWidth={isTP5 ? (!node.isFilled ? 1 : 0) : 0}
|
|
289
301
|
key={key}
|
|
290
302
|
/>
|
|
291
303
|
) : node.shape === 'person' ? (
|
|
292
304
|
<path
|
|
305
|
+
className='cdc-waffle-chart__node'
|
|
293
306
|
style={{
|
|
294
|
-
transform:
|
|
307
|
+
transform: isTP5
|
|
308
|
+
? `translateX(${node.x}px) translateY(${node.y + nodeWidthNum * 0.1}px) scale(${
|
|
309
|
+
(nodeWidthNum * 0.8) / 448
|
|
310
|
+
})`
|
|
311
|
+
: `translateX(${node.x + nodeWidthNum / 4}px) translateY(${node.y}px) scale(${nodeWidthNum / 20})`,
|
|
312
|
+
transitionDelay: `${0.1 * key}ms`
|
|
295
313
|
}}
|
|
296
|
-
fill={node.color}
|
|
297
|
-
fillOpacity={node.opacity}
|
|
314
|
+
fill={isTP5 ? (node.isFilled ? '#009EC1' : 'transparent') : node.color}
|
|
315
|
+
fillOpacity={isTP5 ? 1 : node.opacity}
|
|
316
|
+
stroke={isTP5 ? (!node.isFilled ? '#009EC1' : undefined) : undefined}
|
|
317
|
+
strokeWidth={isTP5 ? (!node.isFilled ? 448 / nodeWidthNum : 0) : 0}
|
|
298
318
|
key={key}
|
|
299
|
-
d=
|
|
300
|
-
|
|
301
|
-
|
|
319
|
+
d={
|
|
320
|
+
isTP5
|
|
321
|
+
? 'M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z'
|
|
322
|
+
: '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,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,.9375-.9375V13.75h.625A.9375.9375,0,0,0,7.5,12.8125V7.5A1.875,1.875,0,0,0,5.625,5.625Z'
|
|
323
|
+
}
|
|
302
324
|
></path>
|
|
303
325
|
) : (
|
|
304
326
|
<Circle
|
|
@@ -306,18 +328,28 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
|
|
|
306
328
|
style={{ transitionDelay: `${0.1 * key}ms` }}
|
|
307
329
|
cx={node.x}
|
|
308
330
|
cy={node.y}
|
|
309
|
-
r={nodeWidthNum / 2}
|
|
310
|
-
fill={node.color}
|
|
311
|
-
fillOpacity={node.opacity}
|
|
331
|
+
r={isTP5 && !node.isFilled ? nodeWidthNum / 2 - 1 : nodeWidthNum / 2}
|
|
332
|
+
fill={isTP5 ? (node.isFilled ? '#009EC1' : '#DFF2F6') : node.color}
|
|
333
|
+
fillOpacity={isTP5 ? 1 : node.opacity}
|
|
334
|
+
stroke={isTP5 ? (!node.isFilled ? '#009EC1' : undefined) : undefined}
|
|
335
|
+
strokeWidth={isTP5 ? (!node.isFilled ? 1 : 0) : 0}
|
|
312
336
|
key={key}
|
|
313
337
|
/>
|
|
314
338
|
)
|
|
315
339
|
)
|
|
316
|
-
}, [theme, dataPercentage, shape, nodeWidth, nodeSpacer])
|
|
340
|
+
}, [theme, dataPercentage, shape, nodeWidth, nodeSpacer, config.visualizationType, config.visual?.whiteBackground])
|
|
317
341
|
|
|
318
342
|
const setRatio = useCallback(() => {
|
|
319
|
-
|
|
320
|
-
|
|
343
|
+
const isTP5 = config.visualizationType === 'TP5 Waffle'
|
|
344
|
+
const width = isTP5 ? TP5_NODE_WIDTH : nodeWidth
|
|
345
|
+
const spacer = isTP5 ? TP5_NODE_SPACER : nodeSpacer
|
|
346
|
+
return width * 10 + spacer * 9
|
|
347
|
+
}, [nodeWidth, nodeSpacer, config.visualizationType])
|
|
348
|
+
|
|
349
|
+
const setSvgSize = useCallback(() => {
|
|
350
|
+
// Add 2px padding to account for strokes on edges
|
|
351
|
+
return setRatio() + 2
|
|
352
|
+
}, [nodeWidth, nodeSpacer, config.visualizationType])
|
|
321
353
|
|
|
322
354
|
const { innerContainerClasses, contentClasses } = useDataVizClasses(config)
|
|
323
355
|
|
|
@@ -358,76 +390,108 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
|
|
|
358
390
|
)
|
|
359
391
|
}
|
|
360
392
|
|
|
393
|
+
// Render waffle chart content (without title)
|
|
394
|
+
const renderChartContent = () => (
|
|
395
|
+
<>
|
|
396
|
+
{!config.newViz && config.runtime && config.runtime.editorErrorMessage && (
|
|
397
|
+
<Error updateConfig={updateConfig} config={config} />
|
|
398
|
+
)}
|
|
399
|
+
{config.newViz && showConfigConfirm && <Confirm updateConfig={updateConfig} config={config} />}
|
|
400
|
+
<div className='cove-component__content-wrap p-0'>
|
|
401
|
+
{config.visualizationType === 'Gauge' && (
|
|
402
|
+
<div className={`cove-gauge-chart${config.overallFontSize ? ' font-' + config.overallFontSize : ''}`}>
|
|
403
|
+
<div className='cove-gauge-chart__chart'>
|
|
404
|
+
<div className='cove-waffle-chart__data--primary' style={dataFontSize}>
|
|
405
|
+
{prefix ? prefix : ' '}
|
|
406
|
+
{config.showPercent ? dataPercentage : waffleNumerator}
|
|
407
|
+
{suffix ? suffix + ' ' : ' '} {config.valueDescription}{' '}
|
|
408
|
+
{config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
|
|
409
|
+
</div>
|
|
410
|
+
<div className='cove-waffle-chart__data--text'>{parse(content)}</div>
|
|
411
|
+
<svg height={config.gauge.height + 4} width={'100%'} style={{ overflow: 'visible' }}>
|
|
412
|
+
<Group top={2} left={2}>
|
|
413
|
+
<foreignObject
|
|
414
|
+
style={{ border: '1px solid black' }}
|
|
415
|
+
x={0}
|
|
416
|
+
y={0}
|
|
417
|
+
width={config.gauge.width}
|
|
418
|
+
height={config.gauge.height}
|
|
419
|
+
fill='#fff'
|
|
420
|
+
/>
|
|
421
|
+
<Bar x={0} y={0} width={xScale(waffleNumerator)} height={config.gauge.height} fill={gaugeColor} />
|
|
422
|
+
</Group>
|
|
423
|
+
</svg>
|
|
424
|
+
<div className={'cove-waffle-chart__subtext subtext'}>{parse(subtext)}</div>
|
|
425
|
+
</div>
|
|
426
|
+
</div>
|
|
427
|
+
)}
|
|
428
|
+
{config.visualizationType !== 'Gauge' && (
|
|
429
|
+
<div
|
|
430
|
+
className={`cove-waffle-chart${orientation === 'vertical' ? ' cove-waffle-chart--verical' : ''}${
|
|
431
|
+
config.overallFontSize ? ' font-' + config.overallFontSize : ''
|
|
432
|
+
}`}
|
|
433
|
+
>
|
|
434
|
+
<div className='cove-waffle-chart__chart' style={{ width: setRatio() }}>
|
|
435
|
+
<svg width={setSvgSize()} height={setSvgSize()} style={{ display: 'block' }}>
|
|
436
|
+
<Group top={1} left={1}>
|
|
437
|
+
{buildWaffle()}
|
|
438
|
+
</Group>
|
|
439
|
+
</svg>
|
|
440
|
+
</div>
|
|
441
|
+
{(dataPercentage || content) && (
|
|
442
|
+
<div className='cove-waffle-chart__data'>
|
|
443
|
+
{dataPercentage && (
|
|
444
|
+
<div className='cove-waffle-chart__data--primary' style={dataFontSize}>
|
|
445
|
+
{prefix ? prefix : null}
|
|
446
|
+
{dataPercentage}
|
|
447
|
+
{suffix ? suffix : null}
|
|
448
|
+
</div>
|
|
449
|
+
)}
|
|
450
|
+
<div className='cove-waffle-chart__data--text'>{parse(content)}</div>
|
|
451
|
+
|
|
452
|
+
{subtext && <div className='cove-waffle-chart__subtext subtext fst-italic'>{parse(subtext)}</div>}
|
|
453
|
+
</div>
|
|
454
|
+
)}
|
|
455
|
+
</div>
|
|
456
|
+
)}
|
|
457
|
+
</div>
|
|
458
|
+
</>
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
// TP5 Style: render with callout wrapper inside cove-component__content
|
|
462
|
+
if (config.visualizationType === 'TP5 Waffle') {
|
|
463
|
+
const calloutClasses = ['cdc-callout', 'd-flex', 'flex-column']
|
|
464
|
+
if (!config.visual?.whiteBackground) {
|
|
465
|
+
calloutClasses.push('dfe-block', 'cdc-callout--data')
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return (
|
|
469
|
+
<div className='cove-component__content p-0 border-0'>
|
|
470
|
+
<div className={calloutClasses.join(' ')}>
|
|
471
|
+
{!config.visual?.whiteBackground && (
|
|
472
|
+
<img src={CalloutFlag} alt='' className='cdc-callout__flag' aria-hidden='true' />
|
|
473
|
+
)}
|
|
474
|
+
{config.showTitle && title && title.trim() && (
|
|
475
|
+
<h3 className='cdc-callout__heading fw-bold flex-shrink-0'>{parse(title)}</h3>
|
|
476
|
+
)}
|
|
477
|
+
<div className='w-100 mw-100 overflow-hidden'>{renderChartContent()}</div>
|
|
478
|
+
</div>
|
|
479
|
+
{link && link}
|
|
480
|
+
</div>
|
|
481
|
+
)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Original Style: Regular title and content
|
|
361
485
|
return (
|
|
362
486
|
<div className='cove-component__content'>
|
|
363
487
|
<Title
|
|
364
488
|
showTitle={config.showTitle}
|
|
365
489
|
title={title}
|
|
490
|
+
titleStyle='legacy'
|
|
366
491
|
config={config}
|
|
367
492
|
classes={['chart-title', `${config.theme}`, 'mb-0']}
|
|
368
493
|
/>
|
|
369
|
-
<div className={contentClasses.join(' ')}>
|
|
370
|
-
{!config.newViz && config.runtime && config.runtime.editorErrorMessage && (
|
|
371
|
-
<Error updateConfig={updateConfig} config={config} />
|
|
372
|
-
)}
|
|
373
|
-
{config.newViz && showConfigConfirm && <Confirm updateConfig={updateConfig} config={config} />}
|
|
374
|
-
<div className='cove-component__content-wrap'>
|
|
375
|
-
{config.visualizationType === 'Gauge' && (
|
|
376
|
-
<div className={`cove-gauge-chart${config.overallFontSize ? ' font-' + config.overallFontSize : ''}`}>
|
|
377
|
-
<div className='cove-gauge-chart__chart'>
|
|
378
|
-
<div className='cove-waffle-chart__data--primary' style={dataFontSize}>
|
|
379
|
-
{prefix ? prefix : ' '}
|
|
380
|
-
{config.showPercent ? dataPercentage : waffleNumerator}
|
|
381
|
-
{suffix ? suffix + ' ' : ' '} {config.valueDescription}{' '}
|
|
382
|
-
{config.showDenominator && waffleDenominator ? waffleDenominator : ' '}
|
|
383
|
-
</div>
|
|
384
|
-
<div className='cove-waffle-chart__data--text'>{parse(content)}</div>
|
|
385
|
-
<svg height={config.gauge.height} width={'100%'}>
|
|
386
|
-
<Group>
|
|
387
|
-
<foreignObject
|
|
388
|
-
style={{ border: '1px solid black' }}
|
|
389
|
-
x={0}
|
|
390
|
-
y={0}
|
|
391
|
-
width={config.gauge.width}
|
|
392
|
-
height={config.gauge.height}
|
|
393
|
-
fill='#fff'
|
|
394
|
-
/>
|
|
395
|
-
<Bar x={0} y={0} width={xScale(waffleNumerator)} height={config.gauge.height} fill={gaugeColor} />
|
|
396
|
-
</Group>
|
|
397
|
-
</svg>
|
|
398
|
-
<div className={'cove-waffle-chart__subtext subtext'}>{parse(subtext)}</div>
|
|
399
|
-
</div>
|
|
400
|
-
</div>
|
|
401
|
-
)}
|
|
402
|
-
{config.visualizationType !== 'Gauge' && (
|
|
403
|
-
<div
|
|
404
|
-
className={`cove-waffle-chart${orientation === 'vertical' ? ' cove-waffle-chart--verical' : ''}${
|
|
405
|
-
config.overallFontSize ? ' font-' + config.overallFontSize : ''
|
|
406
|
-
}`}
|
|
407
|
-
>
|
|
408
|
-
<div className='cove-waffle-chart__chart' style={{ width: setRatio() }}>
|
|
409
|
-
<svg width={setRatio()} height={setRatio()}>
|
|
410
|
-
<Group>{buildWaffle()}</Group>
|
|
411
|
-
</svg>
|
|
412
|
-
</div>
|
|
413
|
-
{(dataPercentage || content) && (
|
|
414
|
-
<div className='cove-waffle-chart__data'>
|
|
415
|
-
{dataPercentage && (
|
|
416
|
-
<div className='cove-waffle-chart__data--primary' style={dataFontSize}>
|
|
417
|
-
{prefix ? prefix : null}
|
|
418
|
-
{dataPercentage}
|
|
419
|
-
{suffix ? suffix : null}
|
|
420
|
-
</div>
|
|
421
|
-
)}
|
|
422
|
-
<div className='cove-waffle-chart__data--text'>{parse(content)}</div>
|
|
423
|
-
|
|
424
|
-
{subtext && <div className='cove-waffle-chart__subtext subtext'>{parse(subtext)}</div>}
|
|
425
|
-
</div>
|
|
426
|
-
)}
|
|
427
|
-
</div>
|
|
428
|
-
)}
|
|
429
|
-
</div>
|
|
430
|
-
</div>
|
|
494
|
+
<div className={contentClasses.join(' ')}>{renderChartContent()}</div>
|
|
431
495
|
{link && link}
|
|
432
496
|
</div>
|
|
433
497
|
)
|
|
@@ -521,21 +585,17 @@ const CdcWaffleChart = ({
|
|
|
521
585
|
let content = <Loading />
|
|
522
586
|
|
|
523
587
|
if (loading === false) {
|
|
524
|
-
let body = (
|
|
525
|
-
<Layout.Responsive isEditor={isEditor}>
|
|
526
|
-
<WaffleChart
|
|
527
|
-
config={config}
|
|
528
|
-
isEditor={isEditor}
|
|
529
|
-
showConfigConfirm={showConfigConfirm}
|
|
530
|
-
updateConfig={updateConfig}
|
|
531
|
-
/>
|
|
532
|
-
</Layout.Responsive>
|
|
533
|
-
)
|
|
534
|
-
|
|
535
588
|
content = (
|
|
536
589
|
<>
|
|
537
|
-
{isEditor && <EditorPanel showConfigConfirm={showConfigConfirm}
|
|
538
|
-
{
|
|
590
|
+
{isEditor && <EditorPanel showConfigConfirm={showConfigConfirm} />}
|
|
591
|
+
<Layout.Responsive isEditor={isEditor}>
|
|
592
|
+
<WaffleChart
|
|
593
|
+
config={config}
|
|
594
|
+
isEditor={isEditor}
|
|
595
|
+
showConfigConfirm={showConfigConfirm}
|
|
596
|
+
updateConfig={updateConfig}
|
|
597
|
+
/>
|
|
598
|
+
</Layout.Responsive>
|
|
539
599
|
</>
|
|
540
600
|
)
|
|
541
601
|
}
|