{"version":3,"sources":["components/chartutils.js","components/chart.js","components/timeSeriesChart.js","components/GAMap.js","components/stateInfoBox.js","sections/cases_by_county/GAMapContainer.js","sections/cases_by_county/casesOverTimeContainer.js","sections/cases_by_county/index.js"],"names":["utils","x","digits","Number","isInteger","toFixed","undefined","data","column","reduce","total","num","index","list","map","item","Object","keys","_sort_order","assign","target","TypeError","arguments","length","source","key","prototype","hasOwnProperty","call","sort","item1","item2","i","order","direction","pos1","indexOf","pos2","number","format","mask","isNaN","Math","round","toLocaleString","style","currency","maximumSignificantDigits","replace","measures","sortorder","result","current","rec","forEach","measure","newfirst","checkkeys","push","newcurrent","groupBy","summands","acc","cur","findIndex","d","group","every","summand","obj","names_from","values_from","fixed","groupVars","value","groupVarValues","groupVar","Set","add","var1","var2","newObj","Chart","this","generateChart","chart","destroy","c3","generate","bindto","node","props","config","otherProps","ref","React","PureComponent","this_chart","createRef","String","endsWith","search","this_len","substring","TimeSeriesChart","divref","chartref","state","chartid","random","toString","updateFlag","date_type","datain","datecolumns","date_col","concat","datacolumns_confirmed","datacolumns_prelim","measure_cols","measure_col_labels","inAnyRegion","categories","chartutils","listValues","cat_data","curr_category","measure_col","sorted","select_data","sortIt","dayData","inRegion","regions","region","test_date","start","end","some","transformData","columns","types","ret","columnName","colors","chartdata","prepareData","color","textAlign","tooltip","title","dateparts","toDateString","split","substr","measure_format","ratio","id","calcnumber","calcpercent","calcpercent_decimal","calcpercent_number","calcdollarMillions","calcdollarBillions","calcdollarNoCents","calcdollar","c3_config","assignTypes","size","height","width","axis","type","tick","toLocaleDateString","month","day","fit","culling","max","min","Date","y","padding","bottom","top","ymax","grid","show","lines","date_lines","line","text","label","legend","hide","point","showPoints","r","bar","zoom","enabled","extent","subchart","Box","justifyContent","updateflag","Component","gaJson","require","GAMap","d3Container","useRef","maxHeight","mapHeight","drawMapCallback","useCallback","svg","mapDiv","d3","baseData","georgiaJson","topojson","objects","GA_Counties","showTooltip","xpos","ypos","transition","duration","html","county","countyInfo","selectedData","get","date","dateColumn","str","tooltipDetails","field","content","thresholdField","tooltipLabel","population","tooltipContent","properties","hideTooltip","empty","selectAll","remove","parentElement","getBoundingClientRect","append","attr","thresholdToCeilingRatio","rate","colorScaleCeiling","colorThresholds","Q3","IQR","toPrecision","colorScale","domain","projection","rotate","fitWidth","path","shapeHeight","bounds","fitSize","features","enter","fillValue","on","pageX","pageY","onSelect","barWidth","range","xAxis","tickSize","ticks","tickFormat","legendContainer","select","legendScale","copy","canvas","document","createElement","context","getContext","fillStyle","fillRect","toDataURL","legendTitle","useEffect","updateComponent","func","wait","timeout","args","clearTimeout","setTimeout","apply","debounce","window","addEventListener","removeEventListener","className","StateInfoBox","stateInfo","stateInfoboxContent","useStyles","makeStyles","theme","toggleContainer","textTransform","selectBox","WebkitAppearance","MozAppearance","fmtDate","inDate","GAMapContainer","classes","useState","views","view","setView","subviews","filter","noDisplay","subview","setSubview","parse","dataset","report_date","selectedDate","setSelectedDate","viewMap","Map","category","handleViewChange","newView","mapData","countyField","toUpperCase","totalPopulation","accumulator","set","dataFromSelectedDate","selectedDateCountyDataMap","delete","comparisonDate","sub","comparisonRange","dataFromComparisonDate","comparisonDateCountyDataMap","header","headerValue","denominator","comparison","display","flexDirection","fontWeight","xs","sm","mx","whiteSpace","overflow","ToggleButtonGroup","exclusive","onChange","event","aria-label","ToggleButton","Select","child","MenuItem","Grid","container","my","newSubview","DateFnsUtils","DatePicker","variant","minDate","maxDate","PopoverProps","anchorOrigin","vertical","horizontal","transformOrigin","disableToolbar","CasesOverTimeContainer","dateType","setDateType","dataType","setDataType","epicurve","epicurve_rpt_date","selectCounty","counties","toISOString","slice","last14Region","now","dateCol","chartDataFiltered","perpos","pcrpos","pcrtest","getSubviewOptions","getMeasureColLabels","_dataType","NativeSelect","console","log","getMeasureCols","pattern","getMeasureColors","labels","measureTypes","getMeasureTypes","mapThresholds","GACasesByCounty","countyList","setCountyList","gaData","setGAData","setEpicurve_rpt_date","testing_curve_rpt_date","setTesting_curve_rpt_date","testing_curve_col_date","setTesting_curve_col_date","currdate","useContext","CacheContext","fetch","then","resp","csv","Papa","skipEmptyLines","dynamicTyping","json","cl","county_name","unshift","activeCounty","setActiveCounty","cases_over_time_ref","mediaFlow","lg","marginRight","Typography","Hidden","mdDown","href","rel","scrollTo","offsetTop","days","lgUp","testing_data","testing_data_col","newcounty"],"mappings":"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","file":"static/js/11.246b6c95.chunk.js","sourcesContent":["import 'core-js/stable'\n\nexport default class utils {\n static totValues (data, column) {\n /**\n * @name totValues (function)\n * @property data - data array\n * @property column - column name to be totalled\n * @example totValues(data, 'column1')\n */\n var total = data.reduce((total, num, index) => {\n return total + num[column]\n }, 0)\n return total\n }\n\n static listValues (data, column) {\n /**\n * @name listValues (function)\n * @property data - data array\n * @property column - column name to enumerate values\n * @example totValues(data, 'column1')\n */\n const list = {}\n data.map((item) => {\n list[item[column]] = item[column]\n return null\n })\n return Object.keys(list).map((item) => list[item])\n }\n\n /**\n * @name sortIt (function)\n * @property data - data to be sorted\n * @property sortorder - array of sort keys in order\n * @property sortorder.key - column to be sorted\n * @property sortorder.direction - 'ASC'/ 'DSC'\n * @property sortorder.order - (optional) array of values for custom order\n * @example sortIt(data, [{key: 'column1', direction: 'ASC'},\n * {key: 'column2', direction: 'ASC',\n * order: ['item1','item2','item4','item5']})\n */\n static sortIt (data, _sort_order) {\n if (typeof Object.assign !== 'function') {\n Object.assign = function (target) {\n // 'use strict';\n if (target == null) {\n throw new TypeError('Cannot convert undefined or null to object')\n }\n\n target = Object(target)\n for (var index = 1; index < arguments.length; index++) {\n var source = arguments[index]\n if (source != null) {\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key]\n }\n }\n }\n }\n return target\n }\n }\n var dataIn = Object.assign([], data)\n var sorteddata = dataIn.sort((item1, item2) => {\n for (var i = 0; i < _sort_order.length; i++) {\n if (_sort_order[i].order === undefined) { // No custom order\n if (((item1[_sort_order[i].key] > item2[_sort_order[i].key]) && _sort_order[i].direction === 'ASC') ||\n ((item1[_sort_order[i].key] < item2[_sort_order[i].key]) && _sort_order[i].direction === 'DSC')\n ) {\n return 1\n } else if (((item1[_sort_order[i].key] < item2[_sort_order[i].key]) && _sort_order[i].direction === 'ASC') ||\n ((item1[_sort_order[i].key] > item2[_sort_order[i].key]) && _sort_order[i].direction === 'DSC')\n ) {\n return -1\n }\n } else { // custom order\n var pos1 = _sort_order[i].order.indexOf(item1[_sort_order[i].key])\n var pos2 = _sort_order[i].order.indexOf(item2[_sort_order[i].key])\n if ((pos1 > pos2 && _sort_order[i].direction === 'ASC') ||\n (pos1 < pos2 && _sort_order[i].direction === 'DSC')) {\n return 1\n } else if ((pos1 < pos2 && _sort_order[i].direction === 'ASC') ||\n (pos1 > pos2 && _sort_order[i].direction === 'DSC')) {\n return -1\n }\n }\n }\n return 0\n })\n return sorteddata\n }\n\n static numFormat (number, format, digits, mask) {\n if (isNaN(number)) {\n number = Number(number)\n }\n switch (format) {\n case 'dollar':\n return digits === 0 ? '$' + Math.round(number).toLocaleString()\n : number.toLocaleString('USD', { style: 'currency', currency: 'USD' })\n case 'dollar-nocents':\n if (number > 999999999) {\n return '$ ' + ((number / 1000000000)).toFixed(1) + ' B'\n } else if (number > 999999) {\n return '$ ' + ((number / 1000000)).toFixed(1) + ' M'\n } else {\n return number.toLocaleString('USD', { style: 'currency', currency: 'USD' })\n }\n case 'percent-number':\n // console.log(\"Mask is \", mask, \"Number is \", number)\n if (isNaN(number) || number === null) {\n return 'N/A'\n } else if (mask === undefined) {\n return Number(number).toFixed(digits === undefined ? 1 : digits)\n } else {\n if (mask === 1) {\n return '>95'\n } else if (mask === 2) {\n return '<5'\n } else if (mask === 3) {\n return '<10'\n } else {\n return Number(number).toFixed(digits)\n }\n }\n case 'percent':\n // console.log(\"Mask is \", mask, \"Number is \", number)\n if (mask === undefined) {\n return Number(number).toFixed(digits === undefined ? 1 : digits) + '%'\n } else {\n if (mask === 1) {\n return '>95%'\n } else if (mask === 2) {\n return '<5%'\n } else if (mask === 3) {\n return '<10%'\n } else {\n return Number(number).toFixed(digits) + '%'\n }\n }\n case 'percent-decimal':\n if (mask === undefined) {\n return Number(number * 100).toFixed(digits === undefined ? 1 : digits) + '%'\n } else {\n if (mask === 1) {\n return '>95%'\n } else if (mask === 2) {\n return '<5%'\n } else if (mask === 3) {\n return '<10%'\n } else {\n return Number(number).toFixed(digits) + '%'\n }\n }\n case 'number':\n\n if (isNaN(number) || number === null) {\n return 'N/A'\n } else if (mask === undefined) {\n return digits === undefined || digits < 1 ? Math.round(Number(number)).toLocaleString() : Number(number).toFixed(digits).toLocaleString({ maximumSignificantDigits: digits })\n } else {\n if (mask === 1) {\n return 'N/A'\n } else if (mask === 2) {\n return 'N/A'\n } else if (mask === 3) {\n return '<10'\n } else {\n return Number(number).toFixed(digits)\n }\n }\n default:\n break\n }\n }\n\n calcpercent (x, digits) {\n if (x > 100) {\n return null\n } else {\n if (Number.isInteger(x)) {\n return x.toFixed(digits === undefined ? 0 : digits) + ' %'\n } else if (x === null) { return 'N/A' } else {\n return x.toFixed(digits === undefined ? 2 : digits) + ' %'\n }\n }\n }\n\n static calcpercent_number (x, digits) {\n if (x > 100) { return null } else {\n if (Number.isInteger(x)) { return x.toFixed(digits === undefined ? 0 : digits) } else if (x === null) { return 'N/A' } else { return x.toFixed(digits === undefined ? 2 : digits) }\n }\n }\n\n static calcpercent_decimal (x, digits) {\n if (x > 1) { return null } else {\n // var value = 100*Number(x);\n if (Number.isInteger(x)) {\n // console.log(\"Calcpercent_decimal\",x,\"Formatted\",(x*100).toFixed(digits === undefined ? 0 : digits) + \" %\" );\n return (x * 100).toFixed(0) + ' %'\n } else if (x === null) { return 'N/A' } else {\n // console.log(\"Calcpercent_decimal-2\",x,value,Math.round(value),\"Formatted\",(x*100).toFixed(digits === undefined ? 1 : digits) + \" %\" );\n return (x * 100).toFixed(digits === undefined ? 1 : digits) + ' %'\n }\n }\n }\n\n static calcnumber (x, digits) {\n digits = digits === undefined ? 2 : digits\n if (Number.isInteger(x)) { return x.toLocaleString() } else { return (Number(Math.round(x + 'e' + digits) + 'e-' + digits)).toLocaleString() }\n }\n\n static calcdollar (x, digits) {\n return '$' + Number(x).toFixed(2).replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,')\n }\n\n static calcdollarNoCents (x, digits) {\n if (x > 999999999) {\n return '$ ' + ((x / 1000000000)).toFixed(1) + ' B'\n } else if (x > 999999) {\n return '$ ' + ((x / 1000000)).toFixed(1) + ' M'\n } else {\n return 0 // numFormat(x,\"dollar\",0);\n }\n }\n\n static calcdollarMillions (x, digits) {\n return '$ ' + ((x / 1000000)).toFixed(1) + ' M'\n }\n\n static calcdollarBillions (x, digits) {\n return '$ ' + ((x / 1000000000)).toFixed(1) + ' B'\n }\n\n static sumMeasures (data, keys, measures, sortorder) {\n // data -JSON Array to be summarized\n // key - key for values to summarize\n // amount - value to be used to create subtotals\n // limitentries - Maximum number of entries\n // console.log(\"Data in SumMeasures\", data, keys,measures)\n const result = []\n const checkkeys = (item1, item2, keys) => {\n let result = true\n keys.forEach((key) => { if (item1[key] !== item2[key]) { result = false } })\n // console.log(\"Compare \", result, item1, item2)\n return result\n }\n const newfirst = (item) => {\n const rec = {}\n measures.forEach((measure) => rec[measure] = 0)\n keys.forEach((key) => rec[key] = item[key])\n return rec\n }\n const newcurrent = (item) => {\n const rec = {}\n measures.forEach((measure) => rec[measure] = item[measure])\n keys.forEach((key) => rec[key] = item[key])\n return rec\n }\n let current = newfirst(data[0])\n data.map(function (item, index) {\n if (!checkkeys(item, current, keys)) {\n result.push(current)\n current = newcurrent(item)\n } else {\n for (let i = 0; i < measures.length; i++) {\n current[measures[i]] = current[measures[i]] + data[index][measures[i]]\n }\n }\n return null\n })\n result.push(current)\n // console.log(\"Result\", result)\n return result\n }\n\n /** Sums an array of objects by a grouping variable.\n * Returns an array of objects, one for each level of the grouby variable.\n *@param {array} data\n *@param {string[]} groupBy Variables to group by\n *@param {string[]} summands Variables to sum up\n */\n static sumByGroup (data, groupBy, summands) {\n const ret = data.reduce((acc, cur) => {\n const i = acc.findIndex((d) => {\n return groupBy.map((group) => d[group] === cur[group]).every(item => item === true)\n })\n if (i > -1) {\n for (const summand of summands) {\n acc[i][summand] = acc[i][summand] + cur[summand]\n }\n } else {\n const obj = {}\n for (const group of groupBy) {\n obj[group] = cur[group]\n }\n for (const summand of summands) {\n obj[summand] = cur[summand]\n }\n acc.push(obj)\n }\n return acc\n }, []\n )\n return ret\n }\n\n /** \"Widens\" data, increasing the number of columns and decreasing the number of rows.\n * Returns a (shorter) array of objects, one for each level of the \"fixed\" variable\n * @param {array} data\n * @param {string} names_from which column to get the name of the output columns from\n * @param {string} values_from which column to get the cell values from\n * @param {string} fixed columns that do not get pivotted\n */\n static pivotWider (data, names_from, values_from, fixed) {\n const ret = data.reduce((acc, cur) => {\n const i = acc.findIndex((d) => {\n return (d[fixed] === cur[fixed])\n })\n if (i > -1) {\n acc[i][cur[names_from]] = cur[values_from]\n } else {\n const obj = {}\n obj[fixed] = cur[fixed]\n obj[cur[names_from]] = cur[values_from]\n acc.push(obj)\n }\n return acc\n }, []\n )\n return ret\n }\n\n /** Find missing combinations of groupVars and add in zeroes.\n * Only works for combinations of 2 variables.\n * @param {array} data\n * @param {string[]} groupVars The variables whose combinations we need values for\n * @param {string} value The name of the value column that needs to be filled in\n */\n static fillMissing (data, groupVars, value) {\n // Get all unique values of each groupVar\n const groupVarValues = {}\n for (const groupVar of groupVars) {\n groupVarValues[groupVar] = new Set()\n data.forEach((value) => {\n groupVarValues[groupVar].add(value[groupVar])\n })\n }\n\n // For each combination of groupvars, see if an entry exists in the data\n // If not, add an entry with that combination of groupvars and a value of 0\n for (const var1 of groupVarValues[groupVars[0]]) {\n for (const var2 of groupVarValues[groupVars[1]]) {\n const i = data.findIndex((d) => {\n return (d[groupVars[0]] === var1 && d[groupVars[1]] === var2)\n })\n if (i < 0) {\n const newObj = {}\n newObj[groupVars[0]] = var1\n newObj[groupVars[1]] = var2\n newObj[value] = 0\n data.push(newObj)\n }\n }\n }\n // console.log('fillMissing', data)\n return data\n }\n\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport c3 from 'c3';\n// import * as d3 from 'd3';\nexport default class Chart extends React.PureComponent {\n static propTypes = {\n config: PropTypes.object,\n };\n static this_chart = React.createRef;\n\n componentDidMount() {\n this.generateChart();\n }\n\n componentDidUpdate() {\n this.generateChart();\n }\n\n componentWillUnmount() {\n this.chart = this.chart.destroy();\n }\n\n\n generateChart() {\n this.chart = c3.generate({\n bindto: this.node,\n ...this.props.config,\n }); \n \n // let columns = this.props.config.data.columns.map((column) => column[0]);\n // let colors = this.props.config.color.pattern;\n // columns.splice(0,1) \n // let thischart = this.chart\n // console.log(\"Generate chart\", this.props,columns, this.chart) \n // d3.select(this.node).insert('div', '.chart').attr('class', 'legend').selectAll('span')\n // .data(columns) \n // .enter().append('span')\n // .attr('data-id', function (id) { return id; })\n // .html(function (id) { return id; })\n // .each(function (id,idx) {\n // d3.select(this).style('background-color', colors[idx]);\n // })\n // .on('mouseover', function (id) {\n // thischart.focus(id);\n // })\n // .on('mouseout', function (id) {\n // thischart.revert();\n // })\n // .on('click', function (id) {\n // thischart.toggle(id);\n // });\n }\n\n render() {\n // return <div ref={node => (this.node = node)} {...otherProps} />;\n const { config, ...otherProps } = this.props;\n return <div ref={node => (this.node = node)} {...otherProps} />;\n }\n}","import React from \"react\";\n// import ReactDOM from \"react-dom\";\n// import * as d3 from 'd3';\nimport Chart from \"./chart.js\";\n\n// import { makeStyles } from '@material-ui/core/styles';\nimport \"c3/c3.css\";\nimport \"../css/c3.css\";\nimport chartutils from \"./chartutils.js\";\nimport { Box } from \"@material-ui/core\";\n\nif (!String.prototype.endsWith) {\n // eslint-disable-next-line\n String.prototype.endsWith = function (search, this_len) {\n if (this_len === undefined || this_len > this.length) {\n this_len = this.length;\n }\n return this.substring(this_len - search.length, this_len) === search;\n };\n}\nexport default class TimeSeriesChart extends React.Component {\n // classes = useStyles();\n constructor(props) {\n super(props);\n\n this.divref = React.createRef();\n this.chartref = React.createRef();\n this.state = {\n chartid: \"c3_chart\" + Math.random().toString,\n updateFlag: true,\n date_type: \"onset\",\n };\n }\n\n transformData(datain) {\n const datecolumns = [this.props.date_col].concat(\n datain.map((data) => data[this.props.date_col])\n );\n let datacolumns_confirmed = [];\n let datacolumns_prelim = [];\n if (this.props.measure_cols !== undefined) {\n datacolumns_confirmed = this.props.measure_cols.map((measure, index) => {\n const measure_col_label =\n this.props.measure_col_labels === undefined\n ? measure\n : this.props.measure_col_labels[index];\n return [measure_col_label].concat(\n datain.map((data) => {\n return data.inAnyRegion ? null : data[measure];\n })\n );\n });\n datacolumns_prelim = this.props.measure_cols.map((measure, index) => {\n const measure_col_label =\n this.props.measure_col_labels === undefined\n ? measure + \" (Preliminary)\"\n : this.props.measure_col_labels[index] + \" (Preliminary)\";\n return [measure_col_label].concat(\n datain.map((data) => {\n return data.inAnyRegion ? data[measure] : null;\n })\n );\n });\n } else {\n const categories = chartutils.listValues(\n datain,\n this.props.categories[0]\n );\n let cat_data = [];\n let curr_category = 0;\n datain.forEach((data, index) => {\n if (data[this.props.categories[0]] !== categories[curr_category]) {\n datacolumns_confirmed.push(\n [categories[curr_category]].concat(cat_data)\n );\n cat_data = [data.inAnyRegion ? null : data[this.props.measure_col]];\n cat_data = [];\n curr_category = curr_category + 1;\n cat_data.push(data.inAnyRegion ? null : data[this.props.measure_col]);\n } else {\n cat_data.push(data.inAnyRegion ? null : data[this.props.measure_col]);\n }\n });\n datacolumns_confirmed.push([categories[curr_category]].concat(cat_data));\n cat_data = [];\n curr_category = 0;\n datain.forEach((data, index) => {\n if (data[this.props.categories[0]] !== categories[curr_category]) {\n datacolumns_prelim.push(\n [categories[curr_category] + \" (Preliminary)\"].concat(cat_data)\n );\n cat_data = [data.inAnyRegion ? data[this.props.measure_col] : null];\n cat_data = [];\n curr_category = curr_category + 1;\n } else {\n cat_data.push(data.inAnyRegion ? data[this.props.measure_col] : null);\n }\n });\n datacolumns_prelim.push(\n [categories[curr_category] + \" (Preliminary)\"].concat(cat_data)\n );\n }\n return [datecolumns]\n .concat(datacolumns_confirmed)\n .concat(datacolumns_prelim);\n // return datacolumns\n }\n\n prepareData() {\n const select_data = this.props.data;\n if (select_data.length < 2) {\n return null;\n }\n // console.log(\"Select data\",this.state.current_select, this.props.filter_select,select_data)\n let sorted;\n if (this.props.sort === false) {\n sorted = select_data;\n } else {\n sorted = chartutils.sortIt(select_data, [\n { key: this.props.date_col, direction: \"ASC\" },\n ]);\n }\n sorted = sorted.map((dayData) => {\n const inRegion =\n this.props.regions === undefined\n ? undefined\n : this.props.regions.map(\n (region) =>\n dayData.test_date > region.start &&\n dayData.test_date <= region.end\n );\n if (this.props.regions !== undefined) {\n dayData.inAnyRegion = inRegion.some((region) => region === true);\n }\n return dayData;\n });\n const data = this.transformData(sorted);\n const regions = {};\n if (this.props.regions !== undefined) {\n data.map((item, index) => {\n if (index === 0) return null;\n regions[item[0]] = this.props.regions.map((region) => {\n return { start: region.start, end: region.end };\n });\n return null;\n });\n }\n return {\n x: this.props.date_col,\n columns: data,\n regions: this.props.regions === undefined ? undefined : regions,\n types: this.props.types,\n };\n }\n\n assignTypes(types, columns) {\n const ret = {};\n columns.forEach((column) => {\n let columnName = column[0];\n if (columnName.endsWith(\"(Preliminary)\")) {\n ret[columnName] = \"scatter\";\n } else {\n ret[columnName] = types === undefined ? undefined : types[columnName];\n }\n });\n return ret;\n }\n\n render() {\n // console.log(this.props);\n const { colors } = this.props;\n const chartdata = this.prepareData();\n if (chartdata === null) {\n return (\n <h3 style={{ color: \"white\", textAlign: \"center\" }}>\n Not enough data to draw a chart\n </h3>\n );\n }\n var tooltip = {\n order: null,\n format: {\n title: (x, index) => {\n const dateparts = x.toDateString().split(\" \");\n return dateparts[2] + dateparts[1] + dateparts[3].substr(2, 3);\n },\n },\n };\n if (this.state.measure_format === \"number\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcnumber(value, this.props.digits);\n } else if (this.state.measure_format === \"percent\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcpercent(value, this.props.digits);\n } else if (this.state.measure_format === \"percent-decimal\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcpercent_decimal(value);\n } else if (this.state.measure_format === \"percent-number\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcpercent_number(value);\n } else if (this.state.measure_format === \"dollar-millions\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcdollarMillions(value);\n } else if (this.state.measure_format === \"dollar-billions\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcdollarBillions(value);\n } else if (this.state.measure_format === \"dollar-nocents\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcdollarNoCents(value);\n } else if (\n this.state.measure_format === \"dollar\" &&\n this.state.digits === 0\n ) {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcdollarNoCents(value);\n } else if (this.state.measure_format === \"dollar\") {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcdollar(value);\n } else {\n tooltip.format.value = (value, ratio, id, index) =>\n chartutils.calcnumber(value, this.props.digits);\n }\n\n const c3_config = {\n data: {\n x: chartdata.x,\n columns: chartdata.columns,\n types: this.assignTypes(this.props.types, chartdata.columns),\n },\n size: {\n height: this.props.height === undefined ? undefined : this.props.height,\n width: this.props.width === undefined ? undefined : this.props.width,\n },\n axis: {\n x: {\n type: \"timeseries\",\n tick: {\n format: (x) => {\n const dateparts = x.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n });\n return dateparts;\n },\n // count: 7,\n fit: false,\n culling: {\n max: 5,\n },\n },\n min: new Date(2020, 2, 1),\n },\n y: {\n tick: {\n format: (x) => {\n if (Number.isInteger(x) === true) {\n return x;\n } else {\n return null;\n }\n },\n },\n padding: {\n bottom: 0,\n top: this.props.ymax === undefined ? undefined : this.props.ymax / 10,\n },\n max: this.props.ymax,\n },\n },\n grid: {\n x: {\n show: true,\n lines:\n this.props.date_lines === undefined\n ? undefined\n : this.props.date_lines.map((line) => {\n return {\n value: line.value,\n text: line.label,\n };\n }),\n },\n y: {\n show: true,\n },\n },\n // this.props.date_lines === undefined\n // ? undefined\n // : {\n // x: {\n // lines: this.props.date_lines.map((line) => {\n // return {\n // value: line.value,\n // text: line.label,\n // // position: \"start\",\n // };\n // }),\n // },\n // },\n regions:\n this.props.regions === undefined ? undefined : this.props.regions,\n color: colors,\n legend: {\n hide: chartdata.columns.reduce((result, column) => {\n if (column[0].endsWith(\"(Preliminary)\")) {\n // console.log(\"Hide \", \"|\" + column[0] + \"|\");\n result.push(column[0]);\n }\n return result;\n }, []),\n },\n tooltip: tooltip,\n point: {\n show: this.props.showPoints,\n r: 3,\n },\n bar: {\n width: 3,\n },\n zoom: {\n enabled: true,\n extent: [1, 100],\n },\n subchart: {\n show: this.props.subchart,\n size: {\n height: 100,\n },\n axis: {\n x: {\n show: false,\n },\n },\n },\n\n // types: this.props.types\n };\n // c3_config.legend.item = { onclick: function (id) { console.log(\"Clicked on legend\", id)} }\n // console.log(\"C3 Config \",c3_config)\n // console.log(\"Props \",this.props.filter_select.default_select !== this.state.current_select,this.props.filter_select,this.state )\n return (\n <Box ref={this.divref} justifyContent=\"center\">\n <Chart\n ref={this.chartref}\n updateflag={this.state.updateFlag.toString()}\n config={c3_config}\n />\n </Box>\n );\n }\n}\n","import React, { useEffect, useRef } from \"react\";\n\nimport * as d3 from \"d3\";\nimport * as topojson from \"topojson-client\";\n\n// this is not genereated by ETL, so leaving as JSON\nconst gaJson = require(\"../data/GA_Counties.json\")\n\nconst GAMap = (props) => {\n const d3Container = useRef();\n let maxHeight = props.mapHeight;\n\n const drawMap = () => {\n // const margin = { top: 20, right: 20, bottom: 20, left: 20 }\n let svg = null;\n let mapDiv = d3.select(d3Container.current);\n let baseData = null;\n let tooltip = null;\n let width = 10;\n let height = 10;\n let parentdim = null;\n const mapMatchField = \"COUNTYUC\";\n const georgiaJson = topojson.feature(gaJson, gaJson.objects.GA_Counties);\n\n const onMouseOver = (d) => {\n showTooltip(d, d3.event.pageX, d3.event.pageY);\n };\n const onMouseOut = (d) => {\n hideTooltip();\n };\n const showTooltip = (d, xpos, ypos) => {\n const tooltipContent = (county) => {\n const countyInfo = props.selectedData.get(county);\n const date = d3.timeFormat(\"%B %d\")(\n d3.timeParse(\"%Y-%m-%d\")(countyInfo[props.dateColumn])\n );\n let str =\n '<div class=\"tooltip-content\">' +\n '<div class=\"header\">' +\n countyInfo.county +\n \" County - \" +\n date +\n \"</div>\";\n props.tooltipDetails.forEach((field) => {\n let content =\n countyInfo[field.thresholdField] === undefined\n ? \"N/A\"\n : d3.format(field.format)(countyInfo[field.thresholdField]);\n str +=\n '<div class=\"details\">' +\n \"<label>\" +\n field.tooltipLabel +\n \": </label>\" +\n content +\n \"</div>\";\n });\n str +=\n '<div class=\"details\">' +\n \"<label>\" +\n \"Population: \" +\n \"</label>\" +\n d3.format(\",.0f\")(baseData.get(county).population) +\n \"</div>\";\n return str;\n };\n tooltip.transition().duration(200).style(\"opacity\", 0.9);\n tooltip\n .html(tooltipContent(d.properties[mapMatchField]))\n .style(\"left\", xpos + \"px\")\n .style(\"top\", ypos - 28 + \"px\");\n };\n const hideTooltip = () => {\n tooltip.transition().duration(500).style(\"opacity\", 0);\n };\n const countySelect = (d) => {\n const countyInfo = baseData.get(d.properties[mapMatchField]);\n\n props.onSelect(countyInfo);\n };\n\n mapDiv = d3.select(d3Container.current);\n if (!mapDiv.empty()) {\n mapDiv.selectAll(\"*\").remove();\n } else {\n return;\n }\n\n baseData = props.baseData\n\n if (mapDiv.node()) {\n const node = mapDiv.node();\n parentdim = node.parentElement.getBoundingClientRect();\n width = parentdim.width;\n tooltip = d3\n .select(d3Container.current)\n .append(\"div\")\n .attr(\"class\", \"tooltip\")\n .style(\"opacity\", 0);\n\n }\n\n // Ratio Between 3rd Quartile and colorscale Ceiling.\n // 2 if it's a per capita value, 5 if its a total\n const thresholdToCeilingRatio = props.rate ? 2 : 5;\n\n // Color Scale Ceiling is 3rd Quartile * ratio defined above\n // Quartile is rounded to 2 significant digits to make numbers nicer\n const colorScaleCeiling = +(\n props.colorThresholds[props.thresholdField].Q3 +\n props.colorThresholds[props.thresholdField].IQR * thresholdToCeilingRatio\n ).toPrecision(2);\n\n //YellowOrangeRed\n const colorScale = d3\n .scaleSequential(d3.interpolateYlOrRd)\n .domain([0, colorScaleCeiling]);\n\n // Project constrained by width\n let projection = d3\n .geoTransverseMercator()\n .rotate([82 + 10 / 60, -30])\n .fitWidth(width, georgiaJson);\n\n let path = d3.geoPath().projection(projection);\n\n // check how tall georgia is\n let shapeHeight = path.bounds(georgiaJson)[1][1];\n\n // if georgia is too tall, project constrained by height\n if (shapeHeight > maxHeight) {\n projection = d3\n .geoTransverseMercator()\n .rotate([82 + 10 / 60, -30])\n .fitSize([width, maxHeight], georgiaJson);\n path = d3.geoPath().projection(projection);\n height = maxHeight;\n } else {\n height = shapeHeight;\n }\n\n // create SVG container\n svg = mapDiv\n .append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height + 75);\n\n // Move down to make room for legend\n const g = svg.append(\"g\").attr(\"transform\", \"translate(0,75)\");\n\n // Draw Counties\n g.selectAll(\"path\")\n .data(georgiaJson.features)\n .enter()\n .append(\"path\")\n .attr(\"fill\", function (d) {\n // const baseCountyInfo = baseData.get(d.properties[mapMatchField]);\n let colorData = props.selectedData.get(d.properties[mapMatchField]);\n let fillValue = colorData[props.thresholdField];\n if (fillValue === 0 || fillValue === undefined) {\n return \"#ddd\";\n }\n return colorScale(fillValue);\n }) // applying a fill color.\n .attr(\"d\", path)\n .on(\"mouseover\", onMouseOver)\n .on(\"mouseout\", onMouseOut)\n .on(\"click\", countySelect);\n\n // How much space should the legend bar take?\n // Make sure there's room for the 0 box\n let barWidth = width * 0.7;\n if (barWidth < 400) {\n barWidth = Math.min(width - 105, 400);\n }\n\n // Create Legend\n let x = d3\n .scaleLinear()\n .domain([0, colorScaleCeiling])\n .range([0, barWidth]);\n\n let xAxis = d3.axisBottom(x).tickSize(22).ticks(4, props.tickFormat);\n\n let legendContainer = svg\n .append(\"g\")\n .attr(\"class\", \"legend\")\n .call(xAxis)\n .attr(\"transform\", \"translate(\" + (width - barWidth) / 2 + \", 30)\")\n .attr(\"text-anchor\", \"end\");\n\n // Remove first (0) tick\n legendContainer.select(\".tick\").remove();\n\n // Get rid of axis line on legend\n legendContainer.select(\".domain\").remove();\n\n const legendScale = colorScale.copy().domain([0, barWidth]);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = barWidth;\n canvas.height = 1;\n const context = canvas.getContext(\"2d\");\n for (let i = 0; i < barWidth; ++i) {\n context.fillStyle = legendScale(i);\n context.fillRect(i, 0, 1, 1);\n }\n\n legendContainer\n .append(\"image\")\n .attr(\"height\", 16)\n .attr(\"width\", barWidth)\n .attr(\"preserveAspectRatio\", \"none\")\n .attr(\"xlink:href\", canvas.toDataURL())\n .attr(\"class\", \"map-legend-bar\");\n\n legendContainer\n .append(\"rect\")\n .attr(\"height\", 16)\n .attr(\"width\", barWidth)\n .attr(\"class\", \"map-legend-block\");\n\n // Box for 0 on the legend\n legendContainer\n .append(\"rect\")\n .attr(\"height\", 16)\n .attr(\"width\", 32)\n .attr(\"transform\", \"translate(-40,0)\")\n .attr(\"fill\", \"#ddd\")\n .attr(\"class\", \"map-legend-block\");\n\n legendContainer\n .append(\"text\")\n .attr(\"dx\", -24)\n .attr(\"dy\", 36)\n .attr(\"text-anchor\", \"middle\")\n .text(\"0/NA*\");\n\n // Box for ceiling on the legend\n legendContainer\n .append(\"rect\")\n .attr(\"height\", 16)\n .attr(\"width\", 32)\n .attr(\"transform\", \"translate(\" + (barWidth + 8) + \",0)\")\n .attr(\"fill\", colorScale(colorScaleCeiling))\n .attr(\"class\", \"map-legend-block\");\n\n legendContainer\n .append(\"text\")\n .attr(\"dx\", barWidth + 8)\n .attr(\"dy\", 36)\n .attr(\"text-anchor\", \"start\")\n .text(\">\" + d3.format(props.tickFormat)(colorScaleCeiling));\n\n // Legend Title\n legendContainer\n .append(\"text\")\n .attr(\"dy\", -12)\n .attr(\"dx\", -40)\n .attr(\"text-anchor\", \"start\")\n .text(props.legendTitle);\n };\n\n const drawMapCallback = React.useCallback(drawMap, [props]);\n\n useEffect(() => {\n drawMapCallback();\n });\n\n useEffect(() => {\n const debounce = function (func, wait) {\n let timeout;\n return function (...args) {\n if (timeout) clearTimeout(timeout);\n timeout = setTimeout(() => {\n timeout = null;\n func.apply(args);\n }, wait);\n };\n };\n\n const updateComponent = debounce(drawMapCallback, 500);\n window.addEventListener(\"resize\", updateComponent);\n return () => {\n window.removeEventListener(\"resize\", updateComponent);\n };\n }, [drawMapCallback]);\n\n return <div className=\"ga-map\" ref={d3Container} />\n};\nexport default GAMap;\n","import React from \"react\";\nimport * as d3 from \"d3\";\n\nconst StateInfoBox = (props) => {\n const baseData = props.baseData;\n\n const stateInfo = props.selectedData.get(\"GEORGIA\");\n const date = d3.timeFormat(\"%B %d\")(\n d3.timeParse(\"%Y-%m-%d\")(stateInfo[props.dateColumn])\n );\n\n let stateInfoboxContent = props.tooltipDetails.map((field) => {\n let content =\n stateInfo[field.thresholdField] === undefined\n ? \"N/A\"\n : d3.format(field.format)(stateInfo[field.thresholdField]);\n return (\n <div className=\"details\" key={field.tooltipLabel}>\n <label>{field.tooltipLabel + \": \"}</label>\n {content}\n </div>\n );\n });\n\n return (\n <div\n className=\"stateInfobox\"\n >\n <div className=\"tooltip-content\">\n <div className=\"header\">{stateInfo.county + \" - \" + date}</div>\n {stateInfoboxContent}\n <div className=\"details\">\n <label>{\"Population: \"}</label>\n {d3.format(\",.0f\")(baseData.get(\"GEORGIA\").population)}\n </div>\n </div>\n </div>\n );\n};\n\nexport default StateInfoBox;\n","import React from \"react\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport ToggleButton from \"@material-ui/lab/ToggleButton\";\nimport ToggleButtonGroup from \"@material-ui/lab/ToggleButtonGroup\";\nimport Grid from \"@material-ui/core/Grid\";\nimport GAMap from \"../../components/GAMap\";\nimport { Select, MenuItem, Box } from \"@material-ui/core\";\nimport { DatePicker, MuiPickersUtilsProvider } from \"@material-ui/pickers\";\nimport DateFnsUtils from \"@date-io/date-fns\";\nimport { sub, parse, format } from \"date-fns\";\nimport StateInfoBox from \"../../components/stateInfoBox\";\n\nconst useStyles = makeStyles((theme) => ({\n toggleContainer: {\n color: \"white\",\n textTransform: \"none\",\n },\n selectBox: {\n WebkitAppearance: \"menulist\",\n MozAppearance: \"menulist\",\n },\n}));\n\nconst rateTotalCensorLimit = 5; // censor rates for counties where total is < 5\n// const testingCensorLimit = 10; // censor testing when <10 total tests\n\nconst fmtDate = (inDate) => format(inDate, \"yyyy-MM-dd\");\n\n/**\n *\n * @param {{\n * mapData: Object\n * maxDate: String\n * onSelect: selectionCallback\n * views: mapView[]\n * countyField: String\n * colorThresholds: Object\n * }} props\n */\nconst GAMapContainer = (props) => {\n const classes = useStyles();\n const [view, setView] = React.useState(props.views[0]);\n const [subview, setSubview] = React.useState(\n view.subviews.filter((item) => !item.noDisplay)[0]\n );\n const [selectedDate, setSelectedDate] = React.useState(\n parse(\n view.dataset[view.dataset.length - 1].report_date,\n \"yyyy-MM-dd\",\n new Date()\n )\n );\n\n const viewMap = new Map(props.views.map((item) => [item.category, item]));\n\n // Sets subview to first option in list when view changes\n const handleViewChange = (newView) => {\n if (newView !== null) {\n setView(viewMap.get(newView));\n setSubview(\n viewMap.get(newView).subviews.filter((item) => !item.noDisplay)[0]\n );\n }\n };\n\n const handleSubviewChange = (newSubview) => {\n setSubview(newSubview);\n };\n\n let baseData = new Map(\n props.mapData.map((item) => [\n item[props.countyField] ? item[props.countyField].toUpperCase() : \"\",\n item,\n ])\n );\n\n const totalPopulation = props.mapData.reduce(\n (accumulator, current) => accumulator + current.population,\n 0\n );\n\n baseData.set(\"GEORGIA\", {\n population: totalPopulation,\n });\n\n let dataFromSelectedDate = view.dataset.filter(\n (d) => d[view.dateColumn] === fmtDate(selectedDate)\n );\n let selectedDateCountyDataMap = new Map(\n dataFromSelectedDate.map((d) => [\n d.county.toUpperCase(),\n Object.assign({}, d),\n ])\n );\n selectedDateCountyDataMap.delete(\"UNKNOWN\");\n\n const comparisonDate = sub(selectedDate, props.comparisonRange);\n let dataFromComparisonDate = view.dataset.filter(\n (d) => d[view.dateColumn] === fmtDate(comparisonDate)\n );\n let comparisonDateCountyDataMap = new Map(\n dataFromComparisonDate.map((d) => [\n d.county.toUpperCase(),\n Object.assign({}, d),\n ])\n );\n\n // Big blob of business logic\n /* if (view.category === \"PCR Testing\") {\n selectedDateCountyDataMap.forEach((value, key) => {\n for (const header of view.subviews) {\n let headerValue = value[view.column];\n let denominator = value.cum_pcrtest;\n if (header.comparison) {\n headerValue =\n headerValue - comparisonDateCountyDataMap.get(key)[view.column];\n denominator =\n value.cum_pcrtest -\n comparisonDateCountyDataMap.get(key).cum_pcrtest;\n }\n if (header.rate) {\n headerValue =\n denominator > testingCensorLimit\n ? headerValue / denominator\n : undefined;\n }\n value[header.thresholdField] = headerValue;\n }\n });\n } else */\n if (view.category === \"Total Cases\") {\n selectedDateCountyDataMap.forEach((value, key) => {\n for (const header of view.subviews) {\n let headerValue = value[header.column];\n let denominator = baseData.get(key).population / 100000;\n if (header.comparison) {\n headerValue =\n headerValue - comparisonDateCountyDataMap.get(key)[header.column];\n }\n if (header.rate) {\n headerValue =\n headerValue > rateTotalCensorLimit\n ? headerValue / denominator\n : undefined;\n }\n value[header.thresholdField] = headerValue;\n }\n });\n } else {\n selectedDateCountyDataMap.forEach((value, key) => {\n for (const header of view.subviews) {\n let headerValue = value[view.column];\n let denominator = baseData.get(key).population / 100000;\n if (header.comparison) {\n headerValue =\n headerValue - comparisonDateCountyDataMap.get(key)[view.column];\n }\n if (header.rate) {\n headerValue =\n headerValue > rateTotalCensorLimit\n ? headerValue / denominator\n : undefined;\n }\n value[header.thresholdField] = headerValue;\n }\n });\n }\n\n return (\n <Box display=\"flex\" flexDirection=\"column\" justifyContent=\"center\">\n <h3\n style={{\n color: \"white\",\n textAlign: \"center\",\n fontWeight: \"normal\",\n }}\n >\n COVID-19 By County\n </h3>\n\n <Box\n display={{ xs: \"none\", sm: \"block\" }}\n mx=\"auto\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n <ToggleButtonGroup\n value={view.category}\n exclusive\n onChange={(event, value) => {\n handleViewChange(value);\n }}\n aria-label=\"map view\"\n className={classes.toggleContainer}\n >\n {props.views.map((view) => (\n <ToggleButton key={view.category} value={view.category}>\n {view.category}\n </ToggleButton>\n ))}\n </ToggleButtonGroup>\n </Box>\n <Box display={{ xs: \"block\", sm: \"none\" }} mx=\"auto\">\n <Select\n id=\"selectbox\"\n className={classes.selectBox}\n value={view.category}\n onChange={(event, child) => {\n handleViewChange(event.target.value);\n }}\n >\n {props.views.map((view) => (\n <MenuItem key={view.category} value={view.category}>\n {view.category}\n </MenuItem>\n ))}\n </Select>\n </Box>\n\n <Grid container>\n <Grid item xs={12} sm={6}>\n <Box textAlign=\"center\" my={1}>\n <Select\n id=\"subviewSelect\"\n className={classes.selectBox}\n value={subview}\n onChange={(event, child) => {\n handleSubviewChange(event.target.value);\n }}\n >\n {view.subviews\n .filter((item) => !item.noDisplay)\n .map((subview) => (\n <MenuItem key={subview.title} value={subview}>\n {subview.title}\n </MenuItem>\n ))}\n </Select>\n </Box>\n </Grid>\n\n <Grid item xs={12} sm={6}>\n <Box textAlign=\"center\" my={1}>\n <MuiPickersUtilsProvider utils={DateFnsUtils}>\n <DatePicker\n variant=\"inline\"\n value={selectedDate}\n onChange={setSelectedDate}\n minDate={new Date(2020, 1, 15)}\n maxDate={props.maxDate}\n PopoverProps={{\n anchorOrigin: {\n vertical: \"bottom\",\n horizontal: \"left\",\n },\n transformOrigin: {\n vertical: \"top\",\n horizontal: \"left\",\n },\n }}\n disableToolbar\n />\n </MuiPickersUtilsProvider>\n </Box>\n </Grid>\n </Grid>\n\n <GAMap\n baseData={baseData}\n selectedData={selectedDateCountyDataMap}\n // comparisonData={comparisonData}\n onSelect={props.onSelect}\n countyField={props.countyField}\n thresholdField={subview.thresholdField}\n // colorField={view.column}\n rate={subview.rate}\n colorThresholds={props.colorThresholds}\n legendTitle={subview.legendTitle}\n tickFormat={subview.format}\n tooltipDetails={view.subviews}\n mapHeight={500}\n dateColumn={view.dateColumn}\n // showTooltip={showTooltip}\n // hideTooltip={hideTooltip}\n />\n\n <StateInfoBox\n baseData={baseData}\n selectedData={selectedDateCountyDataMap}\n tooltipDetails={view.subviews}\n dateColumn={view.dateColumn}\n />\n </Box>\n );\n};\nexport default GAMapContainer;\n","import React, { useState } from \"react\";\nimport { NativeSelect, Box, Grid, Select, MenuItem } from \"@material-ui/core\";\nimport \"react-tabs/style/react-tabs.css\";\n// import useMediaQuery from '@material-ui/core/useMediaQuery'\nimport TimeSeriesChart from \"../../components/timeSeriesChart\";\nimport { makeStyles } from \"@material-ui/core/styles\";\n\nconst useStyles = makeStyles((theme) => ({\n toggleContainer: {\n color: \"white\",\n textTransform: \"none\",\n },\n selectBox: {\n WebkitAppearance: \"menulist\",\n MozAppearance: \"menulist\",\n },\n}));\n\n\nconst CasesOverTimeContainer = (props) => {\n const [dateType, setDateType] = useState(\"report\");\n const [dataType, setDataType] = useState(\"pcr_cases\");\n\n const epicurve = props.epicurve;\n const epicurve_rpt_date = props.epicurve_rpt_date;\n // const testing_rpt_data = props.testing_data;\n // const testing_col_data = props.testing_data_col;\n const selectCounty = props.selectCounty;\n const county = props.county;\n const counties = props.counties;\n\n const classes = useStyles();\n\n let showDateOption = true;\n\n const date_lines =\n dateType === \"onset\"\n ? [\n {\n label: \"14-day window\",\n value: new Date(new Date() - 1000 * 60 * 60 * 24 * 14)\n .toISOString()\n .slice(0, 10),\n },\n {\n label: \"Large Gathering Ban\",\n value: new Date(2020, 2, 23).toISOString().slice(0, 10),\n },\n {\n label: \"Shelter in Place\",\n value: new Date(2020, 3, 2).toISOString().slice(0, 10),\n },\n {\n label: \"Shelter in Place extended for at risk\",\n value: new Date(2020, 4, 1).toISOString().slice(0, 10),\n },\n ]\n : [\n {\n label: \"Large Gathering Ban\",\n value: new Date(2020, 2, 23).toISOString().slice(0, 10),\n },\n {\n label: \"Shelter in Place\",\n value: new Date(2020, 3, 2).toISOString().slice(0, 10),\n },\n {\n label: \"Shelter in Place extended for at risk\",\n value: new Date(2020, 4, 1).toISOString().slice(0, 10),\n },\n ];\n\n const last14Region = [\n {\n start: new Date(Date.now() - 1000 * 60 * 60 * 24 * 14)\n .toISOString()\n .slice(0, 10),\n end: new Date().toISOString().slice(0, 10),\n },\n ];\n\n let chartData = dateType === \"onset\" ? epicurve : epicurve_rpt_date;\n let dateCol = dateType === \"onset\" ? \"test_date\" : \"report_date\";\n let regions = dateType === \"onset\" ? last14Region : undefined;\n let ymax = undefined;\n\n /* if (dataType === \"total_tests\" || dataType === \"per_pos\") {\n chartData = dateType === \"onset\" ? testing_col_data : testing_rpt_data;\n dateCol = dateType === \"onset\" ? \"collection_dt\" : \"report_date\";\n // regions = undefined;\n showDateOption = true;\n } */\n\n if (dataType === \"per_pos\") {\n ymax = 50;\n }\n\n const chartDataFiltered = chartData.filter((value) => {\n return value.county === county;\n });\n\n chartDataFiltered.forEach((x) => {\n x.perpos = (x.pcrpos / x.pcrtest) * 100;\n });\n\n const getSubviewOptions = (dataType) => {\n switch (dataType) {\n case \"deaths\":\n return [\"Death\"];\n /* case \"total_tests\":\n return [\"Collection\", \"Report\"];\n case \"per_pos\":\n return [\"Collection\", \"Report\"]; */\n default:\n return [\"Onset\", \"Report\"];\n }\n };\n\n const getMeasureCols = (dataType) => {\n switch (dataType) {\n case \"pcr_cases\":\n return [\"positives\", \"moving_avg_cases\"];\n case \"ant_cases\":\n return [\"antigens\", \"moving_avg_antigen\"];\n case \"total_cases\":\n return [\"total_cases\", \"moving_avg_total_cases\"];\n case \"cum_cases\":\n return [\"positives_cum\", \"death_cum\"];\n case \"deaths\":\n return [\"deathcnt\", \"moving_avg_deaths\"];\n /* case \"total_tests\":\n return [\"pcrtest\"];\n case \"per_pos\":\n return [\"perpos\", \"day7_per_pcrpos\"]; */\n default:\n console.log(\"No dataType defined on cases_over_time graph\");\n return [\"positives\", \"moving_avg_cases\"];\n }\n };\n\n const getMeasureColLabels = (dataType) => {\n switch (dataType) {\n case \"pcr_cases\":\n return [\"Confirmed Cases\", \"7-day Moving Average\"];\n case \"ant_cases\":\n return [\"Confirmed Cases\", \"7-day Moving Average\"];\n case \"total_cases\":\n return [\"Total Cases\", \"7-day Moving Average\"];\n case \"cum_cases\":\n return [\"Cumulative Confirmed Cases\", \"Cumulative Deaths\"];\n case \"deaths\":\n return [\"Deaths\", \"7-day moving average\"];\n /* case \"total_tests\":\n return [\"Total PCR Tests\"];\n case \"per_pos\":\n return [\"% PCR Tests Positive\", \"7-day moving average\"]; */\n default:\n return [\"Confirmed Cases\", \"7-day Moving Average\"];\n }\n };\n\n const getMeasureColors = (dataType) => {\n switch (dataType) {\n case \"pcr_cases\":\n case \"ant_cases\":\n case \"total_cases\":\n return { pattern: [\"#33a3ff\", \"#ffcc32\"] };\n case \"cum_cases\":\n return { pattern: [\"#33a3ff\", \"#dd5757\"] };\n case \"deaths\":\n return { pattern: [\"#dd5757\", \"#ffcc32\"] };\n default:\n return { pattern: [\"#33a3ff\", \"#ffcc32\"] };\n }\n };\n\n const getMeasureTypes = (dataType) => {\n let labels = getMeasureColLabels(dataType);\n const measureTypes = {};\n measureTypes[labels[0]] = \"bar\";\n measureTypes[labels[1]] = \"area\";\n return measureTypes;\n };\n\n return (\n <Box display=\"flex\" flexDirection=\"column\" justifyContent=\"center\">\n <h3\n style={{\n color: \"white\",\n textAlign: \"center\",\n fontWeight: \"normal\",\n }}\n >\n COVID-19 Over Time\n </h3>\n <Box\n mx=\"auto\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n <Select\n className={classes.selectBox}\n value={dataType}\n onChange={(event, child) => {\n const _dataType = event.target.value;\n setDataType(_dataType);\n if (_dataType === 'deaths') setDateType('onset');\n }}\n >\n <MenuItem value=\"pcr_cases\">PCR Cases</MenuItem>\n <MenuItem value=\"ant_cases\">Antigen Cases</MenuItem>\n <MenuItem value=\"total_cases\">Total Cases</MenuItem>\n <MenuItem value=\"cum_cases\">Cumulative Cases</MenuItem>\n <MenuItem value=\"deaths\">Confirmed Deaths</MenuItem>\n { /* <MenuItem value=\"total_tests\">PCR Total Tests</MenuItem>\n <MenuItem value=\"per_pos\">PCR Percent Positive</MenuItem> */ }\n </Select>\n </Box>\n <Grid container>\n <Grid item xs={12} sm={6}>\n <Box textAlign=\"center\" my={1}>\n <NativeSelect\n value={county}\n onChange={(event) => selectCounty(event.target.value)}\n >\n {counties.map((item) => {\n return (\n <option key={item.id} value={item.id}>\n {item.label}\n </option>\n );\n })}\n </NativeSelect>\n </Box>\n </Grid>\n {showDateOption? (\n <Grid item xs={12} sm={6}>\n <Box textAlign=\"center\" my={1}>\n {getSubviewOptions(dataType).length > 1? (\n <NativeSelect\n value={dateType}\n onChange={(event) => setDateType(event.target.value)}\n >\n <option value=\"onset\">\n Date of {getSubviewOptions(dataType)[0]}\n </option>\n <option value=\"report\">\n Date of {getSubviewOptions(dataType)[1]}\n </option>\n </NativeSelect>\n ) : (\n <p style={{ color:'white' }}>Date of {getSubviewOptions(dataType)[0]}</p>\n )}\n </Box>\n </Grid>)\n : null\n }\n </Grid>\n <TimeSeriesChart\n data={chartDataFiltered}\n date_col={dateCol}\n measure_cols={getMeasureCols(dataType)}\n height=\"700\"\n digits={1}\n regions={regions}\n date_lines={date_lines}\n measure_col_labels={getMeasureColLabels(dataType)}\n colors={getMeasureColors(dataType)}\n showPoints={false}\n types={getMeasureTypes(dataType)}\n subchart={false}\n ymax={ymax}\n />\n </Box>\n );\n};\n\nexport default CasesOverTimeContainer;\n","import React, { useRef } from \"react\";\nimport Papa from 'papaparse';\n\nimport { Box, Grid, Typography, Hidden } from \"@material-ui/core\";\nimport GAMapContainer from \"./GAMapContainer\";\nimport CasesOverTimeContainer from \"./casesOverTimeContainer\";\nimport CacheContext from \"../../cacheBuster\";\n\nconst mapThresholds = require(\"../../data/threshold.json\"); // this is not generated by ETL, so leaving here\n\nconst scrollToRef = (ref) => {\n window.scrollTo(0, ref.current.offsetTop);\n};\n\n/**\n * Cases by County Section\n *\n * @param {{\n * classes: import(\"@material-ui/core\").Theme,\n * epicurve: [{\n * measure: String,\n * county: String,\n * test_date: String,\n * positives: number,\n * deathcnt: number,\n * positives_cum: number,\n * death_cum: number,\n * moving_avg_cases: number,\n * moving_avg_deaths: number\n * }]\n * }} props\n * @param props.classes material ui theme object\n * @param props.epicurve epi data for each county by test date\n */\nconst GACasesByCounty = (props) => {\n const [countyList, setCountyList] = React.useState([]);\n const [gaData, setGAData] = React.useState([]);\n const [epicurve_rpt_date, setEpicurve_rpt_date] = React.useState([]);\n const [testing_curve_rpt_date, setTesting_curve_rpt_date] = React.useState([]);\n const [testing_curve_col_date, setTesting_curve_col_date] = React.useState([]);\n \n const currdate = React.useContext(CacheContext);\n React.useEffect(() => {\n fetch('./data/map_data.csv?tstamp='+currdate)\n .then((resp) => resp.text())\n .then(csv => Papa.parse(csv, { header:true, skipEmptyLines:true, dynamicTyping:true }))\n .then((json) => {\n setGAData(json.data);\n \n const cl = json.data.map((county) => {\n return {\n id: county.county_name,\n label: county.county_name + \" County\",\n };\n })\n .sort()\n .filter((county) => county.id !== \"Non-GA Resident/Unknown State\");\n cl.unshift({ id: \"Georgia\", label: \"Georgia\" }); //unshift adds Georgia to the front\n \n setCountyList(cl);\n });\n fetch('./data/epicurve_rpt_date.csv?tstamp='+currdate)\n .then((resp) => resp.text())\n .then(csv => Papa.parse(csv, { header:true, skipEmptyLines:true, dynamicTyping:true }))\n .then((json) => {\n setEpicurve_rpt_date(json.data);\n });\n fetch('./data/pcr_positives.csv?tstamp='+currdate)\n .then((resp) => resp.text())\n .then(csv => Papa.parse(csv, { header:true, skipEmptyLines:true, dynamicTyping:true }))\n .then((json) => {\n setTesting_curve_rpt_date(json.data);\n });\n fetch('./data/pcr_positives_col.csv?tstamp='+currdate)\n .then((resp) => resp.text())\n .then(csv => Papa.parse(csv, { header:true, skipEmptyLines:true, dynamicTyping:true }))\n .then((json) => {\n setTesting_curve_col_date(json.data);\n });\n },[currdate]);\n \n const classes = props.classes;\n const epicurve = props.epicurve;\n\n // The selected county for cases over time chart\n const [activeCounty, setActiveCounty] = React.useState(\"Georgia\");\n\n const cases_over_time_ref = useRef(null);\n\n /**\n * @callback selectionCallback\n * @param {County} county\n */\n const countySelected = (county) => {\n scrollToRef(cases_over_time_ref);\n setActiveCounty(county.county_name);\n };\n const selectCounty = (newcounty) => {\n setActiveCounty(newcounty);\n };\n\n /**\n * @typedef {Object} mapView\n * Main tabs for the map\n *\n * @property {String} category - The name in the toggleButton for this view.\n * @property {Object} dataset - The dataset for this view\n * @property {String} column - The column from which all of the values are calculated. Usually cases, deaths, etc.\n * @property {String} dateColumn - The column in `dataset` that contains the date\n * @property {mapSubview[]} subviews - The subviews for the dropdown and the tooltip\n */\n\n /**\n * @typedef {Object} mapSubview\n * Dropdown options for the map\n *\n * @property {String} title - Title above the bar in the legend\n * @property {String} thresholdField - The field in threshold.json this corresponds to. This defines the range of the bar in the legend\n * @property {Boolean} [noDisplay] - Whether the subview is selectable in the dropdown menu. True if you only want it in the tooltip.\n * @property {Boolean} [comparison] - Is it a cumulative total, or time limited (ie last 2 weeks). Default cumulative\n * @property {Boolean} [rate] - Total or per capita rate?\n */\n\n /**\n * Array of Available Map Views\n * - Defines the options available for the main map\n * - Views are the larger tabs above, while subviews are options in the dropdown\n *\n * @type {mapView[]}\n */\n const mapViews = () => [\n {\n category: \"PCR Cases\",\n dataset: epicurve_rpt_date,\n column: \"positives_cum\",\n dateColumn: \"report_date\",\n subviews: [\n {\n title: \"PCR Last 2 Weeks\",\n thresholdField: \"in14day_positive\",\n noDisplay: true,\n comparison: true,\n format: \",.0f\",\n tooltipLabel: \"Cases (last 2 weeks)\",\n },\n {\n title: \"Last 2 Weeks\",\n thresholdField: \"in14day_rate\",\n legendTitle: \"Reported PCR cases per 100,000 people last 14 days\",\n rate: true,\n comparison: true,\n format: \",.0f\",\n tooltipLabel: \"Cases per 100k (last 2 weeks)\",\n },\n {\n title: \"Cases\",\n thresholdField: \"positive\",\n legendTitle: \"Total cases by county\",\n format: \",.0f\",\n tooltipLabel: \"Cases (total)\",\n },\n {\n title: \"Cases Per 100k\",\n thresholdField: \"rate\",\n legendTitle: \"Total PCR cases per 100,000 people\",\n rate: true,\n format: \",.5\",\n tooltipLabel: \"Cases per 100k (total)\",\n },\n ],\n },\n /*\n {\n category: \"PCR Testing\",\n dataset: testing_curve_col_date,\n column: \"cum_pcrpos\",\n dateColumn: \"collection_dt\",\n subviews: [\n {\n title: \"% Positive Last 2 Weeks\",\n thresholdField: \"pcr_pos14\",\n legendTitle: \"% Tests Positive, Specimen Collected Last 14 days\",\n rate: true,\n comparison: true,\n format: \".1%\",\n tooltipLabel: \"% Positive Last 2 Weeks\",\n },\n {\n title: \"% Positive Overall\",\n thresholdField: \"pcr_pos\",\n legendTitle: \"% of Tests Positive Overall\",\n rate: true,\n format: \".1%\",\n tooltipLabel: \"% Positive Overall\",\n },\n ],\n },*/\n {\n category: \"Confirmed Deaths\",\n dataset: epicurve,\n column: \"death_cum\",\n dateColumn: \"test_date\",\n subviews: [\n {\n title: \"Total Deaths\",\n thresholdField: \"deaths\",\n legendTitle: \"Total deaths by county\",\n format: \",.0f\",\n tooltipLabel: \"Total Deaths\",\n },\n {\n title: \"Deaths per 100k\",\n thresholdField: \"death_rate\",\n legendTitle: \"Total deaths per 100k\",\n rate: true,\n format: \".1f\",\n tooltipLabel: \"Deaths per 100k\",\n },\n ],\n },\n {\n category: \"Total Cases\",\n dataset: epicurve_rpt_date,\n dateColumn: \"report_date\",\n subviews: [\n {\n title: \"Last 2 Weeks\",\n column: \"total_cases_cum\",\n thresholdField: \"in14day_rate\",\n legendTitle: \"Total cases per 100K (last 2 Weeks)\",\n rate: true,\n comparison: true,\n format: \".0f\",\n tooltipLabel: \"Total Cases per 100K (last 2 Weeks)\",\n },\n {\n title: \"Total [PCR + Antigen]\",\n column: \"total_cases_cum\",\n thresholdField: \"positive\",\n legendTitle: \"Total PCR and antigen cases\",\n format: \",.0f\",\n tooltipLabel: \"Total PCR and Antigen Cases\",\n },\n {\n title: \"Total Cases per 100K\",\n column: \"total_cases_cum\",\n thresholdField: \"rate\",\n legendTitle: \"Total cases per 100K\",\n format: \",.0f\",\n rate: true,\n tooltipLabel: \"Total Cases per 100K\",\n },\n {\n title: \"Total Last 2 Weeks\",\n column: \"total_cases_cum\",\n thresholdField: \"in14day_positive\",\n noDisplay: true,\n comparison: true,\n format: \",.0f\",\n tooltipLabel: \"Total Cases (last 2 weeks)\",\n },\n ],\n },\n ];\n\n return (\n <Grid\n container\n direction=\"row\"\n justifyContent=\"space-around\"\n className={classes.mediaFlow}\n >\n <Grid item xs={12}>\n <h2 style={{ color: \"white\", textAlign: \"center\" }}>\n Georgia Cases by County\n </h2>\n </Grid>\n\n <Grid item xs={12} lg={6}>\n <Box marginRight={2}>\n <Typography color=\"textSecondary\" variant=\"body1\">\n The maps below show the number and rate of confirmed (PCR positive)\n and total (PCR and antigen positive) COVID-19 cases\n by county of residence.\n Choose \"PCR Cases\", \"Confirmed Deaths\", or \"Total Cases\"\n then use the drop-down menu to choose cumulative\n \"Cases\", \"Cases per 100K\", \"Total Deaths\", \"Deaths per 100K\", \"Total Cases\", or \"Total Cases per 100K\" or data for the \"Last 2 Weeks\".\n By clicking on the date above the map, you can select a past date to see historic maps, using the current color scale.\n On the map, you can hover or click to find out additional details such as number of deaths, case rate, etc.\n Selecting a county will also update the cases over time charts.\n <br />\n <br />\n The color scale is based on the distribution of county-level case counts or rates,\n outlier values are removed from the scale calculation.\n The scale will change as needed to accommodate increasing or decreasing case counts\n and maintain distinctions between counties and will be calculated based on the current data.\n Historic maps can be viewed by changing the date above the map.\n </Typography>\n </Box>\n </Grid>\n\n <Hidden mdDown>\n <Grid item xs={12} lg={6}>\n <Box>\n <Typography color=\"textSecondary\">\n The charts below present the number of newly confirmed (PCR positive),\n antigen positive, total (PCR and antigen positive) COVID-19 cases,\n and confirmed deaths over time.\n This chart is meant to aid understanding of whether case reports are growing,\n leveling off, or declining and can help to guide local COVID-19 response.\n Cases over time can be viewed using two date options,\n Symptom Onset Date or Date of Report, and they can also be viewed by county.\n See <a href=\"docs/GA_COVID19_Dashboard_Guide.pdf\" className=\"body\" target='_blank' rel='noopener noreferrer'>Guide: Understand the data (PDF)</a> for more information about the dates.\n To zoom in on a specific time period, clon ick on a graph and use the mouse to zoom in or out.\n </Typography>\n </Box>\n </Grid>\n </Hidden>\n \n {!!gaData.length && !!epicurve_rpt_date.length && !!testing_curve_col_date.length?\n <Grid item xs={12} lg={6} id=\"cases_over_time\" ref={cases_over_time_ref}>\n <GAMapContainer\n mapData={gaData}\n maxDate={currdate}\n onSelect={countySelected}\n comparisonRange={{ days: 14 }}\n views={mapViews()}\n countyField=\"county_name\"\n colorThresholds={mapThresholds}\n />\n </Grid>\n : null\n }\n\n <Hidden lgUp>\n <Grid item xs={12} lg={6}>\n <Box>\n <Typography color=\"textSecondary\">\n The charts below present the number of newly confirmed (PCR positive),\n antigen positive, total (PCR and antigen positive) COVID-19 cases,\n and confirmed deaths over time.\n This chart is meant to aid understanding of whether case reports are growing,\n leveling off, or declining and can help to guide local COVID-19 response.\n Cases over time can be viewed using two date options,\n Symptom Onset Date or Date of Report, and they can also be viewed by county.\n See <a href=\"docs/GA_COVID19_Dashboard_Guide.pdf\" className=\"body\" target='_blank' rel='noopener noreferrer'>Guide: Understand the data (PDF)</a> for more information about the dates.\n To zoom in on a specific time period, click on a graph and use the mouse to zoom in or out.\n </Typography>\n </Box>\n </Grid>\n </Hidden>\n <Grid item xs={12} lg={6}>\n {!!epicurve.length && !!epicurve_rpt_date.length && !!testing_curve_rpt_date.length && !!testing_curve_col_date.length?\n <CasesOverTimeContainer\n epicurve={epicurve}\n epicurve_rpt_date={epicurve_rpt_date}\n testing_data={testing_curve_rpt_date}\n testing_data_col={testing_curve_col_date}\n selectCounty={selectCounty}\n county={activeCounty}\n counties={countyList}\n />\n : null\n }\n </Grid>\n {/* </Grid> */}\n <Typography color=\"textSecondary\">\n <b>Note – </b>\n Report Date counts may be affected by laboratories reporting a backlog of tests or by temporary lapses in reporting,\n leading to an artificial increase or decrease in cases or lab tests on a given day.\n Additionally, at-home tests are not reportable to DPH and are not reflected here.\n Symptom Onset Date data may be incomplete. \n Reported case delays occur due to the lag in time between when a case was tested\n and/or reported and submitted to the Georgia DPH for reporting purposes.\n This delay can vary depending on the testing facility and/or jurisdiction.\n <br />\n <b>*</b>\n Rates may not be accurate when case counts are <5 and are not presented.\n </Typography>\n </Grid>\n );\n};\n\nexport default GACasesByCounty;\n"],"sourceRoot":""}