JustLooking
JustLooking

Reputation: 2486

Chart.js OnClick event with a mixed chart, which chart did I click?

EDIT: Modified to add options, and a suggested (from the answer) chartClickEvent, here is a jsfiddle: http://jsfiddle.net/jmpxgufu/174/

Imagine if you will a Chart.js mixed chart with the following config:

var config = {
   type: 'bar',
   data: {
      labels: ["Test","Test","Test"],
      datasets: [{
         label: 'Dataset1',
         yAxisID: 'Dataset1',
         type: "line",
         borderColor: "red",
         backgroundColor: "red",
         data: [70,60,50],
         fill: false
      },
      {
         label: 'Dataset0',
         type: "bar",
         backgroundColor: "blue",
         data: [100,90,80]
      }]
   },
   options: {
      scales: {
         xAxes: [{ barPercentage: 1.0 }],
         yAxes: [{ id: 'Dataset1', position: 'left', type: 'linear',
                   ticks: { display: false, min: 0, beginAtZero: true, max: 120 },
                   scaleLabel: { display: true, labelString: "TestScale" } }]
      },
      responsive: true,
      maintainAspectRatio: false,
      legend : { display: true, position: 'bottom' },
      onClick: chartClickEvent
   }
}; // end of var config

function chartClickEvent(event, array)
{
   if (window.myChart === undefined || window.myChart == null)
   {
      return;
   }
   if (event === undefined || event == null)
   {
      return;
   }
   if (array === undefined || array == null)
   {
      return;
   }
   if (array.length <= 0)
   {
      return;
   }
   var active = window.myChart.getElementAtEvent(event);
   if (active === undefined || active == null)
   {
      return;
   }
   var elementIndex = active[0]._datasetIndex;
   console.log("elementIndex: " + elementIndex + "; array length: " + array.length);
   if (array[elementIndex] === undefined || array[elementIndex] == null)
   {
      return;
   }

   var chartData = array[elementIndex]['_chart'].config.data;
   var idx = array[elementIndex]['_index'];

   var label = chartData.labels[idx];
   var value = chartData.datasets[elementIndex].data[idx];
   var series = chartData.datasets[elementIndex].label;

   alert(series + ':' + label + ':' + value);
}

As my chartClickEvent says, my array is length 2, because I have two charts. That's great and all, but I have no idea how to figure out whether to use array[0] or array[1]. If they click specifically the line data point, I want to do something with that data (array[0]), if they click the big blue bar, I want to do something with that data (array[1]). How do I tell whether they clicked on the line or the bar?

Thank you.

Upvotes: 6

Views: 12723

Answers (2)

fruitloaf
fruitloaf

Reputation: 2930

In Treemap under OPTIONS:

        options: {
            onClick: (el: any, arr: any) =>
                console.log('item clicked', arr[0]._index),

You pass 2 arguments into the 'onClick' function, the names can be anything, BUT first argument is EVENT, second argument is an [N] array.

Second argument is the one you need.

inside this [N] array, if you console.log it, you will see 2 things you can use to identify, which DATA is being clicked on the Treemap.

either:

  1. _index: arr[0]._index
  2. _options.backgroundColor: arr[0]._options.backgroundColor

You can console.log this array:

            onClick: (el: any, arr: any) =>
                console.log('item clicked', arr[0]),

and see other things related to your chart, BUT I found Index to be the easiest to use.

Upvotes: 0

Matt
Matt

Reputation: 1082

HTML

<div id="test" style="height:600px; width:600px;">
    <canvas id="myCanvas" style="border: 1px solid black; margin: 25px 25px, display: none;" height="300" >Canvas</canvas>
</div>

JS

var ctx = document.getElementById("myCanvas");
var newArr;

var config = new Chart(ctx,{
   type: 'bar',
   data: {
      labels: ["Test","Test","Test"],
      datasets: [{
         label: 'Dataset1',
         yAxisID: 'Dataset1',
         type: "line",
         borderColor: "red",
         backgroundColor: "red",
         data: [70,60,50],
         fill: false
      },
      {
         label: 'Dataset0',
         type: "bar",
         backgroundColor: "blue",
         data: [100,90,80]
      }]
   },
   options: {
      scales: {
         xAxes: [{ barPercentage: 1.0 }],
         yAxes: [{ id: 'Dataset1', position: 'left', type: 'linear',
                   ticks: { display: false, min: 0, beginAtZero: true, max: 120 },
                   scaleLabel: { display: true, labelString: "TestScale" } }]
      },
      responsive: true,
      maintainAspectRatio: false,
      legend : { display: true, position: 'bottom' },
      onClick: chartClickEvent
   }
}); // end of var config

function chartClickEvent(event, array){
   if(typeof newArr === 'undefined'){
        newArr = array;
   }

   if (window.config === 'undefined' || window.config == null)
   {
      return;
   }
   if (event === 'undefined' || event == null)
   {
      return;
   }
   if (newArr === 'undefined' || newArr == null)
   {
      return;
   }
   if (newArr.length <= 0)
   {
      return;
   }
   var active = window.config.getElementAtEvent(event);
   if (active === 'undefined' || active == null || active.length === 0)
   {
      return;
   }

   var elementIndex = active[0]._datasetIndex;
   console.log("elementIndex: " + elementIndex + "; array length: " + newArr.length);

   if (newArr[elementIndex] === 'undefined' || newArr[elementIndex] == null){
      return;
   }

   var chartData = newArr[elementIndex]['_chart'].config.data;
   var idx = newArr[elementIndex]['_index'];

   var label = chartData.labels[idx];
   var value = chartData.datasets[elementIndex].data[idx];
   var series = chartData.datasets[elementIndex].label;

   alert(series + ':' + label + ':' + value);
}

Upvotes: 7

Related Questions