9

I'm usinging v1.7.1 of nvd3. I have a page in which I render rows of charts with the same configuration but different data. I'm using interactive tooltip option on the multi line chart. The tooltip is rendering correctly, but as you scroll down the page, when you rollover the line, the tooltip is being rendered in the same position at the top of the page. It appears that the first few rows render the tooltip in the appropriate position but as you scroll down the tooltip goes out of view. I've tried manipulating the position with the tooltipContent (which seems to be the api available), but this doesn't work. Something like below:

var chartOffset = $(id + ' svg').offset(),
        x = chartOffset.left,
        y = chartOffset.top;
      //chart.tooltip.position({"top":top,"left":left});
      //chart.interactiveLayer.tooltip.fixedTop(null);
     chart.tooltipContent(function (key, x, y, e) {
        if (e.value >= 0) {
          return '<h3>' + key + '</h3>' +
            '<p>' + y + ' at ' + x + '</p>';
        } else {
          return '';
        }
      });

I've also tried styling .nvtooltip margin, but didn't see a fix.enter image description here

The picture below shows how the tool tip has become very disconnected from the line that you're mousing

Any hints at fixing this?

Here are full nvd3 chart options:

var chart = nv.models.lineChart()
        .height(height)
        .width(width)
        .forceY([0, 1])
        .x(function (d) {
          return new Date(d[0]);
        })
        .y(function (d) {
          return d[1];
        })
        .color(chartcolors)
        .useInteractiveGuideline(true)
        .tooltips(true);

      chart.xAxis
        .axisLabel("")
        .tickFormat(function (d) {
          return d3.time.format('%x')(new Date(d))
        });

      chart.yAxis
        .axisLabel(yaxisLabel)
        .tickFormat(d3.format(',.1%'));

      chart.showLegend(true);

      var chartOffset = $(id + ' svg').offset(),
        x = chartOffset.left,
        y = chartOffset.top;

     chart.tooltipContent(function (key, x, y, e) {
        if (e.value >= 0) {
          return '<h3>' + key + '</h3>' +
            '<p>' + y + ' at ' + x + '</p>';
        } else {
          return '';
        }
      });
Rebecca Peltz
  • 177
  • 1
  • 7

3 Answers3

6

I discovered a similar bug in 1.8.6-dev just today and fixed it by adding window.scrollY to top on line 742 by changing this block:

    var positionTooltip = function() {
    nv.dom.read(function() {
        var pos = position(),
            gravityOffset = calcGravityOffset(pos),
            left = pos.left + gravityOffset.left,
            top = pos.top + gravityOffset.top;

To:

    var positionTooltip = function() {
    nv.dom.read(function() {
        var pos = position(),
            gravityOffset = calcGravityOffset(pos),
            left = pos.left + gravityOffset.left,
            top = pos.top + gravityOffset.top+window.scrollY;

In this case, it was not that there's a bug with multiple charts so much as there is a bug with scrolling, which is usually implied when one page has multiple charts.

RedScourge
  • 976
  • 1
  • 8
  • 12
  • Wow, that's a big bug! Solved the problem for me! Did you submit a pull request? – Fabian Jul 11 '19 at 18:47
  • I wasn't very familiar with Git at the time, but someone else did. I recently received an email claiming that pull request was merged in, so I assume the bug is now fixed on the latest version. – RedScourge Aug 02 '19 at 05:24
  • I have the same problem and your solution works for chrome and edge, but for IE it shows now the tooltip always in the top left corner. Do you have a solution for this? Thanks – Kᴀτᴢ Nov 29 '19 at 14:02
  • @Katz I would try wrapping an extra DIV tag around the chart and setting it to position:relative; and see if that solves it. It sounds like the tooltips, which I assume use CSS position: absolute; are becoming relative to the page container or viewport due to a lack of a direct parent being set to relative. – RedScourge Dec 09 '19 at 01:01
  • @Katz I tried my suggestion and it didn't work. I suspect there is no solution for IE11. It is quite possible that there is no reasonably possible way to solve this, due to some sort of IE-specific limitations. – RedScourge Dec 09 '19 at 01:08
2

I fixed my problem by changing the default gravity to 's'. I couldn't figure out how to set it as an option, so I just changed the nvd3 code. I'd love to just change it as an option, but the docs weren't clear on that.

Rebecca Peltz
  • 177
  • 1
  • 7
1

I had a similar problem. The current implementation of the nvd3's native showTooltip method looks as follows:

var showTooltip = function(e, offsetElement) {
  var left = e.pos[0] + ( offsetElement.offsetLeft || 0),
    top = e.pos[1] + ( offsetElement.offsetTop || 0),
    x = xAxis.tickFormat()(multibar.x()(e.point, e.pointIndex)),
    y = yAxis.tickFormat()(multibar.y()(e.point, e.pointIndex)),
    content = tooltip(e.series.key, x, y, e, chart);

  nv.tooltip.show([left, top], content, e.value < 0 ? 'e' : 'w', null, offsetElement);
};

The implementation mis-align tooltips in different ways. So I've modified the behavior which fixed the problem for me. You can check out my fork https://github.com/ovvn/nvd3/blob/master/build/nv.d3.js

Osman Mazinov
  • 1,436
  • 11
  • 33
  • Thanks for the post. I tried just plugging in your code and it didn't fix my problem. It seems like my problem comes from line 832: if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; This is calculating to -1768 and I think that is what is pushing it off the page when you scroll down an attempt to look at tooltips. – Rebecca Peltz Apr 13 '15 at 17:28
  • I fixed my problem by changing the default gravity to 's'. I couldn't figure out how to set it as an option, so I just changed the nvd3 code. I'd love to just change it as an option, but the docs weren't clear on that. – Rebecca Peltz Apr 13 '15 at 17:46
  • Well, according to [documentation](http://nvd3-community.github.io/nvd3/examples/documentation.html) there's an option, i.e. chart.tooltip.gravity("n") – Osman Mazinov Apr 13 '15 at 19:14
  • chart.tooltip.gravity('s'); --> Uncaught TypeError: Cannot read property 'gravity' of undefined The docs don't see up to date. I'm not sure how to get ahold of the tooltip from the chart - anyone? – Rebecca Peltz Apr 14 '15 at 20:10
  • 3
    finally figured it out: chart.interactiveLayer.tooltip.gravity('s'); you get access to the tooltip as a property of the chart.interactiveLayer – Rebecca Peltz Apr 17 '15 at 21:03
  • Glad you've figured it out – Osman Mazinov Apr 20 '15 at 11:48
  • is there any update for this using the new version of nvd3? – Dinesh Oct 20 '16 at 19:31