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

1

7

Using different dimensions of the same dataset, there are three dc.js Line Charts on screen.

When user clicks a datapoint on any lineChart, I wish to locate and return the data values for that corresponding point from all other charts, including the one clicked on.

I am also attempting (on mouseover) to change the circle fill color to red for the datapoint being hovered, as well as for the corresponding datapoint (same "x" value) for all other charts.

I am using the .filter() method but haven't been successful getting the desired data. The error message is: "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)
Homestretch answered 12/2, 2017 at 23:32 Comment(0)
W
10

myCSV contains all three data points, so I don't see the need to loop through the three charts independently - findAllPoints is going to find the same array entry for all three data series anyway.

The main problem you have here is that date objects don't compare equal if they have the same value. This is because == (and ===) evaluate object identity if the operands are objects:

> 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

There are two ways to deal with this.

Approach 1: use second event argument

If the items in all the charts match up item by item, you can just use the index.

All d3 callbacks pass both the datum and the index. So you can modify your callback like this:

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/

Approach 2: compare by date

If the different charts might have different data indices, you probably want to compare by date, but use Date.getTime() to get an integer you can compare with ===:

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/

Note that in either case, you're going to need to also change the opacity of the dot in the other charts, because otherwise they don't show until they are hovered.

Not sure when you want to reset this - I guess it might make more sense to show the corresponding dots on mouseover and hide them on mouseout. Hopefully this is enough to get you started!

Willpower answered 13/2, 2017 at 14:22 Comment(3)
That worked perfectly. Thanks for the two approaches - most informative and useful.Homestretch
No need to ping me, I follow the tag. =}Willpower
Thanks for the extra attention your bounty attracted to this answer, @crashwap. I guess you didn't award the bounty in time, so it disappeared into the void, but I appreciate the thought!Willpower

© 2022 - 2024 — McMap. All rights reserved.