Source

src/components/Panels/DataPanel.jsx

// This components formats the data for the selected geography
// and displays it in the right side panel.

// Import main libraries
import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'

// Import helper libraries
import styled from 'styled-components'
// import FormControl from "@mui/material/FormControl";
import useGetSidebarData from '../../hooks/useGetSidebarData'

// Import config and sub-components
import Tooltip from '../Interface/Tooltip'
import TwoWeekChart from '../Charts/TwoWeekLineChart'
import colors from '../../config/colors'
import { TextStatistics } from '..'
import { Button } from '@mui/material'
import { paramsSelectors, paramsActions } from '../../stores/paramsStore'
const { selectPanelState, selectSelectionKeys, selectDates } = paramsSelectors
const { clearSelection } = paramsActions
//// Styled components CSS
// Main container for entire panel
const DataPanelContainer = styled.div`
    /* position: absolute;
  width:20%;
  right: 0;
  top: 0; */
    overflow-x: hidden;
    position: relative;

    ::-webkit-scrollbar {
        width: 10px;
    }

    /* Track */
    ::-webkit-scrollbar-track {
        background: #2b2b2b;
    }

    /* Handle */
    ::-webkit-scrollbar-thumb {
        background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #999;
        background-position: center center;
        background-repeat: no-repeat, no-repeat;
        background-size: 50%, 100%;
        transition: 125ms all;
    }

    /* Handle on hover */
    ::-webkit-scrollbar-thumb:hover {
        background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #f9f9f9;
        background-position: center center;
        background-repeat: no-repeat, no-repeat;
        background-size: 50%, 100%;
    }
    /* overflow-y: scroll; */
    /* height: calc(100vh - 50px); */
    background-color: ${colors.gray}fa;
    /* box-shadow: -2px 0px 5px rgba(0, 0, 0, 0.7); */
    padding: 20px;
    flex: 1 1 auto;
    box-sizing: border-box;
    transition: 250ms all;
    font-family: 'Lato', sans-serif;
    color: white;
    font-size: 100%;
    padding: 0;
    z-index: 5;
    display: none;
    h4 {
        margin: 10px 0;
    }
    &.open {
        display: initial;
    }
    @media (max-width: 1024px) {
        min-width: 25%;
    }
    @media (max-width: 600px) {
        width: 100%;
        left: 0;
        top: 10em;
        z-index: 51;
        position: fixed;
        overflow-y: auto;
        padding-bottom: 20vh;
        height: calc(100% - 10em);
    }

    div {
        div {
            p {
                line-height: 1.5;
                margin: 0;
                display: inline-block;
            }
        }
    }
    h2 {
        padding: 15px 0 5px 0;
        margin: 0;
        display: inline-block;
        max-width: 200px;
    }
    h6,
    p {
        padding: 0 0 15px 0;
        margin: 0;
        max-width: 30ch;
        a {
            color: ${colors.yellow};
            text-decoration: none;
        }
    }

    h6.alt-index {
        padding-bottom: 0;
        margin-left: 2px;
        color: ${colors.orange};
        &:before {
            content: '*';
        }
    }
    p {
        padding-right: ${(props) => (props.expanded ? '10px' : '0px')};
    }
`
// Scrollable Wrapper for main report information
const ReportWrapper = styled.div`
    /* overflow-y:scroll; */
    ::-webkit-scrollbar {
        width: 10px;
    }

    /* Track */
    ::-webkit-scrollbar-track {
        background: #2b2b2b;
    }

    /* Handle */
    ::-webkit-scrollbar-thumb {
        background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #999;
        background-position: center center;
        background-repeat: no-repeat, no-repeat;
        background-size: 50%, 100%;
        transition: 125ms all;
    }

    /* Handle on hover */
    ::-webkit-scrollbar-thumb:hover {
        background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #f9f9f9;
        background-position: center center;
        background-repeat: no-repeat, no-repeat;
        background-size: 50%, 100%;
    }
`

