@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.
- package/dist/cdcchart.js +52543 -50830
- package/examples/feature/__data__/area-chart.json +56 -0
- package/examples/{planet-example-data.json → feature/__data__/planet-example-data.json} +3 -8
- package/examples/feature/__data__/planet-logaritmic-data.json +56 -0
- package/examples/feature/area/area-chart-category.json +240 -0
- package/examples/{area-chart.json → feature/area/area-chart-date.json} +70 -13
- package/examples/feature/bar/example-bar-chart.json +558 -0
- package/examples/{horizontal-chart-max-increase.json → feature/bar/horizontal-chart-max-increase.json} +10 -4
- package/examples/{horizontal-chart.json → feature/bar/horizontal-chart.json} +10 -4
- package/examples/{horizontal-stacked-bar-chart.json → feature/bar/horizontal-stacked-bar-chart.json} +7 -3
- package/examples/{planet-chart-horizontal-example-config.json → feature/bar/planet-chart-horizontal-example-config.json} +8 -3
- package/examples/feature/bar/planet-chart-logaritmic-config.json +170 -0
- package/examples/{planet-example-config.json → feature/bar/planet-example-config.json} +2 -2
- package/examples/{box-plot.json → feature/boxplot/boxplot.json} +7 -7
- package/examples/feature/boxplot/testing.csv +38 -0
- package/examples/feature/boxplot/valid-boxplot.csv +17 -0
- package/examples/feature/combo/combochart-categories_are_numbers .json +18 -0
- package/examples/{planet-combo-example-config.json → feature/combo/planet-combo-example-config.json} +1 -1
- package/examples/{planet-deviation-config.json → feature/deviation/planet-deviation-config.json} +2 -2
- package/examples/{planet-deviation-data.json → feature/deviation/planet-deviation-data.json} +9 -9
- package/examples/feature/filters/filter-testing.json +212 -0
- package/examples/feature/forecasting/case_date_example.csv +130 -0
- package/examples/feature/forecasting/effective_reproduction.json +202 -0
- package/examples/feature/forecasting/r_data.csv +130 -0
- package/examples/feature/forecasting/random_data.csv +366 -0
- package/examples/feature/line/line-chart.json +124 -0
- package/examples/{paired-bar-example.json → feature/paired-bar/paired-bar-example.json} +10 -4
- package/examples/{planet-pie-example-config.json → feature/pie/planet-pie-example-config.json} +2 -2
- package/examples/{scatterplot.json → feature/scatterplot/scatterplot.json} +1 -1
- package/examples/feature/test-highlight/test-highlight-2.json +789 -0
- package/examples/feature/test-highlight/test-highlight-vertical.json +561 -0
- package/examples/feature/test-highlight/test-highlight.json +100 -0
- package/examples/{case-rate-example-config.json → feature/tests-case-rate/case-rate-example-config.json} +2 -2
- package/examples/{covid-confidence-example-config.json → feature/tests-covid/covid-confidence-example-config.json} +8 -3
- package/examples/{covid-example-config.json → feature/tests-covid/covid-example-config.json} +7 -3
- package/examples/{cutoff-example-config.json → feature/tests-cutoff/cutoff-example-config.json} +7 -3
- package/examples/{date-exclusions-config.json → feature/tests-date-exclusions/date-exclusions-config.json} +2 -2
- package/examples/{example-bar-chart-nonnumeric.json → feature/tests-non-numerics/example-bar-chart-nonnumeric.json} +1 -1
- package/examples/{planet-pie-example-config-nonnumeric.json → feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json} +2 -2
- package/examples/{sparkline-chart-nonnumeric.json → feature/tests-non-numerics/sparkline-chart-nonnumeric.json} +1 -1
- package/examples/{stacked-vertical-bar-example-nonnumerics.json → feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json} +1 -2
- package/examples/gallery/bar-chart-horizontal/horizontal-highlight.json +345 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +145 -7
- package/examples/gallery/paired-bar/paired-bar-chart.json +1 -0
- package/index.html +73 -49
- package/package.json +2 -2
- package/src/CdcChart.jsx +405 -40
- package/src/components/AreaChart.jsx +122 -80
- package/src/components/BarChart.jsx +126 -49
- package/src/components/BoxPlot.jsx +28 -20
- package/src/components/DataTable.jsx +7 -6
- package/src/components/DeviationBar.jsx +34 -34
- package/src/components/EditorPanel.jsx +1332 -352
- package/src/components/Legend.jsx +40 -4
- package/src/components/LineChart.jsx +10 -23
- package/src/components/LinearChart.jsx +133 -286
- package/src/components/PairedBarChart.jsx +6 -6
- package/src/components/PieChart.jsx +2 -4
- package/src/components/SparkLine.jsx +6 -42
- package/src/data/initial-state.js +23 -4
- package/src/hooks/useHighlightedBars.js +154 -0
- package/src/hooks/useMinMax.js +92 -0
- package/src/hooks/useReduceData.js +31 -57
- package/src/hooks/useScales.js +202 -0
- package/src/index.jsx +2 -1
- package/src/scss/editor-panel.scss +15 -0
- package/src/scss/main.scss +8 -6
- package/examples/box-plot.csv +0 -5
- package/examples/dynamic-legends.json +0 -125
- package/examples/example-bar-chart.json +0 -36
- package/examples/line-chart.json +0 -34
- package/examples/temp-example-config.json +0 -64
- package/examples/temp-example-data.json +0 -130
- package/src/components/Filters.jsx +0 -126
- /package/examples/{age-adjusted-rates.json → feature/__data__/age-adjusted-rates.json} +0 -0
- /package/examples/{new-data.csv → feature/__data__/new-data.csv} +0 -0
- /package/examples/{planet-example-data-max-increase.json → feature/__data__/planet-example-data-max-increase.json} +0 -0
- /package/examples/{Barchart_with_negative.json → feature/bar/Barchart_with_negative.json} +0 -0
- /package/examples/{stacked-vertical-bar-example-negative.json → feature/bar/stacked-vertical-bar-example-negative.json} +0 -0
- /package/examples/{stacked-vertical-bar-example.json → feature/bar/stacked-vertical-bar-example.json} +0 -0
- /package/examples/{box-plot-data.json → feature/boxplot/box-plot-data.json} +0 -0
- /package/examples/{newdata.json → feature/boxplot/boxplot-data.json} +0 -0
- /package/examples/{line-chart-max-increase.json → feature/line/line-chart-max-increase.json} +0 -0
- /package/examples/{paired-bar-data.json → feature/paired-bar/paired-bar-data.json} +0 -0
- /package/examples/{paired-bar-formatted.json → feature/paired-bar/paired-bar-formatted.json} +0 -0
- /package/examples/{scatterplot-continuous.csv → feature/scatterplot/scatterplot-continuous.csv} +0 -0
- /package/examples/{example-sparkline.json → feature/sparkline/example-sparkline.json} +0 -0
- /package/examples/{big-small-test-bar.json → feature/tests-big-small/big-small-test-bar.json} +0 -0
- /package/examples/{big-small-test-line.json → feature/tests-big-small/big-small-test-line.json} +0 -0
- /package/examples/{big-small-test-negative.json → feature/tests-big-small/big-small-test-negative.json} +0 -0
- /package/examples/{case-rate-example-data.json → feature/tests-case-rate/case-rate-example-data.json} +0 -0
- /package/examples/{covid-example-data-confidence.json → feature/tests-covid/covid-example-data-confidence.json} +0 -0
- /package/examples/{covid-example-data.json → feature/tests-covid/covid-example-data.json} +0 -0
- /package/examples/{cutoff-example-data.json → feature/tests-cutoff/cutoff-example-data.json} +0 -0
- /package/examples/{date-exclusions-data.json → feature/tests-date-exclusions/date-exclusions-data.json} +0 -0
- /package/examples/{example-combo-bar-nonnumeric.json → feature/tests-non-numerics/example-combo-bar-nonnumeric.json} +0 -0
- /package/examples/{line-chart-nonnumeric.json → feature/tests-non-numerics/line-chart-nonnumeric.json} +0 -0
- /package/examples/{planet-example-data-nonnumeric.json → feature/tests-non-numerics/planet-example-data-nonnumeric.json} +0 -0
|
@@ -7,9 +7,18 @@ import { colorPalettesChart } from '@cdc/core/data/colorPalettes'
|
|
|
7
7
|
|
|
8
8
|
const CoveBoxPlot = ({ xScale, yScale }) => {
|
|
9
9
|
const { config, setConfig } = useContext(ConfigContext)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (config.legend.hide === false) {
|
|
13
|
+
setConfig({
|
|
14
|
+
...config,
|
|
15
|
+
legend: {
|
|
16
|
+
...config.legend,
|
|
17
|
+
hide: true
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
}, []) // eslint-disable-line
|
|
13
22
|
|
|
14
23
|
// tooltips
|
|
15
24
|
const tooltip_id = `cdc-open-viz-tooltip-${config.runtime.uniqueId}`
|
|
@@ -23,17 +32,16 @@ const CoveBoxPlot = ({ xScale, yScale }) => {
|
|
|
23
32
|
`
|
|
24
33
|
}
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}, []) // eslint-disable-line
|
|
35
|
+
// accessors & constants
|
|
36
|
+
const max = d => Number(d.columnMax)
|
|
37
|
+
const min = d => Number(d.columnMin)
|
|
38
|
+
const median = d => Number(d.columnMedian)
|
|
39
|
+
const thirdQuartile = d => Number(d.columnThirdQuartile)
|
|
40
|
+
const firstQuartile = d => Number(d.columnFirstQuartile)
|
|
41
|
+
const fillOpacity = 0.5
|
|
42
|
+
const boxWidth = xScale.bandwidth()
|
|
43
|
+
const constrainedWidth = Math.min(40, boxWidth)
|
|
44
|
+
const color_0 = colorPalettesChart[config?.palette][0] ? colorPalettesChart[config?.palette][0] : '#000'
|
|
37
45
|
|
|
38
46
|
return (
|
|
39
47
|
<ErrorBoundary component='BoxPlot'>
|
|
@@ -50,15 +58,15 @@ const CoveBoxPlot = ({ xScale, yScale }) => {
|
|
|
50
58
|
<BoxPlot
|
|
51
59
|
data-left={xScale(d.columnCategory) + config.yAxis.size + offset / 2 + 0.5}
|
|
52
60
|
key={`box-plot-${i}`}
|
|
53
|
-
min={
|
|
54
|
-
max={
|
|
61
|
+
min={min(d)}
|
|
62
|
+
max={max(d)}
|
|
55
63
|
left={Number(xScale(d.columnCategory)) + Number(config.yAxis.size) + offset / 2 + 0.5}
|
|
56
|
-
firstQuartile={
|
|
57
|
-
thirdQuartile={
|
|
58
|
-
median={
|
|
64
|
+
firstQuartile={firstQuartile(d)}
|
|
65
|
+
thirdQuartile={thirdQuartile(d)}
|
|
66
|
+
median={median(d)}
|
|
59
67
|
boxWidth={constrainedWidth}
|
|
60
68
|
fill={color_0}
|
|
61
|
-
fillOpacity={
|
|
69
|
+
fillOpacity={fillOpacity}
|
|
62
70
|
stroke='black'
|
|
63
71
|
valueScale={yScale}
|
|
64
72
|
outliers={config.boxplot.plotOutlierValues ? d.columnOutliers : []}
|
|
@@ -12,7 +12,7 @@ import ConfigContext from '../ConfigContext'
|
|
|
12
12
|
import CoveMediaControls from '@cdc/core/components/CoveMediaControls'
|
|
13
13
|
|
|
14
14
|
export default function DataTable() {
|
|
15
|
-
const { rawData,
|
|
15
|
+
const { rawData, tableData: data, config, colorScale, parseDate, formatDate, formatNumber: numberFormatter, colorPalettes } = useContext(ConfigContext)
|
|
16
16
|
|
|
17
17
|
const section = config.orientation === 'horizontal' ? 'yAxis' : 'xAxis'
|
|
18
18
|
const [tableExpanded, setTableExpanded] = useState(config.table.expanded)
|
|
@@ -35,7 +35,7 @@ export default function DataTable() {
|
|
|
35
35
|
switch (type) {
|
|
36
36
|
case 'download':
|
|
37
37
|
return (
|
|
38
|
-
<a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`btn btn-download no-border`}>
|
|
38
|
+
<a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`btn btn-download no-border margin-sm`}>
|
|
39
39
|
Download Data (CSV)
|
|
40
40
|
</a>
|
|
41
41
|
)
|
|
@@ -75,7 +75,9 @@ export default function DataTable() {
|
|
|
75
75
|
values: labels.values,
|
|
76
76
|
columnTotal: labels.total,
|
|
77
77
|
columnSd: 'Standard Deviation',
|
|
78
|
-
nonOutlierValues: 'Non Outliers'
|
|
78
|
+
nonOutlierValues: 'Non Outliers',
|
|
79
|
+
columnLowerBounds: labels.lowerBounds,
|
|
80
|
+
columnUpperBounds: labels.upperBounds
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
let resolvedName = columnLookup[props.row.original[0]]
|
|
@@ -232,8 +234,7 @@ export default function DataTable() {
|
|
|
232
234
|
</div>
|
|
233
235
|
<div className='table-container' hidden={!tableExpanded} style={{ maxHeight: config.table.limitHeight && `${config.table.height}px`, overflowY: 'scroll' }}>
|
|
234
236
|
<table className={tableExpanded ? 'data-table' : 'data-table cdcdataviz-sr-only'} {...getTableProps()} aria-rowcount={config?.series?.length ? config?.series?.length : '-1'}>
|
|
235
|
-
<caption className='cdcdataviz-sr-only'>{config.table.caption ? config.table.caption : ''}</caption>
|
|
236
|
-
<caption className='visually-hidden'>{config.table.label}</caption>
|
|
237
|
+
<caption className='cdcdataviz-sr-only visually-hidden'>{config.table.caption ? config.table.caption : config.table.label ? config.table.label : 'Data Table'}</caption>
|
|
237
238
|
<thead>
|
|
238
239
|
{headerGroups.map((headerGroup, index) => (
|
|
239
240
|
<tr {...headerGroup.getHeaderGroupProps()} key={`headerGroups--${index}`}>
|
|
@@ -275,7 +276,7 @@ export default function DataTable() {
|
|
|
275
276
|
})}
|
|
276
277
|
</tbody>
|
|
277
278
|
</table>
|
|
278
|
-
{config.regions && config.regions.length > 0 &&
|
|
279
|
+
{config.regions && config.regions.length > 0 && config.visualizationType !== 'Box Plot' ? (
|
|
279
280
|
<table className='region-table data-table'>
|
|
280
281
|
<caption className='visually-hidden'>Table of the highlighted regions in the visualization</caption>
|
|
281
282
|
<thead>
|
|
@@ -6,38 +6,7 @@ import { Text } from '@visx/text'
|
|
|
6
6
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
7
7
|
import chroma from 'chroma-js'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
function getTextProps(isLollipopChart, textFits, lollipopShapeSize, fill) {
|
|
11
|
-
if (isLollipopChart) {
|
|
12
|
-
return {
|
|
13
|
-
right: {
|
|
14
|
-
textAnchor: 'start',
|
|
15
|
-
dx: lollipopShapeSize + 6,
|
|
16
|
-
fill: '#000000'
|
|
17
|
-
},
|
|
18
|
-
left: {
|
|
19
|
-
textAnchor: 'end',
|
|
20
|
-
dx: -lollipopShapeSize,
|
|
21
|
-
fill: '#000000'
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
} else {
|
|
25
|
-
return {
|
|
26
|
-
right: {
|
|
27
|
-
textAnchor: textFits ? 'end' : 'start',
|
|
28
|
-
dx: textFits ? -6 : 6,
|
|
29
|
-
fill: textFits ? fill : '#000000'
|
|
30
|
-
},
|
|
31
|
-
left: {
|
|
32
|
-
textAnchor: textFits ? 'start' : 'end',
|
|
33
|
-
dx: textFits ? 6 : -6,
|
|
34
|
-
fill: textFits ? fill : '#000000'
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function DeviationBar({ height, xScale }) {
|
|
9
|
+
export default function DeviationBar({ height, xScale }) {
|
|
41
10
|
const { transformedData: data, config, formatNumber, twoColorPalette, getTextWidth, updateConfig, parseDate, formatDate } = useContext(ConfigContext)
|
|
42
11
|
|
|
43
12
|
if (!config || config?.series?.length !== 1 || config.orientation !== 'horizontal') return
|
|
@@ -56,7 +25,7 @@ export function DeviationBar({ height, xScale }) {
|
|
|
56
25
|
const lollipopBarHeight = config.lollipopSize === 'large' ? 7 : config.lollipopSize === 'medium' ? 6 : 5
|
|
57
26
|
const lollipopShapeSize = config.lollipopSize === 'large' ? 14 : config.lollipopSize === 'medium' ? 12 : 10
|
|
58
27
|
|
|
59
|
-
const targetX = Math.max(xScale(0), Math.min(xScale(target), xScale(maxVal
|
|
28
|
+
const targetX = Math.max(xScale(0), Math.min(xScale(target), xScale(maxVal)))
|
|
60
29
|
|
|
61
30
|
const applyRadius = barPosition => {
|
|
62
31
|
if (barPosition === undefined || barPosition === null || barStyle !== 'rounded') return
|
|
@@ -122,7 +91,7 @@ export function DeviationBar({ height, xScale }) {
|
|
|
122
91
|
{data.map((d, index) => {
|
|
123
92
|
const barValue = Number(d[seriesKey])
|
|
124
93
|
const barHeight = config.isLollipopChart ? lollipopBarHeight : Number(config.barHeight)
|
|
125
|
-
const barSpace = Number(config.barSpace)
|
|
94
|
+
const barSpace = Number(config.barSpace)
|
|
126
95
|
const barWidth = Math.abs(xScale(barValue) - targetX)
|
|
127
96
|
const barBaseX = xScale(barValue)
|
|
128
97
|
const barX = barValue > target ? targetX : barBaseX
|
|
@@ -189,3 +158,34 @@ export function DeviationBar({ height, xScale }) {
|
|
|
189
158
|
</ErrorBoundary>
|
|
190
159
|
)
|
|
191
160
|
}
|
|
161
|
+
|
|
162
|
+
// create function to position text based where bar is located left/or right
|
|
163
|
+
function getTextProps(isLollipopChart, textFits, lollipopShapeSize, fill) {
|
|
164
|
+
if (isLollipopChart) {
|
|
165
|
+
return {
|
|
166
|
+
right: {
|
|
167
|
+
textAnchor: 'start',
|
|
168
|
+
dx: lollipopShapeSize + 6,
|
|
169
|
+
fill: '#000000'
|
|
170
|
+
},
|
|
171
|
+
left: {
|
|
172
|
+
textAnchor: 'end',
|
|
173
|
+
dx: -lollipopShapeSize,
|
|
174
|
+
fill: '#000000'
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
return {
|
|
179
|
+
right: {
|
|
180
|
+
textAnchor: textFits ? 'end' : 'start',
|
|
181
|
+
dx: textFits ? -6 : 6,
|
|
182
|
+
fill: textFits ? fill : '#000000'
|
|
183
|
+
},
|
|
184
|
+
left: {
|
|
185
|
+
textAnchor: textFits ? 'start' : 'end',
|
|
186
|
+
dx: textFits ? 6 : -6,
|
|
187
|
+
fill: textFits ? fill : '#000000'
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|