如何更改Google图表工具提示的弹出位置

5

我目前拥有启用了HTML的工具提示,还可以显示"子图形"。 但是,如果所有工具提示都可以弹出到固定位置或具有相对位置调整的偏移量,那就太好了。

enter image description here

这是我拥有的工具提示(空数据)的示例。 我想把它移到右边。 希望能够提供任何建议,包括任何JavaScript技巧。


这个有帮助吗?(链接为http://jqfaq.com/how-to-customize-tooltip-text-using-html-tags-in-google-charts/) - Chankey Pathak
这只是修改工具提示中的 HTML,与其实际弹出位置无关。 - Red Shift
我们实际上刚刚实现了略微控制工具提示方向的功能。它将在下一个版本(v40)中发布,但我无法告诉您何时发布,因为Google不会预先公布。我建议您关注google-visualization-api邮件列表以获取发布信息。应该会在几天/几周内宣布。此外,@asgallant的答案往往是可靠的。请查看以下内容... - Jeremy Faller
3个回答

17

虽然答案很好,但现在有点过时了。Google已经实现了CSS控制,因此无需通过JavaScript进行黑客攻击即可获得更大的灵活性。

.google-visualization-tooltip {  position:relative !important; top:0 !important;right:0 !important; z-index:+1;} 

会提供一个位于图表底部的工具提示,现场演示:http://www.taxformcalculator.com/federal-budget/130000.html

或者您可以调整左边距...

.google-visualization-tooltip {  margin-left: 150px !important; z-index:+1;}
请注意,通过使用z-index将容器向前拉可以减少(但不能完全停止)鼠标移动时的可见性闪烁。闪烁程度会因图表大小、调用等而异。个人而言,我更喜欢修复工具提示并将其作为设计的一部分,就像第一个示例一样。希望这对那些被JS hack所吓倒的人有所帮助(这很好,但实际上不再必要)。

5

提示框位置是内联设置的,因此需要监听提示框的DOM插入并手动更改位置。变异事件已弃用,因此如果有可用的MutationObserver(Chrome、Firefox、IE11),则使用它,如果没有(IE9、10),则使用DOMNodeInserted事件处理程序。这在IE8中不起作用。

google.visualization.events.addOneTimeListener(myChart, 'ready', function () {
    var container = document.querySelector('#myChartDiv > div:last-child');
    function setPosition () {
        var tooltip = container.querySelector('div.google-visualization-tooltip');
        tooltip.style.top = 0;
        tooltip.style.left = 0;
    }
    if (typeof MutationObserver === 'function') {
        var observer = new MutationObserver(function (m) {
            for (var i = 0; i < m.length; i++) {
                if (m[i].addedNodes.length) {
                    setPosition();
                    break; // once we find the added node, we shouldn't need to look any further
                }
            }
        });
        observer.observe(container, {
            childList: true
        });
    }
    else if (document.addEventListener) {
        container.addEventListener('DOMNodeInserted', setPosition);
    }
    else {
        container.attachEvent('onDOMNodeInserted', setPosition);
    }
});
MutationObserver 应该没问题,但是事件可能需要一些调整;我没有测试过它们。

@asgallant很好的回答,尽管我在实施过程中遇到了一些困难,但我已经添加了下面的答案。 - AGB
太好了,现在它运行得很好。同时也感谢@AlanBuchanan的回答。 - Red Shift
我无法让它正常工作。MutationObserver回调从未执行过。 我猜当用户悬停在图表上时,应该执行它,这会使工具提示出现。 - Adrien

3

我和Redshift有着差不多的问题,一直在尝试将工具提示移动到鼠标悬停的节点相对位置。使用asgallant的绝妙答案后,我按照下面的代码进行了实现。

我无法测试这是否适用于MutationObserver,因为在Firefox、Chrome和IE11中测试时,它总是失败并使用addEventListener。文档建议它应该可以工作。

我必须引入一个超时来实际操作样式,否则元素的左侧和顶部位置始终报告为0。我认为事件在添加节点时触发,但DOM还没有准备好。虽然这只是一个猜测,但我对以这种方式实现并不完全满意。

  var chart = new google.visualization.LineChart(document.getElementById('line_chart'));
  google.visualization.events.addOneTimeListener(chart, 'ready', function () {
    var container = document.querySelector('#line_chart > div:last-child');
    function setPosition(e) {
      if (e && e.target) {
        var tooltip = $(e.target);
          setTimeout(function () {
            var left = parseFloat(tooltip.css('left')) - 49;
            var top = parseFloat(tooltip.css('top')) - 40;
            tooltip.css('left', left + 'px');
            tooltip.css('top', top + 'px');
            $(".google-visualization-tooltip").fadeIn(200);
          }, 1);
      }
      else {
        var tooltip = container.querySelector('.google-visualization-tooltip');
        var left = parseFloat(tooltip.style.left) - 49;
        var top = parseFloat(tooltip.style.top) - 40;
        tooltip.style.left = left + 'px';
        tooltip.style.top = top + 'px';
        $(".google-visualization-tooltip").fadeIn(200);
      }
    }
    if (typeof MutationObserver === 'function') {
      var observer = new MutationObserver(function (m) {
        if (m.length && m[0].addedNodes.length) {
          setPosition(m);
        }
      });
      observer.observe(container, {
        childList: true
      });
    }
    else if (document.addEventListener) {
      container.addEventListener('DOMNodeInserted', setPosition);
    }
    else {
      container.attachEvent('onDOMNodeInserted', setPosition);
    }
  });
  chart.draw(data, options);
}

编辑:根据asgallant的评论更新,以使MutationObserver正常工作。


这是我的失误 - 应该是 typeof MutationObserver === 'function' - asgallant
@asgallant 谢谢,现在可以工作了,我已经相应地更新了我的答案。 - AGB
1
@asgallant,我已经将你们两个的工作结合起来,现在有了部分可行的解决方案。我的问题是,当鼠标离开一个点然后移到另一个点时,工具提示不会移动。由于我的点非常靠近彼此,经常发生的情况是,当一个工具提示正在显示时,我移动到另一个点(而不是消失),工具提示位置重置为默认值。你们两个有什么建议吗?无论如何,感谢你们的努力。 - Red Shift
MutationObserver 对象的工作方式与事件不同(请参阅MDN文档);可能会观察到多个变化,因此您需要解析整个数组而不是检查第一个元素。我将更新我的答案,并提供代码来完成这个任务。 - asgallant
在我的答案中的新代码中,我在定位新插入的元素后进行了中断,但是我不确定这将与您的版本正确工作,因为您正在传递事件对象,如果有多个提示生成在观察之间,则可能会指向已删除的节点。 - asgallant
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接