vue-chartjs で二重Y軸を扱う
各単語について
Vue.js
Javascriptのフレームワークの一つ. HTML側とJS側で値の共有ができ(双方向データバインディング), また,HTML側でforやif文が書けるようになる便利なやつ.Chart.js
JavaScriptで洒落たグラフを簡単に書けるようにするライブラリ.vue-chartjs
Vue.js
上でChart.js
を使うためにChart.js
をラップしたもの.
今回の開発の概要
vue-chartjs
の二重Y軸の扱いに結構詰まったので,
今回の対処をメモする.
今回は以下の流れで開発した.
vue-chartjs
で同じ描画先に棒グラフを2本描画- Y軸を2本描画し,各グラフで異なるY軸を参照
- 各グラフが紐づくY軸を,切り替えるボタンを作成
Y軸を2本描画し,各グラフで異なるY軸を参照
"vue-chartjs
で同じ描画先に棒グラフを2本描画"はメモするまでもないので省略.
Y軸を複数描画する際は,グラフ描画関数の引数のoptions
要素を編集する.
具体的には,以下の様にyAxes
要素を配列にする.
options: { scales: { yAxes: [{ id: "y-axis-1", position: "left" }, { id: "y-axis-2", position: "right" }] ...
position
の値で描画先の上下左右どこに描画するか定義できる.
また,各グラフでどちらのY軸に紐付かせるかは,上記のid
を以下の様にyAxisID
要素に格納することで,定義できる.
{ type: 'bar', label: 'label1', backgroundColor: '#f87979', data: [11, 11, 19, 8, 8, 9, 30, 24, 25, 22, 11, 15], fill: false, tension: 0, yAxisID: 'y-axis-1' }, { type: 'bar', label: 'label2', backgroundColor: '#f87000', data: [5, 25, 17, 6, 29, 5, 5, 13, 16, 10, 14, 29], fill: false, tension: 0, yAxisID: 'y-axis-2' }
以下の用にY軸が左右に描画される. ピンクの棒グラフが左のY軸,オレンジの棒グラフが右のY軸に紐づいている.
各グラフが紐づくY軸を,切り替えるボタンを作成
ここで詰まった.結局,いいやり方にはなっていないと思うが, 今回は以下の方法で対処した.
- ボタンクリックにより,
yAxisID
の値を変更 - 修正したグラフのデータの
_meta
要素を削除し,グラフを再描画
ボタンクリックにより,yAxisID
の値を変更
以下のコードでyAxisID
の値を変更するラジオボタンを設置
<td v-for="col in filteredData.datasets.length"> <!-- id には (axis_select-列番号-軸番号) を格納 --> <input type="radio" :id="['axis_select-' + (col-1) + '-1']" value="y-axis-1" v-model="filteredData.datasets[col-1].yAxisID" @input="deleteMeta"> <label for="y-axis-1">軸1</label> <input type="radio" :id="['axis_select-' + (col-1) + '-2']" value="y-axis-2" v-model="filteredData.datasets[col-1].yAxisID" @input="deleteMeta"> <label for="y-axis-2">軸2</label> </td>
filteredData
変数にグラフ描画に使うデータが入っている.
上記コードで設置したボタンをクリックすることにより,deleteMeta()
関数を呼び出し,_meta
要素を削除する.
修正したグラフのデータの_meta
要素を削除し,グラフを再描画
上で設置したラジオボタンのクリックにより発火するdetaMeta()
関数は以下の通り.
// データの(_meta)要素を削除し,グラフを更新 deleteMeta (e) { // buttonId は axis_select-0-1 の形式 // ハイフン区切りで,(axis_select 列番号 軸番号) を意味する const buttonId = e.target.id; const index = Number(buttonId.split('-')[1]); delete this.localData.datasets[index]._meta; // グラフを更新 this.reloadGraph(); }
動作テスト
以下は今回開発したものを実際に動かしたものです. 二つ目のグラフ(オレンジの棒)のY軸を 左->右->左 と動かしています. オレンジのグラフの最大値はピンクのグラフの最大値よりも大きいため, ピンクの方のグラフも動いています.
感想
とりあえず,ちゃんと動くものはできたので,目的は達成しました. でも対処の仕方があまりきれいではないので,すっきりしない.
開発には関係ないことですが,今回初めて画面キャプチャで動画を作成し,GIFを作成しました. 楽しい.