@cdc/chart 1.3.4 → 9.22.9
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 +6 -6
- package/examples/cutoff-example-config.json +2 -0
- package/examples/cutoff-example-data.json +1 -1
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +198 -0
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +241 -0
- package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +248 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +137 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +80 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +81 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +68 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +111 -0
- package/examples/gallery/lollipop/lollipop-style-horizontal.json +220 -0
- package/examples/gallery/paired-bar/paired-bar-chart.json +196 -0
- package/examples/horizontal-chart.json +3 -0
- package/examples/paired-bar-data.json +1 -1
- package/examples/paired-bar-example.json +2 -0
- package/examples/planet-combo-example-config.json +2 -0
- package/examples/planet-example-config.json +2 -2
- package/examples/planet-example-data.json +1 -1
- package/examples/planet-pie-example-config.json +2 -0
- package/examples/private/line-test-data.json +22 -0
- package/examples/private/line-test-two.json +216 -0
- package/examples/private/line-test.json +102 -0
- package/examples/stacked-vertical-bar-example.json +228 -0
- package/package.json +3 -3
- package/src/CdcChart.tsx +79 -47
- package/src/components/BarChart.tsx +82 -39
- package/src/components/DataTable.tsx +17 -10
- package/src/components/EditorPanel.js +233 -169
- package/src/components/LineChart.tsx +3 -0
- package/src/components/LinearChart.tsx +171 -77
- package/src/components/PairedBarChart.tsx +139 -42
- package/src/components/PieChart.tsx +31 -6
- package/src/components/SparkLine.js +4 -1
- package/src/components/useIntersectionObserver.tsx +32 -0
- package/src/data/initial-state.js +17 -7
- package/src/hooks/useReduceData.ts +50 -23
- package/src/index.html +5 -9
- package/src/scss/editor-panel.scss +34 -4
- package/src/scss/main.scss +165 -5
- package/src/components/BarStackVertical.js +0 -0
|
@@ -6,6 +6,7 @@ import Pie, { ProvidedProps, PieArcDatum } from '@visx/shape/lib/shapes/Pie';
|
|
|
6
6
|
import chroma from "chroma-js";
|
|
7
7
|
import { Group } from '@visx/group';
|
|
8
8
|
import { Text } from '@visx/text';
|
|
9
|
+
import useIntersectionObserver from "./useIntersectionObserver";
|
|
9
10
|
|
|
10
11
|
import Context from '../context';
|
|
11
12
|
|
|
@@ -20,11 +21,21 @@ const enterUpdateTransition = ({ startAngle, endAngle }: PieArcDatum<any>) => ({
|
|
|
20
21
|
});
|
|
21
22
|
|
|
22
23
|
export default function PieChart() {
|
|
23
|
-
const { transformedData: data, config, dimensions, seriesHighlight, colorScale, formatNumber, currentViewport } = useContext<any>(Context);
|
|
24
|
+
const { transformedData: data, config, dimensions, seriesHighlight, colorScale, formatNumber, currentViewport, handleChartAriaLabels } = useContext<any>(Context);
|
|
24
25
|
|
|
25
26
|
const [filteredData, setFilteredData] = useState<any>(undefined);
|
|
27
|
+
const [animatedPie, setAnimatePie] = useState<boolean>((!config.animate));
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
const triggerRef = useRef();
|
|
30
|
+
const dataRef = useIntersectionObserver(triggerRef, {
|
|
31
|
+
freezeOnceVisible: false
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if( dataRef?.isIntersecting && config.animate && ! animatedPie ) {
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
setAnimatePie(true);
|
|
37
|
+
}, 500);
|
|
38
|
+
}
|
|
28
39
|
|
|
29
40
|
type AnimatedPieProps<Datum> = ProvidedProps<Datum> & {
|
|
30
41
|
animate?: boolean;
|
|
@@ -66,7 +77,14 @@ export default function PieChart() {
|
|
|
66
77
|
|
|
67
78
|
const tooltip = `<div>
|
|
68
79
|
${yAxisTooltip}<br />
|
|
69
|
-
${xAxisTooltip}<br
|
|
80
|
+
${xAxisTooltip}<br />
|
|
81
|
+
Percent: ${Math.round(
|
|
82
|
+
(((arc.endAngle - arc.startAngle) * 180) /
|
|
83
|
+
Math.PI /
|
|
84
|
+
360) *
|
|
85
|
+
100
|
|
86
|
+
) + "%"}
|
|
87
|
+
`
|
|
70
88
|
|
|
71
89
|
return (
|
|
72
90
|
<Group key={key} style={{ opacity: (config.legend.behavior === "highlight" && seriesHighlight.length > 0 && seriesHighlight.indexOf(arc.data[config.runtime.xAxis.dataKey]) === -1) ? 0.5 : 1 }}>
|
|
@@ -94,12 +112,12 @@ export default function PieChart() {
|
|
|
94
112
|
props: PieStyles;
|
|
95
113
|
key: string;
|
|
96
114
|
}) => {
|
|
97
|
-
|
|
115
|
+
|
|
98
116
|
const [centroidX, centroidY] = path.centroid(arc);
|
|
99
117
|
const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.1;
|
|
100
118
|
|
|
101
119
|
let textColor = "#FFF";
|
|
102
|
-
if (chroma.contrast(textColor, colorScale(arc.data[config.runtime.xAxis.dataKey])) < 3.5) {
|
|
120
|
+
if (colorScale(arc.data[config.runtime.xAxis.dataKey]) && chroma.contrast(textColor, colorScale(arc.data[config.runtime.xAxis.dataKey])) < 3.5) {
|
|
103
121
|
textColor = "000";
|
|
104
122
|
}
|
|
105
123
|
|
|
@@ -165,7 +183,13 @@ export default function PieChart() {
|
|
|
165
183
|
|
|
166
184
|
return (
|
|
167
185
|
<ErrorBoundary component="PieChart">
|
|
168
|
-
<svg
|
|
186
|
+
<svg
|
|
187
|
+
width={width}
|
|
188
|
+
height={height}
|
|
189
|
+
className={`animated-pie group ${animatedPie ? 'animated' : ''}`}
|
|
190
|
+
role="img"
|
|
191
|
+
aria-label={handleChartAriaLabels(config)}
|
|
192
|
+
>
|
|
169
193
|
<Group top={centerY} left={centerX}>
|
|
170
194
|
<Pie
|
|
171
195
|
data={filteredData || data}
|
|
@@ -183,6 +207,7 @@ export default function PieChart() {
|
|
|
183
207
|
</Pie>
|
|
184
208
|
</Group>
|
|
185
209
|
</svg>
|
|
210
|
+
<div ref={triggerRef} />
|
|
186
211
|
<ReactTooltip id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`} html={true} type="light" arrowColor="rgba(0,0,0,0)" className="tooltip"/>
|
|
187
212
|
</ErrorBoundary>
|
|
188
213
|
)
|
|
@@ -20,7 +20,7 @@ import Context from '../context';
|
|
|
20
20
|
|
|
21
21
|
export default function SparkLine({width: parentWidth, height: parentHeight}) {
|
|
22
22
|
|
|
23
|
-
const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale } = useContext(Context);
|
|
23
|
+
const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale, handleChartAriaLabels } = useContext(Context);
|
|
24
24
|
let width = parentWidth
|
|
25
25
|
const { minValue, maxValue } = useReduceData(config, data)
|
|
26
26
|
// if (config && config.legend && !config.legend.hide && (currentViewport === 'lg' || currentViewport === 'md')) {
|
|
@@ -107,9 +107,12 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
|
|
|
107
107
|
return (
|
|
108
108
|
<ErrorBoundary component="SparkLine">
|
|
109
109
|
<svg
|
|
110
|
+
role="img"
|
|
111
|
+
aria-label={handleChartAriaLabels(config)}
|
|
110
112
|
width={width}
|
|
111
113
|
height={height}
|
|
112
114
|
className={'sparkline'}
|
|
115
|
+
tabIndex={0}
|
|
113
116
|
>
|
|
114
117
|
{(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => (
|
|
115
118
|
<>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {useEffect, useState} from "react";
|
|
2
|
+
|
|
3
|
+
export default function useIntersectionObserver(
|
|
4
|
+
elementRef,
|
|
5
|
+
{ threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false }
|
|
6
|
+
) {
|
|
7
|
+
const [entry, setEntry] = useState<any>();
|
|
8
|
+
|
|
9
|
+
const frozen = entry?.isIntersecting && freezeOnceVisible;
|
|
10
|
+
|
|
11
|
+
const updateEntry = ([entry]) => {
|
|
12
|
+
setEntry(entry);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const node = elementRef?.current;
|
|
17
|
+
const hasIOSupport = !!window.IntersectionObserver;
|
|
18
|
+
|
|
19
|
+
// console.log('node: ', node)
|
|
20
|
+
|
|
21
|
+
if (!hasIOSupport || frozen || !node) return;
|
|
22
|
+
|
|
23
|
+
const observerParams = { threshold, root, rootMargin };
|
|
24
|
+
const observer = new IntersectionObserver(updateEntry, observerParams);
|
|
25
|
+
|
|
26
|
+
observer.observe(node);
|
|
27
|
+
|
|
28
|
+
return () => observer.disconnect();
|
|
29
|
+
}, [elementRef, threshold, root, rootMargin, frozen]);
|
|
30
|
+
|
|
31
|
+
return entry;
|
|
32
|
+
}
|
|
@@ -2,6 +2,7 @@ export default {
|
|
|
2
2
|
type: 'chart',
|
|
3
3
|
title: '',
|
|
4
4
|
theme: 'theme-blue',
|
|
5
|
+
animate: false,
|
|
5
6
|
fontSize: 'medium',
|
|
6
7
|
lineDatapointStyle: 'hover',
|
|
7
8
|
barHasBorder: 'false',
|
|
@@ -9,20 +10,25 @@ export default {
|
|
|
9
10
|
lollipopShape: 'circle',
|
|
10
11
|
lollipopColorStyle: 'two-tone',
|
|
11
12
|
visualizationSubType: 'regular',
|
|
13
|
+
barStyle:'',
|
|
14
|
+
roundingStyle:'standard',
|
|
15
|
+
tipRounding:'top',
|
|
12
16
|
padding: {
|
|
13
17
|
left: 5,
|
|
14
18
|
right: 5
|
|
15
19
|
},
|
|
16
20
|
yAxis: {
|
|
17
21
|
hideAxis: false,
|
|
22
|
+
displayNumbersOnBar:false,
|
|
18
23
|
hideLabel: false,
|
|
19
24
|
hideTicks: false,
|
|
20
25
|
size: 50,
|
|
21
26
|
gridLines: false,
|
|
22
|
-
min:
|
|
23
|
-
max:
|
|
27
|
+
min:'',
|
|
28
|
+
max:'',
|
|
24
29
|
},
|
|
25
30
|
barThickness: 0.35,
|
|
31
|
+
barHeight: 25,
|
|
26
32
|
height: 300,
|
|
27
33
|
xAxis: {
|
|
28
34
|
type: 'categorical',
|
|
@@ -31,18 +37,22 @@ export default {
|
|
|
31
37
|
hideTicks: false,
|
|
32
38
|
size: 75,
|
|
33
39
|
tickRotation: 0,
|
|
34
|
-
min:
|
|
35
|
-
max:
|
|
40
|
+
min: '',
|
|
41
|
+
max:'',
|
|
36
42
|
},
|
|
37
43
|
table: {
|
|
38
44
|
label: 'Data Table',
|
|
39
|
-
expanded: true
|
|
45
|
+
expanded: true,
|
|
46
|
+
limitHeight:false,
|
|
47
|
+
height:"",
|
|
48
|
+
caption:""
|
|
40
49
|
},
|
|
41
50
|
orientation: 'vertical',
|
|
42
51
|
legend: {
|
|
43
52
|
behavior: 'isolate',
|
|
44
53
|
position: 'right',
|
|
45
|
-
reverseLabelOrder:false
|
|
54
|
+
reverseLabelOrder:false,
|
|
55
|
+
description:''
|
|
46
56
|
},
|
|
47
57
|
exclusions: {
|
|
48
58
|
active: false,
|
|
@@ -51,7 +61,7 @@ export default {
|
|
|
51
61
|
palette: 'qualitative-bold',
|
|
52
62
|
isPaletteReversed: false,
|
|
53
63
|
labels: false,
|
|
54
|
-
dataFormat: {},
|
|
64
|
+
dataFormat: {commas:false,prefix:'',suffix:""},
|
|
55
65
|
confidenceKeys: {},
|
|
56
66
|
visual: {
|
|
57
67
|
border: true,
|
|
@@ -1,30 +1,43 @@
|
|
|
1
1
|
|
|
2
2
|
function useReduceData(config,data) {
|
|
3
|
+
// for combo charts check all Data Series set to Bar;
|
|
4
|
+
const isBar = config?.series?.every(element=>element?.type === 'Bar');
|
|
3
5
|
|
|
4
|
-
const getMaxValueFromData = ()=>{
|
|
5
|
-
|
|
6
|
+
const getMaxValueFromData = () => {
|
|
7
|
+
let max; // will hold max number from data.
|
|
8
|
+
if (
|
|
9
|
+
(config.visualizationType === "Bar" || (config.visualizationType === "Combo" && isBar )) &&
|
|
10
|
+
config.visualizationSubType === "stacked"
|
|
11
|
+
) {
|
|
12
|
+
const yTotals = data.reduce((allTotals, xValue) => {
|
|
13
|
+
const totalYValues = config.runtime.seriesKeys.reduce((yTotal, k) => {
|
|
14
|
+
yTotal += Number(xValue[k]);
|
|
15
|
+
return yTotal;
|
|
16
|
+
}, 0);
|
|
6
17
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
yTotal += Number(xValue[k]);
|
|
11
|
-
return yTotal;
|
|
12
|
-
}, 0);
|
|
13
|
-
allTotals.push(totalYValues);
|
|
14
|
-
if(totalYValues > max){
|
|
15
|
-
max = totalYValues;
|
|
16
|
-
}
|
|
17
|
-
return allTotals;
|
|
18
|
-
}, [] as number[]);
|
|
19
|
-
|
|
20
|
-
max = Math.max(...yTotals);
|
|
21
|
-
} else if(config.visualizationType === 'Bar' && config.confidenceKeys && config.confidenceKeys.upper) {
|
|
22
|
-
max = Math.max(...data.map((d) => Number(d[config.confidenceKeys.upper])));
|
|
23
|
-
} else {
|
|
24
|
-
max = Math.max(...data.map((d) => Math.max(...config.runtime.seriesKeys.map((key) => Number(d[key])))));
|
|
18
|
+
allTotals.push(totalYValues);
|
|
19
|
+
if (totalYValues > max) {
|
|
20
|
+
max = totalYValues;
|
|
25
21
|
}
|
|
22
|
+
return allTotals;
|
|
23
|
+
}, [] as number[]);
|
|
24
|
+
|
|
25
|
+
max = Math.max(...yTotals);
|
|
26
|
+
} else if (
|
|
27
|
+
config.visualizationType === "Bar" &&
|
|
28
|
+
config.series &&
|
|
29
|
+
config.series.dataKey
|
|
30
|
+
) {
|
|
31
|
+
max = Math.max(...data.map((d) => Number(d[config.series.dataKey])));
|
|
32
|
+
} else {
|
|
33
|
+
max = Math.max(
|
|
34
|
+
...data.map((d) =>
|
|
35
|
+
Math.max(...config.runtime.seriesKeys.map((key) => Number(d[key])))
|
|
36
|
+
)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
return max;
|
|
28
41
|
};
|
|
29
42
|
|
|
30
43
|
const getMinValueFromData = ()=> {
|
|
@@ -34,10 +47,24 @@ const getMinValueFromData = ()=> {
|
|
|
34
47
|
|
|
35
48
|
return min;
|
|
36
49
|
};
|
|
50
|
+
|
|
51
|
+
const findPositiveNum = ():boolean=>{
|
|
52
|
+
// loop throught provided data to find positve number in arr based on series keys.
|
|
53
|
+
let existPositiveValue = false;
|
|
54
|
+
if (config.runtime.seriesKeys) {
|
|
55
|
+
for(let i = 0; i < config.runtime.seriesKeys.length; i++) {
|
|
56
|
+
existPositiveValue = data.some(d => d[config.runtime.seriesKeys[i]] >= 0);
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
return existPositiveValue;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
|
|
37
63
|
|
|
38
64
|
const maxValue = getMaxValueFromData();
|
|
39
|
-
const minValue = getMinValueFromData()
|
|
40
|
-
|
|
65
|
+
const minValue = getMinValueFromData();
|
|
66
|
+
const existPositiveValue = findPositiveNum();
|
|
67
|
+
return {minValue,maxValue,existPositiveValue};
|
|
41
68
|
}
|
|
42
69
|
|
|
43
70
|
export default useReduceData
|
package/src/index.html
CHANGED
|
@@ -31,19 +31,15 @@
|
|
|
31
31
|
<!-- <div class="react-container" data-config="/examples/covid-example-config.json"></div> -->
|
|
32
32
|
<!-- <div class="react-container" data-config="/examples/cutoff-example-config.json"></div> -->
|
|
33
33
|
<!-- <div class="react-container" data-config="/examples/covid-confidence-example-config.json"></div> -->
|
|
34
|
-
<div class="react-container" data-config="/examples/planet-example-config.json"></div>
|
|
34
|
+
<!-- <div class="react-container" data-config="/examples/planet-example-config.json"></div> -->
|
|
35
35
|
<!-- <div class="react-container" data-config="/examples/planet-chart-horizontal-example-config.json"></div> -->
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
<!-- <div class="react-container" data-config="/examples/planet-combo-example-config.json"></div>-->
|
|
37
|
+
<!-- <div class="react-container" data-config="/examples/planet-pie-example-config.json"></div>-->
|
|
38
|
+
<div class="react-container" data-config="/examples/date-exclusions-config.json"></div>
|
|
39
39
|
<!--<div class="react-container" data-config="/examples/case-rate-example-config.json"></div>-->
|
|
40
|
-
<!-- <div class="react-container" data-config="/examples/private/example-bar-chart.json"></div> -->
|
|
41
|
-
|
|
42
|
-
<!-- LINE -->
|
|
43
|
-
<!-- <div class="react-container" data-config="/examples/line-chart.json"></div> -->
|
|
44
40
|
|
|
45
41
|
<!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/bar-chart.html#examples -->
|
|
46
|
-
|
|
42
|
+
|
|
47
43
|
<!-- HORIZONTAL BAR CHARTS -->
|
|
48
44
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
|
|
49
45
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
|
|
@@ -265,7 +265,6 @@
|
|
|
265
265
|
display: block;
|
|
266
266
|
text-align: left;
|
|
267
267
|
cursor: pointer;
|
|
268
|
-
color: rgba(0, 0, 0, .5);
|
|
269
268
|
text-decoration: underline;
|
|
270
269
|
|
|
271
270
|
span {
|
|
@@ -310,6 +309,8 @@
|
|
|
310
309
|
z-index: 3;
|
|
311
310
|
}
|
|
312
311
|
|
|
312
|
+
|
|
313
|
+
legend,
|
|
313
314
|
label {
|
|
314
315
|
text-transform: uppercase;
|
|
315
316
|
display: block;
|
|
@@ -341,6 +342,29 @@
|
|
|
341
342
|
}
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
legend {
|
|
346
|
+
font-weight: normal;
|
|
347
|
+
margin-bottom: 0.3em;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
legend + span {
|
|
351
|
+
float: left;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.radio-label {
|
|
355
|
+
font-weight: normal;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.accordion__panel fieldset:not(:first-child) {
|
|
359
|
+
margin-top: 1em;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.accordion__panel fieldset {
|
|
363
|
+
label:not(:first-child) {
|
|
364
|
+
margin-top: 0rem;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
344
368
|
input[type="text"], input[role="combobox"], input[type="number"], textarea {
|
|
345
369
|
min-width: 100%;
|
|
346
370
|
max-width: 100%; // Doing this prevents width of textarea from being changed
|
|
@@ -350,7 +374,7 @@
|
|
|
350
374
|
min-height: 140px;
|
|
351
375
|
}
|
|
352
376
|
|
|
353
|
-
.header .color-palette
|
|
377
|
+
.header .color-palette button {
|
|
354
378
|
width: 21px;
|
|
355
379
|
height: 21px;
|
|
356
380
|
border-radius: 40px;
|
|
@@ -365,7 +389,7 @@
|
|
|
365
389
|
list-style: none;
|
|
366
390
|
flex-wrap: wrap;
|
|
367
391
|
|
|
368
|
-
|
|
392
|
+
button {
|
|
369
393
|
width: 45px;
|
|
370
394
|
height: 23px;
|
|
371
395
|
margin-right: 4px;
|
|
@@ -375,6 +399,7 @@
|
|
|
375
399
|
overflow: hidden;
|
|
376
400
|
cursor: pointer;
|
|
377
401
|
position: relative;
|
|
402
|
+
padding: 0;
|
|
378
403
|
|
|
379
404
|
.click-target {
|
|
380
405
|
position: absolute;
|
|
@@ -390,12 +415,17 @@
|
|
|
390
415
|
|
|
391
416
|
span {
|
|
392
417
|
width: 33.3%;
|
|
418
|
+
height: 100%;
|
|
393
419
|
}
|
|
394
420
|
}
|
|
395
421
|
}
|
|
396
422
|
|
|
397
423
|
fieldset {
|
|
398
424
|
display: block;
|
|
425
|
+
|
|
426
|
+
.float-left {
|
|
427
|
+
float: left;
|
|
428
|
+
}
|
|
399
429
|
}
|
|
400
430
|
|
|
401
431
|
.primary-fieldset {
|
|
@@ -641,7 +671,7 @@
|
|
|
641
671
|
cursor: auto;
|
|
642
672
|
}
|
|
643
673
|
|
|
644
|
-
[type="radio"] {
|
|
674
|
+
input[type="radio"] {
|
|
645
675
|
border: 1px solid #8c8f94;
|
|
646
676
|
border-radius: 50%;
|
|
647
677
|
margin-right: 5px;
|
package/src/scss/main.scss
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
@import '~@cdc/core/styles/v2/themes/color-definitions';
|
|
6
6
|
|
|
7
7
|
.form-container {
|
|
8
|
-
overflow:
|
|
8
|
+
overflow-y: auto;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.d-flex { display: flex; }
|
|
@@ -96,6 +96,10 @@
|
|
|
96
96
|
margin-bottom: 20px;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
.section-subtext {
|
|
100
|
+
padding: 15px;
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
.legend-container {
|
|
100
104
|
background: #fff;
|
|
101
105
|
width: 100%;
|
|
@@ -215,7 +219,10 @@
|
|
|
215
219
|
}
|
|
216
220
|
|
|
217
221
|
.filters-section {
|
|
218
|
-
|
|
222
|
+
@include breakpoint(md) {
|
|
223
|
+
display: flex;
|
|
224
|
+
gap: 30px;
|
|
225
|
+
}
|
|
219
226
|
|
|
220
227
|
label:not(:empty) {
|
|
221
228
|
margin-right: .4em;
|
|
@@ -225,8 +232,8 @@
|
|
|
225
232
|
font-size: 1em;
|
|
226
233
|
}
|
|
227
234
|
|
|
228
|
-
.single-filter
|
|
229
|
-
margin-
|
|
235
|
+
.single-filter {
|
|
236
|
+
margin-bottom: .5em;
|
|
230
237
|
}
|
|
231
238
|
}
|
|
232
239
|
|
|
@@ -331,9 +338,163 @@
|
|
|
331
338
|
}
|
|
332
339
|
}
|
|
333
340
|
}
|
|
341
|
+
|
|
334
342
|
[tabindex]:focus-visible {
|
|
335
343
|
outline: 2px solid rgb(0, 95, 204) !important;
|
|
336
344
|
}
|
|
345
|
+
/*
|
|
346
|
+
// ANIMATIONS
|
|
347
|
+
|
|
348
|
+
// Pie Chart Animations
|
|
349
|
+
.animated-pie {
|
|
350
|
+
transition: all .4s ease-in-out;
|
|
351
|
+
opacity: 0;
|
|
352
|
+
transform-origin: center;
|
|
353
|
+
transform: scale(0, 0);
|
|
354
|
+
|
|
355
|
+
&.animated {
|
|
356
|
+
opacity: 1;
|
|
357
|
+
transform-origin: center;
|
|
358
|
+
transform: scale(1, 1);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
path,
|
|
362
|
+
text {
|
|
363
|
+
border: rgba(0,0,0,.3) 1px solid !important;
|
|
364
|
+
box-shadow: rgba(0,0,0,.1) 3px 3px 7px;
|
|
365
|
+
opacity: 1;
|
|
366
|
+
line-height: 1.4em;
|
|
367
|
+
font-size: 1em;
|
|
368
|
+
border-radius: 4px;
|
|
369
|
+
padding: 8px 12px;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.animated-pie-text {
|
|
373
|
+
opacity: 0;
|
|
374
|
+
transition: opacity .5s ease-in-out;
|
|
375
|
+
transition-delay: .4s;
|
|
376
|
+
|
|
377
|
+
&.animated {
|
|
378
|
+
opacity: 1;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Line/Combo Chart Animations
|
|
384
|
+
.linear,
|
|
385
|
+
.Line,
|
|
386
|
+
.Combo {
|
|
387
|
+
&.animated path {
|
|
388
|
+
opacity: 0;
|
|
389
|
+
}
|
|
390
|
+
&.animate {
|
|
391
|
+
path {
|
|
392
|
+
opacity: 1;
|
|
393
|
+
stroke-dasharray: 2000;
|
|
394
|
+
stroke-dashoffset: 2000;
|
|
395
|
+
animation: dash 2s ease-in-out forwards;
|
|
396
|
+
}
|
|
397
|
+
@keyframes dash {
|
|
398
|
+
to {
|
|
399
|
+
stroke-dashoffset: 0;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Bar/Combo Chart Animations
|
|
406
|
+
.linear,
|
|
407
|
+
.Bar,
|
|
408
|
+
.Combo {
|
|
409
|
+
.visx-group {
|
|
410
|
+
position: relative;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
&.animated {
|
|
414
|
+
.vertical rect ,
|
|
415
|
+
.vertical foreignObject {
|
|
416
|
+
opacity: 0;
|
|
417
|
+
animation: growBar 0.5s linear forwards;
|
|
418
|
+
animation-play-state: paused;
|
|
419
|
+
//transform-origin: bottom;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.horizontal rect,
|
|
423
|
+
.horizontal foreignObject {
|
|
424
|
+
//transform: scale(0, 1);
|
|
425
|
+
//display: none;
|
|
426
|
+
//opacity: 1;
|
|
427
|
+
animation: growBarH 0.5s linear forwards;
|
|
428
|
+
animation-play-state: paused;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
circle {
|
|
432
|
+
opacity: 0;
|
|
433
|
+
animation: revealLolly 0.25s linear forwards;
|
|
434
|
+
animation-delay: 0.5s;
|
|
435
|
+
animation-play-state: paused;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
&.animate {
|
|
439
|
+
rect,
|
|
440
|
+
foreignObject {
|
|
441
|
+
//opacity: 1;
|
|
442
|
+
animation-play-state: running;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
circle {
|
|
446
|
+
animation-play-state: running;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.group-1,
|
|
451
|
+
.group-2 {
|
|
452
|
+
transform-origin: center;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
*/
|
|
459
|
+
@keyframes revealLolly {
|
|
460
|
+
from {
|
|
461
|
+
opacity: 0;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
to {
|
|
465
|
+
opacity: 1;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
@keyframes growBar {
|
|
470
|
+
from {
|
|
471
|
+
opacity: 1;
|
|
472
|
+
transform: scale(1, 0) ;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
to {
|
|
476
|
+
opacity: 1;
|
|
477
|
+
transform: scale(1) ;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
@keyframes growBarH {
|
|
482
|
+
from {
|
|
483
|
+
transform: scale(0, 1) ;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
to {
|
|
487
|
+
transform: scale(1) ;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.cdc-visualization__paired-bar-chart {
|
|
493
|
+
text-align: center;
|
|
494
|
+
transform: scale(1);
|
|
495
|
+
> .visx-group[style] {
|
|
496
|
+
transform: scale(1);
|
|
497
|
+
}
|
|
337
498
|
}
|
|
338
499
|
|
|
339
500
|
#paired-bar-legend {
|
|
@@ -353,7 +514,6 @@
|
|
|
353
514
|
}
|
|
354
515
|
}
|
|
355
516
|
|
|
356
|
-
|
|
357
517
|
.isEditor.type-sparkline .cdc-chart-inner-container {
|
|
358
518
|
margin: 3em auto 0;
|
|
359
519
|
max-width: 60%;
|
|
File without changes
|