- ベストアンサー
chart.jsの多重円グラフで系列表示について
- chart.jsを使って多重円グラフを作成する方法について学んでいます。基本的なグラフ作成はできたのですが、系列の凡例の表示方法についてわからないです。
- 質問のコードでは、1月や2月などの凡例は表示されていますが、仙台や札幌などの系列名を同様に表示して、クリックで円を非表示・表示するようにしたいです。
- 多重円の中から任意の円を非表示・表示させるコードを教えていただきたいです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
No.1の補足コメントに対して回答します。 なるほど。generateLabelsというオプションがありましたね。onClickと組み合わせてデータの表示・非表示を切り替えるのはoptions.legendを下記のようにするとできると思います。 labels: { generateLabels: function(chart) { return chart.data.datasets.map(function(datasets, i) { return { datasetIndex: i, text: datasets.label, fillStyle: datasets.backgroundColor, strokeStyle: datasets.borderColor, // 表示状態に連動して取り消し線表示 hidden: !chart.isDatasetVisible(i), }; }); } }, onClick: function(e, legendItem){ const index = legendItem.datasetIndex; const ci = this.chart; const meta = ci.getDatasetMeta(index); meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null; ci.update(); } onClickにはChart.jsデフォルトの凡例クリック時の動作を利用しています。 参考: https://www.chartjs.org/docs/latest/configuration/legend.html#custom-on-click-actions
その他の回答 (1)
- Proof4
- ベストアンサー率78% (151/192)
Chart.jsの機能で系列名を凡例に表示したり、それをクリックしてデータの表示切替をするのは円グラフの場合は難しそうです。(棒グラフなどほかのグラフだと容易にできそうです。) そこで、独自にそのような機能を実現するには下記のような実装があります。 まず、系列名の凡例の代わりに下記のようなボタンを用意します。 <button class="toggleDataset" data-id="0">仙台</button> <button class="toggleDataset" data-id="1">札幌</button> <button class="toggleDataset" data-id="2">渋谷</button> 続いて、スクリプトを次のように書き換えます。 <script> var datasets = [ { label: '仙台', data: [320000, 590000, 400000, 420000, 380000, 250000, 420000], }, { label: '札幌', data: [520000, 450000, 380000, 280000, 590000, 400000, 530000], }, { label: '渋谷', data: [650000, 230000, 480000, 600000, 620000, 700000, 760000], }, ]; var visibility = [1, 1, 1]; // 各データの表示状態フラグ 1: 表示、0: 非表示 var ctx = document.getElementById('myPieChart'); var config = { type: 'pie', data: { labels: ['1月', '2月', '3月', '4月', '5月', '6月', '7月'], datasets: datasets }, options: { title: { display: true, text: '' }, legend: { // 凡例 display: true, // 表示の有無 position: 'top' // 表示位置 } }, plugins: { colorschemes: { scheme: 'office.Red6' } } }; window.myPieChart = new Chart(ctx, config); var buttons = document.getElementsByClassName('toggleDataset'); for(button of buttons){ button.addEventListener('click', function(e){ // クリックされたボタンに応じてデータの表示切り替え var dataId = e.target.getAttribute('data-id'); if(visibility[dataId] == 1){ // 非表示 config.data.datasets = config.data.datasets.filter( data => data != datasets[dataId] ); e.target.style = 'text-decoration: line-through;'; }else{ // 表示 config.data.datasets.push(datasets[dataId]); e.target.style = ''; } // 表示状態フラグとグラフの更新 visibility[dataId] = 1 - visibility[dataId]; window.myPieChart.update(); }); } </script> これにより、ボタンをクリックすることで円グラフ内の対応するデータの表示/非表示を切り替えることができます。 参考 - Chart.js samples - Pie https://www.chartjs.org/samples/latest/charts/pie.html
お礼
早速の回答ありがとうありがとうございます。ボタンのクリックで凡例と同じように系列の表示、非表示が出るようになりました。参考で示されていたサンプルは承知しておりますが、前に私が見た凡例として系列をを使った多重円グラフサンプルは、Chart.js samplesには載っていなくて、質問前からどこで見たのか探していましたが未だ発見に至りません。確かにURLはChart.jsのsampleでmultiple pie~htmlとあったのだけ記憶にあります。今回の回答ような方法で作られていたかも定かでありませんが動作的には表示非表示は凡例と同じようでした。私的には、chart.jsドキュメントの凡例の設定オプションと配列の書き方でどうにかならないかと思っていた次第です、如何せん基本的なグラフを作るまでしかの力ではどうにもなりませんでした。今回の回答も内容的には理解が未だ至っていないのでこれから理解に努めて参ります。繰り返しですが改めてお礼申し上げます。
補足
時間がたってからの補足です、系列をlabelsの代わりに下記のコードを追加して表示させることまでできましたが表示非表示をさせる方法までに至りません。onClickでイベントを発生させればなんとかなると思うが知識が無い! options: { title: { display: true, text:'Pie' }, legend: { // 凡例 display: true, // 表示の有無 position: 'top', // 表示位置 labels: { generateLabels: function(chart) { return chart.data.datasets.map(function(datasets,i) { return { datasetIndex: i, text:datasets.label, fillStyle: datasets.backgroundColor, strokeStyle: datasets.borderColor, }; }); } } } },
お礼
度々の回答ありがとうございました。前に見た凡例で系列の表示/非表示を下記のコードで実現できました。誠にありがとうございます。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>円グラフ</title> </head> <body> <canvas id="myPieChart" ></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script> <script type="text/javascript" src="Chart.js"></script> <script type="text/javascript" src="chartjs-plugin-colorschemes.js"></script> <script> const ctx = document.getElementById("myPieChart"); const myPieChart = new Chart(ctx, { type: 'pie', data: { labels: ['Jan','Feb','Mar','Apr','May','June'], // X軸のラベル datasets: [ { label: 'NY', data: [32, 59, 40, 42, 38, 25], }, { label: 'LA', data: [52, 45, 38, 28, 59, 40], }, { label: 'CHI', data: [65, 23, 48, 60, 62, 70], }, ] }, options: { title: { display: true, text:'Pie' }, legend: { // 凡例 display: true, // 表示の有無 position: 'top', // 表示位置 labels: { generateLabels: function(chart) { return chart.data.datasets.map(function(datasets, i) { return { datasetIndex: i, text: datasets.label, fillStyle: datasets.backgroundColor, strokeStyle: datasets.borderColor, // 表示状態に連動して取り消し線表示 hidden: !chart.isDatasetVisible(i), }; }); } }, onClick: function(e, legendItem){ const index = legendItem.datasetIndex; const ci = this.chart; const meta = ci.getDatasetMeta(index); meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null; ci.update(); } } }, plugins: { colorschemes: { scheme: 'office.Red6' //デフォルトで固定されているので効果なし? } } }); </script> </body> </html>