@cdc/chart 1.3.4 → 4.22.10

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 (50) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cdcchart.js +6 -6
  3. package/examples/cutoff-example-config.json +2 -0
  4. package/examples/cutoff-example-data.json +1 -1
  5. package/examples/dynamic-legends.json +125 -0
  6. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +198 -0
  7. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +241 -0
  8. package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +248 -0
  9. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +137 -0
  10. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +80 -0
  11. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +81 -0
  12. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +68 -0
  13. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +111 -0
  14. package/examples/gallery/lollipop/lollipop-style-horizontal.json +220 -0
  15. package/examples/gallery/paired-bar/paired-bar-chart.json +196 -0
  16. package/examples/horizontal-chart.json +3 -0
  17. package/examples/paired-bar-data.json +1 -1
  18. package/examples/paired-bar-example.json +2 -0
  19. package/examples/planet-combo-example-config.json +2 -0
  20. package/examples/planet-example-config.json +2 -2
  21. package/examples/planet-example-data.json +1 -1
  22. package/examples/planet-pie-example-config.json +2 -0
  23. package/examples/private/line-test-data.json +22 -0
  24. package/examples/private/line-test-two.json +216 -0
  25. package/examples/private/line-test.json +102 -0
  26. package/examples/private/shawn.json +1296 -0
  27. package/examples/private/yaxis-test.json +132 -0
  28. package/examples/private/yaxis-testing.csv +27 -0
  29. package/examples/private/yaxis.json +28 -0
  30. package/examples/stacked-vertical-bar-example.json +228 -0
  31. package/package.json +2 -2
  32. package/src/CdcChart.tsx +121 -168
  33. package/src/components/BarChart.tsx +92 -40
  34. package/src/components/DataTable.tsx +28 -13
  35. package/src/components/EditorPanel.js +286 -182
  36. package/src/components/Legend.js +334 -0
  37. package/src/components/LineChart.tsx +57 -17
  38. package/src/components/LinearChart.tsx +171 -77
  39. package/src/components/PairedBarChart.tsx +139 -42
  40. package/src/components/PieChart.tsx +33 -6
  41. package/src/components/SparkLine.js +28 -27
  42. package/src/components/useIntersectionObserver.tsx +30 -0
  43. package/src/data/initial-state.js +23 -7
  44. package/src/hooks/useChartClasses.js +35 -0
  45. package/src/hooks/useLegendClasses.js +20 -0
  46. package/src/hooks/useReduceData.ts +72 -24
  47. package/src/index.html +29 -30
  48. package/src/scss/editor-panel.scss +34 -4
  49. package/src/scss/main.scss +201 -5
  50. 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,23 @@ 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>(false);
26
28
 
27
-
29
+ const triggerRef = useRef();
30
+ const dataRef = useIntersectionObserver(triggerRef, {
31
+ freezeOnceVisible: false
32
+ });
33
+
34
+ useEffect( () => {
35
+ if (dataRef?.isIntersecting && config.animate && !animatedPie) {
36
+ setTimeout(() => {
37
+ setAnimatePie(true);
38
+ }, 500);
39
+ }
40
+ }, [dataRef?.isIntersecting, config.animate])
28
41
 
