如何使用 Chart.js 向我的折线图添加点击事件

Posted

技术标签:

【中文标题】如何使用 Chart.js 向我的折线图添加点击事件【英文标题】:How to add an on click event to my Line chart using Chart.js 【发布时间】:2014-10-20 07:24:58 【问题描述】:

我正在尝试使用Chart.js 将点击事件添加到我的折线图中。我已经启用了工具提示来显示折线图中的信息,但我还想添加一个点击方法,让我知道用户在 x 轴上点击的位置。现在我只想弹出一个警报,给我用户点击的 x 轴上的值。

研究:

我查看了documentation of Chart.js,发现了这个方法:.getPointsAtEvent(event)

在您的 Chart 实例上调用 getPointsAtEvent(event) 传递一个 事件或 jQuery 事件的参数将返回点元素 与该事件的位置相同。

canvas.onclick = function(evt)
    var activePoints = myLineChart.getPointsAtEvent(evt);
    // => activePoints is an array of points on the canvas that are at the same position as the click event. ;

我只是不知道如何使用或在我的代码中放置函数的位置。如果有人能帮我弄清楚我可以在哪里将它添加到我的代码中,将不胜感激!

我的代码:(在 javascript 中)

  //NOTE: the div 'roomForChart' has been already declared as <div id="roomForChart"></div>


 //creating html code inside of javascript to display the canvas used for the graph
 htmlForGraph = "<canvas id='myChart' width ='500' height='400'>";
 document.getElementById('roomForChart').innerHTML += htmlForGraph;

 //NOW TO CREATE DATA

   //the data for my line chart
    var data = 
         labels: ["Aug 1", "Aug 2", "Aug 3","Aug 4","Aug 5"], //the x axis
          datasets: [
               //my red line
                label: "Usage Plan",
                fillColor: "rgba(255,255,255,0.2)", //adds the color below the line
                strokeColor: "rgba(224,0,0,1)",//creates the line
                pointColor: "rgba(244,0,0,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(220,220,220,1)",
                data: [1024, 1024, 1024, 1024, 1024]
           ,

           //my green line
            label: "Overall Usage",
            fillColor: "rgba(48,197,83,0.2)",
            strokeColor: "rgba(48,197,83,1)",
            pointColor: "rgba(48,197,83,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(48,197,83,1)",
            data: [15, 25, 45, 45, 1500]
       ,
          //my blue line
            label: "Daily Usage",
            fillColor: "rgba(151,187,205,0.2)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(151,187,205,1)",
            data: [15, 10, 20, 0, 5]
       

     ] //ending the datasets
     ; //ending data


    //creating a variable for my chart
    var ctx = document.getElementById("myChart").getContext("2d");




//code to create a maximum y value on the chart
var maxUsage = 1024;
var maxSteps = 5;
var myLineChart = new Chart(ctx).Line(data, 
    pointDot: false,
    scaleOverride: true,
    scaleSteps: maxSteps,
    scaleStepWidth: Math.ceil(maxUsage / maxSteps),
    scaleStartValue: 0

);

 //what I have tried but it doesn't show an alert message
ctx.onclick = function(evt)
    var activePoints = myLineChart.getPointsAtEvent(evt);
    // => activePoints is an array of points on the canvas that are at the same position as the click event.
   alert("See me?");
;

对于那些难以在此处可视化图表的人:

希望我已经提供了足够的信息来获得帮助。如果我需要解释自己,请告诉我。先感谢您!!! :)

【问题讨论】:

【参考方案1】:

如果您使用的是新的 ChartJs 版本,请使用:

canvas.onclick = function(evt)
   var activePoints = myLineChart.getElementsAtEvent(evt);
;

【讨论】:

谢谢兄弟,你节省了我的时间^_^!它非常适用于新的 charjs 版本。 非常感谢。在 2.1.6 版本中解决了我的问题。【参考方案2】:

改变这一行

document.getElementById('roomForChart').innerHTML += htmlForGraph;

到这里

holder = document.getElementById('roomForChart');
holder.innerHTML += htmlForGraph;

你还会有你的 sn-p,稍微修改一下

holder.onclick = function(evt)
    var activePoints = myLineChart.getPointsAtEvent(evt);
    // => activePoints is an array of points on the canvas that are at the same position as the click event.
   alert("See me?");
;

在 onclick 处理程序中添加 console.log(activePoints); 以查看 activePoints 变量的内容。如我所见,共有三个对象。例如,这些是 activePoints[0] 的值

datasetLabel: "Usage Plan"
fillColor: "rgba(244,0,0,1)"
highlightFill: "#fff"
highlightStroke: "rgba(220,220,220,1)"
label: "Aug 4"
strokeColor: "#fff"
value: 1024
x: 371
y: 12.356097560975627

它们可以通过以下方式访问

activePoints[0].label
activePoints[0].x
activePoints[0].y
activePoints[0].value

