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

时间:2016-10-20 15:28:39

标签: 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

2 个答案:

答案 0 :(得分:2)

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

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

传说中的

悬停 - >行将为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>

编辑

在选择图例然后移动鼠标

后,上述操作无法删除十字准线

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

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

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>

答案 1 :(得分:0)

我使用mouseover事件来检测指针在哪里。

如果在图例上,请从chartData选项中删除十字线属性,否则将其返回。

mouseOver(event) {
    // if mouse pointer over legend
    if (event.position.row === null && this.googleChartData.options.crosshair) {
      this.googleChartData.options.crosshair = undefined;
      this.chartComponent.draw();
    // if mouse pointer over something else other legend
    } else if (event.position.row !== null && this.googleChartData.options.crosshair === undefined) {
      this.initializeData();
    }
  }

initializeData重新分配googleChartData

相关问题