@cdc/chart 4.22.10 → 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.
Files changed (72) hide show
  1. package/README.md +5 -5
  2. package/dist/cdcchart.js +4 -4
  3. package/examples/age-adjusted-rates.json +1486 -1218
  4. package/examples/case-rate-example-config.json +1 -1
  5. package/examples/covid-confidence-example-config.json +33 -33
  6. package/examples/covid-example-config.json +34 -34
  7. package/examples/covid-example-data-confidence.json +30 -30
  8. package/examples/covid-example-data.json +20 -20
  9. package/examples/cutoff-example-config.json +36 -36
  10. package/examples/cutoff-example-data.json +36 -36
  11. package/examples/date-exclusions-config.json +1 -1
  12. package/examples/dynamic-legends.json +124 -124
  13. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +191 -197
  14. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +230 -240
  15. package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +239 -247
  16. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +136 -136
  17. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +79 -79
  18. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +80 -80
  19. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +67 -67
  20. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +110 -110
  21. package/examples/gallery/lollipop/lollipop-style-horizontal.json +215 -219
  22. package/examples/gallery/paired-bar/paired-bar-chart.json +195 -195
  23. package/examples/horizontal-chart.json +35 -35
  24. package/examples/horizontal-stacked-bar-chart.json +34 -34
  25. package/examples/line-chart.json +75 -75
  26. package/examples/paired-bar-data.json +16 -14
  27. package/examples/paired-bar-example.json +48 -48
  28. package/examples/paired-bar-formatted.json +36 -36
  29. package/examples/planet-chart-horizontal-example-config.json +33 -33
  30. package/examples/planet-combo-example-config.json +34 -31
  31. package/examples/planet-example-config.json +35 -33
  32. package/examples/planet-example-data.json +56 -56
  33. package/examples/planet-pie-example-config.json +28 -28
  34. package/examples/private/filters.json +170 -0
  35. package/examples/private/line-test-data.json +21 -21
  36. package/examples/private/line-test-two.json +209 -215
  37. package/examples/private/line-test.json +101 -101
  38. package/examples/private/new.json +48800 -0
  39. package/examples/private/shawn.json +1105 -1295
  40. package/examples/private/test.json +10123 -10123
  41. package/examples/private/yaxis-test.json +4 -3
  42. package/examples/private/yaxis.json +26 -26
  43. package/examples/stacked-vertical-bar-example.json +1 -1
  44. package/examples/temp-example-config.json +61 -54
  45. package/examples/temp-example-data.json +1 -1
  46. package/package.json +2 -2
  47. package/src/CdcChart.tsx +339 -380
  48. package/src/components/BarChart.tsx +425 -469
  49. package/src/components/DataTable.tsx +164 -195
  50. package/src/components/EditorPanel.js +1009 -710
  51. package/src/components/Legend.js +279 -329
  52. package/src/components/LineChart.tsx +90 -79
  53. package/src/components/LinearChart.tsx +376 -434
  54. package/src/components/PairedBarChart.tsx +197 -213
  55. package/src/components/PieChart.tsx +95 -151
  56. package/src/components/SparkLine.js +179 -201
  57. package/src/components/useIntersectionObserver.tsx +17 -20
  58. package/src/context.tsx +3 -3
  59. package/src/data/initial-state.js +37 -16
  60. package/src/hooks/useActiveElement.js +13 -13
  61. package/src/hooks/useChartClasses.js +34 -28
  62. package/src/hooks/useColorPalette.ts +56 -63
  63. package/src/hooks/useLegendClasses.js +18 -10
  64. package/src/hooks/useReduceData.ts +62 -78
  65. package/src/hooks/useRightAxis.js +25 -0
  66. package/src/hooks/useTopAxis.js +6 -0
  67. package/src/index.html +45 -45
  68. package/src/index.tsx +13 -16
  69. package/src/scss/DataTable.scss +5 -4
  70. package/src/scss/editor-panel.scss +71 -69
  71. package/src/scss/main.scss +157 -114
  72. package/src/scss/variables.scss +1 -1
@@ -1,241 +1,225 @@
1
- import React, { useContext } from 'react';
2
- import { Group } from '@visx/group';
3
- import { Bar } from '@visx/shape';
4
- import { scaleLinear, scaleBand } from '@visx/scale';
5
- import { Text } from '@visx/text';
6
-
7
- import Context from '../context';
8
- import chroma from 'chroma-js';
1
+ import React, { useContext } from 'react'
2
+ import { Group } from '@visx/group'
3
+ import { Bar } from '@visx/shape'
4
+ import { scaleLinear, scaleBand } from '@visx/scale'
5
+ import { Text } from '@visx/text'
9
6
 
