【问题标题】:Chart.js OnClick event with a mixed chart, which chart did I click?Chart.js OnClick 事件与混合图表,我点击了哪个图表?
【发布时间】:2017-10-10 17:50:28
【问题描述】:

编辑:修改为添加选项,以及建议的(来自答案)chartClickEvent,这是一个 jsfiddle:http://jsfiddle.net/jmpxgufu/174/

想象一下,如果您将使用以下配置的 Chart.js 混合图表:

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);
}

正如我的 chartClickEvent 所说,我的数组长度为 2,因为我有两个图表。这很好,但我不知道如何确定是使用数组 [0] 还是数组 [1]。如果他们专门点击线数据点,我想用那个数据(数组[0])做点什么,如果他们点击蓝色的大条,我想用那个数据做点什么(数组[1])。如何判断他们点击的是线条还是栏?

谢谢。

【问题讨论】:

  • 使用array[0]array[1] 是什么意思?你可以使用任何你想要的东西。请记住,数组的顺序可能与您作为数据输入的顺序相同。
  • 是的,我同意。我的意思是我想弄清楚他们是否点击了栏或线条。正如我所提到的,array[0] 将包含有关线的信息,array[1] 将包含有关条的信息。换句话说,我的代码中有一个点我会执行: var chartData = array[0]['_chart'].config.data;如果它是我想要数据的行,或者 var chartData = array[1]['_chart'].config.data;如果它是我想要数据的酒吧。但是我怎么知道他们是否点击了线条与条形?是的,我有一个长度为 2 的数组,但我使用这两项中的哪一项?
  • 尝试调试event 对象。它可能包含event.target
  • 是的,我一直在摆弄它,希望我能从那里得到它。 event 是 PointerEvent,当然,但 event.target 是一个 HTMLCanvasElement 对象,而 event.target.id 是图表区域(这只是我给我的画布标签的 id(它包含在一个 div 标签中)。所以我很难检查此 CanvasElement 以获取我需要的信息。

标签: javascript charts chart.js2


【解决方案1】:

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);
}

【讨论】:

  • 带上它进行虚拟拥抱!谢谢!
  • 呃-哦。在使用 datasetIndex 时发现了一个错误。假设您有一条线和一条条(如我的示例)。该行的 datasetIndex 为 0,条形的 datasetIndex 为 1。数组的长度为 2。到目前为止,一切都很好。这就是问题所在:如果通过使用 chart.js 图例,我隐藏了线条,这就是我得到的(因为现在只有一个条):datasetIndex 为 1,数组大小为 1!所以,现在我已经超过了数组的长度。如何根据可见的内容找到真正的“索引”?
  • 显然,在这种情况下,我只有一个条和一条线。因此,当然,如果数组长度为 1,我可以从该数组中获取第 0 个索引。但这是将此事件硬编码到该数据中。我正在寻找一个通用的解决方案。我的意思是,例如,假设有 6 条条和线,你从图例中隐藏了 3 个项目,你得到的 dataIndex 是 5,数组长度是 3。现在你会怎么做?这就是为什么我一直在寻找通用的东西。
  • 你在做什么来得到这个错误?我放置了另一个线或条形数据集并隐藏了中间的数据集,我会收到Unable to get property '_datasetIndex' of undefined or null reference 错误,但我仍然可以单击其他 2 个并获取它们的索引。如果您现在可以让我知道您正在尝试用它做什么,那么我可以重新创建问题并提供更好的帮助
  • 我修改了我的原始问题以包含我正在使用的选项,以及我放在一起的 chartClickEvent(使用 config.getElementAtEvent)。我认为您所描述的错误。如果隐藏了某些东西,我不应该变得不确定。例如,只有一个简单的条和线(我没有改变它),在第一次加载时,如果我点击蓝色的大条(其中任何一个,我选择了第一个),我会收到一条警报,上面写着:Dataset0:测试:100(我想从该数据元素中获得的所有信息)。 console.log 告诉我该栏是 elementIndex 1,数组长度为 2。
猜你喜欢
  • 2017-08-08
  • 2016-09-04
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
相关资源
最近更新 更多