Google Charts/Visualization - dismiss tooltip on click away

后端 未结 3 694
暗喜
暗喜 2020-12-21 13:23

Using Google Charts (haven\'t migrated to the Material ones yet), one can make tooltips require a click by using the {trigger: \'selection\'} option. However, u

相关标签:
3条回答
  • 2020-12-21 13:49

    based on dennisr2000's answer I did this:

    function onChartSelection(e) {
      var selection = chart.getSelection([e]); //note: if currently selected datapoint is clicked, selection is emptied ([] received)
      var dataPointIndex = (selection.length != 0)? selection[0].row : -1; //using -1 for deselection
    
      if (_chartSelectionChangedCallback != null)
        _chartSelectionChangedCallback(dataPointIndex);
      }
    
    function plotElevationsDistances(elevations, distances, selectionCallback) {
      //console.log('elevations: ', JSON.stringify(elevations));
      //console.log('distances: ', JSON.stringify(distances));
    
      chart =
        //new google.visualization.ColumnChart(document.getElementById('chart_div')); 
        /**/new google.visualization.LineChart(document.getElementById('chart_div'));
    
      // Add data selection handler:
      google.visualization.events.addListener(chart, 'select', onChartSelection);
      google.visualization.events.addListener(chart, 'onmouseover', function(e){
          chart.setSelection([{row: e.row, column: e.column}]);
          onChartSelection(e);
      });
    
      var data = new google.visualization.DataTable();
      //data.addColumn('string', '# Marker');
      /**/data.addColumn('number', 'Distance (km)');
      data.addColumn('number', 'Elevation (m)');
      data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});
    
      var elevationCount = elevations.length;
      for (var i = 0; i < elevationCount; i++)
        data.addRow([
            /*''*/distances[i],
            elevations[i],
            '<div class="chartTooltip" onClick="$(this).closest(\'.google-visualization-tooltip\').hide()">Distance: <strong>' + distances[i] + ' km</strong><br />Elevation: <strong>' + elevations[i] + ' m</strong></div><div class="chartTooltipCloseBtn" onClick="$(this).closest(\'.google-visualization-tooltip\').hide()" draggable="false" title="Close" aria-label="Close" type="button" onClick ><img class="chartTooltipCloseBtnImg" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224px%22%20height%3D%2224px%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22%23000000%22%3E%0A%20%20%20%20%3Cpath%20d%3D%22M19%206.41L17.59%205%2012%2010.59%206.41%205%205%206.41%2010.59%2012%205%2017.59%206.41%2019%2012%2013.41%2017.59%2019%2019%2017.59%2013.41%2012z%22%2F%3E%0A%20%20%20%20%3Cpath%20d%3D%22M0%200h24v24H0z%22%20fill%3D%22none%22%2F%3E%0A%3C%2Fsvg%3E%0A"></button>'
            ]);
    
      chart.draw(data, chartOptions);
    }
    

    combined with these styles:

    .chartTooltip {
        margin:10px;
        text-align: left;
    }
    
    .chartTooltipCloseBtn {
        background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%;
        display: block;
        border: 0px none;
        margin: 0px;
        padding: 0px;
        position: absolute;
        cursor: pointer;
        -moz-user-select: none;
        top: -6px;
        right: -6px;
        width: 30px;
        height: 30px;
        outline: currentcolor none medium;
        opacity: 0.6;
    }
    
    .chartTooltipCloseBtn:hover {
        opacity: 1;
    }
    
    .chartTooltipCloseBtnImg {
        .pointer-events: none;
        display: block;
        width: 14px;
        height: 14px;
        margin: 8px;
    }
    

    The styles are based on the x shown by Google Maps infoboxes

    Note the two listeners (I didn't want to clear selection on hover, but instead reselect the hovered point) and the "onClick" attribute in the tooltip.

    Note that I have the close action on both the tooltip (useful for touch screens) AND on the x button for mouse users with a hover effect on that button as the maps infobox also does (maps infobox doesn't seem to close on touch btw, just with the x button)

    The callback I have in onChartSelection is cause setSelection on the chart via the API doesn't seem to fire a selection event, only manual actions do. So like that I do selection on hover as if the user had clicked on the data point and the tooltip is shown immediately and persists (like a combined "selection" and "focus" mode for the "tooltip.trigger", which Google isn't providing out of the box)

    0 讨论(0)
  • 2020-12-21 14:02

    I was able to get something similar to work: not to get the tooltip to vanish when you click away, but when you click on the tooltip iteself. Maybe you can add a close button to the tooltip.

    First, it has to be an html tooltip:

    tooltip: { isHtml: true }
    

    Then you must add the following somewhere in the string html that you pass to the chart (assuming jQuery):

    $("<div></div>").attr("onclick", "$(this).closest('.google-visualization-tooltip').hide()")
    

    Or something similar if you're not using jQuery. This only seems to work for an inner div of the html content you pass for the tooltip, so this needs to be a child div.

    Also, you will need to add the following event handler to the chart:

    google.visualization.events.addListener(chart, "onmouseover", function(event){
          chart.setSelection(null);
    });
    

    Otherwise the tooltip will pop back up when you hover the chart.

    0 讨论(0)
  • 2020-12-21 14:09

    You could attach a click event handler for the body element to clear the chart's selection as demonstrated below:

    Example

    google.setOnLoadCallback(drawChart);
    
    var chart;
    function drawChart() {
    
        var data = google.visualization.arrayToDataTable([
            ['Year', 'Fixations'],
            ['2015', 80],
            ['2016', 90],
            ['2017', 100],
            ['2018', 90],
            ['2019', 80], ]);
    
        var options = {
            tooltip: {
                isHtml: true,
                trigger: 'selection'
            },
            legend: {
                position: 'none'
            },
            bar: {
                groupWidth: '90%'
            },
            colors: ['#A61D4C'],
            enableInteractivity: true
        };
    
        chart = new google.visualization.ColumnChart(document.getElementById('tooltip_rotated'));
    
        chart.draw(data, options);
        addEvent(document.querySelector('body'),'click',clearSelection);
    }
    
    
    function clearSelection (e) {
        if (!document.querySelector('#tooltip_rotated').contains(e.srcElement)) {   
           chart.setSelection();
        }
    }
    
    
    function addEvent(element, evnt, funct){
      if (element.attachEvent)
       return element.attachEvent('on'+evnt, funct);
      else
       return element.addEventListener(evnt, funct, false);
    }
    <script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
    <div id="tooltip_rotated" style="width: 400px; height: 400px;"></div>

    0 讨论(0)
提交回复
热议问题