// Inner container for report content
const ReportContainer = styled.div`
    padding: 0.5em 0 0 1em;
    box-sizing: border-box;
    overflow-x: visible;
    // Multi-column layout (NYI)
    // display:flex;
    // flex-direction:column;
    // flex-wrap:wrap;
    // width:500px;
    // columns:${(props) => props.cols} 250px;
    // column-gap:10px;
    // display:inline-block;
    h3 {
        font-size: ${(props) => (props.expanded ? '150%' : '100%')};
        display: ${(props) => (props.expanded ? 'block' : 'inline')};
        margin: ${(props) => (props.expanded ? '0' : '0 15px 0 0')};
        padding: ${(props) => (props.expanded ? '0 0 15px 0 !important' : '0')};
        &:before {
            content: ': ';
            display: ${(props) => (props.expanded ? 'none' : 'initial')};
        }
        &:after {
            content: ' ';
            white-space: pre;
            height: 0;
            display: ${(props) => (props.expanded ? 'none' : 'block')};
        }
    }
    div.numberChartContainer {
        width: 100%;
        display: ${(props) => (props.expanded ? 'flex' : 'inline')};
        align-items: center;
    }
    div.numberContainer {
        display: ${(props) => (props.expanded ? 'flex' : 'inline')};
    }
    .bigOnly {
        display: ${(props) => (props.expanded ? 'initial' : 'none')};
    }
`

// Subsection of report
const ReportSection = styled.span`
    padding-right: 20px;
    box-sizing: border-box;
    // width:100%;
    // display:inline-block;
    padding: 0;
    margin: 0;
`

// // Toggle styling for condensed and expanded drop down
// const ExpandSelect = styled(FormControl)`
//   outline: none;
//   border: none;
//   position: absolute !important;
//   right: 25px;
//   top: 15px;
//   div.MuiInputBase-root:before {
//     display: none !important;
//   }
//   div.MuiInputBase-root:after {
//     display: none !important;
//   }
//   svg {
//     path {
//       fill: white;
//     }
//   }
// `;

/**
 * Data panel renderer component. Derives data from `useGetSidebarData` hook and
 * uses manual component-level selection keys or redux state selection keys if
 * no prop present.
 *
 * @param {Object} props
 * @param {number[]} props.manualSelectionKeys Manual override for selection GEOIDs to use and overwrite redux state
 * @param {boolean} props.manualOpen Manually open the panel and overwrite redux state
 */
