图表Js折线图,单击时带有其图例文本的完整信息 [英] Chart Js Line chart with fill on click with full information of its legend text
问题描述
我正在使用chart.js 2.9.3.我在选项中使用了 onClick
处理程序以及 getElementAtEvent
来实现我想要的功能但是我得到了 empty 数组,该事件没有有关被单击区域的信息.单击每个点都可以,但是单击整条线的区域并不能给我太多信息.
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.
这是图表的代码段.
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);
},
}
});
推荐答案
最后,我尝试通过单击折线图每个填充区域的区域来使用某些DOM操作来解决此问题,以获取信息.示例在这里:
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>
这篇关于图表Js折线图,单击时带有其图例文本的完整信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!