29
42
  type AnimatedPieProps<Datum> = ProvidedProps<Datum> & {
30
43
  animate?: boolean;
@@ -66,7 +79,14 @@ export default function PieChart() {
66
79
 
67
80
  const tooltip = `<div>
68
81
  ${yAxisTooltip}<br />
69
- ${xAxisTooltip}<br />`
82
+ ${xAxisTooltip}<br />
83
+ Percent: ${Math.round(
84
+ (((arc.endAngle - arc.startAngle) * 180) /
85
+ Math.PI /
86
+ 360) *
87
+ 100
88
+ ) + "%"}
89
+ `
70
90
 
71
91
  return (
72
92
  <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 +114,12 @@ export default function PieChart() {
94
114
  props: PieStyles;
95
115
  key: string;
96
116
  }) => {
97
-
117
+
98
118
  const [centroidX, centroidY] = path.centroid(arc);
99
119
  const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.1;
100
120
 
101
121
  let textColor = "#FFF";
102
- if (chroma.contrast(textColor, colorScale(arc.data[config.runtime.xAxis.dataKey])) < 3.5) {
122
+ if (colorScale(arc.data[config.runtime.xAxis.dataKey]) && chroma.contrast(textColor, colorScale(arc.data[config.runtime.xAxis.dataKey])) < 3.5) {
103
123
  textColor = "000";
104
124
  }
105
125
 
@@ -165,7 +185,13 @@ export default function PieChart() {
165
185
 
166
186
  return (
167
187
  <ErrorBoundary component="PieChart">
168
- <svg width={width} height={height}>
188
+ <svg
189
+ width={width}
190
+ height={height}
191
+ className={`group ${animatedPie ? 'animated' : ''}`}
192
+ role="img"
193
+ aria-label={handleChartAriaLabels(config)}
194
+ >
169
195
  <Group top={centerY} left={centerX}>
170
196
  <Pie
171
197
  data={filteredData || data}
@@ -183,6 +209,7 @@ export default function PieChart() {
183
209
  </Pie>
184
210
  </Group>
185
211
  </svg>
212
+ <div ref={triggerRef} />
186
213
  <ReactTooltip id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`} html={true} type="light" arrowColor="rgba(0,0,0,0)" className="tooltip"/>
187
214
  </ErrorBoundary>
188
215
  )
@@ -15,17 +15,14 @@ import ReactTooltip from 'react-tooltip';
15
15
 
16
16
  import useReduceData from '../hooks/useReduceData';
17
17
 
18
-
19
18
  import Context from '../context';
20
19
 
21
20
  export default function SparkLine({width: parentWidth, height: parentHeight}) {
22
21
 
23
- const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale } = useContext(Context);
22
+ const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale, handleChartAriaLabels } = useContext(Context);
24
23
  let width = parentWidth
25
24
  const { minValue, maxValue } = useReduceData(config, data)
26
- // if (config && config.legend && !config.legend.hide && (currentViewport === 'lg' || currentViewport === 'md')) {
27
- // width = width * 0.73;
28
- // }
25
+
29
26
  const margin = ({ top: 5, right: 10, bottom: 10, left: 10 })
30
27
  const height = parentHeight;
31
28
 
@@ -38,16 +35,14 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
38
35
  let xScale;
39
36
  let yScale;
40
37
  let seriesScale;
41
-
38
+ const {max:enteredMaxValue,min:enteredMinValue} = config.runtime.yAxis;
39
+ const isMaxValid = Number(enteredMaxValue) >= Number(maxValue);
40
+ const isMinValid = Number(enteredMinValue) <= Number(minValue);
42
41
 
