@cdc/chart 1.3.2 → 1.3.3

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 (35) hide show
  1. package/dist/cdcchart.js +77 -4
  2. package/examples/age-adjusted-rates.json +1218 -0
  3. package/examples/case-rate-example-config.json +36 -0
  4. package/examples/case-rate-example-data.json +33602 -0
  5. package/examples/date-exclusions-config.json +62 -0
  6. package/examples/date-exclusions-data.json +162 -0
  7. package/examples/horizontal-chart.json +35 -0
  8. package/examples/horizontal-stacked-bar-chart.json +36 -0
  9. package/examples/line-chart.json +76 -0
  10. package/examples/paired-bar-data.json +14 -0
  11. package/examples/paired-bar-example.json +48 -0
  12. package/examples/paired-bar-formatted.json +37 -0
  13. package/examples/planet-chart-horizontal-example-config.json +35 -0
  14. package/examples/planet-example-config.json +1 -0
  15. package/examples/private/newtest.csv +101 -0
  16. package/examples/private/test.json +10124 -0
  17. package/package.json +9 -5
  18. package/src/CdcChart.tsx +417 -149
  19. package/src/components/BarChart.tsx +431 -24
  20. package/src/components/BarStackVertical.js +0 -0
  21. package/src/components/DataTable.tsx +55 -28
  22. package/src/components/EditorPanel.js +914 -260
  23. package/src/components/LineChart.tsx +4 -3
  24. package/src/components/LinearChart.tsx +258 -88
  25. package/src/components/PairedBarChart.tsx +144 -0
  26. package/src/components/PieChart.tsx +30 -16
  27. package/src/components/SparkLine.js +206 -0
  28. package/src/data/initial-state.js +59 -32
  29. package/src/hooks/useActiveElement.js +19 -0
  30. package/src/hooks/useColorPalette.ts +83 -0
  31. package/src/hooks/useReduceData.ts +43 -0
  32. package/src/index.html +49 -13
  33. package/src/index.tsx +6 -2
  34. package/src/scss/editor-panel.scss +12 -4
  35. package/src/scss/main.scss +112 -3
@@ -3,6 +3,7 @@ import { animated, useTransition, interpolate } from 'react-spring';
3
3
  import ReactTooltip from 'react-tooltip';
4
4
 
5
5
  import Pie, { ProvidedProps, PieArcDatum } from '@visx/shape/lib/shapes/Pie';
6
+ import chroma from "chroma-js";
6
7
  import { Group } from '@visx/group';
7
8
  import { Text } from '@visx/text';
8
9
 
@@ -19,16 +20,18 @@ const enterUpdateTransition = ({ startAngle, endAngle }: PieArcDatum<any>) => ({
19
20
  });
20
21
 
