反応とD 3:ダイナミックCOVID‐19可視化(第2部:国比較ダッシュボード)


先週、私はインタラクティブなデータ視覚化のために私のビジョンを共有し、どのように私は反応とD 3を使用してCOVI - 19世界地図可視化に双方向性の建物に近づいた方法を説明した.その時点で、私のアプリは進行中の仕事であった.今週、私はどのように同じビジョンを使用してバーのチャートで相互活動に近づくために、ユーザーが国のCOVID - 19ケースの最初の日以来、複数の国の経験を比較できるようにする方法を説明します.私の希望は、ユーザーが従事し、地図ビューに表示されるデータと対話し、彼らが調査したい質問を開発し、バーグラフのコレクションを介してデータの詳細な分析をガイドするためにそれらの質問を使用しています.始めましょう!
  • このシリーズの第1部を逃しました?ここでチェックしてください.
  • あなただけのライブサイトにジャンプするアンチシーですか?まず、チェックアウトquick video demo そして、README.md file プロジェクトのクイックツアー.
  • 次に、ここのライブサイトを探るCOVID-19 World Tracker
  • 棒グラフ可視化を用いた国固有の歴史データの比較



    利用可能なデータ


    私のトラッカー上の地図の可視化は、リアルタイム、累積グローバルデータに焦点を当てながら、私は同様に縦断的なデータを含めることを望んだ.私は、ユーザーが新しいcovid - 19のケースの「カーブ」と「カーブを平らにする」の各々の国の経験を調べることができたことを望みました.私は、彼らに多数の国を横切って、活発な、そして、回復したケースの率を見るために見ることができました、そして、死の数.私は、多くの国がこれらの指標の各々に劇的に異なるカーブを持っているだろうと思っていました、そして、制限の緩和と同様にアウトブレークに対する各国の脆弱性、利用できる資源と発生への政治的反応についてより多くの調査につながるかもしれません.私も、私たちができるだけ多くの国のためにデータを提供することができたことを確認したいと思いました.
    これらの目標はCoronavirus COVID19 API , ジョンズホプキンス大学からの情報源.コンテナコンポーネントを設定します.JSは、基本的な国のデータ(名前、スラッグ、コードなど)を取得します.
        useEffect( () => {
            async function fetchData() {
                var requestOptions = {
                    method: 'GET',
                    redirect: 'follow'
                  };
    
                const response = await fetch("https://api.covid19api.com/countries", requestOptions)
                const data = await response.json()
                setCountries(data)
            }
            fetchData();
        }, []); 
    
    次に、地方のドロップダウンコンポーネントを設定します.
     <select onChange={ event => {setCollection([...collection, [event.target.value.split(",")[1], event.target.value.split(",")[2], event.target.value.split(",")[0]]]); 
       fetchCountry(event.target.value.split(",")[0], event.target.value.split(",")[1])}}>
    
    <option placeholder="Choose a Collection of Countries">Choose a Collection of Countries</option>
       {props.options.map(option => (
           <option
              id={props.id}
              key={option.value}
              value={[option.value, option.name, option.flagCode]}
           >
           {option.name}
           </option>
       ))}
    </select>
    
    <NavLink 
      to = {{
         pathname: `/collection`,
         countryData,
         collection
      }}>
      <button className="dark" disabled={invalid()}>View Collection</button>
    </NavLink>
    
    それぞれの国のエントリーには以下の情報が含まれており、国とスラッグキーを抽出する必要があった.

    ユーザーが国をクリックすると、それぞれの国の国旗が下に表示され、それらの国がコレクションに追加されます.

    ユーザーがコレクションを作成するときに、別のフェッチ要求は、コレクション内の国ごとに国固有のCOVID - 19データを取得し、国(スラグ)と国名(フルネーム)を引数として渡します.
        const fetchCountry = (country, countryName) => {
            async function fetchData() {
                const requestOptions = {
                    method: 'GET',
                    redirect: 'follow'
                };
    
                const response = await fetch(`https://api.covid19api.com/total/dayone/country/` + `${country}`, requestOptions)
                const data = await response.json()
                setCountryData(countryData => [...countryData, {[countryName]: [data], slug: country}])
            }
            fetchData();
        }
    ...
    
    取得されたデータは、次の形式で受信されます:コレクション内の各国に対して、我々はOB配列オブジェクトを受け取ります.そして、1つのオブジェクトが1日の価値のcovidデータを表しています(その国のために).

    最後に、「ビューコレクション」ボタンがクリックされると、NavLinkは国と国の国のコンポーネントをレンダリングするコレクションコンポーネントに国とコレクションデータを渡します.各国のコンポーネントは、最初にD 3の可視化のために使用される形式にデータを解析し、次にVizコンポーネントは、ユーザーがダッシュボード(またはインデックスビュー)と個々の国(表示ビュー)の間を移動できるようになりますNavLinkにラップをレンダリングします.VIZコンポーネントは、「D」が各バーグラフを付けることができる「Viz」(加えて国スラグ)のクラス名で空の< div >をレンダリングすることによって、反応とD 3の間の接続をするプレースホルダ構成要素だけです.
    import React, { useEffect } from 'react';
    import DrawBar from './DrawBar'
    
    const Viz = (props) => {
    
        useEffect( () => {
    
            DrawBar(props.countryName, props.totalCases, props.dailyData, props.id, props.caseType)
        }, [])
    
        return (
            <div className={"viz" + props.id} ></div>
        )
    }
    
    export default Viz
    

    利用可能なデータに基づくオプションの作成


    最後に、このイベントチェーンは、国の比較ダッシュボードをレンダリングします.

    ホームページ上のマイマップの可視化の構造に従って、私はコロナビアCovid 19 APIから取得したデータのキーに整列したオプションを持つ垂直ボタンメニューを作成しました.クリックすると、ボタンはユーザーが見たい特定のデータに従ってcasetypeをセットします.そして、それは各々のVIZコンポーネントの再レンダリングを引き起こします.そして、新しいcasetypeに合ったデータを使っている地図を再描画します.
    const Collection = (props) => {
        const [caseType, setCaseType] = useState("");
    
        return (
          <div>
    
            <button onClick={event => (setCaseType(event.target.value), selectAll("svg").remove())} className="deathsPerOneMillion block" value="deaths">Deaths</button>
    
            ...
    
            {props.location.countryData.map((country, index) => { 
              return (                         
                 <Country key={index} id={index} country={country} caseType={caseType} collection={props.location.countryData}/> 
              )
            })}
        </div>
      )
    }
    

    ユーザが選択したデータを視覚化する


    ユーザーがメニュー・ボタンと相互に作用するように、各々のSVGは選ばれて、取られて、それから新規なデータによって、再描画される.drawbar関数は、バーグラフを動的にする際のロジックの全てを含みます.
  • 国名-グラフのタイトルをフォーマットするために使用
  • Totalcase -グラフのサブタイトルに使用されます
  • DailyData - 1つのオブジェクトが発生の毎日を表している国のためのデータの配列
  • id -グラフの適切なHTML要素への接続に使用する国のスラッグ名
  • casetype -ユーザーが選択したデータの種類(合計ケース、回収されたケース、死亡、またはアクティブなケース)
  • 機能を通して、casetypeと他の引数は正しいタイトルと副題をレンダリングするために挿入されます、適切に軸をスケールして、適切なサイズのバーを与えてください、そして、カラーコードはバーとツールチップテキストをコード化します.たとえば、次のコードスニペットは、特定の国の< svg >要素をAグループに追加する方法を示し、caseType変数に基づいてバーカラーを割り当て、DailyData DayCountキーから値に基づいてXAxisを設定し、ブラケット表記を使用してcaseTypeを補間することによってyaxisとbar heightを設定します.類似の補間パターンは、ユーザーがスクリーン上のメニュー・ボタンを使用することによって、それらのビューをカスタマイズすることができるdrawbar機能を通じて繰り返される.
        const svg = select(`.${vizName}`)
            .append("svg")
            .attr("preserveAspectRatio", "xMinYMid meet")
            .attr("viewBox", [0, 0, width, height])
    
        const g = svg.append("g")
            .attr("fill", color(caseType))
            .selectAll('rect')
            .data(dailyData)
            .join("rect")
            .attr('x', d => xScale(d.dayCount))
    
            .attr("y", d => yScale(d[`${caseType}`]))
            .attr("width", xScale.bandwidth())
            .attr("height", d => yScale(0) - yScale(d[`${caseType}`]))
    
    You can view the code for the DrawBar() function in my repository

    追加のインタラクティブ機能の追加


    アプリのための私のビジョンに基づいて、それは本当にユーザーがダッシュボードのビューで一度にすべての国を表示できるようにするために重要であり、すぐに国全体で比較を行うためにサムネイルビューでデータと対話します.しかし、そのアプローチはデータを読むのに非常に困難にします.私はこの課題に次のような特徴を示しました.
    私は、ユーザーがバーの上にホバーすることができるように、データのラベルとツールチップを追加し、ケースの各タイプの日、日付、およびデータを表示します.これは大きなHTML文字列を作成することによって達成されました.
        const tip = d3Tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function(d) {
                return "<p>" + "<span style='color:white'>" + "Day " + d.dayCount + "<br/>" +
                    d.date.toLocaleDateString() + "<br/>" + "</span>" +
                    "<span style='color:#BD2D28'>" + d.total + " Total" + "<br/>" + "</span>" +
                    "<span style='color:#E3BA22'>" + d.active + " Active" + "<br/>" + "</span>" +
                    "<span style='color:#A0B700'>" + d.recovered + " Recovered" + "<br/>" + "</span>" +
                    "<span style='color:#BA5F06'>" + d.deaths + " Deaths" + "</p>" 
            })
    

    私は、各グラフをクリックして表示ページを表示するためにユーザーをクリックすることができますNavinkで各vizコンポーネントを包んだ拡大グラフ.
         <NavLink
             to = {{
                 pathname: `/countries/${props.country.slug}`,
                 countryName,
                 totalCases: totalCases(),
                 dailyData: parseData(dailyData, array), 
                 slug: props.country.slug, 
                 id: props.country.slug,
                 collection: props.collection
             }}>
             <Viz countryName={countryName} totalCases={totalCases()} dailyData={parseData(dailyData, array)} id={props.country.slug} slug={props.country.slug} caseType={props.caseType}/>
         </NavLink>
    
    ここで、ユーザは上述したのと同様の相互作用の全てを有するが、より大きなスケールである.

    ユーザーは、ダッシュボードとショーページの間を地図をクリックすることによって移動して、前後に動かすことができて、それから「コレクションへの復帰」ボタンをクリックすることができます.
        <NavLink
           to = {{
              pathname: `/collection`,
              countryData: props.location.collection
           }}>
           <button className="reset block">Return to Collection</button>
       </NavLink>
    

    最後の思考


    チェンコービーとして、私は9ヶ月間コーディングしていました.私は1ヶ月前にFlatiron学校のソフトウェア工学Bootcampを卒業し、その時点で、新しいスキルを学び、私が既に持っているスキルを練習する.そのゴールリストを見て、このプロジェクトは私が非常に有意義な方法ですべての6ゴールを達成するのを助けました:
  • ライフサイクルメソッドとは対照的にフックを使用する
  • クラスコンポーネントに依存しない機能コンポーネントを作成する
  • 余分なフレームワークとライブラリの私の使用を制限します
  • Reduxストアではなく、ローカルの状態を使用して小道具を渡す練習
  • 外部APIからデータを取得する
  • D 3を使用してデータの可視化を作成してレンダリングする
  • このプロジェクトは完璧ですか?いいえ、私は応答性とユーザインタフェースの改善、特にモバイルデバイスのために特にしたいです.そして、GitHubページは非常にうまく反応ルータで遊んでいないので、私は若干の自動リダイレクトを失いました.私のコードとリファクタをクリーンアップする必要がある領域がいくつかあります.しかし、コーデヴィビーとして、それは私自身のための新しい目標を設定し、新しい有意義なプロジェクトを介してそれらを達成するために移動する時間です.
    あなたがライブサイトにジャンプせずにこれをした場合は、今すぐチェックアウト!
  • まず、チェックアウトquick video demo そして、README.md file プロジェクトのクイックツアー.
  • 次に、ここのライブサイトを探るCOVID-19 World Tracker
  • このシリーズの第1部を逃しました?ここでチェックしてください.
  • サイトを探検するなら、下記のコメントで何を考えているかを知らせてください.
  • どうやってそのサイトを探検しましたか.
  • 君はどんな質問を思いつきましたか.何を調べたのですか.
  • 一緒に多くの質問を開発し、より良いCOVID - 19パンデミックを理解するために一緒にマップビューとカントリーダッシュボードの仕事をしましたか?