43
42
  if (data) {
44
- let min = config.runtime.yAxis.min !== undefined ? config.runtime.yAxis.min : minValue
45
- let max = config.runtime.yAxis.max !== undefined ? config.runtime.yAxis.max : Number.MIN_VALUE;
46
-
47
- if ((config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && min > 0) {
48
- min = 0;
49
- }
50
- //If data value max wasn't provided, calculate it
43
+ let min = (enteredMinValue && isMinValid) ? enteredMinValue : minValue;
44
+ let max = (enteredMaxValue && isMaxValid )? enteredMaxValue : Number.MIN_VALUE;
45
+
51
46
  if (max === Number.MIN_VALUE) {
52
47
  max = maxValue
53
48
  }
@@ -107,15 +102,19 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
107
102
  return (
108
103
  <ErrorBoundary component="SparkLine">
109
104
  <svg
105
+ role="img"
106
+ aria-label={handleChartAriaLabels(config)}
110
107
  width={width}
111
108
  height={height}
112
109
  className={'sparkline'}
110
+ tabIndex={0}
113
111
  >
114
112
  {(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => (
115
113
  <>
116
114
  <Group
117
115
  className='sparkline-group'
118
116
  height={parentHeight}
117
+ style={{ height: parentHeight}}
119
118
  top={margin.top}
120
119
  key={`series-${seriesKey}`}
121
120
  opacity={config.legend.behavior === "highlight" && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
@@ -126,13 +125,12 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
126
125
  let xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${d[config.runtime.xAxis.dataKey]}` : d[config.runtime.xAxis.dataKey]
127
126
 
128
127
  const tooltip = `<div>
129
- ${yAxisTooltip}<br />
130
- ${xAxisTooltip}<br />
131
- ${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
132
- </div>`
128
+ ${yAxisTooltip}<br />
129
+ ${xAxisTooltip}<br />
130
+ ${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
131
+ </div>`
133
132
 
134
133
  let circleRadii = 4.5
135
-
136
134
  return (
137
135
  <Group key={`series-${seriesKey}-point-${dataIndex}`}>
138
136
  <Text
@@ -144,7 +142,7 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
144
142
  {formatNumber(d[seriesKey])}
145
143
  </Text>
146
144
 
147
- {dataIndex + 1 !== data.length &&
145
+ { dataIndex + 1 !== data.length && ( (config.lineDatapointStyle === 'always show') || (config.lineDatapointStyle === 'hover') ) &&
148
146
  <circle
149
147
  key={`${seriesKey}-${dataIndex}`}
150
148
  r={circleRadii}
@@ -168,16 +166,19 @@ export default function SparkLine({width: parentWidth, height: parentHeight}) {
168
166
  strokeWidth={2}
169
167
  strokeOpacity={1}
170
168
  shapeRendering="geometricPrecision"
171
- marker-end="url(#arrow)"
169
+ marker-end={`url(#${'arrow'}--${index})`}
172
170
 
173
171
  />
174
- <MarkerArrow
175
- id="arrow"
176
- refX={2}
177
- size={6}
178
- marker-end="url(#arrow)"
179
- fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
180
- />
172
+ <MarkerArrow
173
+ id={`arrow--${index}`}
174
+ refX={2}
175
+ size={6}
176
+ marker-end={`url(#${'arrow'}--${index})`}
177
+ strokeOpacity={1}
178
+ fillOpacity={1}
179
+ // stroke={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
180
+ fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
181
+ />
181
182
 
182
183
  </Group>
183
184
  <AxisBottom
@@ -0,0 +1,30 @@
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
+ if (!hasIOSupport || frozen || !node) return;
20
+
21
+ const observerParams = { threshold, root, rootMargin };
22
+ const observer = new IntersectionObserver(updateEntry, observerParams);
23
+
24
+ observer.observe(node);
25
+
26
+ return () => observer.disconnect();
27
+ }, [elementRef, threshold, root, rootMargin, frozen]);
28
+
29
+ return entry;
30
+ }
@@ -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: undefined,
23
- max:undefined
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,28 @@ export default {
31
37
  hideTicks: false,
32
38
  size: 75,
33
39
  tickRotation: 0,
34
- min: undefined,
35
- max:undefined
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
+ colorCode:'',
55
+ reverseLabelOrder:false,
56
+ description:'',
57
+ dynamicLegend: false,
58
+ dynamicLegendDefaultText: "Show All",
59
+ dynamicLegendItemLimit: 5,
60
+ dynamicLegendItemLimitMessage: 'Dynamic Legend Item Limit Hit.',
61
+ dynamicLegendChartMessage: 'Select Options from the Legend',
46
62
  },
47
63
  exclusions: {
48
64
  active: false,
@@ -51,7 +67,7 @@ export default {
51
67
  palette: 'qualitative-bold',
52
68
  isPaletteReversed: false,
53
69
  labels: false,
54
- dataFormat: {},
70
+ dataFormat: {commas:false,prefix:'',suffix:""},
55
71
  confidenceKeys: {},
56
72
  visual: {
57
73
  border: true,
@@ -0,0 +1,35 @@
1
+ export default function useChartClasses(config) {
2
+ let lineDatapointClass = ''
3
+ let barBorderClass = ''
4
+
5
+ if (config.lineDatapointStyle === "hover") { lineDatapointClass = ' chart-line--hover' }
6
+ if (config.lineDatapointStyle === "always show") { lineDatapointClass = ' chart-line--always' }
7
+ if (config.barHasBorder === "false") { barBorderClass = ' chart-bar--no-border' }
8
+
9
+ let innerContainerClasses = ['cove-component__inner']
10
+ config.title && innerContainerClasses.push('component--has-title')
11
+ config.subtext && innerContainerClasses.push('component--has-subtext')
12
+ config.biteStyle && innerContainerClasses.push(`bite__style--${config.biteStyle}`)
13
+ config.general?.isCompactStyle && innerContainerClasses.push(`component--isCompactStyle`)
14
+
15
+ let contentClasses = ['cove-component__content'];
16
+ config.visualizationType === 'Spark Line' && contentClasses.push('sparkline')
17
+ !config.visual?.border && contentClasses.push('no-borders');
18
+ config.visual?.borderColorTheme && contentClasses.push('component--has-borderColorTheme');
19
+ config.visual?.accent && contentClasses.push('component--has-accent');
20
+ config.visual?.background && contentClasses.push('component--has-background');
21
+ config.visual?.hideBackgroundColor && contentClasses.push('component--hideBackgroundColor');
22
+
23
+ let sparkLineStyles = {
24
+ width: '100%',
25
+ height: '100px',
26
+ }
27
+
28
+ return {
29
+ barBorderClass,
30
+ lineDatapointClass,
31
+ contentClasses,
32
+ innerContainerClasses,
33
+ sparkLineStyles
34
+ };
35
+ }
@@ -0,0 +1,20 @@
1
+ export default function useLegendClasses(config) {
2
+ let containerClasses = ['legend-container']
3
+ let innerClasses = ['legend-container__inner'];
4
+
5
+ // Legend Positioning
6
+ if (config.legend.position === "left") {
7
+ containerClasses.push('left')
8
+ }
9
+
10
+ // Legend > Item Ordering
11
+ if (config.legend.reverseLabelOrder) {
12
+ innerClasses.push('d-flex')
13
+ innerClasses.push('flex-column-reverse')
14
+ }
15
+
16
+ return {
17
+ containerClasses,
18
+ innerClasses
19
+ };
20
+ }
@@ -1,30 +1,64 @@
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
- let max; // will hold max number from data.
6
-
7
- if (config.visualizationType === 'Bar' && config.visualizationSubType === 'stacked') {
8
- const yTotals = data.reduce((allTotals, xValue) => {
9
- const totalYValues = config.runtime.seriesKeys.reduce((yTotal, k) => {
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])))));
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);
17
+
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
+
33
+ }else if(config.visualizationType === "Combo" && config.visualizationSubType === "stacked" && !isBar){
34
+ let total = []
35
+
36
+ if(config.runtime.barSeriesKeys && config.runtime.lineSeriesKeys ){
37
+ // get barSeries max Values added to each other
38
+ data.map(function (d,index) {
39
+ const totalYValues =config.runtime.barSeriesKeys.reduce((yTotal, k) => {
40
+ yTotal += Number(d[k]);
41
+ return yTotal;
42
+ }, 0);
43
+ total.push(totalYValues)
44
+
45
+ });
46
+ // get lineSeries largest values
47
+ const lineMax = Math.max(...data.map((d) =>Math.max(...config.runtime.lineSeriesKeys.map((key) => Number(d[key])))));
26
48
 
27
- return max;
49
+ const barMax = Math.max(...total)
50
+
51
+ max = (Number(barMax) > Number(lineMax)) ? barMax : lineMax;
52
+ }
53
+ }else {
54
+ max = Math.max(
55
+ ...data.map((d) =>
56
+ Math.max(...config.runtime.seriesKeys.map((key) => Number(d[key])))
57
+ )
58
+ );
59
+ }
60
+
61
+ return max;
28
62
  };
29
63
 
30
64
  const getMinValueFromData = ()=> {
@@ -34,10 +68,24 @@ const getMinValueFromData = ()=> {
34
68
 
35
69
  return min;
36
70
  };
71
+
72
+ const findPositiveNum = ():boolean=>{
73
+ // loop throught provided data to find positve number in arr based on series keys.
74
+ let existPositiveValue = false;
75
+ if (config.runtime.seriesKeys) {
76
+ for(let i = 0; i < config.runtime.seriesKeys.length; i++) {
77
+ existPositiveValue = data.some(d => d[config.runtime.seriesKeys[i]] >= 0);
78
+ };
79
+ };
80
+ return existPositiveValue;
81
+ };
82
+
83
+
37
84
 
38
85
  const maxValue = getMaxValueFromData();
39
- const minValue = getMinValueFromData()
40
- return {minValue,maxValue}
86
+ const minValue = getMinValueFromData();
87
+ const existPositiveValue = findPositiveNum();
88
+ return {minValue,maxValue,existPositiveValue};
41
89
  }
42
90
 
43
91
  export default useReduceData
package/src/index.html CHANGED
@@ -1,25 +1,25 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
3
+
4
+ <head>
4
5
  <meta charset="utf-8" />
5
- <meta
6
- name="viewport"
7
- content="width=device-width, initial-scale=1, shrink-to-fit=no"
8
- />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
9
7
  <style>
10
- body {
11
- /* max-width: 1000px; */
12
- margin: 0 auto !important;
13
- display: flex;
14
- flex-direction: column;
15
- justify-content: center;
16
- }
17
- .react-container + .react-container {
18
- margin-top: 3rem;
19
- }
8
+ body {
9
+ /* max-width: 1000px; */
10
+ margin: 0 auto !important;
11
+ display: flex;
12
+ flex-direction: column;
13
+ justify-content: center;
14
+ }
15
+
16
+ .react-container+.react-container {
17
+ margin-top: 3rem;
18
+ }
20
19
  </style>
21
- </head>
22
- <body>
20
+ </head>
21
+
22
+ <body>
23
23
  <!-- <div class="react-container" data-config="/examples/temp-example-config.json"></div> -->
24
24
 
25
25
  <!-- <select id="cove_select">
@@ -28,22 +28,20 @@
28
28
  <option value="Hispanic or Latino">Test 2</option>
29
29
  </select> -->
30
30
 
31
- <!-- <div class="react-container" data-config="/examples/covid-example-config.json"></div> -->
31
+ <!-- <div class="react-container" data-config="/examples/dynamic-legends.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
- <!-- <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> -->
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
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/textelements.json"></div> -->
40
41
  <!-- <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
-
42
+ <!-- <div class="react-container" data-config="/examples/example-sparkline.json"></div> -->
45
43
  <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/bar-chart.html#examples -->
46
-
44
+
47
45
  <!-- HORIZONTAL BAR CHARTS -->
48
46
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
49
47
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
@@ -51,18 +49,19 @@
51
49
 
52
50
 
53
51
  <!-- VERTICAL BAR CHARTS -->
54
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
52
+ <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div>
55
53
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
56
54
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
57
55
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-with-confidence.json"></div> -->
58
56
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
59
-
57
+
60
58
  <!-- LOLLIPOP CHARTS -->
61
59
  <!-- <div class="react-container" data-config="/examples/gallery/lollipop/lollipop-style-horizontal.json"></div> -->
62
-
60
+
63
61
  <!-- PAIRED BAR CHARTS -->
64
62
  <!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
65
63
 
66
64
  <noscript>You need to enable JavaScript to run this app.</noscript>
67
- </body>
65
+ </body>
66
+
68
67
  </html>
@@ -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 li {
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
- li {
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;