@cdc/chart 4.22.10 → 4.23.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.
Files changed (80) hide show
  1. package/README.md +5 -5
  2. package/dist/495.js +3 -0
  3. package/dist/703.js +1 -0
  4. package/dist/cdcchart.js +723 -6
  5. package/examples/age-adjusted-rates.json +1486 -1218
  6. package/examples/box-plot-data.json +71 -0
  7. package/examples/box-plot.csv +5 -0
  8. package/examples/{private/yaxis-test.json → box-plot.json} +46 -54
  9. package/examples/case-rate-example-config.json +1 -1
  10. package/examples/covid-confidence-example-config.json +33 -33
  11. package/examples/covid-example-config.json +34 -34
  12. package/examples/covid-example-data-confidence.json +30 -30
  13. package/examples/covid-example-data.json +20 -20
  14. package/examples/cutoff-example-config.json +36 -36
  15. package/examples/cutoff-example-data.json +36 -36
  16. package/examples/date-exclusions-config.json +1 -1
  17. package/examples/dynamic-legends.json +124 -124
  18. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +191 -197
  19. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +230 -240
  20. package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +239 -247
  21. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +138 -136
  22. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +79 -79
  23. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +80 -80
  24. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +67 -67
  25. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +179 -110
  26. package/examples/gallery/lollipop/lollipop-style-horizontal.json +215 -219
  27. package/examples/gallery/paired-bar/paired-bar-chart.json +195 -195
  28. package/examples/horizontal-chart.json +35 -35
  29. package/examples/horizontal-stacked-bar-chart.json +34 -34
  30. package/examples/line-chart.json +75 -75
  31. package/examples/new-data.csv +17 -0
  32. package/examples/newdata.json +90 -0
  33. package/examples/paired-bar-data.json +16 -14
  34. package/examples/paired-bar-example.json +48 -48
  35. package/examples/paired-bar-formatted.json +36 -36
  36. package/examples/planet-chart-horizontal-example-config.json +33 -33
  37. package/examples/planet-combo-example-config.json +34 -31
  38. package/examples/planet-example-config.json +35 -33
  39. package/examples/planet-example-data.json +56 -56
  40. package/examples/planet-pie-example-config.json +28 -28
  41. package/examples/stacked-vertical-bar-example.json +1 -1
  42. package/examples/temp-example-config.json +61 -54
  43. package/examples/temp-example-data.json +1 -1
  44. package/package.json +3 -2
  45. package/src/CdcChart.tsx +449 -434
  46. package/src/components/BarChart.tsx +383 -497
  47. package/src/components/BoxPlot.js +92 -0
  48. package/src/components/DataTable.tsx +182 -197
  49. package/src/components/EditorPanel.js +1068 -722
  50. package/src/components/Filters.js +131 -0
  51. package/src/components/Legend.js +286 -329
  52. package/src/components/LineChart.tsx +143 -81
  53. package/src/components/LinearChart.tsx +432 -451
  54. package/src/components/PairedBarChart.tsx +197 -213
  55. package/src/components/PieChart.tsx +105 -151
  56. package/src/components/SparkLine.js +179 -201
  57. package/src/components/useIntersectionObserver.tsx +19 -20
  58. package/src/context.tsx +3 -3
  59. package/src/data/initial-state.js +44 -17
  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 +64 -77
  65. package/src/hooks/useRightAxis.js +25 -0
  66. package/src/hooks/useTopAxis.js +6 -0
  67. package/src/index.html +19 -19
  68. package/src/index.tsx +13 -16
  69. package/src/scss/DataTable.scss +6 -5
  70. package/src/scss/editor-panel.scss +71 -69
  71. package/src/scss/main.scss +188 -114
  72. package/src/scss/variables.scss +1 -1
  73. package/examples/private/line-test-data.json +0 -22
  74. package/examples/private/line-test-two.json +0 -216
  75. package/examples/private/line-test.json +0 -102
  76. package/examples/private/newtest.csv +0 -101
  77. package/examples/private/shawn.json +0 -1296
  78. package/examples/private/test.json +0 -10124
  79. package/examples/private/yaxis-testing.csv +0 -27
  80. package/examples/private/yaxis.json +0 -28
@@ -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={Number(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