I am using chart.js 2.9.3. I have used onClick
handler in options as well as getElementAtEvent
to achieve what I want but I get the items empty array and the event doesn't have the the information about the area that is clicked. Clicking on each point works fine, but clicking on Area of whole line doesn't give me much information.
Here is the code snippet of my chart.
var chart_canvas = document.getElementById("myChart");
var stackedLine = new Chart(chart_canvas, {
type: 'line',
data: {
labels: ["0.0", "0.2", "0.4", "0.6", "0.8", "1.0"],
fill: true,
datasets: [{
label: 'One',
pointRadius: 3,
data: [.5, .3, .2, .1, .4, .3],
borderWidth: 1
}, {
label: 'Two',
pointRadius: 3,
data: [.0, .1, .2, .4, .1, .4],
borderWidth: 1
}]
},
options: {
responsive: true,
onClick : (event, items) =>{
console.log("event",event);
},
}
});
Finally I tried to solve this using some DOM manipulation to get the information by clicking on area of each filled area of line chart. Example is here:
https://codepen.io/amiablesyed/pen/RwKxaqE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.js"></script>
</head>
<body>
<div style="background-color: gainsboro">
Data:<span id="Data"></span>
</div>
<div style="width: 500px; height: 400px">
<canvas id="mainChart" width="700" height="400"> </canvas>
</div>
<script>
var ctx = document.getElementById("mainChart").getContext("2d");
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: [
"Red",
"Blue",
"Yellow",
"Green",
"Purple",
"Orange",
"Pink",
"Black",
"Grey",
],
datasets: [
{
lineTension: 0,
label: "Data A",
data: [11, 12, 1, 3, 1, 1, 3, 5, 2],
backgroundColor: "#ffe8e8",
borderColor: ["#ffe8e8"],
borderWidth: 1,
},
{
lineTension: 0,
label: "Data B",
data: [12, 17, 3, 5, 2, 3, 6, 8, 4],
backgroundColor: "#e2ffcb",
borderColor: ["#e2ffcb"],
borderWidth: 1,
},
{
lineTension: 0,
label: "Data C",
data: [15, 23, 6, 9, 3, 8, 7, 10, 11],
backgroundColor: "#ffe689",
borderColor: ["#ffe689"],
borderWidth: 1,
},
],
},
});
document
.getElementById("mainChart")
.addEventListener("click", function (e) {
areaClick(e);
});
function areaClick(e) {
if (!myChart.scales["y-axis-0"]._gridLineItems) return;
var gridLineH = myChart.scales["y-axis-0"]._gridLineItems[0];
var lenH = myChart.scales["y-axis-0"]._gridLineItems.length;
var width = gridLineH.x2 - gridLineH.x1;
var yMax = myChart.scales["y-axis-0"].max;
var yMaxPixcel = myChart.scales["y-axis-0"].bottom - gridLineH.y1;
var gridLineV = myChart.scales["x-axis-0"]._gridLineItems[0];
var lenV = myChart.scales["x-axis-0"]._gridLineItems.length;
var height = gridLineV.y2 - gridLineV.y1;
var xMax = myChart.scales["x-axis-0"].maxIndex;
var scaleX = width / (lenV - 1);
var scaleY = height / (lenH - 1);
var yPixcel =
yMaxPixcel - (e.pageY - e.target.offsetTop - gridLineH.y1);
var yVal = yMax * (yPixcel / yMaxPixcel);
console.log(yVal);
var curXPixcel = e.pageX - e.target.offsetLeft - gridLineH.x1;
var xVal = Math.floor(curXPixcel / scaleX);
var xAxis = myChart.scales["x-axis-0"];
var label = "Others";
if (xVal < xAxis.maxIndex && xVal >= xAxis.minIndex) {
var x1x2Pixcels = getx1x2Pixcels(xVal, gridLineH.x1);
document.getElementById("Data").innerText = getDataLable(
xVal,
yVal,
x1x2Pixcels,
curXPixcel
);
}
}
function getx1x2Pixcels(xVal, offset) {
var x1x2 = {};
x1x2.x1 =
myChart.scales["x-axis-0"]._gridLineItems[xVal].x1 - offset + 0.5;
x1x2.x2 =
myChart.scales["x-axis-0"]._gridLineItems[xVal + 1].x1 - offset + 0.5;
return x1x2;
}
function getDataLable(xVal, yVal, x1x2Pixcels, curXPixcel) {
var datasetes = myChart.config.data.datasets;
var dataLable = "";
if (datasetes.length > 1) {
for (var i = datasetes.length; i > 0; i--) {
if (myChart.getDatasetMeta(i - 1).hidden) continue;
var dataA = datasetes[i - 1];
var dataALable = dataA.label;
var y1 = dataA.data[xVal];
var y2 = dataA.data[xVal + 1];
var isBelow = IsBelowTheLine(
curXPixcel,
yVal,
x1x2Pixcels.x1,
y1,
x1x2Pixcels.x2,
y2
);
if (isBelow) {
dataLable = isBelow ? dataALable : dataLable;
if (i == 1) {
var isBelowZeroLine = IsBelowTheLine(
curXPixcel,
yVal,
x1x2Pixcels.x1,
0,
x1x2Pixcels.x2,
0
);
dataLable = isBelowZeroLine ? "" : dataLable;
}
} else break;
}
}
return dataLable;
}
function IsBelowTheLine(x, y, x1, y1, x2, y2) {
var v1 = [x2 - x1, y2 - y1];
var v2 = [x2 - x, y2 - y];
var xp = v1[0] * v2[1] - v1[1] * v2[0];
return xp >= 0;
}
</script>
</body>
</html>