[Chart.js] カーソル移動に合わせて、縦軸にラインを引く方法

2021年7月5日

chart.js テクノロジー プログラミング

eyecatch チャートの表示を極めておくと、自分で作るwebシステムのクオリティがめちゃくちゃアップすることに気がついた、ユゲタです。 今回も、仕事で使ったChart.jsの、よく使いガチだけど、ネットであまり情報がなかった備忘録を書いておきます。 グラフ表示をした時に、その表示している数が多い場合に、自分の居場所がわかりづらくなる場合があります。 そんな時に、居場所のガイド線を表示してあげることで、グラフのユーザーインターフェイスが一気に向上します。 そんな時のテクニックですね。 【お断り】 このブログ記事は、Chart.jsの標準的な使い方ができる人が対象です。 Char.jsの基本設定などは、本家サイトのサンプルなどで使える人を対象にしていますので、下記リンクから環境を作ってから本ページを参照ください。 Chart.js

グラフ内のX軸にカーソルラインを表示させる方法(失敗パターン)

今回の機能の実現で、かなり時間を費やしたので、失敗パターンも書いておきます。 (function(){ function MAIN(){ this.colors = [ "rgba(255,0,0,0.5)", "rgba(0,255,0,0.5)", "rgba(0,0,255,0.5)", "rgba(255,128,0,0.5)", "rgba(0,255,255,0.5)", "rgba(0,0,0,0.5)", "rgba(255,0,255,0.5)" ]; this.view_chart_1(); } MAIN.prototype.view_chart_1 = function(){ let canvas_1 = document.getElementById("graph_1"); if(canvas_1){ let col_num = 2; let data_count = 50; // setting let ctx = canvas_1.getContext('2d'); let labels = []; for(let i=1; i<=data_count; i++){ labels.push(i); } let datas = []; for(let i=0; i<labels.length; i++){ datas.push(Math.floor(Math.random() * 10)); } let datasets = [ { data : datas, borderColor : this.colors[col_num], backgroundColor : this.colors[col_num], label : "graph-1" } ]; let options = { responsive: true, tooltips : { intersect : false, mode: 'index', axis: 'x', callbacks : { afterBody : (function(){ var activePoint = this.chart_1.tooltip._active[0]; var ctx = this.chart_1.ctx; var x = activePoint.element.x; var topY = this.chart_1.chartArea.top; var bottomY = this.chart_1.chartArea.bottom; ctx.save(); ctx.beginPath(); ctx.moveTo(x, topY); ctx.lineTo(x, bottomY); ctx.lineWidth = 2.0; ctx.strokeStyle = 'red'; ctx.stroke(); ctx.restore(); }).bind(this) } } }; // view this.chart_1 = new Chart(ctx, { type : "line", data : { labels : labels, datasets : datasets }, options : options, plugins: [{ // beforeDraw : this.chart_plugin.bind(this) }] }); } }; switch(document.readyState){ case "complete" : new MAIN();break; default : window.addEventListener("load" , function(){new MAIN()});break; } })()

解説

Tooltipのcallbackで、値も取得できるし、問題なく表示できるだろうと思っていたところ、 Chart.jsは、mousemoveイベントで、常にcanvasの書き換えが行われているらしく、 カーソルを移動すると、ラインがチカチカして、マウスを止めた時に、ラインが表示されていない状態になってしまいました。 tooltipのcallbackで描画関連の処理はご法度なんですね。

グラフ内のX軸にカーソルラインを表示させる方法(成功パターン)

(function(){ function MAIN(){ this.colors = [ "rgba(255,0,0,0.5)", "rgba(0,255,0,0.5)", "rgba(0,0,255,0.5)", "rgba(255,128,0,0.5)", "rgba(0,255,255,0.5)", "rgba(0,0,0,0.5)", "rgba(255,0,255,0.5)" ]; this.view_chart_2(); } MAIN.prototype.view_chart_2 = function(){ let canvas_2 = document.getElementById("graph_2"); if(canvas_2){ let col_num = 3; let data_count = 50; // setting let ctx = canvas_2.getContext('2d'); let labels = []; for(let i=1; i<=data_count; i++){ labels.push(i); } let datas = []; for(let i=0; i<labels.length; i++){ datas.push(Math.floor(Math.random() * 10)); } let datasets = [ { data : datas, borderColor : this.colors[col_num], backgroundColor : this.colors[col_num], label : "graph-2" } ]; let options = { responsive: true, tooltips : { intersect : false, mode: 'index', axis: 'x' } }; // view this.chart_2 = new Chart(ctx, { type : "line", data : { labels : labels, datasets : datasets }, options : options, plugins: [{ beforeDraw : this.chart_plugin.bind(this) }] }); } }; MAIN.prototype.chart_plugin = function(target){ let ctx = target.ctx; var x = this.chart_2.tooltip.caretX; var topY = this.chart_2.chartArea.top; var bottomY = this.chart_2.chartArea.bottom; ctx.save(); ctx.beginPath(); ctx.moveTo(x, topY); ctx.lineTo(x, bottomY); ctx.lineWidth = 2.0; ctx.strokeStyle = 'red'; ctx.stroke(); ctx.restore(); }; switch(document.readyState){ case "complete" : new MAIN();break; default : window.addEventListener("load" , function(){new MAIN()});break; } })()

解説

そして、前回どう同様に、pluginsの設定で、素敵な感じにできることを発見しました。 しかも、こちらの方が、値取得が楽だということもわかり、Chart.jsの内部構造が深く理解できましたね。 基本的には、次のポイントを抑えておくと良いでしょう。 ポイント1 let options = { responsive: true, tooltips : { intersect : false, mode: 'index', axis: 'x' } }; options設定にtooltipsを加えて、intersectをfalseに、modeをindex、今回は横軸(X)のライン描画だったので、axisをxに設定して、 plugin関数内のchart_plugin(任意関数)で、座標をしていしてcanvas描画をするという流れです。 x軸の値は、マウス座標ではなく、表示しているグラフの値に沿った形にするので、 this.chart_2.tooltip.caretX この値で、今現在カーソルのある位置がどのラベルになるのかを取得することができます。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。