7
+ import Context from '../context'
8
+ import chroma from 'chroma-js'
10
9
 
11
10
  interface PairedBarChartProps {
12
- width: number,
13
- height: number
11
+ width: number
12
+ height: number
14
13
  }
15
14
 
16
15
  const PairedBarChart: React.FC<PairedBarChartProps> = ({ width, height }) => {
17
-
18
- const { config, colorScale, transformedData, formatNumber, seriesHighlight } = useContext<any>(Context);
19
-
20
- if(!config || config?.series?.length < 2) return;
21
-
22
- const data = transformedData
23
- const adjustedWidth = width;
24
- const adjustedHeight = height;
25
- const halfWidth = adjustedWidth / 2;
26
-
27
- const groupOne = {
28
- parentKey: config.dataDescription.seriesKey,
29
- dataKey: config.series[0].dataKey,
30
- color: colorScale(config.runtime.seriesLabels[config.series[0].dataKey]),
31
- max: Math.max.apply(Math, data.map(item => item[config.series[0].dataKey])),
32
- labelColor: ''
33
- }
34
-
35
- const groupTwo = {
36
- parentKey: config.dataDescription.seriesKey,
37
- dataKey: config.series[1].dataKey,
38
- color: colorScale(config.runtime.seriesLabels[config.series[1].dataKey]),
39
- max: Math.max.apply(Math, data.map(item => item[config.series[1].dataKey])),
40
- labelColor: ''
41
- }
42
-
43
- const xScale = scaleLinear({
44
- domain: [0, Math.max(groupOne.max, groupTwo.max)],
45
- range: [0, halfWidth]
46
- });
47
-
48
-
49
- const yScale = scaleBand({
50
- range: [0, adjustedHeight],
51
- domain: data.map(d => d[config.dataDescription.xKey]),
52
- });
53
-
54
- // Set label color
55
- let labelColor = '#000000';
56
-
57
- if (chroma.contrast(labelColor, groupOne.color) < 4.9) {
58
- groupOne.labelColor = '#FFFFFF';
59
- }
60
-
61
- if (chroma.contrast(labelColor, groupTwo.color) < 4.9) {
62
- groupTwo.labelColor = '#FFFFFF';
63
- }
64
-
65
- const dataTipOne = (d) => {
66
- return (
67
- `<p>
16
+ const { config, colorScale, transformedData, formatNumber, seriesHighlight } = useContext<any>(Context)
17
+
18
+ if (!config || config?.series?.length < 2) return
19
+
20
+ const data = transformedData
21
+ const adjustedWidth = width
22
+ const adjustedHeight = height
23
+ const halfWidth = adjustedWidth / 2
24
+
25
+ const groupOne = {
26
+ parentKey: config.dataDescription.seriesKey,
27
+ dataKey: config.series[0].dataKey,
28
+ color: colorScale(config.runtime.seriesLabels[config.series[0].dataKey]),
29
+ max: Math.max.apply(
30
+ Math,
31
+ data.map(item => item[config.series[0].dataKey])
32
+ ),
33
+ labelColor: ''
34
+ }
35
+
36
+ const groupTwo = {
37
+ parentKey: config.dataDescription.seriesKey,
38
+ dataKey: config.series[1].dataKey,
39
+ color: colorScale(config.runtime.seriesLabels[config.series[1].dataKey]),
40
+ max: Math.max.apply(
41
+ Math,
42
+ data.map(item => item[config.series[1].dataKey])
43
+ ),
44
+ labelColor: ''
45
+ }
46
+
47
+ const xScale = scaleLinear({
48
+ domain: [0, Math.max(groupOne.max, groupTwo.max)],
49
+ range: [0, halfWidth]
50
+ })
51
+
52
+ const yScale = scaleBand({
53
+ range: [0, adjustedHeight],
54
+ domain: data.map(d => d[config.dataDescription.xKey])
55
+ })
56
+
57
+ // Set label color
58
+ let labelColor = '#000000'
59
+
60
+ if (chroma.contrast(labelColor, groupOne.color) < 4.9) {
61
+ groupOne.labelColor = '#FFFFFF'
62
+ }
63
+
64
+ if (chroma.contrast(labelColor, groupTwo.color) < 4.9) {
65
+ groupTwo.labelColor = '#FFFFFF'
66
+ }
67
+
68
+ const dataTipOne = d => {
69
+ return `<p>
68
70
  ${config.dataDescription.seriesKey}: ${groupOne.dataKey}<br/>
69
71
  ${config.xAxis.dataKey}: ${d[config.xAxis.dataKey]}<br/>
70
72
  ${config.dataDescription.valueKey}: ${formatNumber(d[groupOne.dataKey])}
71
73
  </p>`
72
- )
73
- }
74
+ }
74
75
 
75
- const dataTipTwo = (d) => {
76
- return (
77
- `<p>
76
+ const dataTipTwo = d => {
77
+ return `<p>
78
78
  ${config.dataDescription.seriesKey}: ${groupTwo.dataKey}<br/>
79
79
  ${config.xAxis.dataKey}: ${d[config.xAxis.dataKey]}<br/>
80
80
  ${config.dataDescription.valueKey}: ${formatNumber(d[groupTwo.dataKey])}
81
81
  </p>`
82
- )
83
- }
82
+ }
84
83
 
85
- const isLabelBelowBar = config.yAxis.labelPlacement === "Below Bar";
86
- const isLabelOnYAxis = config.yAxis.labelPlacement === "On Date/Category Axis";
87
- const isLabelMissing = !config.yAxis.labelPlacement;
84
+ const isLabelBelowBar = config.yAxis.labelPlacement === 'Below Bar'
85
+ const isLabelOnYAxis = config.yAxis.labelPlacement === 'On Date/Category Axis'
86
+ const isLabelMissing = !config.yAxis.labelPlacement
88
87
 
89
- return (width > 0) && (
90
- <>
91
- <style>
92
- {`
88
+ return (
89
+ width > 0 && (
90
+ <>
91
+ <style>
92
+ {`
93
93
  #cdc-visualization__paired-bar-chart,
94
94
  #cdc-visualization__paired-bar-chart > .visx-group {
95
95
  transform-origin: center
96
96
  }
97
97
  `}
98
- </style>
99
- <svg
100
- id="cdc-visualization__paired-bar-chart"
101
- width={width}
102
- height={height}
103
- viewBox={`0 0 ${width} ${height}`}
104
- role="img"
105
- tabIndex={0}
106
- >
107
- <Group top={0} left={config.xAxis.size} >
108
- {data.filter(item => config.series[0].dataKey === groupOne.dataKey).map( (d,index) => {
109
-
110
- let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(config.series[0].dataKey) === -1;
111
- let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(config.series[0].dataKey) !== -1;
112
- let barWidth = (xScale(d[config.series[0].dataKey]))
113
- let barHeight = Number(config.barHeight) ? Number(config.barHeight) : 25;
114
- let barPadding = barHeight;
115
- config.barHeight = Number(config.barHeight) ? Number(config.barHeight) : 25;
116
- config.barPadding = config.barHeight;
117
-
118
- if (config.orientation=== "horizontal") {
119
-
120
- if(isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
121
- if(barHeight < 40) {
122
- config.barPadding = 40;
123
- } else {
124
- config.barPadding = barPadding;
125
- }
126
- } else {
127
- config.barPadding = barPadding / 2;
128
- }
129
- }
130
-
131
- config.height = (Number(barHeight) ) * data.length + (config.barPadding * data.length);
132
-
133
- let y = yScale([d[config.dataDescription.xKey]]) + config.barHeight/1.5;
134
- y = Number(config.barPadding) > 20 ? y += Number(config.barPadding/3.5) - config.barHeight/2 : y += 0
135
-
136
- return (
137
- <>
138
- <Group key={`group-${groupOne.dataKey}-${d[config.xAxis.dataKey]}`} className='horizontal'>
139
- <Bar
140
- id={`bar-${groupOne.dataKey}-${d[config.dataDescription.xKey]}`}
141
- className='bar group-1'
142
- key={`bar-${groupOne.dataKey}-${d[config.dataDescription.xKey]}`}
143
- x={halfWidth - barWidth}
144
- y={ y }
145
- width={xScale(d[config.series[0].dataKey])}
146
- height={barHeight}
147
- fill={groupOne.color}
148
- data-tip={ dataTipOne(d) }
149
- data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
150
- stroke="#333"
151
- strokeWidth={config.barBorderThickness || 1}
152
- opacity={transparentBar ? 0.5 : 1}
153
- display={displayBar ? 'block' : 'none'}
154
- />
155
- {config.yAxis.displayNumbersOnBar && displayBar &&
156
- <Text
157
- textAnchor={barWidth < 100 ? 'end' : 'start' }
158
- verticalAnchor="middle"
159
- x={halfWidth - (barWidth < 100 ? barWidth + 10 : barWidth - 5)}
160
- y={ y + config.barHeight/2}
161
- fill={barWidth > 100 ? groupOne.labelColor : '#000' }>
162
- {formatNumber(d[groupOne.dataKey])}
163
- </Text>
164
- }
165
- </Group>
166
- </>
167
- )}
168
- )}
169
- {data.filter(item => config.series[1].dataKey === groupTwo.dataKey).map(d => {
170
- let barWidth = (xScale(d[config.series[1].dataKey]))
171
- let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(config.series[1].dataKey) === -1;
172
- let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(config.series[1].dataKey) !== -1;
173
-
174
- let barHeight = config.barHeight ? config.barHeight : 25;
175
- let barPadding = barHeight;
176
- config.barHeight = Number(config.barHeight)
177
-
178
- let y = yScale([d[config.dataDescription.xKey]]) + config.barHeight/1.5;
179
- y = Number(config.barPadding) > 20 ? y += Number(config.barPadding/3.5) - config.barHeight/2 : y += 0
180
-
181
- if (config.orientation=== "horizontal") {
182
-
183
- if(isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
184
- if(barHeight < 40) {
185
- config.barPadding = 40;
186
- } else {
187
- config.barPadding = barPadding;
188
- }
189
- } else {
190
- config.barPadding = barPadding / 2;
191
- }
192
- }
193
-
194
- return(
195
- <>
196
- <style>
197
- {`
98
+ </style>
99
+ <svg id='cdc-visualization__paired-bar-chart' width={width} height={height} viewBox={`0 0 ${width} ${height}`} role='img' tabIndex={0}>
100
+ <Group top={0} left={config.xAxis.size}>
101
+ {data
102
+ .filter(item => config.series[0].dataKey === groupOne.dataKey)
103
+ .map((d, index) => {
104
+ let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(config.series[0].dataKey) === -1
105
+ let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(config.series[0].dataKey) !== -1
106
+ let barWidth = xScale(d[config.series[0].dataKey])
107
+ let barHeight = Number(config.barHeight) ? Number(config.barHeight) : 25
108
+ let barPadding = barHeight
109
+ config.barHeight = Number(config.barHeight) ? Number(config.barHeight) : 25
110
+ config.barPadding = config.barHeight
111
+
112
+ if (config.orientation === 'horizontal') {
113
+ if (isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
114
+ if (barHeight < 40) {
115
+ config.barPadding = 40
116
+ } else {
117
+ config.barPadding = barPadding
118
+ }
119
+ } else {
120
+ config.barPadding = barPadding / 2
121
+ }
122
+ }
123
+
124
+ config.height = Number(barHeight) * data.length + config.barPadding * data.length
125
+
126
+ let y = yScale([d[config.dataDescription.xKey]]) + config.barHeight / 1.5
127
+ y = Number(config.barPadding) > 20 ? (y += Number(config.barPadding / 3.5) - config.barHeight / 2) : (y += 0)
128
+
129
+ return (
130
+ <>
131
+ <Group key={`group-${groupOne.dataKey}-${d[config.xAxis.dataKey]}`} className='horizontal'>
132
+ <Bar
133
+ id={`bar-${groupOne.dataKey}-${d[config.dataDescription.xKey]}`}
134
+ className='bar group-1'
135
+ key={`bar-${groupOne.dataKey}-${d[config.dataDescription.xKey]}`}
136
+ x={halfWidth - barWidth}
137
+ y={y}
138
+ width={xScale(d[config.series[0].dataKey])}
139
+ height={barHeight}
140
+ fill={groupOne.color}
141
+ data-tip={dataTipOne(d)}
142
+ data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
143
+ stroke='#333'
144
+ strokeWidth={config.barBorderThickness || 1}
145
+ opacity={transparentBar ? 0.5 : 1}
146
+ display={displayBar ? 'block' : 'none'}
147
+ />
148
+ {config.yAxis.displayNumbersOnBar && displayBar && (
149
+ <Text textAnchor={barWidth < 100 ? 'end' : 'start'} verticalAnchor='middle' x={halfWidth - (barWidth < 100 ? barWidth + 10 : barWidth - 5)} y={y + config.barHeight / 2} fill={barWidth > 100 ? groupOne.labelColor : '#000'}>
150
+ {formatNumber(d[groupOne.dataKey])}
151
+ </Text>
152
+ )}
153
+ </Group>
154
+ </>
155
+ )
156
+ })}
157
+ {data
158
+ .filter(item => config.series[1].dataKey === groupTwo.dataKey)
159
+ .map(d => {
160
+ let barWidth = xScale(d[config.series[1].dataKey])
161
+ let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(config.series[1].dataKey) === -1
162
+ let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(config.series[1].dataKey) !== -1
163
+
164
+ let barHeight = config.barHeight ? config.barHeight : 25
165
+ let barPadding = barHeight
166
+ config.barHeight = Number(config.barHeight)
167
+
168
+ let y = yScale([d[config.dataDescription.xKey]]) + config.barHeight / 1.5
169
+ y = Number(config.barPadding) > 20 ? (y += Number(config.barPadding / 3.5) - config.barHeight / 2) : (y += 0)
170
+
171
+ if (config.orientation === 'horizontal') {
172
+ if (isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
173
+ if (barHeight < 40) {
174
+ config.barPadding = 40
175
+ } else {
176
+ config.barPadding = barPadding
177
+ }
178
+ } else {
179
+ config.barPadding = barPadding / 2
180
+ }
181
+ }
182
+
183
+ return (
184
+ <>
185
+ <style>
186
+ {`
198
187
  .bar-${groupTwo.dataKey}-${d[config.xAxis.dataKey]} {
199
188
  transform-origin: ${halfWidth}px ${y}px
200
189
  }
201
190
  `}
202
- </style>
203
- <Group key={`group-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`} className='horizontal'>
204
- <Bar
205
- id={`bar-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`}
206
- className="bar group-2"
207
- key={`bar-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`}
208
- x={halfWidth}
209
- y={ y }
210
- width={xScale(d[config.series[1].dataKey])}
211
- height={barHeight}
212
- fill={groupTwo.color}
213
- data-tip={ dataTipTwo(d) }
214
- data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
215
- strokeWidth={config.barBorderThickness || 1}
216
- stroke="#333"
217
- opacity={transparentBar ? 0.5 : 1}
218
- display={displayBar ? 'block' : 'none'}
219
- />
220
- {config.yAxis.displayNumbersOnBar && displayBar &&
221
- <Text
222
- textAnchor={barWidth < 100 ? 'start' : 'end' }
223
- verticalAnchor="middle"
224
- x={halfWidth + (barWidth < 100 ? barWidth + 10 : barWidth - 10 )}
225
- y={ y + config.barHeight/2}
226
- fill={barWidth > 100 ? groupTwo.labelColor : '#000' }>
227
- {formatNumber(d[groupTwo.dataKey])}
228
- </Text>
229
- }
230
- </Group>
231
- </>
232
- )
233
- }
234
- )}
235
- </Group>
236
- </svg>
237
- </>
238
- );
191
+ </style>
192
+ <Group key={`group-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`} className='horizontal'>
193
+ <Bar
194
+ id={`bar-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`}
195
+ className='bar group-2'
196
+ key={`bar-${groupTwo.dataKey}-${d[config.dataDescription.xKey]}`}
197
+ x={halfWidth}
198
+ y={y}
199
+ width={xScale(d[config.series[1].dataKey])}
200
+ height={barHeight}
201
+ fill={groupTwo.color}
202
+ data-tip={dataTipTwo(d)}
203
+ data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
204
+ strokeWidth={config.barBorderThickness || 1}
205
+ stroke='#333'
206
+ opacity={transparentBar ? 0.5 : 1}
207
+ display={displayBar ? 'block' : 'none'}
208
+ />
209
+ {config.yAxis.displayNumbersOnBar && displayBar && (
210
+ <Text textAnchor={barWidth < 100 ? 'start' : 'end'} verticalAnchor='middle' x={halfWidth + (barWidth < 100 ? barWidth + 10 : barWidth - 10)} y={y + config.barHeight / 2} fill={barWidth > 100 ? groupTwo.labelColor : '#000'}>
211
+ {formatNumber(d[groupTwo.dataKey])}
212
+ </Text>
213
+ )}
214
+ </Group>
215
+ </>
216
+ )
217
+ })}
218
+ </Group>
219
+ </svg>
220
+ </>
221
+ )
222
+ )
239
223
  }
240
224
 
241
- export default PairedBarChart;
225
+ export default PairedBarChart