作ったもの
世界の新型コロナウィルス感染症のデータを表示させてるだけのページになります。
STAY HOMEのゴールデンウィークでちょっといじってみようと思って、やってみました。
東京都の有名になったあのサイトもNuxt.js を使ってますが、あれほどのものじゃないです。
あと、APIは英語なので、国名は英語になります。
ひとまずGithub pagesで静的ページが見れます。
https://seki0809.github.io/covid19/
ソースコードはこちら
https://github.com/seki0809/covid19
国ごとの一覧が表示されます。
国の一覧で「累計感染者」「現在感染者」「回復者」「死亡者」の見出し押すと並び替えをします。(降順のみ)
↓国の一覧から国を選択すると、その国の日毎のグラフが見れます。
使ったもの
- Nuxt.js
- Rakuten RapidAPI
- Chart.js
- axios
- PHP
Nuxt.js で何か作りたかったのと、Rakuten RapidAPI で何か作りかったというのがあります。
ただ、フロントエンドはNuxt.jsですが、RapidAPIからの取得と加工はPHPでやってます。
Nuxt.js
Nuxt.jsのインストールについて書いた記事はこちら。
nuxt.jsインストール手順備忘録
https://qiita.com/seki0809/items/5f831d63146e44dc106a
Rakuten RapidAPI
データはRakuten RapidAPI から取得しています。
最初は下記が完全無料で良いと思って作っていたのですが、3月20日以降しかデータが入っていなかったので、断念しました。
https://api.rakuten.net/api-sports/api/covid-193
で、こっちは登録が必要でしたが、1月22からのデータがあったので、こちらを使いました。
https://api.rakuten.net/Gramzivi/api/covid-19-data
やったこと
バックエンド側
バックエンド側はPHPで書いてます。
1.Jsonの保存
アクセスがあるたび毎回APIを叩くわけにはいかないので、一旦Jsonをファイルとして保存しました。
これはPHPで処理します。
2.Jsonの加工
保存したJsonのデータは日ごとにファイルが別れていたので、1つにまとめます。
ここまでバックエンド側はPHPで書いてます。
フロントエンド側
ここからフロントエンド側のNuxt.jsになります。
3.世界の合計を表示
↓これは単純にJsonから表示させているだけです。
getSummary() {
const action = `${this.apiUrl}json/summary/summary.json`
axios.get(action)
.then(response => {
this.summary = response.data[0]
}).catch(error => {
console.error(error)
})
}
3.世界の一覧を表示
国の一覧はJsonを取得して、デフォルトは累計感染者の降順にして、表示後は見出しをクリックした箇所で降順に並び替えます。
↓最初の取得です。
getCountries() {
const action = `${this.apiUrl}api/get_country_list`
axios.get(action)
.then(response => {
this.countries = response.data
this.sortCountries()
}).catch(error => {
console.error(error)
})
},
↓並び替えの着火です。targetが並び替えする対象です。
changeSort (target) {
this.sort = target
this.sortCountries()
},
↓並び替えの本体です。
あとでリファクタリングはした方が良さそうです。
sortCountries() {
const compare = (a, b) => {
if(a.target > b.target) return -1;
if(a.target < b.target) return 1;
return b - a
}
let temp = []
this.countries.forEach((row, index) => {
temp.push(
{
key: index,
target: row.total[this.sort]
}
)
}, this)
temp.sort(compare)
let array = []
temp.forEach((row2) => {
this.countries.forEach((row3, index3) => {
if (row2.key === index3) {
array.push(row3)
}
}, this)
})
this.countries = array
}
4.詳細ページでグラフを表示
↓まずはJsonを取得します。
getHistory() {
const action = `${this.apiUrl}api/get_country_history/${this.params}`
axios.get(action)
.then(response => {
this.history = response.data
this.createChart();
}).catch(error => {
console.error(error)
})
}
↓Chart.jsは1つずつ配列が必要なので、必要な部分を抽出して分けます。
createChart () {
this.history.forEach((row, index) => {
this.chartDate[index] = row.date
this.chartConfirmed[index] = row.total.confirmed
this.chartRecovered[index] = row.total.recovered
this.chartDeaths[index] = row.total.deaths
this.chartActive[index] = row.total.active
}, this)
this.outputChart()
}
↓Chart.jsでグラフを表示させます。
outputChart () {
const ctx = document.getElementById('chart').getContext('2d')
new Chart(ctx, {
type: 'bar',
data: {
datasets: [
{
label: '死亡者',
data: this.chartDeaths,
type: 'line',
order: 1,
borderColor: '#0d70ff',
backgroundColor: '#9ec6ff'
},
{
label: '回復者',
data: this.chartRecovered,
type: 'line',
order: 2,
borderColor: '#23d5ae',
backgroundColor: '#a7eedf'
},
{
label: '現在感染者',
data: this.chartActive,
type: 'line',
order: 3,
borderColor: '#fc0368',
backgroundColor: '#fe9ac3'
},
{
label: '累計感染者',
data: this.chartConfirmed,
order: 4,
borderColor: '#fedaa0',
backgroundColor: '#fedaa0'
}
],
labels: this.chartDate
},
options: {
responsive: false
}
})
}
所感
こんな感じです。
最初は機能ごとにコンポーネントを分けていましたが、とくに再利用性は無いので、pagesの中に入れてしましました。
バックエンド側でPHPでも結構書いてるのですが、今回は省略です。
デザインはグリッドのフレームワークだけ引用し、あとは勘で書いてます。
(スマホは見にくいです)
一周回って中国の方が安全って言われてますけど、
下の画像で、上のグラフが中国で下が日本なんですが、やはり中国のピークは2月下旬までで、日本は3月の後半から上がり続けてるんですよね。
1日でも早く日常が戻ってくることを願ってます。
追記
どうやらAPIが有料になったらしく、データの更新は止めます