@cdc/chart 4.23.3 → 4.23.5

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 (98) hide show
  1. package/dist/cdcchart.js +52543 -50830
  2. package/examples/feature/__data__/area-chart.json +56 -0
  3. package/examples/{planet-example-data.json → feature/__data__/planet-example-data.json} +3 -8
  4. package/examples/feature/__data__/planet-logaritmic-data.json +56 -0
  5. package/examples/feature/area/area-chart-category.json +240 -0
  6. package/examples/{area-chart.json → feature/area/area-chart-date.json} +70 -13
  7. package/examples/feature/bar/example-bar-chart.json +558 -0
  8. package/examples/{horizontal-chart-max-increase.json → feature/bar/horizontal-chart-max-increase.json} +10 -4
  9. package/examples/{horizontal-chart.json → feature/bar/horizontal-chart.json} +10 -4
  10. package/examples/{horizontal-stacked-bar-chart.json → feature/bar/horizontal-stacked-bar-chart.json} +7 -3
  11. package/examples/{planet-chart-horizontal-example-config.json → feature/bar/planet-chart-horizontal-example-config.json} +8 -3
  12. package/examples/feature/bar/planet-chart-logaritmic-config.json +170 -0
  13. package/examples/{planet-example-config.json → feature/bar/planet-example-config.json} +2 -2
  14. package/examples/{box-plot.json → feature/boxplot/boxplot.json} +7 -7
  15. package/examples/feature/boxplot/testing.csv +38 -0
  16. package/examples/feature/boxplot/valid-boxplot.csv +17 -0
  17. package/examples/feature/combo/combochart-categories_are_numbers .json +18 -0
  18. package/examples/{planet-combo-example-config.json → feature/combo/planet-combo-example-config.json} +1 -1
  19. package/examples/{planet-deviation-config.json → feature/deviation/planet-deviation-config.json} +2 -2
  20. package/examples/{planet-deviation-data.json → feature/deviation/planet-deviation-data.json} +9 -9
  21. package/examples/feature/filters/filter-testing.json +212 -0
  22. package/examples/feature/forecasting/case_date_example.csv +130 -0
  23. package/examples/feature/forecasting/effective_reproduction.json +202 -0
  24. package/examples/feature/forecasting/r_data.csv +130 -0
  25. package/examples/feature/forecasting/random_data.csv +366 -0
  26. package/examples/feature/line/line-chart.json +124 -0
  27. package/examples/{paired-bar-example.json → feature/paired-bar/paired-bar-example.json} +10 -4
  28. package/examples/{planet-pie-example-config.json → feature/pie/planet-pie-example-config.json} +2 -2
  29. package/examples/{scatterplot.json → feature/scatterplot/scatterplot.json} +1 -1
  30. package/examples/feature/test-highlight/test-highlight-2.json +789 -0
  31. package/examples/feature/test-highlight/test-highlight-vertical.json +561 -0
  32. package/examples/feature/test-highlight/test-highlight.json +100 -0
  33. package/examples/{case-rate-example-config.json → feature/tests-case-rate/case-rate-example-config.json} +2 -2
  34. package/examples/{covid-confidence-example-config.json → feature/tests-covid/covid-confidence-example-config.json} +8 -3
  35. package/examples/{covid-example-config.json → feature/tests-covid/covid-example-config.json} +7 -3
  36. package/examples/{cutoff-example-config.json → feature/tests-cutoff/cutoff-example-config.json} +7 -3
  37. package/examples/{date-exclusions-config.json → feature/tests-date-exclusions/date-exclusions-config.json} +2 -2
  38. package/examples/{example-bar-chart-nonnumeric.json → feature/tests-non-numerics/example-bar-chart-nonnumeric.json} +1 -1
  39. package/examples/{planet-pie-example-config-nonnumeric.json → feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json} +2 -2
  40. package/examples/{sparkline-chart-nonnumeric.json → feature/tests-non-numerics/sparkline-chart-nonnumeric.json} +1 -1
  41. package/examples/{stacked-vertical-bar-example-nonnumerics.json → feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json} +1 -2
  42. package/examples/gallery/bar-chart-horizontal/horizontal-highlight.json +345 -0
  43. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +145 -7
  44. package/examples/gallery/paired-bar/paired-bar-chart.json +1 -0
  45. package/index.html +73 -49
  46. package/package.json +2 -2
  47. package/src/CdcChart.jsx +405 -40
  48. package/src/components/AreaChart.jsx +122 -80
  49. package/src/components/BarChart.jsx +126 -49
  50. package/src/components/BoxPlot.jsx +28 -20
  51. package/src/components/DataTable.jsx +7 -6
  52. package/src/components/DeviationBar.jsx +34 -34
  53. package/src/components/EditorPanel.jsx +1332 -352
  54. package/src/components/Legend.jsx +40 -4
  55. package/src/components/LineChart.jsx +10 -23
  56. package/src/components/LinearChart.jsx +133 -286
  57. package/src/components/PairedBarChart.jsx +6 -6
  58. package/src/components/PieChart.jsx +2 -4
  59. package/src/components/SparkLine.jsx +6 -42
  60. package/src/data/initial-state.js +23 -4
  61. package/src/hooks/useHighlightedBars.js +154 -0
  62. package/src/hooks/useMinMax.js +92 -0
  63. package/src/hooks/useReduceData.js +31 -57
  64. package/src/hooks/useScales.js +202 -0
  65. package/src/index.jsx +2 -1
  66. package/src/scss/editor-panel.scss +15 -0
  67. package/src/scss/main.scss +8 -6
  68. package/examples/box-plot.csv +0 -5
  69. package/examples/dynamic-legends.json +0 -125
  70. package/examples/example-bar-chart.json +0 -36
  71. package/examples/line-chart.json +0 -34
  72. package/examples/temp-example-config.json +0 -64
  73. package/examples/temp-example-data.json +0 -130
  74. package/src/components/Filters.jsx +0 -126
  75. /package/examples/{age-adjusted-rates.json → feature/__data__/age-adjusted-rates.json} +0 -0
  76. /package/examples/{new-data.csv → feature/__data__/new-data.csv} +0 -0
  77. /package/examples/{planet-example-data-max-increase.json → feature/__data__/planet-example-data-max-increase.json} +0 -0
  78. /package/examples/{Barchart_with_negative.json → feature/bar/Barchart_with_negative.json} +0 -0
  79. /package/examples/{stacked-vertical-bar-example-negative.json → feature/bar/stacked-vertical-bar-example-negative.json} +0 -0
  80. /package/examples/{stacked-vertical-bar-example.json → feature/bar/stacked-vertical-bar-example.json} +0 -0
  81. /package/examples/{box-plot-data.json → feature/boxplot/box-plot-data.json} +0 -0
  82. /package/examples/{newdata.json → feature/boxplot/boxplot-data.json} +0 -0
  83. /package/examples/{line-chart-max-increase.json → feature/line/line-chart-max-increase.json} +0 -0
  84. /package/examples/{paired-bar-data.json → feature/paired-bar/paired-bar-data.json} +0 -0
  85. /package/examples/{paired-bar-formatted.json → feature/paired-bar/paired-bar-formatted.json} +0 -0
  86. /package/examples/{scatterplot-continuous.csv → feature/scatterplot/scatterplot-continuous.csv} +0 -0
  87. /package/examples/{example-sparkline.json → feature/sparkline/example-sparkline.json} +0 -0
  88. /package/examples/{big-small-test-bar.json → feature/tests-big-small/big-small-test-bar.json} +0 -0
  89. /package/examples/{big-small-test-line.json → feature/tests-big-small/big-small-test-line.json} +0 -0
  90. /package/examples/{big-small-test-negative.json → feature/tests-big-small/big-small-test-negative.json} +0 -0
  91. /package/examples/{case-rate-example-data.json → feature/tests-case-rate/case-rate-example-data.json} +0 -0
  92. /package/examples/{covid-example-data-confidence.json → feature/tests-covid/covid-example-data-confidence.json} +0 -0
  93. /package/examples/{covid-example-data.json → feature/tests-covid/covid-example-data.json} +0 -0
  94. /package/examples/{cutoff-example-data.json → feature/tests-cutoff/cutoff-example-data.json} +0 -0
  95. /package/examples/{date-exclusions-data.json → feature/tests-date-exclusions/date-exclusions-data.json} +0 -0
  96. /package/examples/{example-combo-bar-nonnumeric.json → feature/tests-non-numerics/example-combo-bar-nonnumeric.json} +0 -0
  97. /package/examples/{line-chart-nonnumeric.json → feature/tests-non-numerics/line-chart-nonnumeric.json} +0 -0
  98. /package/examples/{planet-example-data-nonnumeric.json → feature/tests-non-numerics/planet-example-data-nonnumeric.json} +0 -0
