date-fns#parse JavaScript Examples

The following examples show how to use date-fns#parse. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.js    From nyc-makers-vs-covid with GNU General Public License v3.0 7 votes vote down vote up
export function formatDateDistance(date) {
  let deliveryDate = parse(date, 'MM/dd/yyyy', new Date())
  if (isToday(deliveryDate)) {
    return 'Today'
  } else if (isYesterday(deliveryDate)) {
    return 'Yesterday'
  } else {
    return formatDistanceStrict(deliveryDate, startOfToday(), {
      unit: 'day',
      addSuffix: 'true'
    })
  }
}
Example #2
Source File: utils.js    From nyc-makers-vs-covid with GNU General Public License v3.0 6 votes vote down vote up
formatDate = date => {
  let latest = parse(date, 'MM/dd/yyyy', new Date())
  return _formatDate(latest, 'MMMM d, yyyy')
}
Example #3
Source File: utils.js    From nyc-makers-vs-covid with GNU General Public License v3.0 6 votes vote down vote up
export function shouldFormatDateDistance(date) {
  let deliveryDate = parse(date, 'MM/dd/yyyy', new Date())
  let fourDaysFromDeliveryDate = addDays(deliveryDate, 4)
  return isBefore(startOfToday(), fourDaysFromDeliveryDate)
}
Example #4
Source File: common-functions.js    From covid19Nepal-react with MIT License 6 votes vote down vote up
parseTotalTestTimeseries = (data) => {
  const testTimseries = [];
  const today = getNepalDay();
  data.forEach((d) => {
    const date = parse(
      d.updatetimestamp.split(' ')[0],
      'dd/MM/yyyy',
      new Date()
    );
    const totaltested = +d.totalsamplestested;
    if (isBefore(date, today) && totaltested) {
      let dailytested;
      if (testTimseries.length) {
        const prev = testTimseries[testTimseries.length - 1];
        if (isSameDay(date, prev.date)) {
          prev.dailytested += totaltested - prev.totaltested;
          prev.totaltested = totaltested;
        } else {
          if (differenceInDays(date, prev.date) === 1)
            dailytested = totaltested - prev.totaltested;
          else dailytested = NaN;
        }
      } else dailytested = NaN;
      testTimseries.push({
        date: date,
        totaltested: totaltested,
        dailytested: dailytested,
      });
    }
  });
  return testTimseries;
}
Example #5
Source File: common-functions.js    From covid19Nepal-react with MIT License 6 votes vote down vote up
parseStateTestTimeseries = (data) => {
  const stateCodeMap = Object.keys(STATE_CODES).reduce((ret, sc) => {
    ret[STATE_CODES[sc]] = sc;
    return ret;
  }, {});

  const testTimseries = Object.keys(STATE_CODES).reduce((ret, sc) => {
    ret[sc] = [];
    return ret;
  }, {});

  const today = getNepalDay();
  data.forEach((d) => {
    const date = parse(d.updatedon, 'dd/MM/yyyy', new Date());
    const totaltested = +d.totaltested;
    if (isBefore(date, today) && totaltested) {
      const stateCode = stateCodeMap[d.state];
      testTimseries[stateCode].push({
        date: date,
        totaltested: totaltested,
      });
    }
  });
  return testTimseries;
}
Example #6
Source File: common-functions.js    From covid19Nepal-react with MIT License 6 votes vote down vote up
preprocessTimeseries = (timeseries) => {
  return validateCTS(timeseries).map((stat, index) => ({
    date: parse(stat.date, 'dd MMMM', new Date(2020, 0, 1)),
    totalconfirmed: +stat.totalconfirmed,
    totalrecovered: +stat.totalrecovered,
    totaldeceased: +stat.totaldeceased,
    dailyconfirmed: +stat.dailyconfirmed,
    dailyrecovered: +stat.dailyrecovered,
    dailydeceased: +stat.dailydeceased,
    // Active = Confimed - Recovered - Deceased
    totalactive:
      +stat.totalconfirmed - +stat.totalrecovered - +stat.totaldeceased,
    dailyactive:
      +stat.dailyconfirmed - +stat.dailyrecovered - +stat.dailydeceased,
  }));
}
Example #7
Source File: common-functions.js    From covid19Nepal-react with MIT License 6 votes vote down vote up
validateCTS = (data = []) => {
  const dataTypes = [
    'dailyconfirmed',
    'dailydeceased',
    'dailyrecovered',
    'totalconfirmed',
    'totaldeceased',
    'totalrecovered',
  ];
  return data
    .filter((d) => dataTypes.every((dt) => d[dt]) && d.date)
    .filter((d) => dataTypes.every((dt) => Number(d[dt]) >= 0))
    .filter((d) => {
      // Skip data from the current day
      const today = getNepalDay();
      const date = parse(d.date, 'dd MMMM', new Date(2020, 0, 1));
      return isBefore(date, today);
    });
}
Example #8
Source File: DrawLastUpdated.js    From covid19japan with MIT License 5 votes vote down vote up
drawLastUpdated = (lastUpdatedString, currentLanguage) => {
  // Draw the last updated time
  // If this is called before data is loaded, lastUpdated can be null.
  if (!lastUpdatedString) {
    return;
  }

  const display = document.getElementById("last-updated-time");
  if (!display) {
    return;
  }

  let lastUpdated;
  try {
    lastUpdated = parseISO(lastUpdatedString);
    // If the timestamp is not ISO, fall back on the old date format
    // TODO: remove after ISO time format is fully deployed
    if (lastUpdated === "Invalid Date") {
      lastUpdated = parse(
        lastUpdatedString.slice(0, -4),
        TIME_FORMAT,
        new Date()
      );
    }
  } catch (e) {
    // Fall back to raw value on failed parse
    display.textContent = lastUpdatedString;
    return;
  }

  for (const language of LANGUAGES) {
    addRelativeTimeLocalization(lastUpdated, language);
  }

  display.setAttribute("title", lastUpdatedString);
  display.setAttribute("data-i18n", "last-updated-time");
  display.textContent = i18next.getResource(
    currentLanguage,
    "translation",
    "last-updated-time"
  );
}
Example #9
Source File: useDateInput.js    From react-nice-dates with MIT License 5 votes vote down vote up
export default function useDateInput({
  date: selectedDate,
  format: receivedFormatString,
  locale,
  minimumDate,
  maximumDate,
  onDateChange,
  validate
}) {
  const formatString = receivedFormatString || locale.formatLong.date({ width: 'short' })

  const formatDate = date => format(date, formatString, { locale })
  const parseDate = dateString => parse(dateString, formatString, selectedDate || new Date())
  const isValidAndSelectable = date =>
    isValid(date) && isSelectable(date, { minimumDate, maximumDate }) && (!validate || validate(date))

  const [value, setValue] = useState(isValidAndSelectable(selectedDate) ? formatDate(selectedDate) : '')
  const [focused, setFocused] = useState(false)

  const handleFocus = () => {
    setFocused(true)
  }

  const handleChange = event => {
    const newValue = event.target.value
    const parsedDate = parseDate(newValue)
    setValue(newValue)

    if (isValidAndSelectable(parsedDate)) {
      onDateChange(parsedDate)
    }
  }

  const handleBlur = () => {
    if (value) {
      const parsedDate = parseDate(value)

      if (isValidAndSelectable(parsedDate)) {
        setValue(formatDate(parsedDate))
      } else if (isValidAndSelectable(selectedDate)) {
        setValue(formatDate(selectedDate))
      } else {
        setValue('')
      }
    } else if (selectedDate) {
      onDateChange(null)
    }

    setFocused(false)
  }

  useEffect(() => {
    if (!focused) {
      setValue(isValidAndSelectable(selectedDate) ? formatDate(selectedDate) : '')
    }
  }, [selectedDate, focused]) // eslint-disable-line react-hooks/exhaustive-deps

  return {
    onFocus: handleFocus,
    onChange: handleChange,
    onBlur: handleBlur,
    placeholder: formatString.toLowerCase(),
    type: 'text',
    value
  }
}
Example #10
Source File: common-functions.js    From covid19Nepal-react with MIT License 5 votes vote down vote up
parseStateTimeseries = ({states_daily: data}) => {
  const statewiseSeries = Object.keys(STATE_CODES).reduce((a, c) => {
    a[c] = [];
    return a;
  }, {});

  const today = getNepalDay();
  for (let i = 0; i < data.length; i += 3) {
    const date = parse(data[i].date, 'dd-MMM-yy', new Date());
    // Skip data from the current day
    if (isBefore(date, today)) {
      Object.entries(statewiseSeries).forEach(([k, v]) => {
        const stateCode = k.toLowerCase();
        const prev = v[v.length - 1] || {};
        // Parser
        const dailyconfirmed = +data[i][stateCode] || 0;
        const dailyrecovered = +data[i + 1][stateCode] || 0;
        const dailydeceased = +data[i + 2][stateCode] || 0;
        const totalconfirmed = +data[i][stateCode] + (prev.totalconfirmed || 0);
        const totalrecovered =
          +data[i + 1][stateCode] + (prev.totalrecovered || 0);
        const totaldeceased =
          +data[i + 2][stateCode] + (prev.totaldeceased || 0);
        // Push
        v.push({
          date: date,
          dailyconfirmed: dailyconfirmed,
          dailyrecovered: dailyrecovered,
          dailydeceased: dailydeceased,
          totalconfirmed: totalconfirmed,
          totalrecovered: totalrecovered,
          totaldeceased: totaldeceased,
          // Active = Confimed - Recovered - Deceased
          totalactive: totalconfirmed - totalrecovered - totaldeceased,
          dailyactive: dailyconfirmed - dailyrecovered - dailydeceased,
        });
      });
    }
  }

  return statewiseSeries;
}
Example #11
Source File: statemeta.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function StateMeta({
  stateData,
  lastTestObject,
  population,
  lastSevenDaysData,
  totalData,
}) {
  const confirmed = stateData.confirmed;
  const active = stateData.active;
  const deaths = stateData.deaths;
  const recovered = confirmed - active - deaths;
  const sevenDayBeforeData = lastSevenDaysData[0].totalconfirmed;
  const sevenDayBeforeDate = format(lastSevenDaysData[0].date, 'dd MMM');
  const previousDayData = lastSevenDaysData[6].totalconfirmed;
  const previousDayDate = format(lastSevenDaysData[6].date, 'dd MMM');
  const confirmedPerMillion = (confirmed / population) * 1000000;
  const recoveryPercent = (recovered / confirmed) * 100;
  const activePercent = (active / confirmed) * 100;
  const deathPercent = (deaths / confirmed) * 100;
  const testPerMillion = (lastTestObject?.totaltested / population) * 1000000;
  const growthRate =
    ((previousDayData - sevenDayBeforeData) / sevenDayBeforeData) * 100;
  const totalConfirmedPerMillion =
    (totalData[0].confirmed / 1332900000) * 1000000;
  // const doublingRate =
  // growthRate > 0 ? (70 / Math.round(growthRate)).toFixed(2) : 0;

  const updatedDate = !isNaN(
    parse(lastTestObject?.updatedon, 'dd/MM/yyyy', new Date())
  )
    ? `As of ${format(
        parse(lastTestObject?.updatedon, 'dd/MM/yyyy', new Date()),
        'dd MMM'
      )}`
    : '';

  return (
    <React.Fragment>
      <div className="StateMeta population">
        <ReactTooltip
          place="top"
          type="dark"
          effect="solid"
          multiline={true}
          scrollHide={true}
          globalEventOff="click"
          id="stateMeta"
        />
        <div className="meta-item population fadeInUp">
          <h3>Population</h3>
          <h1>{formatNumber(population)}</h1>
        </div>
        <div className="alert">
          <Icon.Compass />
          <div className="alert-right">
            Based on 2019 population projection{' '}
            <a
              href="https://www.citypopulation.de/php/nepal-admin.php"
              target="_noblank"
            >
              report
            </a>
          </div>
        </div>
      </div>

      <div className="StateMeta">
        <StateMetaCard
          className="confirmed"
          title={'Confirmed Per Million'}
          statistic={confirmedPerMillion.toFixed(2)}
          total={totalConfirmedPerMillion.toFixed(2)}
          formula={'(confirmed / state population) * 1 Million'}
          description={`
            ${Math.round(
              confirmedPerMillion
            )} out of every 1 million people in ${
            stateData.state
          } have tested positive for the virus.
            `}
        />

        <StateMetaCard
          className="active"
          title={'Active'}
          statistic={`${activePercent.toFixed(2)}%`}
          formula={'(active / confirmed) * 100'}
          description={`For every 100 confirmed cases, ${activePercent.toFixed(
            0
          )} are currently infected.`}
        />

        <StateMetaCard
          className="recovery"
          title={'Recovery Rate'}
          statistic={`${recoveryPercent.toFixed(2)}%`}
          formula={'(recovered / confirmed) * 100'}
          description={`For every 100 confirmed cases, 
            ${Math.round(
              recoveryPercent.toFixed(0)
            )} have recovered from the virus.`}
        />

        <StateMetaCard
          className="mortality"
          title={'Mortality Rate'}
          statistic={`${deathPercent.toFixed(2)}%`}
          formula={'(deceased / confirmed) * 100'}
          description={`For every 100 confirmed cases, 
            ${Math.round(
              deathPercent.toFixed(0)
            )} have unfortunately passed away from the virus.`}
        />

        <StateMetaCard
          className="gr"
          title={'Avg. Growth Rate'}
          statistic={growthRate > 0 ? `${Math.round(growthRate / 7)}%` : '-'}
          formula={
            '(((previousDayData - sevenDayBeforeData) / sevenDayBeforeData) * 100)/7'
          }
          date={`${sevenDayBeforeDate} - ${previousDayDate}`}
          description={`In the last one week, the number of new infections has grown by an average of ${Math.round(
            growthRate / 7
          )}% every day.`}
        />

        <StateMetaCard
          className="tpm"
          title={'Tests Per Million'}
          statistic={`≈ ${Math.round(testPerMillion)}`}
          formula={
            '(total tests in state / total population of state) * 1 Million'
          }
          date={updatedDate}
          description={`For every 1 million people in ${stateData.state},
            ${Math.round(testPerMillion)} people were tested.`}
        />

        {/* <div className="meta-item ptr fadeInUp">
          <div className="meta-item-top">
            <h3>Positive Test Rate</h3>
            <span
              data-tip={
                'TPM = (total tests in state / total population of state) * 1 Million'
              }
              data-event="touchstart mouseover"
              data-event-off="mouseleave"
              data-for="stateMeta"
            >
              <Icon.Info />
            </span>
          </div>
          <h1>
            {lastTestObject?.testpositivityrate
              ? lastTestObject.testpositivityrate
              : 'N/A'}
          </h1>
          {updatedDate}
          <p>
            {lastTestObject?.testpositivityrate
              ? `Out the of total tests conducted till date month, ${lastTestObject.testpositivityrate}% were positive for the virus`
              : 'N/A'}
          </p>
        </div>*/}

        {/*
          <div className="meta-item dbr fadeInUp">
            <div className="meta-item-top">
              <h3>Doubling Rate</h3>
              <Icon.Info />
            </div>
            <h1>
              {doublingRate > 0 ? Math.round(doublingRate * 7) + ' Days' : '-'}
            </h1>
            <h6 style={{margin: '0'}}>
              {sevenDayBeforeDate} - {previousDayDate}
            </h6>
          </div>
        )*/}
      </div>
    </React.Fragment>
  );
}
Example #12
Source File: state.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function State(props) {
  const stateCode = useParams().stateCode.toUpperCase();
  const stateName = STATE_CODES[stateCode];

  const [allStateData, setAllStateData] = useState({});
  const [fetched, setFetched] = useState(false);
  const [districtZones, setDistrictZones] = useState(null);
  const [timeseries, setTimeseries] = useState({});
  const [stateData, setStateData] = useState(null);
  const [testData, setTestData] = useState({});
  const [sources, setSources] = useState({});
  const [districtData, setDistrictData] = useState({});
  const [mapOption, setMapOption] = useState('confirmed');
  const [mapSwitcher, {width}] = useMeasure();
  const [showAllDistricts, setShowAllDistricts] = useState(false);
  const [regionHighlighted, setRegionHighlighted] = useState({
    state: stateName,
  });

  useEffectOnce(() => {
    getState(stateCode);
  });

  const getState = async (code) => {
    try {
      const [
        {data: dataResponse},
        {data: stateDistrictWiseResponse},
        {data: statesDailyResponse},
        {data: stateTestResponse},
        {data: sourcesResponse},
        {data: zonesResponse},
      ] = await Promise.all([
        axios.get('https://api.nepalcovid19.org/latest_data.json'),
        axios.get('https://api.nepalcovid19.org/state-district-wise.json'),
        axios.get('https://api.nepalcovid19.org/states_daily.json'),
        axios.get('https://api.nepalcovid19.org/state_test_data.json'),
        axios.get('https://api.nepalcovid19.org/sources_list.json'),
        axios.get(`${DATA_DIR}/zones.json`),
      ]);
      const name = STATE_CODES[code];

      const states = dataResponse.statewise;
      setAllStateData(states.filter((state) => state.statecode !== code));
      setStateData([states.find((s) => s.statecode === code)]);
      // Timeseries
      const ts = parseStateTimeseries(statesDailyResponse)[code];
      const testTs = parseStateTestTimeseries(
        stateTestResponse.states_tested_data
      )[code];
      // Merge
      const tsMerged = mergeTimeseries({[code]: ts}, {[code]: testTs});
      setTimeseries(tsMerged[code]);
      // District data
      setDistrictData({
        [name]: stateDistrictWiseResponse[name],
      });
      const sourceList = sourcesResponse.sources_list;
      setSources(sourceList.filter((state) => state.statecode === code));

      const statesTests = stateTestResponse.states_tested_data;
      setTestData(
        statesTests.filter(
          (obj) => obj.state === name && obj.totaltested !== ''
        )
      );

      setDistrictZones(parseDistrictZones(zonesResponse.zones, stateName));

      setFetched(true);
      anime({
        targets: '.highlight',
        duration: 200,
        delay: 3000,
        translateX:
          mapOption === 'confirmed'
            ? `${width * 0}px`
            : mapOption === 'active'
            ? `${width * 0.25}px`
            : mapOption === 'recovered'
            ? `${width * 0.5}px`
            : mapOption === 'deceased'
            ? `${width * 0.75}px`
            : '0px',
        easing: 'spring(1, 80, 90, 10)',
        opacity: 1,
      });
    } catch (err) {
      console.log(err);
    }
  };

  const testObjLast = testData[testData.length - 1];
  const population = STATE_POPULATIONS[stateName];

  function toggleShowAllDistricts() {
    setShowAllDistricts(!showAllDistricts);
  }

  const getGridRowCount = () => {
    const gridColumnCount = window.innerWidth >= 540 ? 3 : 2;
    const districtCount =
      (districtData[stateName] &&
        Object.keys(districtData[stateName].districtData).length) ||
      0;
    const gridRowCount = Math.ceil(districtCount / gridColumnCount);
    return gridRowCount;
  };
  const gridRowCount = getGridRowCount();

  if (!stateName) {
    return <Redirect to="/" />;
  } else {
    return (
      <React.Fragment>
        <Helmet>
          <title>
            Coronavirus Outbreak in {STATE_CODES[stateCode]} - nepalcovid19.org
          </title>
          <meta
            name="title"
            content={`Coronavirus Outbreak in ${STATE_CODES[stateCode]}: Latest Map and Case Count`}
          />
        </Helmet>

        <div className="State">
          <div className="state-left">
            <Breadcrumbs
              stateName={stateName}
              stateCode={stateCode}
              fetched={fetched}
              allStateData={allStateData}
            />

            <div className="header">
              <div
                className="header-left fadeInUp"
                style={{animationDelay: '0.3s'}}
              >
                <h1>{stateName}</h1>
                <h5>
                  Last Updated on{' '}
                  {stateData && Object.keys(stateData[0]).length
                    ? formatDateAbsolute(stateData[0].lastupdatedtime)
                    : ''}
                </h5>
              </div>

              <div
                className="header-right fadeInUp"
                style={{animationDelay: '0.5s'}}
              >
                <h5>Tested</h5>
                <h2>{formatNumber(testObjLast?.totaltested)}</h2>
                <h5 className="timestamp">
                  {!isNaN(
                    parse(testObjLast?.updatedon, 'dd/MM/yyyy', new Date())
                  )
                    ? `As of ${format(
                        parse(testObjLast?.updatedon, 'dd/MM/yyyy', new Date()),
                        'dd MMM'
                      )}`
                    : ''}
                </h5>
                <h5>
                  {'per '}
                  {testObjLast?.totaltested && (
                    <a href={testObjLast.source} target="_noblank">
                      source
                    </a>
                  )}
                </h5>
              </div>
            </div>

            {fetched && (
              <div className="map-switcher" ref={mapSwitcher}>
                <div
                  className={`highlight ${mapOption}`}
                  style={{
                    transform: `translateX(${width * 0}px)`,
                    opacity: 0,
                  }}
                ></div>
                <div
                  className="clickable"
                  onClick={() => {
                    setMapOption('confirmed');
                    anime({
                      targets: '.highlight',
                      translateX: `${width * 0}px`,
                      easing: 'spring(1, 80, 90, 10)',
                    });
                  }}
                ></div>
                <div
                  className="clickable"
                  onClick={() => {
                    setMapOption('active');
                    anime({
                      targets: '.highlight',
                      translateX: `${width * 0.25}px`,
                      easing: 'spring(1, 80, 90, 10)',
                    });
                  }}
                ></div>
                <div
                  className="clickable"
                  onClick={() => {
                    setMapOption('recovered');
                    anime({
                      targets: '.highlight',
                      translateX: `${width * 0.5}px`,
                      easing: 'spring(1, 80, 90, 10)',
                    });
                  }}
                ></div>
                <div
                  className="clickable"
                  onClick={() => {
                    setMapOption('deceased');
                    anime({
                      targets: '.highlight',
                      translateX: `${width * 0.75}px`,
                      easing: 'spring(1, 80, 90, 10)',
                    });
                  }}
                ></div>
              </div>
            )}

            {fetched && <Level data={stateData[0]} />}
            {fetched && <Minigraph timeseries={timeseries} />}
            {fetched && (
              <MapExplorer
                mapName={stateName}
                states={stateData}
                districts={districtData}
                zones={districtZones}
                stateTestData={testData}
                regionHighlighted={regionHighlighted}
                setRegionHighlighted={setRegionHighlighted}
                mapOption={mapOption}
                isCountryLoaded={false}
              />
            )}

            {fetched && (
              <div className="meta-secondary">
                <div className="alert">
                  <Icon.AlertCircle />
                  <div className="alert-right">
                    Awaiting district details for{' '}
                    {districtData[stateName]?.districtData['Unknown']
                      ?.confirmed || '0'}{' '}
                    cases
                  </div>
                </div>
                <div className="alert">
                  <Icon.Compass />
                  <div className="alert-right">
                    Data collected from sources{' '}
                    {sources.length > 0
                      ? Object.keys(sources[0]).map((key, index) => {
                          if (key.match('source') && sources[0][key] !== '') {
                            const num = key.match(/\d+/);
                            return (
                              <React.Fragment key={index}>
                                {num > 1 ? ',' : ''}
                                <a href={sources[0][key]}>{num}</a>
                              </React.Fragment>
                            );
                          }
                          return null;
                        })
                      : ''}
                  </div>
                </div>
              </div>
            )}

            {fetched && (
              <StateMeta
                stateData={stateData[0]}
                lastTestObject={testObjLast}
                population={population}
                lastSevenDaysData={timeseries.slice(-7)}
                totalData={allStateData.filter(
                  (state) => state.statecode === 'TT'
                )}
              />
            )}
          </div>

          <div className="state-right">
            {fetched && (
              <React.Fragment>
                <div
                  className="district-bar"
                  style={!showAllDistricts ? {display: 'flex'} : {}}
                >
                  <div
                    className="district-bar-left fadeInUp"
                    style={{animationDelay: '0.6s'}}
                  >
                    <h2 className={mapOption}>Top districts</h2>
                    <div
                      className={`districts ${
                        showAllDistricts ? 'is-grid' : ''
                      }`}
                      style={
                        showAllDistricts
                          ? {gridTemplateRows: `repeat(${gridRowCount}, 2rem)`}
                          : {}
                      }
                    >
                      {districtData[stateName]
                        ? Object.keys(districtData[stateName].districtData)
                            .filter((d) => d !== 'Unknown')
                            .sort((a, b) => {
                              const districtB =
                                districtData[stateName].districtData[b];
                              const districtA =
                                districtData[stateName].districtData[a];
                              return (
                                districtB[mapOption] - districtA[mapOption]
                              );
                            })
                            .slice(0, showAllDistricts ? undefined : 5)
                            .map((district, index) => {
                              const cases =
                                districtData[stateName].districtData[district];
                              return (
                                <div key={index} className="district">
                                  <h2>{cases[mapOption]}</h2>
                                  <h5>{district}</h5>
                                  {mapOption !== 'active' && (
                                    <div className="delta">
                                      <Icon.ArrowUp className={mapOption} />
                                      <h6 className={mapOption}>
                                        {cases.delta[mapOption]}
                                      </h6>
                                    </div>
                                  )}
                                </div>
                              );
                            })
                        : ''}
                    </div>
                    {districtData[stateName] &&
                      Object.keys(districtData[stateName].districtData).length >
                        5 && (
                        <button
                          className="button"
                          onClick={toggleShowAllDistricts}
                        >
                          {showAllDistricts ? `View less` : `View all`}
                        </button>
                      )}
                  </div>
                  <div className="district-bar-right">
                    {(mapOption === 'confirmed' ||
                      mapOption === 'deceased') && (
                      <div
                        className="happy-sign fadeInUp"
                        style={{animationDelay: '0.6s'}}
                      >
                        {timeseries
                          .slice(-5)
                          .every((day) => day[`daily${mapOption}`] === 0) && (
                          <div
                            className={`alert ${
                              mapOption === 'confirmed' ? 'is-green' : ''
                            }`}
                          >
                            <Icon.Smile />
                            <div className="alert-right">
                              No new {mapOption} cases in the past five days
                            </div>
                          </div>
                        )}
                      </div>
                    )}
                    {
                      <DeltaBarGraph
                        timeseries={timeseries.slice(-5)}
                        arrayKey={`daily${mapOption}`}
                      />
                    }
                  </div>
                </div>

                {false && (
                  <Link to="/essentials">
                    <div
                      className="to-essentials fadeInUp"
                      style={{animationDelay: '0.9s'}}
                    >
                      <h2>Go to essentials</h2>
                      <Icon.ArrowRightCircle />
                    </div>
                  </Link>
                )}

                <TimeSeriesExplorer timeseries={timeseries} />
              </React.Fragment>
            )}
          </div>

          <div className="state-left">
            <div className="Clusters fadeInUp" style={{animationDelay: '0.8s'}}>
              <h1>Network of Transmission</h1>
              <Clusters stateCode={stateCode} />
            </div>
          </div>

          <div className="state-right"></div>
        </div>
        <Footer />
      </React.Fragment>
    );
  }
}
Example #13
Source File: patients.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function Patients(props) {
  const [patients, setPatients] = useState(props.patients);
  const [patient, setPatient] = useState(props.patients.slice(-1));
  const [logs, setLogs] = useState({});
  const [modal, setModal] = useState(false);

  window.onclick = function (event) {
    const modal = document.getElementById('modal');
    if (event.target === modal) {
      setModal(false);
    }
  };

  useEffect(() => {
    setPatients(props.patients);
  }, [props.patients]);

  useEffect(() => {
    if (modal) document.body.classList.add('modal-open');
    else document.body.classList.remove('modal-open');
  }, [modal]);

  const parseByDate = useCallback((patients) => {
    const log = {};
    for (let i = 0; i < patients.length; i++) {
      const day = new Date(
        parse(patients[i].dateannounced, 'dd/MM/yyyy', new Date())
      );
      if (!(day in log)) {
        const list = [];
        list.push(patients[i]);
        log[day] = list;
      } else {
        const list = log[day];
        list.push(patients[i]);
        log[day] = list;
      }
    }
    setLogs(log);
  }, []);

  useEffect(() => {
    if (patients.length) {
      parseByDate(patients);
    }
  }, [parseByDate, patients]);

  const switchPatient = (patientIndexArg) => {
    if (patientIndexArg === '') return;
    try {
      const patientIndex = patientIndexArg.slice(1);
      // eslint-disable-next-line
      patients.map((patient, index) => {
        if (patient.patientnumber === patientIndex) setPatient(patient);
      });
    } catch (err) {
      console.log(err);
    }
  };

  const getClassNameFn = (colorMode) => {
    switch (colorMode) {
      case 'genders':
        return (patient) => {
          return `patient-card ${
            patient.gender === 'F'
              ? 'is-femme'
              : patient.gender === 'M'
              ? 'is-male'
              : ''
          } ${props.expand ? '' : 'is-small'}`;
        };
      case 'transmission':
        return (patient) => {
          return `patient-card ${
            patient.typeoftransmission === 'Local'
              ? 'is-local'
              : patient.typeoftransmission === 'Imported'
              ? 'is-imported'
              : ''
          } ${props.expand ? '' : 'is-small'}`;
        };
      case 'nationality':
        return (patient) => {
          return `patient-card ${
            patient.nationality === 'Nepal'
              ? 'is-np'
              : patient.nationality === 'India'
              ? 'is-in'
              : patient.nationality === 'Myanmar'
              ? 'is-mm'
              : patient.nationality === 'Indonesia'
              ? 'is-id'
              : patient.nationality === 'United Kingdom'
              ? 'is-uk'
              : patient.nationality === 'United States of America'
              ? 'is-us'
              : patient.nationality === 'Thailand'
              ? 'is-th'
              : patient.nationality === 'Phillipines'
              ? 'is-ph'
              : patient.nationality === 'Italy'
              ? 'is-it'
              : patient.nationality === 'Canada'
              ? 'is-ca'
              : ''
          } ${props.expand ? '' : 'is-small'}`;
        };
      case 'age':
        return (patient) => {
          return `patient-card ${props.expand ? '' : 'is-small'}`;
        };
      default:
        return (patient) => {
          return `patient-card ${props.expand ? '' : 'is-small'}`;
        };
    }
  };

  return (
    <React.Fragment>
      <PatientsView
        logs={logs}
        setModal={setModal}
        setPatient={setPatient}
        expand={props.expand}
        applyClass={getClassNameFn(props.colorMode)}
      />

      {modal && (
        <div className="modal" id="modal">
          <div
            className={`modal-content ${modal ? 'fadeInUp' : 'fadeOutDown'}`}
          >
            <div className="close-button">
              <Icon.XCircle
                onClick={() => {
                  setModal(false);
                }}
              />
            </div>

            <div className="modal-top">
              <h1>#{patient.patientnumber}</h1>
            </div>

            <div className="meta">
              <h5>Date Announced</h5>
              <h3>{patient.dateannounced ? patient.dateannounced : '?'}</h3>

              <h5>Contracted from</h5>
              <h3
                className="contracted-from"
                onClick={() => {
                  switchPatient(patient.contractedfromwhichpatientsuspected);
                }}
              >
                {patient.contractedfromwhichpatientsuspected
                  ? patient.contractedfromwhichpatientsuspected
                  : '?'}
              </h3>

              <h5>Detected City</h5>
              <h3>{patient.detectedcity ? patient.detectedcity : '?'}</h3>

              <h5>Detected District</h5>
              <h3>
                {patient.detecteddistrict ? patient.detecteddistrict : '?'}
              </h3>

              <h5>Detected State</h5>
              <h3>{patient.detectedstate ? patient.detectedstate : '?'}</h3>

              <h5>Nationality</h5>
              <h3>{patient.nationality ? patient.nationality : '?'}</h3>

              <h5>Age</h5>
              <h3>{patient.agebracket ? patient.agebracket : '?'}</h3>

              <h5>Gender</h5>
              <h3>{patient.gender ? patient.gender : '?'}</h3>

              <h5>State Patient Number</h5>
              <h3>
                {patient.statepatientnumber ? patient.statepatientnumber : '?'}
              </h3>

              <h5>Type of transmission</h5>
              <h3>
                {patient.typeoftransmission ? patient.typeoftransmission : '?'}
              </h3>
            </div>

            <div className="notes">
              <h5>Notes</h5>
              <h3>{patient.notes}</h3>
            </div>

            <h5>Source 1</h5>
            <div className="link">
              <a href={patient.source1} target="_noblank">
                {patient.source1}
              </a>
            </div>

            <h5>Source 2</h5>
            <div className="link">
              <a href={patient.source2} target="_noblank">
                {patient.source2}
              </a>
            </div>

            <h5>Source 3</h5>
            <div className="link">
              <a href={patient.source3} target="_noblank">
                {patient.source3}
              </a>
            </div>
          </div>
        </div>
      )}
    </React.Fragment>
  );
}
Example #14
Source File: mapexplorer.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function MapExplorer({
  mapName,
  states,
  districts,
  zones,
  stateTestData,
  regionHighlighted,
  setRegionHighlighted,
  anchor,
  setAnchor,
  mapOption,
  setMapOption,
  isCountryLoaded = true,
}) {
  const {t} = useTranslation();
  const [currentMap, setCurrentMap] = useState({
    name: mapName,
    stat: MAP_STATISTICS.TOTAL,
    view:
      MAP_META[mapName].mapType === MAP_TYPES.COUNTRY
        ? MAP_VIEWS.STATES
        : MAP_VIEWS.DISTRICTS,
  });
  const currentMapMeta = MAP_META[currentMap.name];

  const [statistic, currentMapData] = useMemo(() => {
    let currentMapData = {};
    let statistic = {};
    if (currentMap.stat === MAP_STATISTICS.ZONE) {
      const dataTypes = ['Red', 'Orange', 'Green'];
      statistic = dataTypes.reduce((acc, dtype) => {
        acc[dtype] = 0;
        return acc;
      }, {});
      if (currentMapMeta.mapType === MAP_TYPES.COUNTRY) {
        currentMapData = Object.keys(zones).reduce((acc1, state) => {
          acc1[state] = Object.keys(zones[state]).reduce((acc2, district) => {
            const zone = zones[state][district].zone;
            if (zone) {
              acc2[district] = zone;
              statistic[zone] += 1;
            }
            return acc2;
          }, {});
          return acc1;
        }, {});
      } else if (currentMapMeta.mapType === MAP_TYPES.STATE) {
        const state = currentMap.name;
        currentMapData[state] = Object.keys(zones[state]).reduce(
          (acc, district) => {
            const zone = zones[state][district].zone;
            if (zone) {
              acc[district] = zone;
              statistic[zone] += 1;
            }
            return acc;
          },
          {}
        );
      }
    } else {
      const dataTypes = ['confirmed', 'active', 'recovered', 'deceased'];
      statistic = dataTypes.reduce((acc, dtype) => {
        acc[dtype] = {total: 0, max: 0};
        return acc;
      }, {});
      if (currentMapMeta.mapType === MAP_TYPES.COUNTRY) {
        currentMapData = states.reduce((acc, state) => {
          acc[state.state] = {};
          dataTypes.forEach((dtype) => {
            let typeCount = parseInt(
              state[dtype !== 'deceased' ? dtype : 'deaths']
            );
            if (currentMap.stat === MAP_STATISTICS.PER_MILLION)
              typeCount = (1e6 * typeCount) / STATE_POPULATIONS[state.state];
            if (state.state !== 'Total') {
              statistic[dtype].total += typeCount;
              if (typeCount > statistic[dtype].max) {
                statistic[dtype].max = typeCount;
              }
            }
            acc[state.state][dtype] = typeCount;
          });
          return acc;
        }, {});
      } else if (currentMapMeta.mapType === MAP_TYPES.STATE) {
        const districtWiseData = (
          districts[currentMap.name] || {districtData: {}}
        ).districtData;
        currentMapData[currentMap.name] = Object.keys(districtWiseData).reduce(
          (acc, district) => {
            acc[district] = {};
            dataTypes.forEach((dtype) => {
              const typeCount = parseInt(districtWiseData[district][dtype]);
              statistic[dtype].total += typeCount;
              if (typeCount > statistic[dtype].max) {
                statistic[dtype].max = typeCount;
              }
              acc[district][dtype] = typeCount;
            });
            return acc;
          },
          {}
        );
        currentMapData[currentMap.name].Total = states.find(
          (state) => currentMap.name === state.state
        );
      }
    }
    return [statistic, currentMapData];
  }, [
    currentMap.name,
    currentMap.stat,
    currentMapMeta.mapType,
    districts,
    zones,
    states,
  ]);

  const [hoveredRegion, panelRegion] = useMemo(() => {
    if (!regionHighlighted.district) {
      const state = getRegionFromState(
        states.find((state) => regionHighlighted.state === state.state)
      );
      return [state, state];
    } else {
      const stateDistrictObj = districts[regionHighlighted.state] || {
        districtData: {},
      };
      const districtData = stateDistrictObj.districtData[
        regionHighlighted.district
      ] || {
        confirmed: 0,
        active: 0,
        recovered: 0,
        deaths: 0,
      };
      const district = getRegionFromDistrict(
        districtData,
        regionHighlighted.district
      );
      let state = getRegionFromState(
        states.find((state) => state.state === regionHighlighted.state)
      );
      district.district = regionHighlighted.district;
      district.state = state.state;
      if (currentMapMeta.mapType === MAP_TYPES.COUNTRY)
        state = states.find((state) => state.state === 'Total');
      return [district, state];
    }
  }, [states, districts, currentMapMeta.mapType, regionHighlighted]);

  useEffect(() => {
    if (regionHighlighted === undefined || regionHighlighted === null) return;

    if ('district' in regionHighlighted) {
      if (
        currentMap.name !== regionHighlighted.state &&
        !(
          currentMapMeta.mapType === MAP_TYPES.COUNTRY &&
          currentMap.view === MAP_VIEWS.DISTRICTS
        )
      ) {
        const state = regionHighlighted.state;
        const newMapMeta = MAP_META[state];
        if (!newMapMeta) {
          return;
        }
        setCurrentMap({
          name: state,
          view: MAP_VIEWS.DISTRICTS,
          stat:
            currentMap.stat === MAP_STATISTICS.PER_MILLION
              ? MAP_STATISTICS.TOTAL
              : currentMap.stat,
        });
      }
    } else if (isCountryLoaded && currentMapMeta.mapType === MAP_TYPES.STATE) {
      setCurrentMap({
        name: 'Nepal',
        view:
          currentMap.stat === MAP_STATISTICS.ZONE
            ? MAP_VIEWS.DISTRICTS
            : MAP_VIEWS.STATES,
        stat: currentMap.stat,
      });
    }
  }, [isCountryLoaded, regionHighlighted, currentMap, currentMapMeta.mapType]);

  const switchMapToState = useCallback(
    (state) => {
      const newMapMeta = MAP_META[state];
      if (!newMapMeta) {
        return;
      }
      if (newMapMeta.mapType === MAP_TYPES.STATE) {
        const {districtData} = districts[state] || {
          districtData: {},
        };
        const topDistrict = Object.keys(districtData)
          .filter((state) => state !== 'Unknown')
          .sort((a, b) => {
            return districtData[b].confirmed - districtData[a].confirmed;
          })[0];
        ReactDOM.unstable_batchedUpdates(() => {
          setRegionHighlighted({
            district: topDistrict,
            state: state,
          });
          setCurrentMap({
            name: state,
            view: MAP_VIEWS.DISTRICTS,
            stat:
              currentMap.stat === MAP_STATISTICS.PER_MILLION
                ? MAP_STATISTICS.TOTAL
                : currentMap.stat,
          });
        });
      } else {
        ReactDOM.unstable_batchedUpdates(() => {
          setCurrentMap({
            name: 'Nepal',
            view:
              currentMap.stat === MAP_STATISTICS.ZONE
                ? MAP_VIEWS.DISTRICTS
                : MAP_VIEWS.STATES,
            stat: currentMap.stat,
          });
          setRegionHighlighted({
            state: 'Total',
          });
        });
      }
    },
    [currentMap.stat, districts, setRegionHighlighted]
  );

  const testObj = useMemo(
    () =>
      stateTestData.find(
        (obj) => obj.state === panelRegion.state && obj.totaltested !== ''
      ),
    [stateTestData, panelRegion]
  );

  let hoveredRegionCount;
  let hoveredRegionZone;
  if (currentMap.stat !== MAP_STATISTICS.ZONE) {
    const data =
      hoveredRegion.district && currentMapData[hoveredRegion.state]
        ? currentMapData[hoveredRegion.state][hoveredRegion.district]
        : hoveredRegion.state !== currentMap.name
        ? currentMapData[hoveredRegion.state]
        : currentMapData[hoveredRegion.state].Total;
    hoveredRegionCount = data
      ? currentMap.stat === MAP_STATISTICS.PER_MILLION
        ? Number(parseFloat(data[mapOption]).toFixed(2))
        : data[mapOption]
      : 0;
  } else {
    hoveredRegionZone =
      zones[hoveredRegion.state] &&
      zones[hoveredRegion.state][hoveredRegion.district]
        ? zones[hoveredRegion.state][hoveredRegion.district].zone
        : '';
  }

  return (
    <div
      className={`MapExplorer fadeInUp ${
        anchor === 'mapexplorer' ? 'stickied' : ''
      }`}
      style={{
        animationDelay: '1.5s',
        display: anchor === 'timeseries' ? 'none' : '',
      }}
    >
      {window.innerWidth > 769 && (
        <div
          className={`anchor ${anchor === 'mapexplorer' ? 'stickied' : ''}`}
          onClick={() => {
            setAnchor(anchor === 'mapexplorer' ? null : 'mapexplorer');
          }}
        >
          <Icon.Anchor />
        </div>
      )}
      <div className="header">
        <h1>
          {t(currentMap.name)} {t('Map')}
        </h1>
        <h6>
          {window.innerWidth <= 769 ? t('Tap') : t('Hover')} over a{' '}
          {currentMapMeta.mapType === MAP_TYPES.COUNTRY
            ? t('state/UT')
            : t('district')}{' '}
          {t('for more details')}
        </h6>
      </div>

      <div className="map-stats">
        <div
          className={`stats fadeInUp ${
            mapOption === 'confirmed' ? 'focused' : ''
          }`}
          style={{animationDelay: '2s'}}
          onClick={() => setMapOption('confirmed')}
        >
          <h5>{window.innerWidth <= 769 ? t('Cnfmd') : t('Confirmed')}</h5>
          <div className="stats-bottom">
            <h1>{formatNumber(panelRegion.confirmed)}</h1>
            <h6>{`+${formatNumber(panelRegion.deltaconfirmed)}`}</h6>
          </div>
        </div>

        <div
          className={`stats is-blue fadeInUp ${
            mapOption === 'active' ? 'focused' : ''
          }`}
          style={{animationDelay: '2.1s'}}
          onClick={() => setMapOption('active')}
        >
          <h5>{window.innerWidth <= 769 ? t('Actv') : t('Active')}</h5>
          <div className="stats-bottom">
            <h1>{formatNumber(panelRegion.active)}</h1>
            <h6>{` `}</h6>
          </div>
        </div>

        <div
          className={`stats is-green fadeInUp ${
            mapOption === 'recovered' ? 'focused' : ''
          }`}
          style={{animationDelay: '2.2s'}}
          onClick={() => setMapOption('recovered')}
        >
          <h5>{window.innerWidth <= 769 ? t('Rcvrd') : t('Recovered')}</h5>
          <div className="stats-bottom">
            <h1>{formatNumber(panelRegion.recovered)}</h1>
            <h6>{`+${formatNumber(panelRegion.deltarecovered)}`}</h6>
          </div>
        </div>

        <div
          className={`stats is-gray fadeInUp ${
            mapOption === 'deceased' ? 'focused' : ''
          }`}
          style={{animationDelay: '2.3s'}}
          onClick={() => setMapOption('deceased')}
        >
          <h5>{window.innerWidth <= 769 ? t('Dcsd') : t('Deceased')}</h5>
          <div className="stats-bottom">
            <h1>{formatNumber(panelRegion.deaths)}</h1>
            <h6>{`+${formatNumber(panelRegion.deltadeaths)}`}</h6>
          </div>
        </div>

        <div
          className="stats is-purple tested fadeInUp"
          style={{animationDelay: '2.4s'}}
        >
          <h5>{t('Tested')}</h5>
          <div className="stats-bottom">
            <h1>{formatNumber(testObj?.totaltested)}</h1>
          </div>
          <h6 className="timestamp">
            {!isNaN(parse(testObj?.updatedon, 'dd/MM/yyyy', new Date()))
              ? `${t('As of')} ${format(
                  parse(testObj?.updatedon, 'dd/MM/yyyy', new Date()),
                  'dd MMM'
                )}`
              : ''}
          </h6>
          {testObj?.totaltested?.length > 1 && (
            <a href={testObj.source} target="_noblank">
              <Icon.Link />
            </a>
          )}
          {panelRegion.state === 'Total' ? testedToolTip : ''}
        </div>
      </div>

      <div className="meta fadeInUp" style={{animationDelay: '2.4s'}}>
        <h2
          className={`${
            currentMap.stat !== MAP_STATISTICS.ZONE
              ? mapOption !== 'confirmed'
                ? mapOption
                : ''
              : hoveredRegionZone
          }`}
        >
          {hoveredRegion.district
            ? t(hoveredRegion.district)
            : t(hoveredRegion.state)}
        </h2>

        {currentMapMeta.mapType !== MAP_TYPES.STATE &&
          panelRegion.lastupdatedtime && (
            <div className="last-update">
              <h6>{t('Last updated')}</h6>
              <h3>
                {isNaN(Date.parse(formatDate(panelRegion.lastupdatedtime)))
                  ? ''
                  : formatDistance(
                      new Date(formatDate(panelRegion.lastupdatedtime)),
                      new Date()
                    ) +
                    ' ' +
                    t('ago')}
              </h3>
            </div>
          )}

        {currentMapMeta.mapType === MAP_TYPES.STATE ? (
          <Link to={`state/${STATE_CODES_REVERSE[panelRegion.state]}`}>
            <div className="button state-page-button">
              <abbr>{t('Visit state page')}</abbr>
              <Icon.ArrowRightCircle />
            </div>
          </Link>
        ) : null}

        {currentMap.stat !== MAP_STATISTICS.ZONE &&
        (currentMapMeta.mapType === MAP_TYPES.STATE ||
          (currentMapMeta.mapType === MAP_TYPES.COUNTRY &&
            currentMap.stat !== MAP_STATISTICS.TOTAL)) ? (
          <h1
            className={`district ${mapOption !== 'confirmed' ? mapOption : ''}`}
          >
            {hoveredRegionCount}
            <br />
            <span>
              {mapOption}{' '}
              {currentMap.stat === MAP_STATISTICS.PER_MILLION
                ? ` ${t('per million')}`
                : ''}
            </span>
          </h1>
        ) : null}

        {currentMapMeta.mapType === MAP_TYPES.STATE ? (
          <div
            className="button back-button"
            onClick={() => switchMapToState('Nepal')}
          >
            Back
          </div>
        ) : null}

        {currentMapMeta.mapType === MAP_TYPES.STATE &&
        currentMapData.Unknown &&
        currentMapData.Unknown[mapOption] > 0 ? (
          <h4 className="unknown">
            {t('Districts unknown for')} {currentMapData.Unknown[mapOption]}{' '}
            {t('people')}
          </h4>
        ) : null}
      </div>

      <div>
        {mapOption && (
          <ChoroplethMap
            statistic={statistic}
            currentMap={currentMap}
            mapData={currentMapData}
            regionHighlighted={regionHighlighted}
            setRegionHighlighted={setRegionHighlighted}
            changeMap={switchMapToState}
            isCountryLoaded={isCountryLoaded}
            mapOption={mapOption}
          />
        )}
      </div>

      <div className="tabs-map">
        <div
          className={`tab ${
            currentMap.stat === MAP_STATISTICS.TOTAL ? 'focused' : ''
          }`}
          onClick={() => {
            setCurrentMap({
              name: currentMap.name,
              view:
                currentMapMeta.mapType === MAP_TYPES.COUNTRY
                  ? MAP_VIEWS.STATES
                  : MAP_VIEWS.DISTRICTS,
              stat: MAP_STATISTICS.TOTAL,
            });
            if (currentMapMeta.mapType === MAP_TYPES.COUNTRY)
              setRegionHighlighted({
                state: regionHighlighted.state,
              });
          }}
        >
          <h4>{t('Total Cases')}</h4>
        </div>
        {isCountryLoaded && (
          <div
            className={`tab ${
              currentMap.stat === MAP_STATISTICS.PER_MILLION ? 'focused' : ''
            }`}
            onClick={() => {
              if (currentMapMeta.mapType === MAP_TYPES.STATE) return;
              setCurrentMap({
                name: currentMap.name,
                view: MAP_VIEWS.STATES,
                stat: MAP_STATISTICS.PER_MILLION,
              });
              setRegionHighlighted({
                state: regionHighlighted.state,
              });
            }}
          >
            <h4>
              {t('Cases per million')}
              <sup>&dagger;</sup>
            </h4>
          </div>
        )}
        {/* <div
          className={`tab ${
            currentMap.stat === MAP_STATISTICS.ZONE ? 'focused' : ''
          }`}
          onClick={() => {
            setCurrentMap({
              name: currentMap.name,
              view: MAP_VIEWS.DISTRICTS,
              stat: MAP_STATISTICS.ZONE,
            });
            if (currentMapMeta.mapType === MAP_TYPES.COUNTRY)
              setRegionHighlighted({
                state: 'Total',
              });
          }}
        >
          <h4>Zones</h4>
        </div> */}
      </div>

      <h6 className="footnote table-fineprint">
        &dagger; {t('Based on 2019 population projection') + '('}
        <a
          href="https://www.citypopulation.de/php/nepal-admin.php"
          target="_noblank"
          style={{color: '#6c757d'}}
        >
          {t('report')}
        </a>
        )
      </h6>
    </div>
  );
}
Example #15
Source File: totalconfirmedchart.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function TotalConfirmedChart(props) {
  const dates = [];
  const confirmed = [];
  const recovered = [];
  const deceased = [];

  if (!props.timeseries || props.timeseries.length === 0) {
    return <div></div>;
  }

  props.timeseries.forEach((data, index) => {
    if (index >= 31) {
      const date = parse(data.date, 'dd MMMM', new Date(2020, 0, 1));
      dates.push(date);
      confirmed.push(data.totalconfirmed);
      recovered.push(data.totalrecovered);
      deceased.push(data.totaldeceased);
    }
  });

  const dataset = {
    labels: dates,
    datasets: [
      {
        borderWidth: 2,
        data: confirmed,
        borderCapStyle: 'round',
        pointBackgroundColor: '#ff6862',
        label: 'Confirmed',
        borderColor: '#ff6862',
        pointHoverRadius: 2,
      },
      {
        borderWidth: 2,
        data: recovered,
        borderCapStyle: 'round',
        pointBackgroundColor: '#7ebf80',
        label: 'Recovered',
        borderColor: '#7ebf80',
        pointHoverRadius: 2,
      },
      {
        borderWidth: 2,
        data: deceased,
        borderCapStyle: 'round',
        pointBackgroundColor: '#6c757d',
        label: 'Deceased',
        borderColor: '#6c757d',
        pointHoverRadius: 2,
      },
    ],
  };

  const options = deepmerge(defaultOptions, {
    elements: {
      point: {
        radius: 0,
      },
      line: {
        tension: 0.1,
      },
    },
    scales: {
      yAxes: [
        deepmerge(yAxisDefaults, {
          scaleLabel: {
            display: false,
            labelString: 'Total Cases',
          },
        }),
      ],
      xAxes: [
        deepmerge(xAxisDefaults, {
          type: 'time',
          time: {
            unit: 'day',
            tooltipFormat: 'MMM DD',
            stepSize: 7,
            displayFormats: {
              millisecond: 'MMM DD',
              second: 'MMM DD',
              minute: 'MMM DD',
              hour: 'MMM DD',
              day: 'MMM DD',
              week: 'MMM DD',
              month: 'MMM DD',
              quarter: 'MMM DD',
              year: 'MMM DD',
            },
          },
        }),
      ],
    },
  });

  if (props.mode) {
    options.scales.yAxes = [
      {
        type: 'logarithmic',
        ticks: {
          min: 0,
          max: 10000,
          callback: function (value, index, values) {
            if (value === 10000) return '10000';
            if (value === 2000) return '2500';
            if (value === 500) return '500';
            if (value === 100) return '100';
            if (value === 20) return '25';
            if (value === 5) return '5';
            if (value === 0) return '0';
            return null;
          },
        },
        scaleLabel: {
          display: false,
          labelString: 'Total Cases',
        },
      },
    ];
  }

  return (
    <div className="charts-header">
      <div className="chart-title">{props.title}</div>
      <div className="chart-content">
        <Line data={dataset} options={options} />
      </div>
    </div>
  );
}
Example #16
Source File: growthtrendchart.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function GrowthTrendChart(props) {
  const dates = [];

  defaults.global.elements.line.fill = false;

  defaults.global.tooltips.intersect = false;
  defaults.global.tooltips.mode = 'nearest';
  defaults.global.tooltips.position = 'average';
  defaults.global.tooltips.backgroundColor = 'rgba(255, 255, 255, 0.6)';
  defaults.global.tooltips.displayColors = false;
  defaults.global.tooltips.borderColor = '#c62828';
  defaults.global.tooltips.borderWidth = 1;
  defaults.global.tooltips.titleFontColor = '#000';
  defaults.global.tooltips.bodyFontColor = '#000';
  defaults.global.tooltips.caretPadding = 4;
  defaults.global.tooltips.intersect = false;
  defaults.global.tooltips.mode = 'nearest';
  defaults.global.tooltips.position = 'nearest';

  defaults.global.legend.display = true;
  defaults.global.legend.position = 'bottom';

  defaults.global.hover.intersect = false;

  if (!props.data || props.data.length === 0) {
    return <div></div>;
  }

  const statesData = new Map();
  const statesDailyData = new Map();

  props.data.forEach((data, index) => {
    if (data.status !== 'Confirmed') {
      return;
    }

    Object.keys(data).forEach((key) => {
      if (key === 'date') {
        const date = parse(data.date, 'dd-MMM-yy', new Date());
        dates.push(date);
      }

      if (key === 'status' || key === 'date') {
        return;
      }

      const currentValue = data[key] !== '' ? parseInt(data[key]) : 0;

      if (currentValue === 0 && !statesData.has(key)) {
        return;
      }

      if (!statesData.has(key)) {
        statesData.set(key, []);
        statesDailyData.set(key, []);
      }
      const previousValue =
        statesData.get(key).length > 0
          ? parseInt(statesData.get(key)[statesData.get(key).length - 1].x)
          : 0;

      const stateData = statesDailyData.get(key);
      let weekSum = 0;
      for (let i = 1; i <= 7; ++i) {
        const idx = stateData.length - i;
        if (idx >= 0) {
          weekSum += stateData[idx];
        }
      }
      statesData.get(key).push({x: previousValue + currentValue, y: weekSum});
      statesDailyData.get(key).push(currentValue);
    });
  });

  const sortedMap = new Map(
    [...statesData.entries()].sort((a, b) => {
      return a[1][a[1].length - 1].x < b[1][b[1].length - 1].x ? 1 : -1;
    })
  );

  const colors = [
    '#ff073a',
    '#28a745',
    '#342ead',
    '#7D5BA6',
    '#DD7596',
    '#16c8f0',
    '#f67575',
    '#2b580c',
    '#9D44B5',
    '#91132d',
    '#6D9DC5',
    '#2b580c',
    '#6c757d',
    '#f67575',
    '#d4f8e8',
  ];

  let index = 0;
  const datasets = [];
  sortedMap.forEach((data, key) => {
    if (key === 'tt') {
      return;
    }

    if (index >= 10) {
      return;
    }

    datasets.push({
      data: statesData.get(key),
      label: getStateName(key),
      order: index,
      borderWidth: 1.0,
      borderCapStyle: 'round',
      borderColor: colors[index],
      pointBackgroundColor: colors[index],
      pointHoverRadius: 1.0,
    });

    index++;
  });

  const dataset = {
    datasets: datasets,
  };

  const options = {
    responsive: true,
    events: ['click', 'mousemove', 'mouseout', 'touchstart', 'touchmove'],
    maintainAspectRatio: false,
    tooltips: {
      mode: 'index',
      backgroundColor: 'rgba(0, 0, 0, 0.9)',
      borderColor: 'rgba(0, 0, 0, 0)',
      bodyFontColor: 'white',
      titleFontColor: 'white',
      displayColors: true,
    },
    elements: {
      point: {
        radius: 0,
      },
      line: {
        cubicInterpolationMode: 'monotone',
      },
    },
    layout: {
      padding: {
        left: 20,
        right: 20,
        top: 0,
        bottom: 20,
      },
    },
    scales: {
      yAxes: [
        {
          type: 'logarithmic',
          ticks: {
            beginAtZero: true,
            min: 1,
            max: 2000,
            precision: 0,
            callback: function (value, index, values) {
              return Number(value.toString());
            },
          },
          scaleLabel: {
            display: true,
            labelString: 'New Cases (since last 7 days)',
          },
          gridLines: {
            color: 'rgba(0, 0, 0, 0)',
          },
        },
      ],
      xAxes: [
        {
          type: 'logarithmic',
          ticks: {
            beginAtZero: true,
            min: 0,
            max: 2000,
            precision: 0,
            callback: function (value, index, values) {
              return Number(value.toString());
            },
          },
          scaleLabel: {
            display: true,
            labelString: 'Total Cases',
          },
          gridLines: {
            color: 'rgba(0, 0, 0, 0)',
          },
        },
      ],
    },
  };

  return (
    <div className="charts-header">
      <div className="chart-title">{props.title}</div>
      <div className="chart-content">
        <Line data={dataset} options={options} />
      </div>
    </div>
  );
}
Example #17
Source File: dailyconfirmedchart.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function DailyConfirmedChart(props) {
  const dates = [];
  const confirmed = [];
  const recovered = [];
  const deceased = [];

  if (!props.timeseries || props.timeseries.length === 0) {
    return <div></div>;
  }

  props.timeseries.forEach((data, index) => {
    if (index >= 31) {
      const date = parse(data.date, 'dd MMMM', new Date(2020, 0, 1));
      dates.push(format(date, 'dd MMM'));
      confirmed.push(data.dailyconfirmed);
      recovered.push(data.dailyrecovered);
      deceased.push(data.dailydeceased);
    }
  });

  const barDataSet = {
    labels: dates,
    datasets: [
      {
        data: recovered,
        label: 'Recovered',
        backgroundColor: '#7ebf80',
      },
      {
        data: deceased,
        label: 'Deceased',
        backgroundColor: '#6c757d',
      },
      {
        data: confirmed,
        label: 'Confirmed',
        backgroundColor: '#ff6862',
      },
    ],
  };

  const options = deepmerge(defaultOptions, {
    tooltips: {
      mode: 'index',
    },
    legend: {
      display: true,
      reverse: true,
      labels: {
        usePointStyle: true, // Required to change pointstyle to 'rectRounded' from 'circle'
        generateLabels: (chart) => {
          const labels = defaults.global.legend.labels.generateLabels(chart);
          labels.forEach((label) => {
            label.pointStyle = 'rectRounded';
          });
          return labels;
        },
      },
    },
    scales: {
      xAxes: [
        deepmerge(xAxisDefaults, {
          stacked: true,
        }),
      ],
      yAxes: [
        deepmerge(yAxisDefaults, {
          stacked: true,
          ticks: {
            callback: (value) => formatNumber(value),
          },
        }),
      ],
    },
  });

  return (
    <div className="charts-header">
      <div className="chart-title">{props.title}</div>
      <div className="chart-content">
        <Bar data={barDataSet} options={options} />
      </div>
    </div>
  );
}
Example #18
Source File: allstates.js    From covid19Nepal-react with MIT License 4 votes vote down vote up
function AllStatesChart(props) {
  const dates = [];
  const chartReference = React.createRef();

  if (!props.data || props.data.length === 0) {
    return <div></div>;
  }

  const statesData = new Map();

  props.data.forEach((data) => {
    if (data.status !== 'Confirmed') {
      return;
    }

    Object.keys(data).forEach((key) => {
      if (key === 'date') {
        const date = parse(data.date, 'dd-MMM-yy', new Date());
        dates.push(date);
      }

      if (key === 'status' || key === 'date') {
        return;
      }

      if (!statesData.has(key)) {
        statesData.set(key, []);
      }
      const previousValue =
        statesData.get(key).length > 0
          ? parseInt(statesData.get(key)[statesData.get(key).length - 1])
          : 0;
      const currentValue = data[key] !== '' ? parseInt(data[key]) : 0;
      statesData.get(key).push(previousValue + currentValue);
    });
  });

  const sortedMap = new Map(
    [...statesData.entries()].sort((a, b) => {
      return a[1][a[1].length - 1] < b[1][b[1].length - 1] ? 1 : -1;
    })
  );

  const colors = [
    '#718af0',
    '#7dd6fa',
    '#59b3aa',
    '#9bc26b',
    '#e5d22f',
    '#ffb041',
    '#ff8a66',
    '#db6b8f',
    '#bd66cc',
    '#8e8e8e',
  ];

  let index = 0;
  const datasets = [];
  sortedMap.forEach((data, key) => {
    if (key === 'tt') {
      return;
    }

    if (index >= 10) {
      return;
    }

    datasets.push({
      borderWidth: 2,
      data: statesData.get(key),
      borderCapStyle: 'round',
      pointBackgroundColor: colors[index],
      label: getStateName(key),
      borderColor: colors[index],
      pointHoverRadius: 0.5,
    });

    index++;
  });

  const dataset = {
    labels: dates,
    datasets: datasets,
  };

  const options = deepmerge(defaultOptions, {
    tooltips: {
      mode: 'index',
    },
    elements: {
      point: {
        radius: 0,
      },
      line: {
        tension: 0,
      },
    },
    legend: {
      labels: {
        boxWidth: 20,
        fontSize: 11,
      },
    },
    scales: {
      yAxes: [
        deepmerge(yAxisDefaults, {
          type: 'linear',
          ticks: {
            beginAtZero: true,
            max: undefined,
            precision: 0,
          },
          scaleLabel: {
            display: false,
            labelString: 'Total Cases',
          },
        }),
      ],
      xAxes: [
        deepmerge(xAxisDefaults, {
          type: 'time',
          time: {
            unit: 'day',
            tooltipFormat: 'MMM DD',
            stepSize: 7,
            displayFormats: {
              millisecond: 'MMM DD',
              second: 'MMM DD',
              minute: 'MMM DD',
              hour: 'MMM DD',
              day: 'MMM DD',
              week: 'MMM DD',
              month: 'MMM DD',
              quarter: 'MMM DD',
              year: 'MMM DD',
            },
          },
          gridLines: {
            color: 'rgba(0, 0, 0, 0)',
          },
        }),
      ],
    },
  });

  function toggleSelection() {
    // Get reference of chartInstance and update it
    const ci = chartReference.current.chartInstance;
    for (let i = 0; i < ci.data.datasets.length; i++) {
      const meta = ci.getDatasetMeta(i);
      meta.hidden =
        meta.hidden === null
          ? !chartReference.current.chartInstance.data.datasets[i].hidden
          : null;
    }
    ci.update();
  }

  return (
    <div className="charts-header">
      <div className="chart-title">{props.title}</div>
      <div className="chart-content">
        <Line data={dataset} options={options} ref={chartReference} />
      </div>
      <div className="chart-note" style={{marginTop: '0px', height: '30px'}}>
        <button onClick={toggleSelection}>Toggle Selection</button>
      </div>
    </div>
  );
}