问题描述
我使用的是 chart.js 2.9.3。 我在选项中使用了 onClick
处理程序以及 getElementAtEvent
来实现我想要的,但我得到了项目 empty 数组,事件没有点击区域的信息。点击每个点工作正常,但点击整条线的面积并没有给我太多信息。
这是我的图表的代码片段。
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',data: [.0,.4],borderWidth: 1
}]
},options: {
responsive: true,onClick : (event,items) =>{
console.log("event",event);
},}
});
解决方法
最后,我尝试使用一些 DOM 操作来解决这个问题,通过单击折线图每个填充区域的区域来获取信息。 示例在这里:
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,5,2],backgroundColor: "#ffe8e8",borderColor: ["#ffe8e8"],borderWidth: 1,},{
lineTension: 0,label: "Data B",data: [12,17,2,6,8,4],backgroundColor: "#e2ffcb",borderColor: ["#e2ffcb"],label: "Data C",data: [15,23,9,7,10,11],backgroundColor: "#ffe689",borderColor: ["#ffe689"],});
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,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,x1x2Pixcels.x1,y1,x1x2Pixcels.x2,y2
);
if (isBelow) {
dataLable = isBelow ? dataALable : dataLable;
if (i == 1) {
var isBelowZeroLine = IsBelowTheLine(
curXPixcel,0
);
dataLable = isBelowZeroLine ? "" : dataLable;
}
} else break;
}
}
return dataLable;
}
function IsBelowTheLine(x,y,x1,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>