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

标签 javascript charts google-visualization visualization linechart

十字准线是 Google Charts 的一个很棒的功能,但是如果您为强调各个点的折线图启用了十字准线(通过将 pointSize 设置为略大于 lineWidth),那么它们会做一些不愉快的事情:当用户悬停时在相应的图例 条目上,十字准线将出现在该图形轨迹中的每个 数据点!如果您在该轨迹中有数百个数据点,同时出现数百个十字准线,就会造成丑陋的困惑。

对于未设置 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

最佳答案

结合使用图表的 'onmouseover' 事件,
和突变观察者,我们可以防止图例悬停时出现十字准线

传递给 'onmouseover' 事件的属性包括行和列
已“悬停”的数据点的数量

在图例上悬停 --> 行将为 null

然后使用 mutation observer 找到新的 crosshair 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>


编辑

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

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

请参阅以下工作片段...

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>

关于javascript - 当图例条目具有焦点时,当线和点都显示在 Google 折线图中时,抑制十字准线 - Google Visualization API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40158642/

相关文章:

javascript - 在 FireFox 中将 div 元素定位在左侧和顶部不适用于内容

javascript - 页面重新加载背景位置上的 Stellar.js 出错

用于 Google Charts Api 的 PHP MySQL 查询数组 json_encode

php - Google Chart 在 SQL 字符串之间添加每一天

javascript - 要显示的 ipad 兼容 javascript 库

javascript - 分离、排序的 d3 圆圈沿 X 轴显示

javascript - Laravel 和 Ajax - foreach json 对象并处理重复项

python - mplfinance 是否有对数刻度设置?

jquery - 使用多个透明条目创建面积图 (MIT/GNU)

javascript - 谷歌可视化仪表: Cannot read property 'arrayToDataTable' of undefined