@@ -5,9 +5,10 @@ import { LegendOrdinal, LegendItem, LegendLabel } from '@visx/legend'
5
5
  import LegendCircle from '@cdc/core/components/LegendCircle'
6
6
 
7
7
  import useLegendClasses from './../hooks/useLegendClasses'
8
+ import { useHighlightedBars } from '../hooks/useHighlightedBars'
8
9
 
9
10
  const Legend = () => {
10
- const { config, legend, colorScale, seriesHighlight, highlight, twoColorPalette, highlightReset, setSeriesHighlight, dynamicLegendItems, setDynamicLegendItems, transformedData: data, colorPalettes, rawData, setConfig, currentViewport } = useContext(ConfigContext)
11
+ const { config, legend, colorScale, seriesHighlight, highlight, twoColorPalette, tableData, highlightReset, setSeriesHighlight, dynamicLegendItems, setDynamicLegendItems, transformedData: data, colorPalettes, rawData, setConfig, currentViewport } = useContext(ConfigContext)
11
12
 
12
13
  const { innerClasses, containerClasses } = useLegendClasses(config)
13
14
 
@@ -103,14 +104,14 @@ const Legend = () => {
103
104
  if (config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && colorCode && config.series?.length === 1) {
104
105
  let palette = colorPalettes[config.palette]
105
106
 
106
- while (data.length > palette.length) {
107
+ while (tableData.length > palette.length) {
107
108
  palette = palette.concat(palette)
108
109
  }
109
110
  palette = palette.slice(0, data.length)
110
111
  //store uniq values to Set by colorCode
111
112
  const set = new Set()
112
113
 
113
- data.forEach(d => set.add(d[colorCode]))
114
+ tableData.forEach(d => set.add(d[colorCode]))
114
115
 
115
116
  // create labels with uniq values
116
117
  const uniqeLabels = Array.from(set).map((val, i) => {
@@ -128,11 +129,15 @@ const Legend = () => {
128
129
  return defaultLabels
129
130
  }
130
131
 
131
- const isBottomOrSmallViewport = config.legend.position === 'bottom' || currentViewport === 'sm' || currentViewport === 'xs'
132
+ const isBottomOrSmallViewport = config.legend.position === 'bottom' || currentViewport === 'sm' || currentViewport === 'xs' || currentViewport === 'xxs'
132
133
  const isHorizontal = config.orientation === 'horizontal'
133
134
  const marginTop = isBottomOrSmallViewport && isHorizontal ? `${config.runtime.xAxis.size}px` : '0px'
134
135
  const marginBottom = isBottomOrSmallViewport ? '15px' : '0px'
135
136
 
137
+ const { HighLightedBarUtils } = useHighlightedBars(config)
138
+
139
+ let highLightedLegendItems = HighLightedBarUtils.findDuplicates(config.highlightedBarValues)
140
+
136
141
  if (!legend) return null
137
142
 
138
143
  if (!legend.dynamicLegend)
@@ -182,6 +187,37 @@ const Legend = () => {
182
187
  </LegendItem>
183
188
  )
184
189
  })}
190
+
191
+ {highLightedLegendItems.map((bar, i) => {
192
+ // if duplicates only return first item
193
+ let className = 'legend-item'
194
+ let itemName = bar.legendLabel
195
+
196
+ if (!itemName) return
197
+ if (seriesHighlight.length > 0 && false === seriesHighlight.includes(itemName)) {
198
+ className += ' inactive'
199
+ }
200
+ return (
201
+ <LegendItem
202
+ className={className}
203
+ tabIndex={0}
204
+ key={`legend-quantile-${i}`}
205
+ onKeyPress={e => {
206
+ if (e.key === 'Enter') {
207
+ highlight(bar.legendLabel)
208
+ }
209
+ }}
210
+ onClick={() => {
211
+ highlight(bar.legendLabel)
212
+ }}
213
+ >
214
+ <LegendCircle fill='transparent' borderColor={bar.color ? bar.color : `rgba(255, 102, 1)`} />{' '}
215
+ <LegendLabel align='left' margin='0 0 0 4px'>
216
+ {bar.legendLabel ? bar.legendLabel : bar.value}
217
+ </LegendLabel>
218
+ </LegendItem>
219
+ )
220
+ })}
185
221
  {seriesHighlight.length > 0 && (
186
222
  <button className={`legend-reset ${config.theme}`} onClick={labels => highlightReset(labels)} tabIndex={0}>
187
223
  Reset
@@ -6,16 +6,12 @@ import { LinePath } from '@visx/shape'
6
6
  import { Text } from '@visx/text'
7
7
 
8
8
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
9
-
10
9
  import ConfigContext from '../ConfigContext'
11
-
12
10
  import useRightAxis from '../hooks/useRightAxis'
13
11
 
14
12
  export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData, xMax, yMax, seriesStyle = 'Line' }) {
15
- const { colorPalettes, transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, isNumber, cleanData, updateConfig, handleLineType } = useContext(ConfigContext)
16
- // Just do this once up front otherwise we end up
17
- // calling clean several times on same set of data (TT)
18
- const cleanedData = cleanData(data, config.xAxis.dataKey)
13
+ const { colorPalettes, transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, isNumber, updateConfig, handleLineType } = useContext(ConfigContext)
14
+
19
15
  const { yScaleRight } = useRightAxis({ config, yMax, data, updateConfig })
20
16
 
21
17
  const handleAxisFormating = (axis = 'left', label, value) => {
@@ -45,14 +41,13 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
45
41
  opacity={config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
46
42
  display={config.legend.behavior === 'highlight' || (seriesHighlight.length === 0 && !config.legend.dynamicLegend) || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
47
43
  >
48
- {cleanedData.map((d, dataIndex) => {
44
+ {data.map((d, dataIndex) => {
49
45
  // Find the series object from the config.series array that has a dataKey matching the seriesKey variable.
50
46
  const series = config.series.find(({ dataKey }) => dataKey === seriesKey)
51
47
  const { axis } = series
52
48
 
53
49
  const xAxisValue = config.runtime.xAxis.type === 'date' ? formatDate(parseDate(d[config.runtime.xAxis.dataKey])) : d[config.runtime.xAxis.dataKey]
54
50
  const yAxisValue = getYAxisData(d, seriesKey)
55
-
56
51
  const hasMultipleSeries = Object.keys(config.runtime.seriesLabels).length > 1
57
52
  const labeltype = axis === 'Right' ? 'rightLabel' : 'label'
58
53
  let label = config.runtime.yAxis[labeltype]
@@ -72,16 +67,11 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
72
67
  return (
73
68
  d[seriesKey] !== undefined &&
74
69
  d[seriesKey] !== '' &&
75
- d[seriesKey] !== null && (
70
+ d[seriesKey] !== null &&
71
+ isNumber(d[seriesKey]) && (
76
72
  <Group key={`series-${seriesKey}-point-${dataIndex}`}>
77
73
  {/* Render legend */}
78
- <Text
79
- display={config.labels ? 'block' : 'none'}
80
- x={xScale(getXAxisData(d))}
81
- y={seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey))}
82
- fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
83
- textAnchor='middle'
84
- >
74
+ <Text display={config.labels ? 'block' : 'none'} x={xScale(getXAxisData(d))} y={seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey))} fill={'#000'} textAnchor='middle'>
85
75
  {formatNumber(d[seriesKey], 'left')}
86
76
  </Text>
87
77
 
@@ -99,10 +89,9 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
99
89
  )
100
90
  )
101
91
  })}
102
-
103
92
  <LinePath
104
- curve={allCurves.curveLinear}
105
- data={cleanedData}
93
+ curve={allCurves[seriesData[0].lineType]}
94
+ data={data}
106
95
  x={d => xScale(getXAxisData(d))}
107
96
  y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey)))}
108
97
  stroke={
@@ -116,7 +105,6 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
116
105
  }
117
106
  strokeWidth={2}
118
107
  strokeOpacity={1}
119
- shapeRendering='geometricPrecision'
120
108
  strokeDasharray={lineType ? handleLineType(lineType) : 0}
121
109
  defined={(item, i) => {
122
110
  return item[config.runtime.seriesLabels[seriesKey]] !== '' && item[config.runtime.seriesLabels[seriesKey]] !== null && item[config.runtime.seriesLabels[seriesKey]] !== undefined
@@ -125,8 +113,8 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
125
113
  {config.animate && (
126
114
  <LinePath
127
115
  className='animation'
128
- curve={allCurves.curveLinear}
129
- data={cleanedData}
116
+ curve={seriesData.lineType}
117
+ data={data}
130
118
  x={d => xScale(getXAxisData(d))}
131
119
  y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey)))}
132
120
  stroke='#fff'
@@ -139,7 +127,6 @@ export default function LineChart({ xScale, yScale, getXAxisData, getYAxisData,
139
127
  }}
140
128
  />
141
129
  )}
142
-
143
130
  {/* Render series labels at end if each line if selected in the editor */}
144
131
  {config.showLineSeriesLabels &&
145
132
  (config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map(seriesKey => {