Add hyperlink to custom tooltip in Google Charts

2019-07-22 23:55发布

问题:

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>

回答1:

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>