公私で Chart.js をよく使っています。D3.js と並ぶビジュアライゼーションライブラリですが、各種グラフを描く、という目的であれば Chart.js の方が使いやすいと思っています:

この Chart.js を使って、例えば積み上げ式の棒グラフを描くのであれば、こんな感じで記述します。HTML5 Canvas と JavaScript を使ってデータやオプションを指定して描画します:
このページをウェブブラウザで表示すると以下のようになります。単にグラフが表示されるだけではなく、マウスオーバー時のインタラクティブな処理なども自動的に行われます:

また canvas のコンテキスト要素を使うことで Chart.js のチャートに各データ(棒グラフであれば棒の部分)をクリックした時のイベントハンドリングを実装することも可能です:
で、上記で取得した item というのが「クリックされたオブジェクト」となり、上記のような方法で取得できるのですが、意外と難しかったのが「配列の何番目のデータがクリックされたのか?」を調べる方法でした。上記の方法でクリックされたオブジェクトそのものを取得することはできますし、その中の数値などを取り出すこともできますが、配列の何番目のデータがクリックされたのか? という情報を取得するのに手間取ってしまいまいました。
この辺り、業務で Chart.js を使う機会があったのでそのタイミングで調べてみました。答はこんな方法でした:
最初はこの方法がわからず、クリックイベントのマウス位置やオフセット位置から計算しようとしていたのですが、これだとブラウザごとの違いを意識する必要があり、面倒なコードになってしまっていました。
結論としては上記の item オブジェクトの中の _index という属性に隠れていたようです。ちなみに最初のオブジェクトは 0、2番目のオブジェクトの場合は 1 になるようです。
(追記 2020/04/10)
誤字のご指摘があり、getElementByEvent を getElementAtEvent に修正しました。
(追記終わり)

