Search code examples
d3.jstooltip

D3.js: Need help grabbing data for tooltip


I've got a graph of small multiples with line charts. All is spiffy, except I cannot figure out how to get the tooltip to grab the data I need it to.

The sample and the code is at http://bl.ocks.org/emagee/8b2f557396d6f16ba65f. The tooltip code starts at line 198, with the toolTip variable declared just above that. The tooltip itself is working awesomely, but I cannot figure out how to get the tooltip to show the "date" and "count" variables. I did figure out how to get the "subject" in tool tip, but that is redundant, as you will see.

Specifically, my problem stems from not knowing how to skip a level as I dig deeper into the object -- "key" is the first level, then "values", then an unnamed construct, THEN the data I need ("date" and "count").

Any guidance on how to get from "key" to the "date" and "count" data would be most appreciated. I do understand that it may be more of a basic JS problem than a D3.js problem, but I'm a bit shaky with both!

Addendum (and, I'm afraid, a second question) -- I'm also wondering now if part of the problem is that I'm accessing the entire line/path -- as opposed to individual points. Should I perhaps overlay some appropriately sized, invisible circles/points on the lines and have the tooltip try to take readings from those...


Solution

  • First question you have to ask is do you want the date and count of where they moused over or do you want the date and count of the closest point to where they moused over? I'm assuming the later, so that's what I'll answer.

    To do this, I'd use a combination of invert and a bisector:

     .on("mouseover", function(s) { 
    
       var xDate = x.invert(d3.mouse(this)[0]), //<-- give me the date at the x mouse position
         bisect = d3.bisector(function(d) { return d.date; }).left, //<-- set up a bisector to search the array for the closest point to the left
         idx = bisect(s.values, xDate); //<-- find that point given our mouse position
    

    You can now use:

    s.values[idx].date
    s.values[idx].count
    

    Here's a working example.