🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Chart.js

Chart.jsは、多様なグラフを組み込めるJavaScriptのライブラリ。折れ線グラフや棒グラフ、円グラフ、レーダーチャートなどのグラフの種類が用意されています。HTML5のCanvasを用いて描画され、マークアップも分かりやすく、簡単に編集することが可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

3815閲覧

Chart.jsのプラグイン設定を更新する処理を、簡潔に記述したい

AkihiroIshii

総合スコア67

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Chart.js

Chart.jsは、多様なグラフを組み込めるJavaScriptのライブラリ。折れ線グラフや棒グラフ、円グラフ、レーダーチャートなどのグラフの種類が用意されています。HTML5のCanvasを用いて描画され、マークアップも分かりやすく、簡単に編集することが可能です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/12/26 09:36

やりたいこと

画面に入力された年を基点にして、canvasの背景を塗りつぶしたいです。ひとまず実装はできて、次のような動きが実現できました。

イメージ説明

質問

実装はできたものの、Chart.jsのプラグインの扱いに慣れておらず、チャートの更新処理が冗長になっているように感じます。具体的には、beforeDraw の関数を再度書くのではなく、塗りつぶし開始位置だけ更新したいと思っています。

以下のコードについて改善できる点がありましたら、ご指摘いただけると助かります。

HTMLのbody部分

html

1 <p> 2 塗りつぶし開始年度: 3 <input id="start" type="number" name="start" value="1983" /> 4 </p> 5 <div class="canvas-wrapper"> 6 <canvas id="chart"></canvas> 7 </div>

javaScript(jQuery)

javascript

1$(function(){ 2 /** 3 * グラフ描画(初期処理) 4 */ 5 var ctx = $('#chart')[0].getContext('2d'); 6 var chart = new Chart(ctx, { 7 type: 'line', 8 data: { 9 labels: [1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992], 10 datasets: [{ 11 data: [10, 0, 30, 92, 50, 60, 70, 80, 10, 30], 12 }], 13 }, 14 plugins: [{ 15 beforeDraw: function(chart, options) { 16 // 範囲を設定 17 var xscale = chart.scales["x-axis-0"]; 18 var yscale = chart.scales["y-axis-0"]; 19 var left = xscale.getPixelForValue(1983); // 塗りつぶしを開始するラベル位置 20 var right = xscale.getPixelForValue(1988); // 塗りつぶしを終了するラベル位置 21 var top = yscale.top; // 塗りつぶしの基点(上端) 22 23 // 塗りつぶす長方形の設定 24 ctx.fillStyle = "rgba(0, 0, 255, 0.2)"; 25 ctx.fillRect(left, top, right - left, yscale.height); 26 } 27 }], 28 }); 29 30 /** 31 * 塗りつぶし開始年が変更されたときの処理 32 */ 33 $('#start').change(function(){ 34 // 変更された値を取得 35 var from_year = Number($(this).val()); 36 37 // チャートのプラグインの設定を変更(ここが冗長だと感じます) 38 chart.config.plugins[0].beforeDraw = function(chart, options) { 39 // 範囲を設定 40 var xscale = chart.scales["x-axis-0"]; 41 var yscale = chart.scales["y-axis-0"]; 42 var left = xscale.getPixelForValue(from_year); // (※)開始年を変更 43 var right = xscale.getPixelForValue(from_year + 5); // (※)終了年を変更 44 var top = yscale.top; 45 46 // 塗りつぶす長方形の設定 47 ctx.fillStyle = "rgba(0, 0, 255, 0.2)"; 48 ctx.fillRect(left, top, right - left, yscale.height); 49 }; 50 // チャートを更新 51 chart.update(); 52 }); 53});

使用したライブラリ

  • jQuery 3.4.1
  • Chart.js 2.9.3

関連情報

Chart.js プラグイン
Chart.js チャートの更新

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは、AkihiroIshiiさん

beforeDrawに渡す関数の中で、初期化と更新で異なる変数を利用している部分があったため、
必要な変数を引数で渡し、その変数を確保した状態の関数を返すことで、再利用できるようにしました。

JavaScript

1function handleBeforeDraw(startYear, ctx) { 2 return function(chart, options) { 3 // 範囲を設定 4 var xscale = chart.scales["x-axis-0"]; 5 var yscale = chart.scales["y-axis-0"]; 6 var left = xscale.getPixelForValue(startYear); // 塗りつぶしを開始するラベル位置 7 var right = xscale.getPixelForValue(startYear + 5); // 塗りつぶしを終了するラベル位置 8 var top = yscale.top; // 塗りつぶしの基点(上端) 9 10 // 塗りつぶす長方形の設定 11 ctx.fillStyle = "rgba(0, 0, 255, 0.2)"; 12 ctx.fillRect(left, top, right - left, yscale.height); 13 } 14} 15 16$(function(){ 17 /** 18 * グラフ描画(初期処理) 19 */ 20 var ctx = $('#chart')[0].getContext('2d'); 21 var chart = new Chart(ctx, { 22 type: 'line', 23 data: { 24 labels: [1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992], 25 datasets: [{ 26 data: [10, 0, 30, 92, 50, 60, 70, 80, 10, 30], 27 }], 28 }, 29 plugins: [{ 30 beforeDraw: handleBeforeDraw(1983, ctx), 31 }], 32 }); 33 34 /** 35 * 塗りつぶし開始年が変更されたときの処理 36 */ 37 $('#start').change(function(){ 38 // 変更された値を取得 39 var from_year = Number($(this).val()); 40 41 // チャートのプラグインの設定を変更(ここが冗長だと感じます) 42 chart.config.plugins[0].beforeDraw = handleBeforeDraw(from_year, ctx); 43 // チャートを更新 44 chart.update(); 45 }); 46});

ちなみにこのような手法を クロージャ と呼んだりします。
分かりづらい概念だったりしますので、今回指名した上記の内容や、以下リンクの makeAdder などをご覧いただければ、比較的つかみやすいかと思います。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures

以上、参考になれば、幸いです。

投稿2019/12/26 12:29

gentamura

総合スコア406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AkihiroIshii

2019/12/26 12:44

まさに望んでいた形です!ありがとうございます! なるほど、関数が返り値になるように定義するんですね。クロージャの参考資料もご紹介いただき助かります。勉強させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問