21
22
  export default function PieChart() {
22
- const { filteredData:data, config, dimensions, seriesHighlight, colorScale, formatNumber, currentViewport } = useContext<any>(Context);
23
+ const { transformedData: data, config, dimensions, seriesHighlight, colorScale, formatNumber, currentViewport } = useContext<any>(Context);
23
24
 
24
25
  const [filteredData, setFilteredData] = useState<any>(undefined);
25
26
 
27
+
28
+
26
29
  type AnimatedPieProps<Datum> = ProvidedProps<Datum> & {
27
30
  animate?: boolean;
28
31
  getKey: (d: PieArcDatum<Datum>) => string;
29
32
  delay?: number;
30
33
  };
31
-
34
+
32
35
  function AnimatedPie<Datum>({
33
36
  arcs,
34
37
  path,
@@ -45,6 +48,7 @@ export default function PieChart() {
45
48
  leave: enterUpdateTransition,
46
49
  },
47
50
  );
51
+
48
52
  return (
49
53
  <>
50
54
  {transitions.map(
@@ -89,24 +93,34 @@ export default function PieChart() {
89
93
  item: PieArcDatum<Datum>;
90
94
  props: PieStyles;
91
95
  key: string;
92
- }) => {
96
+ }) => {
97
+
93
98
  const [centroidX, centroidY] = path.centroid(arc);
94
99
  const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.1;
95
100
 
101
+ let textColor = "#FFF";
102
+ if (chroma.contrast(textColor, colorScale(arc.data[config.runtime.xAxis.dataKey])) < 3.5) {
103
+ textColor = "000";
104
+ }
105
+
96
106
  return (
97
107
  <animated.g key={key}>
98
108
  {hasSpaceForLabel && (
99
-
100
- <Text
101
- fill="white"
102
- x={centroidX}
103
- y={centroidY}
104
- dy=".33em"
105
- textAnchor="middle"
106
- pointerEvents="none"
107
- >
108
- {Math.round((arc.endAngle - arc.startAngle) * 180 / Math.PI / 360 * 100) + '%'}
109
- </Text>
109
+ <Text
110
+ style={{ fill: textColor }}
111
+ x={centroidX}
112
+ y={centroidY}
113
+ dy=".33em"
114
+ textAnchor="middle"
115
+ pointerEvents="none"
116
+ >
117
+ {Math.round(
118
+ (((arc.endAngle - arc.startAngle) * 180) /
119
+ Math.PI /
120
+ 360) *
121
+ 100
122
+ ) + "%"}
123
+ </Text>
110
124
  )}
111
125
  </animated.g>
112
126
  );
@@ -121,13 +135,13 @@ export default function PieChart() {
121
135
  if(config && config.legend && !config.legend.hide && currentViewport === 'lg') {
122
136
  width = width * 0.73;
123
137
  }
124
-
138
+
125
139
  const height = config.aspectRatio ? (width * config.aspectRatio) : config.height;
126
140
 
127
141
  const radius = Math.min(width, height) / 2;
128
142
  const centerY = height / 2;
129
143
  const centerX = width / 2;
130
- const donutThickness = radius;
144
+ const donutThickness = (config.pieType === "Donut") ? 75 : radius;
131
145
 
132
146
  useEffect(() => {
133
147
  if(seriesHighlight.length > 0 && config.legend.behavior !== "highlight"){
@@ -0,0 +1,206 @@
1
+ import React, { useContext, useEffect } from 'react';
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';
7
+ import { scaleLinear, scalePoint } from '@visx/scale';
8
+ import { AxisBottom } from '@visx/axis';
9
+ import { MarkerArrow } from '@visx/marker';
10
+
11
+
12
+ import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
13
+
14
+ import ReactTooltip from 'react-tooltip';
15
+
16
+ import useReduceData from '../hooks/useReduceData';
17
+
18
+
19
+ import Context from '../context';
20
+
21
+ export default function SparkLine({width: parentWidth, height: parentHeight}) {
22
+
23
+ const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale } = useContext(Context);
24
+ let width = parentWidth
25
+ const { minValue, maxValue } = useReduceData(config, data)
26
+ // if (config && config.legend && !config.legend.hide && (currentViewport === 'lg' || currentViewport === 'md')) {
27
+ // width = width * 0.73;
28
+ // }
29
+ const margin = ({ top: 5, right: 10, bottom: 10, left: 10 })
30
+ const height = parentHeight;
31
+
32
+ const xMax = width - config.runtime.yAxis.size;
33
+ const yMax = height - margin.top - 20;
34
+
35
+ const getXAxisData = (d) => config.runtime.xAxis.type === 'date' ? (parseDate(d[config.runtime.originalXAxis.dataKey])).getTime() : d[config.runtime.originalXAxis.dataKey];
36
+ const getYAxisData = (d, seriesKey) => d[seriesKey];
37
+
38
+ let xScale;
39
+ let yScale;
40
+ let seriesScale;
41
+
42
+
43
+ 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
51
+ if (max === Number.MIN_VALUE) {
52
+ max = maxValue
53
+ }
54
+
55
+ //Adds Y Axis data padding if applicable
56
+ if (config.runtime.yAxis.paddingPercent) {
57
+ let paddingValue = (max - min) * config.runtime.yAxis.paddingPercent;
58
+ min -= paddingValue;
59
+ max += paddingValue;
60
+ }
61
+
62
+ let xAxisDataMapped = data.map(d => getXAxisData(d));
63
+
64
+ if (config.runtime.horizontal) {
65
+ xScale = scaleLinear({
66
+ domain: [min, max],
67
+ range: [0, xMax]
68
+ });
69
+
70
+ yScale = config.runtime.xAxis.type === 'date' ?
71
+ scaleLinear({ domain: [Math.min(...xAxisDataMapped), Math.max(...xAxisDataMapped)] }) :
72
+ scalePoint({ domain: xAxisDataMapped, padding: 0.5 });
73
+
74
+ seriesScale = scalePoint({
75
+ domain: (config.runtime.barSeriesKeys || config.runtime.seriesKeys),
76
+ range: [0, yMax]
77
+ });
78
+
79
+ yScale.rangeRound([0, yMax]);
80
+ } else {
81
+ min = min < 0 ? min * 1.11 : min
82
+
83
+ yScale = scaleLinear({
84
+ domain: [min, max],
85
+ range: [yMax - margin.bottom, margin.top]
86
+ });
87
+
88
+ xScale = scalePoint({
89
+ domain: xAxisDataMapped,
90
+ range: [margin.left, width - margin.right]
91
+ });
92
+
93
+ seriesScale = scalePoint({
94
+ domain: (config.runtime.barSeriesKeys || config.runtime.seriesKeys),
95
+ range: [0, xMax]
96
+ });
97
+ }
98
+
99
+ }
100
+
101
+ const handleSparkLineTicks = [xScale.domain()[0], xScale.domain()[xScale.domain().length - 1]];
102
+
103
+ useEffect(() => {
104
+ ReactTooltip.rebuild();
105
+ });
106
+
107
+ return (
108
+ <ErrorBoundary component="SparkLine">
109
+ <svg
110
+ width={width}
111
+ height={height}
112
+ className={'sparkline'}
113
+ >
114
+ {(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => (
115
+ <>
116
+ <Group
117
+ className='sparkline-group'
118
+ height={parentHeight}
119
+ top={margin.top}
120
+ key={`series-${seriesKey}`}
121
+ opacity={config.legend.behavior === "highlight" && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
122
+ display={config.legend.behavior === "highlight" || seriesHighlight.length === 0 || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
123
+ >
124
+ {data.map((d, dataIndex) => {
125
+ let yAxisTooltip = config.runtime.yAxis.label ? `${config.runtime.yAxis.label}: ${formatNumber(getYAxisData(d, seriesKey))}` : formatNumber(getYAxisData(d, seriesKey))
126
+ let xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${d[config.runtime.xAxis.dataKey]}` : d[config.runtime.xAxis.dataKey]
127
+
128
+ const tooltip = `<div>
129
+ ${yAxisTooltip}<br />
130
+ ${xAxisTooltip}<br />
131
+ ${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
132
+ </div>`
133
+
134
+ let circleRadii = 4.5
135
+
136
+ return (
137
+ <Group key={`series-${seriesKey}-point-${dataIndex}`}>
138
+ <Text
139
+ display={config.labels ? 'block' : 'none'}
140
+ x={xScale(getXAxisData(d))}
141
+ y={yScale(getYAxisData(d, seriesKey))}
142
+ fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
143
+ textAnchor="middle">
144
+ {formatNumber(d[seriesKey])}
145
+ </Text>
146
+
147
+ {dataIndex + 1 !== data.length &&
148
+ <circle
149
+ key={`${seriesKey}-${dataIndex}`}
150
+ r={circleRadii}
151
+ cx={xScale(getXAxisData(d))}
152
+ cy={yScale(getYAxisData(d, seriesKey))}
153
+ fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
154
+ style={{ fill: colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000' }}
155
+ data-tip={tooltip}
156
+ data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
157
+ />
158
+ }
159
+ </Group>
160
+ )
161
+ })}
162
+ <LinePath
163
+ curve={allCurves.curveLinear}
164
+ data={data}
165
+ x={(d) => xScale(getXAxisData(d))}
166
+ y={(d) => yScale(getYAxisData(d, seriesKey))}
167
+ stroke={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
168
+ strokeWidth={2}
169
+ strokeOpacity={1}
170
+ shapeRendering="geometricPrecision"
171
+ marker-end="url(#arrow)"
172
+
173
+ />
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
+ />
181
+
182
+ </Group>
183
+ <AxisBottom
184
+ top={yMax + margin.top}
185
+ hideAxisLine
186
+ hideTicks
187
+ scale={xScale}
188
+ tickValues={ handleSparkLineTicks }
189
+ tickFormat={formatDate}
190
+ stroke={'black'}
191
+ tickStroke={'black'}
192
+ tickLabelProps={() => ({
193
+ fill: 'black',
194
+ fontSize: 11,
195
+ textAnchor: 'middle',
196
+ })}
197
+
198
+ />
199
+ </>
200
+ ))
201
+ }
202
+ </svg>
203
+ </ErrorBoundary>
204
+
205
+ );
206
+ }
@@ -1,34 +1,61 @@
1
1
  export default {
2
- type: 'chart',
3
- title: '',
4
- theme: 'theme-blue',
5
- fontSize: 'medium',
6
- lineDatapointStyle: 'hover',
7
- barHasBorder: 'false',
8
- padding: {
9
- left: 5,
10
- right: 5
11
- },
12
- yAxis: {
13
- size: 50,
14
- gridLines: false
15
- },
16
- barThickness: 0.35,
17
- height: 300,
18
- xAxis: {
19
- size: 75,
20
- tickRotation: 0
21
- },
22
- table: {
23
- label: 'Data Table',
24
- expanded: true
25
- },
26
- legend: {
27
- behavior: "isolate",
28
- position: "right"
29
- },
30
- palette: "qualitative-bold",
31
- labels: false,
32
- dataFormat: {},
33
- confidenceKeys: {}
2
+ type: 'chart',
3
+ title: '',
4
+ theme: 'theme-blue',
5
+ fontSize: 'medium',
6
+ lineDatapointStyle: 'hover',
7
+ barHasBorder: 'false',
8
+ isLollipopChart: false,
9
+ lollipopShape: 'circle',
10
+ lollipopColorStyle: 'two-tone',
11
+ visualizationSubType: 'regular',
12
+ padding: {
13
+ left: 5,
14
+ right: 5
15
+ },
16
+ yAxis: {
17
+ hideAxis: false,
18
+ hideLabel: false,
19
+ hideTicks: false,
20
+ size: 50,
21
+ gridLines: false,
22
+ min: undefined,
23
+ max:undefined
24
+ },
25
+ barThickness: 0.35,
26
+ height: 300,
27
+ xAxis: {
28
+ type: 'categorical',
29
+ hideAxis: false,
30
+ hideLabel: false,
31
+ hideTicks: false,
32
+ size: 75,
33
+ tickRotation: 0,
34
+ min: undefined,
35
+ max:undefined
36
+ },
37
+ table: {
38
+ label: 'Data Table',
39
+ expanded: true
40
+ },
41
+ orientation: 'vertical',
42
+ legend: {
43
+ behavior: 'isolate',
44
+ position: 'right',
45
+ reverseLabelOrder:false
46
+ },
47
+ exclusions: {
48
+ active: false,
49
+ keys: []
50
+ },
51
+ palette: 'qualitative-bold',
52
+ isPaletteReversed: false,
53
+ labels: false,
54
+ dataFormat: {},
55
+ confidenceKeys: {},
56
+ visual: {
57
+ border: true,
58
+ accent: true,
59
+ background: true
60
+ }
34
61
  }
@@ -0,0 +1,19 @@
1
+ import {useState, useEffect} from 'react'
2
+ // Use for accessibility testing
3
+ const useActiveElement = () => {
4
+ const [active, setActive] = useState(document.activeElement);
5
+
6
+ const handleFocusIn = (e) => {
7
+ setActive(document.activeElement);
8
+ }
9
+
10
+ useEffect(() => {
11
+ document.addEventListener('focusin', handleFocusIn)
12
+ return () => {
13
+ document.removeEventListener('focusin', handleFocusIn)
14
+ };
15
+ }, [])
16
+
17
+ return active;
18
+ }
19
+ export default useActiveElement;
@@ -0,0 +1,83 @@
1
+ import { useEffect, useReducer } from 'react';
2
+
3
+ // constants
4
+ const SEQUENTIAL = 'SEQUENTIAL';
5
+ const SEQUENTIAL_REVERSE = 'SEQUENTIAL_REVERSE';
6
+ export const GET_PALETTE = 'GET_PALETTE';
7
+
8
+
9
+ // types & interfaces
10
+ interface State {
11
+ readonly filteredPallets:string[]
12
+ readonly filteredQualitative:string[]
13
+ readonly isPaletteReversed:boolean;
14
+ paletteName:string|undefined
15
+ }
16
+ interface Action<Palettes> {
17
+ type:
18
+ | 'SEQUENTIAL'
19
+ | 'SEQUENTIAL_REVERSE'
20
+ | 'GET_PALETTE'
21
+ payload: Palettes;
22
+ paletteName?:string
23
+ };
24
+
25
+ // create initial state
26
+ const initialState:State = {
27
+ filteredPallets: [],
28
+ isPaletteReversed:false,
29
+ filteredQualitative: [],
30
+ paletteName:undefined
31
+ };
32
+
33
+ function reducer<T> (state:State,action:Action<T>):State{ // <T> refers to generic type
34
+ const palletNamesArr:string[] = Object.keys(action.payload); // action.payload === colorPalettes object
35
+ let paletteName:string ='';
36
+ switch(action.type){
37
+ case GET_PALETTE:
38
+
39
+ return {...state,paletteName:action.paletteName}
40
+ case SEQUENTIAL:
41
+ paletteName = state.paletteName && state.paletteName.endsWith('reverse') ? String(state.paletteName).substring(0,state.paletteName.length-7) :String(state.paletteName)
42
+ const qualitative = palletNamesArr.filter((name:string)=>String(name).startsWith('qualitative') && !String(name).endsWith('reverse'))
43
+ const sequential = palletNamesArr.filter((name:string)=>String(name).startsWith('sequential') && !String(name).endsWith('reverse'))
44
+ return { ...state, filteredPallets: sequential,filteredQualitative:qualitative, paletteName:paletteName,isPaletteReversed:false};
45
+
46
+ case SEQUENTIAL_REVERSE:
47
+ paletteName = palletNamesArr.find((name:string)=> name === String(state.paletteName).concat('reverse') || name === String(state.paletteName).concat('-reverse') )
48
+ const qualitativeReverse:string[] = palletNamesArr.filter((name:string)=>String(name).startsWith('qualitative') && String(name).endsWith('reverse'));
49
+ const sequentialReverse:string[] = palletNamesArr.filter((name:string)=>String(name).startsWith('sequential') && String(name).endsWith('reverse'));
50
+ return { ...state, filteredQualitative:qualitativeReverse, filteredPallets: sequentialReverse ,paletteName:paletteName,isPaletteReversed:true};
51
+ default : return state;
52
+ }
53
+ };
54
+
55
+ interface Keyable {
56
+ palette:string
57
+ isPaletteReversed:boolean
58
+ }
59
+ function init(initialState){
60
+ return initialState
61
+ }
62
+
63
+ export function useColorPalette<T,Y extends Keyable>(colorPalettes:T,configState:Y){
64
+ const [state, dispatch] = useReducer(reducer, initialState,init);
65
+ const {paletteName,isPaletteReversed,filteredPallets,filteredQualitative} = state
66
+
67
+
68
+
69
+
70
+ useEffect(() => {
71
+ dispatch({ type: SEQUENTIAL, payload: colorPalettes });
72
+ }, []);
73
+
74
+
75
+ useEffect(()=>{
76
+ if(configState.isPaletteReversed){
77
+ dispatch({ type: "SEQUENTIAL_REVERSE", payload: colorPalettes });
78
+ return ()=> dispatch({ type: "SEQUENTIAL", payload: colorPalettes });
79
+ }
80
+ },[configState.isPaletteReversed,dispatch,colorPalettes])
81
+
82
+ return {paletteName,isPaletteReversed,filteredPallets,filteredQualitative, dispatch}
83
+ }
@@ -0,0 +1,43 @@
1
+
2
+ function useReduceData(config,data) {
3
+
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])))));
25
+ }
26
+
27
+ return max;
28
+ };
29
+
30
+ const getMinValueFromData = ()=> {
31
+ let min;
32
+ const minNumberFromData = Math.min(...data.map((d) => Math.min(...config.runtime.seriesKeys.map((key) => Number(d[key])))));
33
+ min = String(minNumberFromData)
34
+
35
+ return min;
36
+ };
37
+
38
+ const maxValue = getMaxValueFromData();
39
+ const minValue = getMinValueFromData()
40
+ return {minValue,maxValue}
41
+ }
42
+
43
+ export default useReduceData
package/src/index.html CHANGED
@@ -1,10 +1,10 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta
6
- name="viewport"
7
- content="width=device-width, initial-scale=1, shrink-to-fit=no"
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1, shrink-to-fit=no"
8
8
  />
9
9
  <style>
10
10
  body {
@@ -18,15 +18,51 @@
18
18
  margin-top: 3rem;
19
19
  }
20
20
  </style>
21
- </head>
21
+ </head>
22
22
  <body>
23
23
  <!-- <div class="react-container" data-config="/examples/temp-example-config.json"></div> -->
24
+
25
+ <!-- <select id="cove_select">
26
+ <option value=""">Choose An Option</option>
27
+ <option value="Non-Hispanic White">Non-Hispanic White</option>
28
+ <option value="Hispanic or Latino">Test 2</option>
29
+ </select> -->
30
+
24
31
  <!-- <div class="react-container" data-config="/examples/covid-example-config.json"></div> -->
25
32
  <!-- <div class="react-container" data-config="/examples/cutoff-example-config.json"></div> -->
26
33
  <!-- <div class="react-container" data-config="/examples/covid-confidence-example-config.json"></div> -->
27
- <!-- <div class="react-container" data-config="/examples/planet-example-config.json"></div> -->
28
- <div class="react-container" data-config="/examples/planet-combo-example-config.json"></div>
34
+ <div class="react-container" data-config="/examples/planet-example-config.json"></div>
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> -->
29
37
  <!-- <div class="react-container" data-config="/examples/planet-pie-example-config.json"></div> -->
30
- <noscript>You need to enable JavaScript to run this app.</noscript>
31
- </body>
32
- </html>
38
+ <!-- <div class="react-container" data-config="/examples/date-exclusions-config.json"></div> -->
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
+
45
+ <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/bar-chart.html#examples -->
46
+
47
+ <!-- HORIZONTAL BAR CHARTS -->
48
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
49
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
50
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-stacked.json"></div> -->
51
+
52
+
53
+ <!-- VERTICAL BAR CHARTS -->
54
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
55
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
56
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
57
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-with-confidence.json"></div> -->
58
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
59
+
60
+ <!-- LOLLIPOP CHARTS -->
61
+ <!-- <div class="react-container" data-config="/examples/gallery/lollipop/lollipop-style-horizontal.json"></div> -->
62
+
63
+ <!-- PAIRED BAR CHARTS -->
64
+ <!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
65
+
66
+ <noscript>You need to enable JavaScript to run this app.</noscript>
67
+ </body>
68
+ </html>
package/src/index.tsx CHANGED
@@ -1,7 +1,8 @@
1
+ import { publish, subscribe } from '@cdc/core/helpers/events';
1
2
  import React from 'react';
2
3
  import { render } from 'react-dom';
3
4
 
4
- import CdcChart from './CdcChart.tsx';
5
+ import CdcChart from './CdcChart';
5
6
 
6
7
  const domContainers = document.querySelectorAll('.react-container');
7
8
 
@@ -10,7 +11,10 @@ let isEditor = window.location.href.includes('editor=true');
10
11
  domContainers.forEach((domContainer) => {
11
12
  render(
12
13
  <React.StrictMode>
13
- <CdcChart configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
14
+ <CdcChart
15
+ configUrl={domContainer.attributes['data-config'].value}
16
+ isEditor={isEditor}
17
+ />
14
18
  </React.StrictMode>,
15
19
  domContainer,
16
20
  );