nvd3.js tooltip position with multiple charts
Asked Answered
A

3

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 '';
        }
      });
Asha answered 10/4, 2015 at 22:46 Comment(0)
C
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

Contorted answered 11/4, 2015 at 10:46 Comment(7)
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.Asha
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.Asha
Well, according to documentation there's an option, i.e. chart.tooltip.gravity("n")Contorted
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?Asha
finally figured it out: chart.interactiveLayer.tooltip.gravity('s'); you get access to the tooltip as a property of the chart.interactiveLayerAsha
Glad you've figured it outContorted
is there any update for this using the new version of nvd3?Alberich
B
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.

Bathometer answered 22/5, 2018 at 9:48 Comment(5)
Wow, that's a big bug! Solved the problem for me! Did you submit a pull request?Single
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.Bathometer
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? ThanksEnteric
@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.Bathometer
@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.Bathometer
A
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.

Asha answered 13/4, 2015 at 17:46 Comment(0)
C
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

Contorted answered 11/4, 2015 at 10:46 Comment(7)
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.Asha
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.Asha
Well, according to documentation there's an option, i.e. chart.tooltip.gravity("n")Contorted
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?Asha
finally figured it out: chart.interactiveLayer.tooltip.gravity('s'); you get access to the tooltip as a property of the chart.interactiveLayerAsha
Glad you've figured it outContorted
is there any update for this using the new version of nvd3?Alberich

© 2022 - 2024 — McMap. All rights reserved.