この Chart.js を使って、例えば積み上げ式の棒グラフを描くのであれば、こんな感じで記述します。HTML5 Canvas と JavaScript を使ってデータやオプションを指定して描画します:
<html> <head> <meta charset="utf8"/> <script type="text/javascript" src="//code.jquery.com/jquery-2.0.3.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.min.js"></script> <script> $(function(){ //. 乱数を使ってデータを生成 var label_data = []; var red_data = []; var green_data = []; var blue_data = []; for( var i = 0; i < 10; i ++ ){ label_data.push( i ); red_data.push( Math.floor( Math.random() * 100 ) ); green_data.push( Math.floor( Math.random() * 100 ) ); blue_data.push( Math.floor( Math.random() * 100 ) ); } var ctx = document.getElementById( 'myChart' ); var myChart = new Chart( ctx, { type: 'bar', data: { labels: label_data, datasets: [{ label: 'Red', borderWidth: 1, backgroundColor: "#ffaaaa", borderColor: "#ff5555", data: red_data }, { label: 'Green', borderWidth: 1, backgroundColor: "#aaffaa", borderColor: "#55ff55", data: green_data },{ label: 'Blue', borderWidth: 1, backgroundColor: "#aaaaff", borderColor: "#5555ff", data: blue_data }] }, options: { title: { display: true, text: '3色', padding: 3 }, scales: { xAxes: [{ stacked: true, categoryPercentage: 0.4 }], yAxes: [{ stacked: true }] }, legend: { labels: { boxWidth: 30, padding: 20 }, display: true }, tooltips: { mode: 'label' } } }); }); </script> </head> <body> <canvas id="myChart" style="position:relative; width:800; height:200;"></canvas> </body> </html>
このページをウェブブラウザで表示すると以下のようになります。単にグラフが表示されるだけではなく、マウスオーバー時のインタラクティブな処理なども自動的に行われます:

また canvas のコンテキスト要素を使うことで Chart.js のチャートに各データ(棒グラフであれば棒の部分)をクリックした時のイベントハンドリングを実装することも可能です:
<html>
<head>
<meta charset="utf8"/>
<script type="text/javascript" src="//code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.min.js"></script>
<script>
$(function(){
//. 乱数を使ってデータを生成
var label_data = [];
var red_data = [];
var green_data = [];
var blue_data = [];
for( var i = 0; i < 10; i ++ ){
label_data.push( i );
red_data.push( Math.floor( Math.random() * 100 ) );
green_data.push( Math.floor( Math.random() * 100 ) );
blue_data.push( Math.floor( Math.random() * 100 ) );
}
var ctx = document.getElementById( 'myChart' );
var myChart = new Chart( ctx, {
type: 'bar',
data: {
labels: label_data,
datasets: [{
label: 'Red',
borderWidth: 1,
backgroundColor: "#ffaaaa",
borderColor: "#ff5555",
data: red_data
},
{
label: 'Green',
borderWidth: 1,
backgroundColor: "#aaffaa",
borderColor: "#55ff55",
data: green_data
},{
label: 'Blue',
borderWidth: 1,
backgroundColor: "#aaaaff",
borderColor: "#5555ff",
data: blue_data
}]
},
options: {
title: {
display: true,
text: '3色',
padding: 3
},
scales: {
xAxes: [{
stacked: true,
categoryPercentage: 0.4
}],
yAxes: [{
stacked: true
}]
},
legend: {
labels: {
boxWidth: 30,
padding: 20
},
display: true
},
tooltips: {
mode: 'label'
}
}
});
//. クリックイベントハンドラー
ctx.addEventListener( 'click', function( evt ){
var item = myChart.getElementByEvent( evt );
var item = myChart.getElementAtEvent( evt );
if( item.length == 0 ){
return;
}
item = item[0]; //. クリックしたオブジェクトデータ(棒)
});
});
</script>
</head>
<body>
<canvas id="myChart" style="position:relative; width:800; height:200;"></canvas>
</body>
</html>
で、上記で取得した item というのが「クリックされたオブジェクト」となり、上記のような方法で取得できるのですが、意外と難しかったのが「配列の何番目のデータがクリックされたのか?」を調べる方法でした。上記の方法でクリックされたオブジェクトそのものを取得することはできますし、その中の数値などを取り出すこともできますが、配列の何番目のデータがクリックされたのか? という情報を取得するのに手間取ってしまいまいました。
この辺り、業務で Chart.js を使う機会があったのでそのタイミングで調べてみました。答はこんな方法でした:
<html> <head> <meta charset="utf8"/> <script type="text/javascript" src="//code.jquery.com/jquery-2.0.3.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.2.1/Chart.min.js"></script> <script> $(function(){ //. 乱数を使ってデータを生成 var label_data = []; var red_data = []; var green_data = []; var blue_data = []; for( var i = 0; i < 10; i ++ ){ label_data.push( i ); red_data.push( Math.floor( Math.random() * 100 ) ); green_data.push( Math.floor( Math.random() * 100 ) ); blue_data.push( Math.floor( Math.random() * 100 ) ); } var ctx = document.getElementById( 'myChart' ); var myChart = new Chart( ctx, { type: 'bar', data: { labels: label_data, datasets: [{ label: 'Red', borderWidth: 1, backgroundColor: "#ffaaaa", borderColor: "#ff5555", data: red_data }, { label: 'Green', borderWidth: 1, backgroundColor: "#aaffaa", borderColor: "#55ff55", data: green_data },{ label: 'Blue', borderWidth: 1, backgroundColor: "#aaaaff", borderColor: "#5555ff", data: blue_data }] }, options: { title: { display: true, text: '3色', padding: 3 }, scales: { xAxes: [{ stacked: true, categoryPercentage: 0.4 }], yAxes: [{ stacked: true }] }, legend: { labels: { boxWidth: 30, padding: 20 }, display: true }, tooltips: { mode: 'label' } } }); //. クリックイベントハンドラー ctx.addEventListener( 'click', function( evt ){var item = myChart.getElementByEvent( evt );var item = myChart.getElementAtEvent( evt ); if( item.length == 0 ){ return; } item = item[0]; var index = item._index; //. 配列の何番目のデータがクリックされたか var item_data = item._chart.config.data.datasets; //. クリックされたオブジェクトのデータセット console.log( index ); console.log( item_data ); }); }); </script> </head> <body> <canvas id="myChart" style="position:relative; width:800; height:200;"></canvas> </body> </html>
最初はこの方法がわからず、クリックイベントのマウス位置やオフセット位置から計算しようとしていたのですが、これだとブラウザごとの違いを意識する必要があり、面倒なコードになってしまっていました。
結論としては上記の item オブジェクトの中の _index という属性に隠れていたようです。ちなみに最初のオブジェクトは 0、2番目のオブジェクトの場合は 1 になるようです。
(追記 2020/04/10)
誤字のご指摘があり、getElementByEvent を getElementAtEvent に修正しました。
(追記終わり)