usr4896260 usr4896260 - 4 months ago 260
Javascript Question

Add hyperlink to custom tooltip in Google Charts

Using this workaround, I was able to mimic showing tooltip upon selection for a google timeline chart. This issue is that I plan on having a mail to link in the tooltip for the user to click on. However, in my function

creatToolTip()
, the tooltip is created but I'm unable to click on the contact link. What is the correct way to do this?

EDIT: I also tried Google's tooltip actions but it is not supported in timeline charts.



google.setOnLoadCallback(drawVisualization);

function drawVisualization() {
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();

dataTable.addColumn({
type: 'string',
id: 'President'
});
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
dataTable.addColumn({
type: 'date',
id: 'Start'
});
dataTable.addColumn({
type: 'date',
id: 'End'
});
dataTable.addRows([
['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
]);
//select-handler
google.visualization.events.addListener(chart, 'select', function(e) {
//the built-in tooltip
var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
//remove previous clone when there is any
if (chart.ttclone) {
chart.ttclone.parentNode.removeChild(chart.ttclone)
}
//create a clone of the built-in tooltip
chart.ttclone = tooltip.cloneNode(true);
//create a custom attribute to be able to distinguish
//built-in tooltip and clone
chart.ttclone.setAttribute('clone', true);
//inject clone into document
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
});

chart.draw(dataTable, {tooltip: {isHtml: true }});
}

function createToolTip() {
var mainDiv = '<div >';
var list =
'<ul class="google-visualization-tooltip-action-list">' +
'<li class="google-visualization-tooltip-action">' +
'<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
'<a href="mailto:test@test.com?Subject=test">Contact</a>' +
'</span>' +
'</li>' +
'</ul>';
var endMainDiv = '</div>';
var tooltip = mainDiv + list + endMainDiv;
return tooltip;
}

.google-visualization-tooltip {
opacity: 0 !important;
max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
opacity: 1 !important;
}
html,
body,
timeline {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['timeline']}]}"></script>
<div id='timeline' style="height:90%"></div>




Answer

looks like pointer-events are set to 'none' by default

change to 'auto' before injecting the clone back into the dom

//inject clone into document
chart.ttclone.style.pointerEvents = 'auto';
tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);

see following working snippet...

google.charts.load('current', {
  callback: function () {
    var container = document.getElementById('timeline');
    var chart = new google.visualization.Timeline(container);
    var dataTable = new google.visualization.DataTable();

    dataTable.addColumn({
      type: 'string',
      id: 'President'
    });
    dataTable.addColumn({ type: 'string', id: 'Name' });
    dataTable.addColumn({ type: 'string', role: 'tooltip', 'p': {'html': true}});
    dataTable.addColumn({
      type: 'date',
      id: 'Start'
    });
    dataTable.addColumn({
      type: 'date',
      id: 'End'
    });
    dataTable.addRows([
      ['Washington', 'test', createToolTip(), new Date(1789, 3, 30), new Date(1797, 2, 4)],
      ['Adams', 'test', createToolTip(), new Date(1797, 2, 4), new Date(1801, 2, 4)],
      ['Jefferson', 'test', createToolTip(), new Date(1801, 2, 4), new Date(1809, 2, 4)]
    ]);
    //select-handler
    google.visualization.events.addListener(chart, 'select', function(e) {
      //the built-in tooltip
      var tooltip = document.querySelector('.google-visualization-tooltip:not([clone])');
      //remove previous clone when there is any
      if (chart.ttclone) {
        chart.ttclone.parentNode.removeChild(chart.ttclone)
      }
      //create a clone of the built-in tooltip
      chart.ttclone = tooltip.cloneNode(true);
      //create a custom attribute to be able to distinguish
      //built-in tooltip and clone
      chart.ttclone.setAttribute('clone', true);
      //inject clone into document
      chart.ttclone.style.pointerEvents = 'auto';
      tooltip.parentNode.insertBefore(chart.ttclone, chart.tooltip);
    });

    function createToolTip() {
       var mainDiv = '<div style="z-index: 1000;">';
       var list =
            '<ul class="google-visualization-tooltip-action-list">' +
                '<li class="google-visualization-tooltip-action">' +
                    '<span style="font-family: Arial; font-size: 12px; color: rgb(0, 0, 0); margin: 0px; text-decoration: none; font-weight: bold;">' +
                        '<a href="mailto:test@test.com?Subject=test">Contact</a>' +
                    '</span>' +
                '</li>' +
            '</ul>';
       var endMainDiv = '</div>';
       var tooltip = mainDiv + list + endMainDiv;
       return tooltip;
    }

    chart.draw(dataTable, {tooltip: {isHtml: true }});
  },
  packages: ['timeline']
});
.google-visualization-tooltip {
  opacity: 0 !important;
  max-width: 200px !important;
}
.google-visualization-tooltip[clone] {
  opacity: 1 !important;
}
html,
body,
timeline {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="timeline" style="height:90%"></div>

Comments