最好先检查属性是否为undefined,因为每个点击事件背后都没有数据。

【讨论】:

你摇滚!我知道我很接近了!感谢您建议我使用支架。我从来没想过! 快速提问!当我写 alert(activePoints);弹出一个警报,其中没有任何信息(我猜它是空的或空的)。我如何获取/提取这些信息? @MadsterMaddness 我刚刚在读那部分;我会在几分钟内给你写一封信;只是为了弄清楚输出的格式。 @MadsterMaddness 关键是图表上的每个像素都没有数据,这就是为什么我在某个点击事件上收到undefined 错误。因此,只需在提醒或显示之前检查该属性是否为undefined ;) 并检查最后一次更新。 我向 activePoints[0] 添加了控制台日志。结果我一直得到[信息],直到我点击图表时奇迹般地得到了:[信息](JavaScript.KKJSObject)值:1024d,标签:“8月5日”,datasetLabel:“使用计划” , strokeColor : "#fff", fillColor : "rgba(244,0,0,1)", ... 为什么图表不能像工具提示一样将标签四舍五入到最接近的值?【参考方案3】:

我无法让onclick 方法工作。

但我终于设法使用click 方法运行它:

$("#canvas_id").click(function(e) 
   var activeBars = myBarChart.getBarsAtEvent(e); 
   console.log(activeBars[0]);
);

注意:此示例适用于条形图 - 其他图表检索点的方法略有不同(请参阅文档)。

【讨论】:

我尝试使用这种方法,但它对我不起作用,我知道为什么。附加了单击事件我还调试了函数 getBarsAtEvent 但检索到的栏不是我刚刚单击的栏,或者有时只是没有检索任何数据。 getPointsAtEvent 是您可以在点击事件中传递的方法,它会在该事件的位置返回一个点数组,但在我的情况下有时会检索一个空数组。【参考方案4】:

迄今为止提供的答案接近正确的解决方案,但不完整。您需要使用 getElementsAtEvent() 来获取正确的元素,但这会为您提供位于单击的 x-index 处的元素集合。即使您使用多个数据集,这也可能是多个值,每个数据集一个。

要找出要从中提取的正确数据集,请调用 getDatasetAtEvent() 方法。这将返回包含单击的数据集元素的元素列表。从其中任何一个中选择数据集 Id,它们都是相同的 Id。

将两者放在一起,您就可以计算出单击元素中包含的数据。在初始化数据集时传递的不仅仅是 x 和 y 值,还可以让你对这个事件做各种巧妙的技巧。 (例如,触发包含有关事件的更详细信息的弹出窗口)

可能有一种更简洁的方式来获取这些数据,但我没有发现它在图表文档和票证周围乱七八糟。也许他们会在未来的版本中添加它。

// chart_name is whatever your chart object is named. here I am using a
// jquery selector to attach the click event.
$('#' + chart_name).click(function (e)

    var activePoints = myChart.getElementsAtEvent(event);
    var activeDataSet = myChart.getDatasetAtEvent(event);

    if (activePoints.length > 0)
    
         var clickedDatasetIndex = activeDataSet[0]._datasetIndex;
         var clickedElementIndex = activePoints[0]._index;
         var value = myChart.data.datasets[clickedDatasetIndex].data[clickedElementIndex];
    
    // todo: add code to do something with value.
);

【讨论】:

你是英雄!【参考方案5】:

V3

您还可以使用 build in onClick 选项,它获取以下参数:(event, activeElements, chartInstance)

因此,您只需读取作为第二个元素获得的数组,即可查看哪些元素处于活动状态。默认情况下,此数组仅包含 1 个项目,但如果您更改交互模式,此处可能会包含多个项目。

var options = 
  type: 'bar',
  data: 
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: 'pink'
      ,
      
        label: '# of Points',
        data: [7, 11, 5, 8, 3, 7],
        backgroundColor: 'orange'
      
    ]
  ,
  options: 
    onClick: (evt, activeElements, chart) => 
      console.log(`DatasetIndex: $activeElements[0].datasetIndex DataIndex: $activeElements[0].index`)
    
  


var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <canvas id="chartJSContainer"  ></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>

在 v3 中,getElementsAtEvent 已被删除,现在您必须使用:chart.getElementsAtEventForMode(event, 'index', intersect: true , false)

如果你想使用getDatasetAtEvent,你现在必须使用:chart.getElementsAtEventForMode(e, 'dataset', intersect: true , false)

【讨论】:

以上是关于如何使用 Chart.js 向我的折线图添加点击事件的主要内容,如果未能解决你的问题,请参考以下文章

chart.js 折线图不显示超过图表中某个点的线

向 Chart.js 折线图添加标题

为啥EXCEL做出的折线图 初始点不在0 如图

Chart.js - 如何在加载时将折线图数据集设置为禁用

ChartJS - 标签背景

Chart.js 折线图未显示