【问题标题】:dc.js access data points in multiple charts when click datapoint in first chart单击第一个图表中的数据点时,dc.js 访问多个图表中的数据点
【发布时间】:2017-02-12 23:32:06
【问题描述】:

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

当用户单击任何 lineChart 上的数据点时,我希望从所有其他图表中找到并返回该对应点的数据值,包括单击的那个。

我还尝试(在鼠标悬停时)将悬停的数据点的圆形填充颜色更改为红色,以及所有其他图表的相应数据点(相同的“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)

【问题讨论】:

    标签: dc.js


    【解决方案1】:

    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
    

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

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

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

    所有 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 上隐藏它们可能更有意义。希望这足以让您入门!

    【讨论】:

    • 效果很好。感谢您提供的两种方法 - 信息量最大且最有用。
    • 不用ping我,我跟着标签。 =}
    • 感谢您的赏金对这个答案的额外关注,@crashwap。我猜你没有及时奖励赏金,所以它消失在虚空中,但我很感激这个想法!
    猜你喜欢
    • 2017-10-14
    • 2015-10-08
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2020-01-19
    • 1970-01-01
    • 2022-01-02
    相关资源
    最近更新 更多