@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,19 +1,22 @@
1
- import React, { useContext } from 'react';
1
+ import React, { useContext } from 'react'
2
2
 
3
- import * as allCurves from '@visx/curve';
4
- import { Group } from '@visx/group';
5
- import { LinePath } from '@visx/shape';
6
- import { Text } from '@visx/text';
3
+ import * as allCurves from '@visx/curve'
4
+ import { Group } from '@visx/group'
5
+ import { LinePath } from '@visx/shape'
6
+ import { Text } from '@visx/text'
7
7
 
8
- import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
8
+ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
9
9
 
10
- import Context from '../context';
10
+ import Context from '../context'
11
+
12
+ import useRightAxis from '../hooks/useRightAxis'
11
13
 
12
14
  export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData, xMax, yMax, seriesStyle = 'Line' }) {
13
- const { colorPalettes, transformedData: data, colorScale, seriesHighlight, config, formatNumber,formatDate,parseDate } = useContext<any>(Context);
15
+ const { colorPalettes, transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, updateConfig } = useContext<any>(Context)
16
+ const { yScaleRight } = useRightAxis({ config, yMax, data, updateConfig })
14
17
 
15
- const handleLineType = (lineType) => {
16
- switch(lineType) {
18
+ const handleLineType = lineType => {
19
+ switch (lineType) {
17
20
  case 'dashed-sm':
18
21
  return '5 5'
19
22
  case 'dashed-md':
@@ -21,96 +24,155 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
21
24
  case 'dashed-lg':
22
25
  return '15 5'
23
26
  default:
24
- return 0;
27
+ return 0
25
28
  }
26
29
  }
27
30
 
28
- console.log('seriesStyle', seriesStyle)
31
+ const handleAxisFormating = (axis = 'left', label, value) => {
32
+ axis = String(axis).toLocaleLowerCase()
33
+ if (label) {
34
+ return `${label}: ${formatNumber(value, axis)}`
35
+ }
36
+ return `${formatNumber(value, axis)}`
37
+ }
29
38
 
30
39
  return (
31
- <ErrorBoundary component="LineChart">
40
+ <ErrorBoundary component='LineChart'>
32
41
  <Group left={config.runtime.yAxis.size}>
33
- { (config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => {
42
+ {(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => {
34
43
  let lineType = config.series.filter(item => item.dataKey === seriesKey)[0].type
44
+ const seriesData = config.series.filter(item => item.dataKey === seriesKey)
45
+ const seriesAxis = seriesData[0].axis ? seriesData[0].axis : 'left'
46
+
35
47
  return (
36
- <Group
37
- key={`series-${seriesKey}`}
38
- opacity={config.legend.behavior === "highlight" && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
39
- display={config.legend.behavior === "highlight" || (seriesHighlight.length === 0 && !config.legend.dynamicLegend) || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
40
- >
41
- { data.map((d, dataIndex) => {
42
- const xAxisValue = config.runtime.xAxis.type==='date' ? formatDate(parseDate(d[config.runtime.xAxis.dataKey])) : d[config.runtime.xAxis.dataKey];
43
- let yAxisTooltip = config.runtime.yAxis.label ? `${config.runtime.yAxis.label}: ${formatNumber(getYAxisData(d, seriesKey))}` : formatNumber(getYAxisData(d, seriesKey))
44
- let xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${xAxisValue}` :xAxisValue;
45
-
46
- const tooltip = `<div>
47
- ${yAxisTooltip}<br />
48
- ${xAxisTooltip}<br />
49
- ${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
50
- </div>`
51
-
52
- let circleRadii = 4.5
53
- return (d[seriesKey] !== undefined && d[seriesKey] !== "") && (
54
- <Group key={`series-${seriesKey}-point-${dataIndex}`}>
55
-
56
- <Text
57
- display={config.labels ? 'block' : 'none'}
58
- x={xScale(getXAxisData(d))}
59
- y={yScale(getYAxisData(d, seriesKey))}
60
- fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
61
- textAnchor="middle">
62
- {formatNumber(d[seriesKey])}
63
- </Text>
64
-
65
- <circle
66
- key={`${seriesKey}-${dataIndex}`}
67
- r={circleRadii}
68
- cx={xScale(getXAxisData(d))}
69
- cy={yScale(getYAxisData(d, seriesKey))}
70
- fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
71
- style={{fill: colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}}
72
- data-tip={tooltip}
73
- data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
74
- />
75
- </Group>
76
- )
77
- })}
48
+ <Group
49
+ key={`series-${seriesKey}`}
50
+ opacity={config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
51
+ display={config.legend.behavior === 'highlight' || (seriesHighlight.length === 0 && !config.legend.dynamicLegend) || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
52
+ >
53
+ {data.map((d, dataIndex) => {
54
+ // Find the series object from the config.series array that has a dataKey matching the seriesKey variable.
55
+ const series = config.series.find(({ dataKey }) => dataKey === seriesKey)
56
+ const { axis } = series
57
+
58
+ const xAxisValue = config.runtime.xAxis.type === 'date' ? formatDate(parseDate(d[config.runtime.xAxis.dataKey])) : d[config.runtime.xAxis.dataKey]
59
+ const yAxisValue = getYAxisData(d, seriesKey)
60
+
61
+ const hasMultipleSeries = Object.keys(config.runtime.seriesLabels).length > 1
62
+ const labeltype = axis === 'Right' ? 'rightLabel' : 'label'
63
+ let label = config.runtime.yAxis[labeltype]
64
+ // if has muiltiple series dont show legend value on tooltip
65
+ if (!hasMultipleSeries) label = config.isLegendValue ? config.runtime.seriesLabels[seriesKey] : label
66
+
67
+ let yAxisTooltip = handleAxisFormating(axis, label, yAxisValue)
68
+ let xAxisTooltip = handleAxisFormating(axis, config.runtime.xAxis.label, xAxisValue)
69
+
70
+ const tooltip = `<div>
71
+ ${config.legend.showLegendValuesTooltip && config.runtime.seriesLabels && Object.keys(config.runtime.seriesLabels).length > 1 ? `${config.runtime.seriesLabels[seriesKey] || ''}<br/>` : ''}
72
+ ${yAxisTooltip}<br />
73
+ ${xAxisTooltip}
74
+ </div>`
75
+ let circleRadii = 4.5
76
+ return (
77
+ d[seriesKey] !== undefined &&
78
+ d[seriesKey] !== '' &&
79
+ d[seriesKey] !== null && (
80
+ <Group key={`series-${seriesKey}-point-${dataIndex}`}>
81
+ <Text
82
+ display={config.labels ? 'block' : 'none'}
83
+ x={xScale(getXAxisData(d))}
84
+ y={seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey))}
85
+ fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
86
+ textAnchor='middle'
87
+ >
88
+ {formatNumber(d[seriesKey])}
89
+ </Text>
90
+
91
+ <circle
92
+ key={`${seriesKey}-${dataIndex}`}
93
+ r={circleRadii}
94
+ cx={xScale(getXAxisData(d))}
95
+ cy={seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey))}
96
+ fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
97
+ style={{ fill: colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000' }}
98
+ data-tip={tooltip}
99
+ data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
100
+ />
101
+ </Group>
102
+ )
103
+ )
104
+ })}
105
+
78
106
  <LinePath
79
107
  curve={allCurves.curveLinear}
80
108
  data={data}
81
- x={(d) => xScale(getXAxisData(d))}
82
- y={(d) => yScale(getYAxisData(d, seriesKey))}
83
- stroke={colorScale && !config.legend.dynamicLegend ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) :
84
- // is dynamic legend
85
- config.legend.dynamicLegend ? colorPalettes[config.palette][index] :
86
- // fallback
87
- '#000'
109
+ x={d => xScale(getXAxisData(d))}
110
+ y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey)))}
111
+ stroke={
112
+ colorScale && !config.legend.dynamicLegend
113
+ ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey)
114
+ : // is dynamic legend
115
+ config.legend.dynamicLegend
116
+ ? colorPalettes[config.palette][index]
117
+ : // fallback
118
+ '#000'
88
119
  }
89
120
  strokeWidth={2}
90
121
  strokeOpacity={1}
91
- shapeRendering="geometricPrecision"
122
+ shapeRendering='geometricPrecision'
92
123
  strokeDasharray={lineType ? handleLineType(lineType) : 0}
93
- defined={(item,i) => {
94
- return item[config.runtime.seriesLabels[seriesKey]] !== "";
124
+ defined={(item, i) => {
125
+ return item[config.runtime.seriesLabels[seriesKey]] !== '' && item[config.runtime.seriesLabels[seriesKey]] !== null
95
126
  }}
96
127
  />
97
- </Group>
98
- )})
99
- }
100
-
128
+ {config.animate && (
129
+ <LinePath
130
+ className='animation'
131
+ curve={allCurves.curveLinear}
132
+ data={data}
133
+ x={d => xScale(getXAxisData(d))}
134
+ y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey)))}
135
+ stroke='#fff'
136
+ strokeWidth={3}
137
+ strokeOpacity={1}
138
+ shapeRendering='geometricPrecision'
139
+ strokeDasharray={lineType ? handleLineType(lineType) : 0}
140
+ defined={(item, i) => {
141
+ return item[config.runtime.seriesLabels[seriesKey]] !== '' && item[config.runtime.seriesLabels[seriesKey]] !== null
142
+ }}
143
+ />
144
+ )}
145
+
146
+ {/* Render series labels at end if each line if selected in the editor */}
147
+ {config.showLineSeriesLabels &&
148
+ (config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map(seriesKey => {
149
+ let lastDatum
150
+ for (let i = data.length - 1; i >= 0; i--) {
151
+ if (data[i][seriesKey]) {
152
+ lastDatum = data[i]
153
+ break
154
+ }
155
+ }
156
+ if (!lastDatum) {
157
+ return <></>
158
+ }
159
+ return (
160
+ <text x={xScale(getXAxisData(lastDatum)) + 5} y={yScale(getYAxisData(lastDatum, seriesKey))} alignmentBaseline='middle' fill={config.colorMatchLineSeriesLabels && colorScale ? colorScale(config.runtime.seriesLabels[seriesKey] || seriesKey) : 'black'}>
161
+ {config.runtime.seriesLabels[seriesKey] || seriesKey}
162
+ </text>
163
+ )
164
+ })}
165
+ </Group>
166
+ )
167
+ })}
168
+
101
169
  {/* Message when dynamic legend and nothing has been picked */}
102
- { (config.legend.dynamicLegend && seriesHighlight.length === 0) &&
103
- <Text
104
- x={ xMax / 2 }
105
- y={yMax / 2}
106
- fill="black"
107
- textAnchor="middle"
108
- color='black'
109
- >
110
- {config.legend.dynamicLegendChartMessage}
170
+ {config.legend.dynamicLegend && seriesHighlight.length === 0 && (
171
+ <Text x={xMax / 2} y={yMax / 2} fill='black' textAnchor='middle' color='black'>
172
+ {config.legend.dynamicLegendChartMessage}
111
173
  </Text>
112
- }
174
+ )}
113
175
  </Group>
114
176
  </ErrorBoundary>
115
- );
177
+ )
116
178
  }