function DataPanel({
    manualSelectionKeys = false,
    manualOpen = false,
}) {
    const panelState = useSelector(selectPanelState)
    const panelOpen = manualOpen || panelState.info
    const reduxSelectionKeys = useSelector(selectSelectionKeys)
    const selectionKeys = manualSelectionKeys || reduxSelectionKeys
    const [expanded] = useState(true)
    const sidebarData = useGetSidebarData({
        selectionKeys,
        panelOpen,
    })
    const dates = useSelector(selectDates)
    const dispatch = useDispatch()
    const handleClearSelection = () => dispatch(clearSelection())
    // Set expanded or contracted view
    // const handleExpandContract = (event) => setExpanded(event.target.value);
    return (
        <DataPanelContainer
            className={panelOpen ? 'open' : ''}
            id="data-panel"
            expanded={expanded}
            otherPanels={panelState.variables}
            dataLength={selectionKeys.length}
        >
            {!selectionKeys.length && (
                <ReportWrapper>
                    <ReportContainer expanded={true}>
                        <p>
                            <b>Data Details</b>
                            <br />
                            Click an area for more detailed data.
                        </p>
                    </ReportContainer>
                </ReportWrapper>
            )}
            {/* {!!selectionKeys.length && (
        <ExpandSelect>
          <Select
            labelId="expand-view-label"
            id="expand-view"
            value={null}
            onChange={handleExpandContract}
          >
            <MenuItem value={true}>Expanded</MenuItem>
            <MenuItem value={false}>Compact</MenuItem>
            <MenuItem value={'text'}>Text</MenuItem>
          </Select>
        </ExpandSelect>
      )} */}
            <ReportWrapper>
                {expanded === 'text' && (
                    <ReportContainer>
                        <TextStatistics geoid={selectionKeys[0]} />
                    </ReportContainer>
                )}
                {expanded === true && (
                    <ReportContainer expanded={expanded}>
                        <ReportSection>
                            {sidebarData.name && <h2>{sidebarData.name}</h2>}
                            <br />
                            {sidebarData.name && (
                                <Button
                                    variant="text"
                                    sx={{
                                        textDecoration: 'underline',
                                        maxWidth: 'calc(100% - 1em)',
                                        padding: 0,
                                        textTransform: 'none',
                                        color: 'white',
                                    }}
                                    onClick={handleClearSelection}
                                >
                                    Clear Selection
                                </Button>
                            )}
                            {sidebarData.date && (
                                <>
                                    <h4>{sidebarData.date}</h4>
                                    {sidebarData.population && (
                                        <>
                                            Population{' '}
                                            <h3>
                                                {sidebarData.population?.toLocaleString(
                                                    'en'
                                                )}
                                            </h3>
                                        </>
                                    )}
                                </>
                            )}
                        </ReportSection>
                        {sidebarData.hasOwnProperty('cases') &&
                            sidebarData.hasOwnProperty('deaths') && (
                                <ReportSection>
                                    Total Cases
                                    <div className="numberChartContainer">
                                        <h3>
                                            {sidebarData.cases?.toLocaleString(
                                                'en'
                                            )}
                                        </h3>
                                        {expanded && (
                                            <TwoWeekChart
                                                data={sidebarData.cases14}
                                                schema="cases/deaths"
                                            />
                                        )}

                                        {sidebarData.hasOwnProperty(
                                            'casesIndex'
                                        ) && (
                                            <h6 className="alt-index">
                                                {sidebarData.casesIndex}
                                            </h6>
                                        )}
                                    </div>
                                    Total Deaths
                                    <div className="numberChartContainer">
                                        <h3>
                                            {sidebarData.deaths?.toLocaleString(
                                                'en'
                                            )}
                                        </h3>
                                        {expanded && (
                                            <TwoWeekChart
                                                data={sidebarData.deaths14}
                                                schema="cases/deaths"
                                            />
                                        )}
                                        {sidebarData.hasOwnProperty(
                                            'deathsIndex'
                                        ) && (
                                            <h6 className="alt-index">
                                                {sidebarData.deathsIndex}
                                            </h6>
                                        )}
                                    </div>
                                    <p>7-Day Average of New Cases</p>
                                    <h3>
                                        {sidebarData.cases7d
                                            ?.toFixed(2)
                                            .toLocaleString('en')}
                                    </h3>
                                    <p>
                                        7-Day Average of New Cases per 100k
                                        Population
                                    </p>
                                    <h3>
                                        {sidebarData.cases100k
                                            ?.toFixed(2)
                                            .toLocaleString('en')}
                                    </h3>
                                    <p>7-Day Average New Deaths</p>
                                    <h3>
                                        {sidebarData.deaths7d
                                            ?.toFixed(2)
                                            .toLocaleString('en')}
                                    </h3>
                                    <p>
                                        7-Day Average of New Deaths per 100k
                                        Population
                                    </p>
                                    <h3>
                                        {sidebarData.deaths100k
                                            ?.toFixed(2)
                                            .toLocaleString('en')}
                                    </h3>
                                    <p>Licensed Hospital Beds</p>
                                    <h3>
                                        {sidebarData.beds.toLocaleString('en')}
                                    </h3>
                                </ReportSection>
                            )}
                        {sidebarData.hasOwnProperty('fully_vaccinated') && (
                            <ReportSection>
                                {/* <h2>COVID Vaccination</h2>
                                {sidebarData.hasOwnProperty(
                                    'vaccine_index'
                                ) && (
                                    <h6 className="alt-index">
                                        {dates[sidebarData.vaccine_index]}
                                    </h6>
                                )}
                                <br />
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://covid.cdc.gov/covid-data-tracker/#vaccinations"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        CDC COVID Data Tracker
                                    </a>
                                </h6>
                                <p>
                                    % of Population
                                    <br className="bigOnly" /> Fully Vaccinated
                                </p>
                                <div className="numberChartContainer">
                                    <h3>
                                        {Math.round(
                                            sidebarData.fully_vaccinatedPc *
                                                10000
                                        ) / 100}
                                        %
                                    </h3>
                                    {expanded && (
                                        <TwoWeekChart
                                            data={
                                                sidebarData.fully_vaccinated14
                                            }
                                            schema="vaccination"
                                        />
                                    )}
                                </div>
                                <p>
                                    Total Number
                                    <br className="bigOnly" /> Fully Vaccinated
                                </p>
                                <h3>
                                    {sidebarData?.fully_vaccinated?.toLocaleString(
                                        'en'
                                    )}
                                </h3> */}
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('one_dose') && (
                            <ReportSection>
                                {/* <p>
                                    % of Population
                                    <br className="bigOnly" /> Received At Least
                                    One Dose
                                </p>
                                <div className="numberChartContainer">
                                    <h3>
                                        {(
                                            sidebarData.one_dosePc * 100
                                        )?.toFixed(2)}
                                        %
                                    </h3>
                                    {expanded && (
                                        <TwoWeekChart
                                            data={sidebarData.one_dose14}
                                            schema="vaccination"
                                        />
                                    )}
                                </div>
                                <p>
                                    Total Number
                                    <br className="bigOnly" /> Received At Least
                                    One Dose
                                </p>
                                <h3>
                                    {sidebarData.one_dose?.toLocaleString('en')}
                                </h3>
                                {sidebarData.hasOwnProperty(
                                    'doses_dist100'
                                ) && (
                                    <>
                                        <p>
                                            Doses to be Administered
                                            <br className="bigOnly" /> Per 100
                                            People
                                        </p>
                                        <h3>
                                            {sidebarData.doses_dist100
                                                ?.toFixed(2)
                                                .toLocaleString('en')}
                                        </h3>
                                    </>
                                )} */}
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('testing') && (
                            <ReportSection>
                                {/* <h2>Testing</h2>
                                {sidebarData.hasOwnProperty(
                                    'testing_index'
                                ) && (
                                    <h6 className="alt-index">
                                        {dates[sidebarData.testing_index]}
                                    </h6>
                                )}
                                <br />
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://healthdata.gov/dataset/covid-19-diagnostic-laboratory-testing-pcr-testing-time-series"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        HHS/CDC
                                    </a>
                                </h6>
                                <p>7-Day Positivity Rate</p>
                                <div className="numberChartContainer">
                                    <h3>{Math.round(sidebarData.wk_pos)}%</h3>
                                    {expanded && (
                                        <TwoWeekChart
                                            data={sidebarData.wk_pos14}
                                            schema="testingPos"
                                        />
                                    )}
                                </div>
                                <p>
                                    7-Day Tests Performed{' '}
                                    <br className="bigOnly" /> per 100k People
                                </p>
                                <div className="numberChartContainer">
                                    <h3>{Math.round(sidebarData.tcap)}</h3>
                                    {expanded && (
                                        <TwoWeekChart
                                            data={sidebarData.tcap14}
                                            schema="testingCap"
                                        />
                                    )}
                                </div>
                                <p>Total Testing</p>
                                <h3>{sidebarData.testing}</h3>
                                <p>
                                    7-Day Confirmed Cases
                                    <br className="bigOnly" /> per Testing
                                </p>
                                <h3>
                                    {sidebarData.ccpt.toLocaleString('en')}%
                                </h3> */}
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('PovChldPrc') && (
                            <ReportSection>
                                <h2>
                                    Community Health Factors
                                    <Tooltip id="healthfactor" />
                                </h2>
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://www.countyhealthrankings.org/"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        County Health Rankings
                                    </a>
                                </h6>
                                <p>Children in poverty</p>
                                <Tooltip id="PovChldPrc" />
                                <h3>{sidebarData.PovChldPrc}%</h3>
                                <p>
                                    Income inequality
                                    <Tooltip id="IncRt" />
                                </p>
                                <h3>{sidebarData.IncRt}</h3>
                                <p>Median household income</p>
                                <Tooltip id="MedianHouseholdIncome" />
                                <h3>
                                    $
                                    {sidebarData.MedianHouseholdIncome.toLocaleString(
                                        'en'
                                    )}
                                </h3>
                                <p>Food insecurity</p>
                                <Tooltip id="FdInsPrc" />
                                <h3>{sidebarData.FdInsPrc}%</h3>
                                <p>Unemployment</p>
                                <Tooltip id="UnEmplyPrc" />
                                <h3>{sidebarData.UnEmplyPrc}%</h3>
                                <p>Uninsured</p>
                                <Tooltip id="UnInPrc" />
                                <h3>{sidebarData.UnInPrc}%</h3>
                                <p>Primary care physicians</p>
                                <Tooltip id="PrmPhysRt" />
                                <h3>{sidebarData.PrmPhysRt}:1</h3>
                                <p>Preventable hospital stays</p>
                                <Tooltip id="PrevHospRt" />
                                <h3>{sidebarData.PrevHospRt}</h3>
                                <p>
                                    Residential segregation <br />
                                    black / white
                                </p>
                                <h3>{sidebarData.RsiSgrBlckRt}</h3>
                                <p>Severe housing problems</p>
                                <Tooltip id="SvrHsngPrbRt" />
                                <h3>{sidebarData.SvrHsngPrbRt}%</h3>
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('EssentialPct') && (
                            <ReportSection>
                                <h2>
                                    Essential Workers
                                    <Tooltip id="essentialWorkers" />
                                </h2>
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://www.census.gov/programs-surveys/acs"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        American Community Survey
                                    </a>
                                </h6>
                                <h3>
                                    {Math.round(sidebarData.EssentialPct * 100)}
                                    %
                                </h3>
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('Over65YearsPrc') && (
                            <ReportSection>
                                <h2>
                                    Community Health Context
                                    <Tooltip id="healthcontext" />
                                </h2>
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://www.countyhealthrankings.org/"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        County Health Rankings
                                    </a>
                                </h6>
                                <p>
                                    65 and older
                                    <Tooltip id="Over65YearsPrc" />
                                </p>
                                <h3>{sidebarData.Over65YearsPrc}%</h3>
                                <p>
                                    Adult obesity
                                    <Tooltip id="AdObPrc" />
                                </p>
                                <h3>{sidebarData.AdObPrc}%</h3>
                                <p>
                                    Diabetes prevalence
                                    <Tooltip id="AdDibPrc" />
                                </p>
                                <h3>{sidebarData.AdDibPrc}%</h3>
                                <p>
                                    Adult smoking
                                    <Tooltip id="SmkPrc" />
                                </p>
                                <h3>{sidebarData.SmkPrc}%</h3>
                                <p>
                                    Excessive drinking
                                    <Tooltip id="ExcDrkPrc" />
                                </p>
                                <h3>{sidebarData.ExcDrkPrc}%</h3>
                                <p>
                                    Drug overdose deaths
                                    <Tooltip id="DrOverdMrtRt" />
                                </p>
                                <h3>{sidebarData.DrOverdMrtRt}</h3>
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('LfExpRt') && (
                            <ReportSection expanded={expanded}>
                                <h2>
                                    Length &amp; Quality of Life
                                    <Tooltip id="healthlife" />
                                </h2>
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://www.countyhealthrankings.org/"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        County Health Rankings
                                    </a>
                                </h6>
                                <p>
                                    Life expectancy
                                    <Tooltip id="LfExpRt" />
                                </p>
                                <h3>{sidebarData.LfExpRt}</h3>
                                <p>
                                    Self-rated health
                                    <Tooltip id="SlfHlthPrc" />
                                </p>
                                <h3>{sidebarData.SlfHlthPrc}%</h3>
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('severity_index') && (
                            <ReportSection>
                                <h2>Forecasting</h2>
                                <br />
                                <h6>
                                    Source:{' '}
                                    <a
                                        href="https://github.com/Yu-Group/covid19-severity-prediction/"
                                        target="_blank"
                                        rel="noopener noreferrer"
                                    >
                                        Yu Group at Berkeley
                                    </a>
                                </h6>

                                <p>
                                    5-Day Severity Index
                                    <Tooltip id="SeverityIndex" />
                                </p>
                                <h3>
                                    {' '}
                                    {
                                        ['', 'Low', 'Medium', 'High'][
                                            Math.round(
                                                sidebarData.severity_index
                                            )
                                        ]
                                    }
                                </h3>

                                <p>
                                    Predicted Deaths{' '}
                                    <Tooltip id="PredictedDeaths" />
                                </p>
                                <br />
                                <p>
                                    {sidebarData.predDates[0]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred1 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[1]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred2 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[2]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred3 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[3]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred4 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[4]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred5 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[5]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred6 * 10) / 10}
                                </h3>

                                <p>
                                    {sidebarData.predDates[6]
                                        .split('_')
                                        .slice(1)
                                        .join('-')}
                                </p>
                                <h3>
                                    {Math.round(sidebarData.pred7 * 10) / 10}
                                </h3>
                            </ReportSection>
                        )}
                        {sidebarData.hasOwnProperty('pct_home') && (
                            <ReportSection>
                                <h2>Mobility</h2>
                                {sidebarData.hasOwnProperty(
                                    'mobility_index'
                                ) && (
                                    <h6 className="alt-index">
                                        {dates[sidebarData.mobility_index]}
                                    </h6>
                                )}
                                <br />
                                <p>Percent Completely At Home</p>
                                <div className="numberChartContainer">
                                    <h3>{sidebarData.pct_home}%</h3>
                                </div>
                                <p>Percent Full Time Behavior</p>
                                <div className="numberChartContainer">
                                    <h3>{sidebarData.pct_fulltime}%</h3>
                                </div>
                                <p>Percent Part Time Behavior</p>
                                <div className="numberChartContainer">
                                    <h3>{sidebarData.pct_parttime}%</h3>
                                </div>
                            </ReportSection>
                        )}
                    </ReportContainer>
                )}
            </ReportWrapper>
        </DataPanelContainer>
    )
}

export default DataPanel;