dc.js 单击第一个图表中的数据点时访问多个图表中的数据点

dc.js access data points in multiple charts when click datapoint in first chart

使用同一数据集的不同维度,屏幕上显示三个 dc.js 折线图。

当用户单击任何折线图上的数据点时,我希望从所有其他图表(包括单击的图表)中找到并 return 该对应点的数据值。

我还尝试(在鼠标悬停时)将悬停的数据点的圆圈填充颜色更改为红色,以及所有其他图表的相应数据点(相同的 "x" 值)。

我正在使用 .filter() 方法,但未能成功获取所需数据。错误信息是:"Uncaught TypeError: myCSV[i].filter is not a function"

Full jsFiddle demo/example

lc1.on('renderlet', function(lc1) {
  var allDots1 = lc1.selectAll('circle.dot');
  var allDots2 = lc2.selectAll('circle.dot');
  var allDots3 = lc3.selectAll('circle.dot');
  allDots1.on('click', function(d) {
     var d2find = d.x;
     var d2find2 = d3.select(this).datum();
     console.log(myCSV);
     alert('Captured:'+"\nX-axis (Date): "+d2find2.x +"\nY-axis (Value): "+ d2find2.y +"\nDesired: display corresponding values from all three charts for this (date/time) datapoint");
     allDots2.filter(d=>d.x == d2find2).attr('fill','red');
     findAllPoints(d2find2);
  });//END allDots1.on(click);

  function findAllPoints(datum) {
     var objOut = {};
     var arrLines=['car','bike','moto'];
     for (var i = 0; i < 3; i++) {
        thisSrx = arrLines[i];
        console.log('thisSrx: '+thisSrx);
        console.log(myCSV[i].date)
        console.log(datum.x);
        //loop thru myCSV obj, compare myCSV[i].date to clicked "x" val
        //build objOut with data from each graph at same "X" (d/t) as clicked
        objOut[i] = myCSV[i].filter(e => e.date === datum.x)[0][thisSrx];
     }
     $('#msg').html( JSON.stringify(objOut) );
     console.log( JSON.stringify(objOut) );
  }//END fn findAllPoints()

});//END lc1.on(renderlet)

myCSV 包含所有三个数据点,因此我认为不需要独立循环遍历三个图表 - findAllPoints 将为所有三个数据系列找到相同的数组条目无论如何。

您在这里遇到的主要问题是,如果日期对象具有相同的值,则它们不会比较相等。这是因为如果操作数是对象,==(和===)计算对象标识

> var d1 = new Date(), d2 = new Date(d1)
undefined
> d1
Mon Feb 13 2017 09:03:53 GMT-0500 (EST)
> d2
Mon Feb 13 2017 09:03:53 GMT-0500 (EST)
> d1==d2
false
> d1.getTime()===d2.getTime()
true

有两种方法可以解决这个问题。

方法 1:使用第二个事件参数

如果所有图表中的项目逐项匹配,则可以使用索引。

所有 d3 回调都传递数据和索引。所以你可以像这样修改你的回调:

allDots1.on('click', function(d,i) {
  // ...
  allDots2.filter((d,j)=> j===i).attr('fill','red').style('fill-opacity', 1);
  alert(JSON.stringify(myCSV[i]));
});

http://jsfiddle.net/gordonwoodhull/drbtmL77/7/

方法 2:按日期比较

如果不同的图表可能有不同的数据索引,您可能想按日期进行比较,但使用 Date.getTime() 得到一个整数,您可以与 ===:

进行比较
allDots1.on('click', function(d) {
  var d2find = d.x;
  // ...
  allDots2.filter(d=> d.x.getTime()===d2find.getTime()).attr('fill','red').style('fill-opacity', 1);
  var row = myCSV.filter(r=>r.date.getTime()===d2find.getTime())
  alert(JSON.stringify(row));
});

http://jsfiddle.net/gordonwoodhull/drbtmL77/10/

请注意,在任何一种情况下,您还需要更改其他图表中圆点的不透明度,否则它们在悬停之前不会显示。

不确定何时要重置它 - 我想在 mouseover 上显示相应的点并在 mouseout 上隐藏它们可能更有意义。希望这足以让您入门!