このエントリーは、Vue.js #3 Advent Calendar 2018アドベントカレンダー初日の記事です.
開幕投手をつとめます、@shinyorkeと申します.
この記事では、「データサイエンスもいいけど自前で可視化ダッシュボード作ると面白いぞ!」っていうテーマで、
で実際作った時の勘どころやノウハウを紹介します.
TL;DR
- データサイエンスに必要なダッシュボードを作りたくなったらnuxt-core-uiを使おうぜ!
- nuxt-core-uiのグラフの動的更新はvue-chartjsのmixins.reactivePropで、API(データ)の呼び出しは普通にaxiosでやろう
- オレオレ分析基盤は作ると楽しい
完成イメージ
データ(DBとか、何でもいい)をグラフで可視化する、Redash(の簡易版)っぽいダッシュボードの雛形をnuxt-core-ui(Nuxt.js + CoreUI)でやってみます.
なお、こちらは今年のPyCon JP 2018で発表したモノでもあります.
おしながき
Who am I?(お前誰よ)
- @shinyorke(しんよーく、と読みます)
- 野球データ解析・分析のベンチャー「ネクストベース」の野球エンジニア兼CTO
- バックエンドにインフラ、データサイエンスにフロントと何でもやってるが基本Pythonの人
なお、Vue.js(含むNuxt.js)歴は半年とちょっとです(今年から触り始めた)*1が、縁あってこんなエントリーを書かせてもらったりもしてます.
登場人物の紹介
このエントリーで登場するモノです.
なお、
- Vue.jsおよびNuxt.jsはSPA(Single Page Application)を作るものだよ
- Vue.jsおよびNuxt.jsで開発できる環境は揃ってるよ(そろってない人は、ここと、ここを見てね&やってね)
- Vue.jsおよびNuxt.jsでグラフを書くならvue-chartjsやぞ
を前提条件としてこの先の話を進めます(要はvue-cliが使えればなんとでもなります).
CoreUI
まず、これはVue.jsに限った話ではないのですが、フロントエンドでWebの管理画面を作るテンプレートとして、CoreUIという便利なテンプレートがあります.
🆓 Free Bootstrap Admin Template · CoreUI
何ができるかは、ライブデモをご覧頂いたほうが早いと思いますが、大雑把に言うと
- 画面遷移ができる状態のテンプレが手に入る、しかもレスポンシブ(Bootstrapがベースとなっている)
- ダッシュボードに必要なコンポーネントがほぼ全て入ってる(グラフ、カードなど)
- (後述の通り)いろんなjavascript frameworkの実装がある
ちゃんと使って作ればRedashのフロントエンドに親しいものは実装できるかと思います.
なお、無料版とプロ版があり、プロ版の方がコンポーネントが揃っていたりサポートもあるみたいですが、今回は無料版でのお話です.
nuxt-coreui(この記事のメイン)
前述の通り、CoreUIは様々な実装があり、
- 通常版(framework使ってない)
- Angular
- React.js
- Vue.js
これらが用意されています.
ちょっとJavaScriptに慣れている人だったり、「俺はVue.jsより○○(ReactとかAngular)何じゃ!」って方はそれぞれのVer.を使えば良いかなと思います.
そんなCoreUIのVue.js版をNuxt.js化したやつがこのエントリーで紹介するnuxt-coreuiというものです.
nuxt-coreuiをはじめる
はじめ方はメチャクチャ簡単です(Vue.jsで開発したことある人にはおなじみの光景).
README.mdとおりにやれば動きます.
インストール
vue-cliが使えている人はこれで終わります.
$ vue init muhibbudins/nuxt-coreui hello_nuxt_coreui $ cd hello_nuxt_coreui $ npm install
ひとまず動かす
npmもしくはyarnで動きます(これもおなじみの光景)
$ npm run dev
デフォルトではPort 3000が開くので、ブラウザでhttp://localhost:3000とかしてあげれば、ライブデモとほぼ同等の内容が動くと思います.
あとはお好きなエディタでページやコンポーネントの中身を変えたり、新しいページを作ったりして中身の理解をしてみましょう.
ダッシュボードを作るための下ごしらえ
優秀なテンプレから実用的なダッシュボード(に限らず、Webサイト全般)を作るためには、
- CoreUIのテンプレから不要なページを追い出す
- assets類を変更する・捨てる
- ページ構成に従い画面遷移を変更する
といった泥臭い仕事作業が必要です.
全部上げるとキリが無いので、私個人が最もハマった
- グラフとページの連携
- 複数のAPI呼び出しを束ねた上での処理
について解説します.
グラフのデータをPage側からの同期で変更する
元リポジトリの棒グラフのサンプル(BarExample.vue)のコードを見ると、
オリジナルの棒グラフ
<script> import { Bar } from 'vue-chartjs' export default { extends: Bar, mounted () { // Overwriting base render method with actual data. this.renderChart({ labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], datasets: [ { label: 'GitHub Commits', backgroundColor: '#f87979', data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11] } ] }) } } </script>
(サンプルという名前の通り)、labelsとdatasetsが直接記載されていて困っちゃいます、現実のアプリではこんな書き方をするわけがありません.
ので、公式の手順に従い、こんな感じでリアクティブに変更可能な書き方にしました.
リアクティブ後の棒グラフ
グラフライブラリの方
<script> import {Bar, mixins} from 'vue-chartjs' export default { extends: Bar, mixins: [mixins.reactiveProp], props: { chartData: Object, options: Object }, mounted() { this.renderChart(this.chartData, this.options) } } </script>
呼び出し方はこんな感じ.
chartDatasetsおよび、chartOptionsにそれぞれdatasetsとoptionを渡します(中身はmethods内とかで一生懸命作る).
<b-card header-tag="header"> <div slot="header"> BarGraph Sample </div> <div class="chart-wrapper"> <bar-graph :chartData="chartDatasets" :options="chartOptions"/> </div> </b-card>
RESTful API呼び出し(axiosを入れる・使う)
このブログのちょっと前のエントリーですが、こちらですこーし触れました.
大雑把に言うと、
- axiosを使って呼び出しをシンプルにする
- 複数APIを束ねて呼ぶときはasync / awaitをうまーく重ねて使う
<script> import axios from 'axios' const HTTP_HEADER = {headers: {'Content-Type': 'application/json'}} export default { name: "hourse", data() { return { // 省略 } }, methods: { search: async function (url) { const response = await axios.get(url, HTTP_HEADER) if (response.status !== 200) { console.error('エラー時の処理') process.exit() } const body = response.data this.getStatsJapan(body.stats_japan) this.getStatsOther(body.stats_other) }, getStatsJapan: async function (url) { const response = await axios.get(url, HTTP_HEADER) if (response.status !== 200) { console.error('エラー時の処理') process.exit() } const body = response.data // TODO データを埋め込む }, getStatsOther: async function (url) { const response = await axios.get(url, HTTP_HEADER) if (response.status !== 200) { console.error('エラー時の処理') process.exit() } const body = response.data // TODO データを埋め込む } // TODO 続く } </script>
先程のグラフデータのdatasets/optionもこの流れで作れるので是非試してみてください!
まとめ
実際に作った分析ダッシュボードは前述の通り、PyCon JP 2018で発表させてもらいました.
発表のメインはnuxt-coreuiではなくてPython(Django、Luigiほか)でしたが笑.
実際作った・使った感想としては、
- 社内のオレオレ分析ダッシュボードとして十分使えるクオリティ、キビキビ・ヌルヌル動いて体験的にも良い.*2
- 追加開発・保守運用もメンバーがVue.js知ってる・使える前提でイケそう.*3
- 基本のグラフ(棒とか折れ線とか)以外のやつもなんとかしたい、d3.jsとか組み込めないものか.*4
ということで、社内で作ってる別のVue.jsアプリと加えて社内基盤として整理できたらなと思っています.
というわけで、nuxt-coreuiいいぞ!の紹介はここまで、明日はpenton310さんよろしくお願いします!