소스 검색

Log scale with toggle

Fela Maslen 5 년 전
부모
커밋
5f1f750cb6
2개의 변경된 파일21개의 추가작업 그리고 5개의 파일을 삭제
  1. 12 2
      src/components/graph-cases.tsx
  2. 9 3
      src/utils/regression.ts

+ 12 - 2
src/components/graph-cases.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import format from 'date-fns/format';
-import { LineChart, XAxis, YAxis, Line, CartesianGrid } from 'recharts';
+import { LineChart, XAxis, YAxis, Line, CartesianGrid, ScaleType } from 'recharts';
 import { lighten } from 'polished';
 
 import { Countries, CountryCases, Data } from '../types';
@@ -24,6 +24,13 @@ type Props = {
 
 const GraphCases: React.FC<Props> = ({ countries }) => {
   const [showCumulative, setCumulative] = React.useState<boolean>(true);
+
+  const [scale, setScale] = React.useState<ScaleType>('log');
+  const toggleLogScale = React.useCallback(
+    () => setScale(last => (last === 'log' ? 'linear' : 'log')),
+    [],
+  );
+
   const [regressionBuffer, setRegressionBuffer] = React.useState<number>(0);
   const onChangeRegressionBuffer = React.useCallback(
     event => setRegressionBuffer(Number(event.target.value)),
@@ -60,6 +67,9 @@ const GraphCases: React.FC<Props> = ({ countries }) => {
         <input type="radio" onChange={(): void => setCumulative(false)} checked={!showCumulative} />
         Daily
       </p>
+      <p>
+        <input type="checkbox" checked={scale === 'log'} onChange={toggleLogScale} /> Log scale
+      </p>
       <p>
         Regression buffer:{' '}
         <input
@@ -78,7 +88,7 @@ const GraphCases: React.FC<Props> = ({ countries }) => {
           tickFormatter={dateTickFormatter}
           type="number"
         />
-        <YAxis tick yAxisId="left" domain={[50, 'auto']} />
+        <YAxis scale={scale} tick yAxisId="left" domain={[50, 'auto']} />
         <CartesianGrid stroke="#f5f5f5" />
         {countries.map(({ country, color }) => (
           <Line

+ 9 - 3
src/utils/regression.ts

@@ -86,8 +86,14 @@ const withExponentialRegression = (cumulative: boolean, regressionBuffer: number
   const slope = covariance / xVariance;
   const intercept = yBar - slope * xBar;
 
-  const regressionAtDate = (date: Date): number =>
-    Math.exp(slope * differenceInDays(date, minDate) + intercept);
+  const regressionAtDate = (date: Date): number | undefined => {
+    const regression = Math.exp(slope * differenceInDays(date, minDate) + intercept);
+    if (regression >= 1) {
+      return regression;
+    }
+
+    return undefined;
+  };
 
   const lastDate = cases[cases.length - 1].date;
 
@@ -195,7 +201,7 @@ export function processCases(
         date,
         xValue,
         value: {
-          [country]: value,
+          [country]: value || undefined,
         },
         regression: {
           [country]: regression,