2017-04-17 38 views
0

當向谷歌圖表svg元素添加懸停事件時,Firefox和Chrome之間的結果是不同的(Chrome正在做我期望的)。 我想實現的是用戶能夠懸停在圖表上,而不在乎他與線條有多接近 - 懸停應該平滑且易於使用。懸停在谷歌圖表上代表奇怪的火狐

下面是相關plunker:鉻看到預期的行爲體在圖表上https://plnkr.co/edit/2IF2BnX0tS2wznAUr5bs?p=preview

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="stylesheet" href="style.css"> 
    <script src="script.js"></script> 
    <script src="https://www.gstatic.com/charts/loader.js"></script> 
</head> 
<body> 
    <script> 
    google.charts.load('current', { 
     callback: drawChart, 
     packages: ['corechart'] 
    }); 

    function drawChart() { 
     var dataTable = new google.visualization.DataTable({ 
      cols: [ 
       { id: 'x', label: 'Num', type: 'number' }, 
       { id: 'y', label: 'Fn', type: 'number' } 
      ] 
     }); 

     for (var i = 0; i < 1000; i++) { 
      var xValue = { v: i }; 
      var yValue = { v: i }; 

      // add data row 
      dataTable.addRow([ 
       xValue, 
       yValue 
      ]); 
     } 

     var container = document.getElementById('chart_div'); 
     var chart = new google.visualization.ChartWrapper({ 
      chartType: 'LineChart', 
      dataTable: dataTable, 
      options: { 
       hAxis: { 
        gridlines: { 
         color: 'transparent' 
        }, 
        title: 'Hover here is also fine' 
       }, 
       tooltip: { 
        trigger: "none" 
       }, 
       vAxis: { 
        gridlines: { 
         color: 'transparent' 
        }, 
        title: 'Hover here is OK' 
       } 
      } 
     }); 

     // add hover line 
     google.visualization.events.addOneTimeListener(chart, 'ready', function() { 
      var svgParent = container.getElementsByTagName('svg')[0]; 
      var layout = chart.getChart().getChartLayoutInterface(); 
      var lineHeight = layout.getBoundingBox('chartarea').height - 18; 
      var lineTop = layout.getBoundingBox('chartarea').top; 

      var hoverLine = container.getElementsByTagName('rect')[0].cloneNode(true); 
      hoverLine.setAttribute('y', lineTop); 
      hoverLine.setAttribute('height', lineHeight); 
      hoverLine.setAttribute('width', '1'); 
      hoverLine.setAttribute('stroke', 'none'); 
      hoverLine.setAttribute('stroke-width', '0'); 
      hoverLine.setAttribute('fill', '#cccccc'); 
      hoverLine.setAttribute('x', 0); 
      svgParent.appendChild(hoverLine); 

      svgParent.addEventListener("mousemove", function (e) { 
       hoverLine.setAttribute('x', e.offsetX); 
      }); 
     }); 

     chart.draw(container); 
    } 
</script> 
<div id="chart_div"></div> 

徘徊。 用firefox懸停在圖表上查看問題。 任何想法如何解決這個問題?這是一個谷歌圖表錯誤?我是否將事件偵聽器添加到了錯誤的元素中?

回答

1

似乎您的svg中的兒童標籤正在捕獲mousemove事件(這是由於事件傳播造成的)。

只需添加一個指針的事件:沒有這些子元素(我建議用一個id爲SVG元素)

svg *{ 
 
    pointer-events: none; 
 
}
<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <link rel="stylesheet" href="style.css"> 
 
    <script src="script.js"></script> 
 
    <script src="https://www.gstatic.com/charts/loader.js"></script> 
 
    </head> 
 

 
    <body> 
 
    <script> 
 
    google.charts.load('current', { 
 
    callback: drawChart, 
 
    packages: ['corechart'] 
 
}); 
 

 
function drawChart() { 
 
    var dataTable = new google.visualization.DataTable({ 
 
    cols: [ 
 
     {id: 'x', label: 'Num', type: 'number'}, 
 
     {id: 'y', label: 'Fn', type: 'number'} 
 
    ] 
 
    }); 
 

 
    for (var i = 0; i < 1000; i++) { 
 
    var xValue = { v: i }; 
 
    var yValue = { v: i }; 
 

 
    // add data row 
 
    dataTable.addRow([ 
 
     xValue, 
 
     yValue 
 
    ]); 
 
    } 
 

 
    var container = document.getElementById('chart_div'); 
 
    var chart = new google.visualization.ChartWrapper({ 
 
    chartType: 'LineChart', 
 
    dataTable: dataTable, 
 
    options: { 
 
     hAxis: { 
 
     gridlines: { 
 
      color: 'transparent' 
 
     }, 
 
     title: 'Hover here is also fine' 
 
     }, 
 
     tooltip: { 
 
     trigger: "none" 
 
     }, 
 
     vAxis: { 
 
     gridlines: { 
 
      color: 'transparent' 
 
     }, 
 
     title: 'Hover here is OK' 
 
     } 
 
    } 
 
    }); 
 

 
    // add hover line 
 
    google.visualization.events.addOneTimeListener(chart, 'ready', function() { 
 
    var svgParent = container.getElementsByTagName('svg')[0]; 
 
    var layout = chart.getChart().getChartLayoutInterface(); 
 
    var lineHeight = layout.getBoundingBox('chartarea').height - 18; 
 
    var lineTop = layout.getBoundingBox('chartarea').top; 
 

 
    var hoverLine = container.getElementsByTagName('rect')[0].cloneNode(true); 
 
    hoverLine.setAttribute('y', lineTop); 
 
    hoverLine.setAttribute('height', lineHeight); 
 
    hoverLine.setAttribute('width', '1'); 
 
    hoverLine.setAttribute('stroke', 'none'); 
 
    hoverLine.setAttribute('stroke-width', '0'); 
 
    hoverLine.setAttribute('fill', '#cccccc'); 
 
    hoverLine.setAttribute('x', 0); 
 
    svgParent.appendChild(hoverLine); 
 
    
 
    svgParent.addEventListener("mousemove", function(e) { 
 
     hoverLine.setAttribute('x', e.offsetX); 
 
    }); 
 
    }); 
 

 
    chart.draw(container); 
 
} 
 
</script> 
 
<div id="chart_div"></div> 
 
</body> 
 
</html>

+0

這個工作般的魅力,非常感謝!你知道這是什麼原因嗎?我真的不明白爲什麼這應該工作... –

+0

當你把鼠標懸停在你的svg元素上..孩子們得到這個懸停和e.offsetX位置計算從兒童元素的位置而不是由於事件的父母傳播 – repzero