首页 文章

当图例线条和点数都显示在Google折线图 - Google Visualization API中时,在图例条目具有焦点时抑制十字准线

提问于
浏览
2

十字准线是Google Charts的一个很好的功能,但是如果你为强调各个点的折线图启用它们(通过将pointSize设置为略大于lineWidth),那么它们会做一些不愉快的事情:当用户将鼠标悬停在相应的位置时 legend 条目,十字光标将出现在该图形轨迹的 every 数据点!如果你在那条踪迹中有数百个数据点,那么就会出现数百个十字准线,这些都会造成难看的混乱 .

对于未设置pointSize的折线图(即,只有线条而不是实际数据点可见),这种情况不会发生 .

有没有办法让十字准线只在鼠标悬停在图表上的数据点时出现,而不是当鼠标悬停在图例上时,在通过设置pointSize使点可见的折线图中?

以下是将鼠标悬停在其中一个数据点上时的图形:

http://www.sealevel.info/crosshairs_problem1.png

how it should look

这是将鼠标悬停在相应的图例条目上时的样子:

http://www.sealevel.info/crosshairs_problem2.png

how it looks when hovering the mouse cursor over the legend entry

如你所见,十字准线几乎掩盖了其他一切 .

这是生成此图表的网页:

http://sealevel.info/crosshairs_problem.html?=1&quadratic=0&lin_PI=1&boxcar=1&boxwidth=3&lin_ci=1&g_date=1930/1-2019/12&c_date=1950/1-2009/12&s_date=1930/1-2018/12

1 回答

  • 2

    使用图表的 'onmouseover' 事件的组合,
    和一个变异观察者,我们可以防止传说中的十字准线悬停

    传递给 'onmouseover' 事件的属性包括行和列
    已经'hovered'的数据点

    在图例悬停 - >行将是 null

    然后使用变异观察器找到新的十字准线svg path 元素
    并将其颜色更改为 'transparent'

    请参阅以下工作代码段...

    google.charts.load('current', {
      callback: drawChart,
      packages: ['corechart']
    });
    
    function drawChart(transparent) {
      var data = new google.visualization.DataTable();
      data.addColumn('number', 'X');
      data.addColumn('number', 'Y');
    
      for (var i = 0; i < 100; i++) {
        data.addRow([
          Math.floor(Math.random()*100),
          Math.floor(Math.random()*100)
        ]);
      }
    
      var options = {
        crosshair: {
          trigger: 'both'
        },
        legend: {
          position: 'bottom',
          textStyle: {
            bold: true,
            fontSize: 20
          }
        }
      };
    
      var chartDiv = document.getElementById('chart_div');
      var chart = new google.visualization.ScatterChart(chartDiv);
    
      var legendHover = false;
    
      google.visualization.events.addListener(chart, 'onmouseover', function (gglEvent) {
        // row property will be null on legend hover
        legendHover = (gglEvent.row === null);
      });
    
      google.visualization.events.addListener(chart, 'onmouseout', function (gglEvent) {
        legendHover = false;
      });
    
      var observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
          mutation.addedNodes.forEach(function (node) {
            if (node.tagName === 'g') {
              node.childNodes.forEach(function (child) {
                if ((child.tagName === 'path') && (legendHover)) {
                  child.setAttribute('stroke', 'transparent');
                }
              });
            }
          });
        });
      });
      observer.observe(chartDiv, {
        childList: true,
        subtree: true
      });
    
      chart.draw(data, options);
    }
    
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
    

    EDIT

    在选择图例然后移动鼠标后,上述操作无法删除十字准线

    请参阅以下工作代码段以防止此行为
    唯一的缺点是,当选择图例/所有点时没有十字准线

    请参阅以下工作代码段...

    google.charts.load('current', {
      callback: drawChart,
      packages: ['corechart']
    });
    
    function drawChart(transparent) {
      var data = new google.visualization.DataTable();
      data.addColumn('number', 'X');
      data.addColumn('number', 'Y');
    
      for (var i = 0; i < 100; i++) {
        data.addRow([
          Math.floor(Math.random()*100),
          Math.floor(Math.random()*100)
        ]);
      }
    
      var options = {
        crosshair: {
          trigger: 'both'
        },
        legend: {
          position: 'bottom',
          textStyle: {
            bold: true,
            fontSize: 20
          }
        }
      };
    
      var chartDiv = document.getElementById('chart_div');
      var chart = new google.visualization.ScatterChart(chartDiv);
    
      var legendHover = false;
      var selection;
    
      google.visualization.events.addListener(chart, 'onmouseover', checkLegendHover);
      google.visualization.events.addListener(chart, 'onmouseout', checkLegendHover);
    
      function checkLegendHover(gglEvent) {
        legendHover = false;
        selection = chart.getSelection();
        if (selection.length > 0) {
          legendHover = (selection[0].row === null);
        }
        if (!legendHover) {
          legendHover = (gglEvent.row === null);
        }
      }
    
      var observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
          mutation.addedNodes.forEach(function (node) {
            if (node.tagName === 'g') {
              node.childNodes.forEach(function (child) {
                if ((child.tagName === 'path') && (legendHover)) {
                  child.setAttribute('stroke', 'transparent');
                }
              });
            }
          });
        });
      });
      observer.observe(chartDiv, {
        childList: true,
        subtree: true
      });
    
      chart.draw(data, options);
    }
    
    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <div id="chart_div"></div>
    

相关问题