Ver código fonte

Pad data with zeroes to avoid discontinuities

Fela Maslen 5 anos atrás
pai
commit
5802d84ba0
3 arquivos alterados com 49 adições e 4 exclusões
  1. 8 0
      src/components/graph-cases.tsx
  2. 4 2
      src/types.ts
  3. 37 2
      src/utils/regression.ts

+ 8 - 0
src/components/graph-cases.tsx

@@ -40,6 +40,14 @@ const GraphCases: React.FC<Props> = ({ countries }) => {
     showCumulative,
   ]);
 
+  if (!data.length) {
+    return (
+      <div>
+        <h3>No data!</h3>
+      </div>
+    );
+  }
+
   return (
     <div>
       <>

+ 4 - 2
src/types.ts

@@ -20,10 +20,12 @@ export type Countries = {
   color: string;
 }[];
 
-export type CountryCases = {
+export type CountryCase = {
   country: Country;
   dataSource: DataSource;
-}[];
+};
+
+export type CountryCases = CountryCase[];
 
 type XPoint = {
   date: Date;

+ 37 - 2
src/utils/regression.ts

@@ -3,7 +3,7 @@ import groupBy from 'lodash/groupBy';
 import flatten from 'lodash/flatten';
 import differenceInDays from 'date-fns/differenceInDays';
 import addDays from 'date-fns/addDays';
-import { Cases, Data, DataPoint, CountryCases, CountryDataPoint } from '../types';
+import { Cases, Data, DataPoint, CountryCase, CountryCases, CountryDataPoint } from '../types';
 
 // Start the regression line after this many cases have been recorded in total
 const regressionStart = 50;
@@ -145,8 +145,43 @@ function combineData(items: Data[]): Data {
     );
 }
 
+function fillData(countryCases: CountryCases): CountryCases {
+  const times: number[] = Array.from(
+    new Set(
+      flatten(
+        countryCases.map(({ dataSource: { cases } }) => cases.map(({ date }) => date.getTime())),
+      ),
+    ),
+  ).sort((timeA, timeB) => timeA - timeB);
+
+  return countryCases.map(
+    ({ country, dataSource }): CountryCase => ({
+      country,
+      dataSource: {
+        ...dataSource,
+        cases: times.reduce((last: Cases, time: number, index: number): Cases => {
+          const matchingCase = dataSource.cases.find(({ date }) => date.getTime() === time);
+          if (matchingCase) {
+            return [...last, matchingCase];
+          }
+
+          return [
+            ...last,
+            {
+              date: new Date(time),
+              value: 0,
+            },
+          ];
+        }, []),
+      },
+    }),
+  );
+}
+
 export function processCases(countryCases: CountryCases, cumulative = true): Data {
-  const data = countryCases.map(({ country, dataSource: { cases } }) =>
+  const filledData = fillData(countryCases);
+
+  const data = filledData.map(({ country, dataSource: { cases } }) =>
     processCountryCases(cases, cumulative).map(({ date, xValue, value, regression }) => ({
       date,
       xValue,