javascript - 需要通过鼠标拖动选择google散点图中点的范围

标签 javascript charts scatter-plot google-visualization

最近我开始研究 Google 图表。到现在为止一切都很好,但现在我面临着多项选择的问题。我可以通过单击鼠标来选择多个点,但我需要通过拖动鼠标来选择点的范围。

你能帮我做这件事吗?

enter image description here

最佳答案

使用这个答案来绘制选择范围--> Select area/rectangle in javascript

使用图表方法 --> chart.getChartLayoutInterface().getBoundingBox()
找到每个点的边界...

chart.getChartLayoutInterface().getBoundingBox('point#0#0')

其中第一个#0代表系列列,
第二个#0代表行索引

如果边界落在选择范围内,
将点添加到选择...

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

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data = google.visualization.arrayToDataTable([
    ['x', 'y'],
    [10, 15],
    [15, 13],
    [18, 20],
    [24, 26],
    [34, 30],
    [40, 43],
    [49, 48],
    [50, 55],
    [65, 67],
    [70, 70],
    [72, 70],
    [73, 70],
    [80, 85]
  ]);

  var container = document.getElementById('chart_div');
  var chart = new google.visualization.ScatterChart(container);
  var options = {
    chartArea: {
      height: '100%',
      width: '100%',
      top: 32,
      left: 32,
      right: 16,
      bottom: 32
    },
    height: '100%',
    width: '100%',
    legend: {
      position: 'top'
    },
    selectionMode: 'multiple'
  };

  google.visualization.events.addListener(chart, 'ready', function () {
    var chartLayout = chart.getChartLayoutInterface();
    var divSelect = document.getElementById('select_div');
    var x1 = 0;
    var y1 = 0;
    var x2 = 0;
    var y2 = 0;
    var x3 = 0;
    var y3 = 0;
    var x4 = 0;
    var y4 = 0;

    function reCalc() {
      x3 = Math.min(x1,x2);
      x4 = Math.max(x1,x2);
      y3 = Math.min(y1,y2);
      y4 = Math.max(y1,y2);
      divSelect.style.left = x3 + 'px';
      divSelect.style.top = y3 + 'px';
      divSelect.style.width = x4 - x3 + 'px';
      divSelect.style.height = y4 - y3 + 'px';
    }
    function selectPoints() {
      var selection = [];
      for (var row = 0; row < data.getNumberOfRows(); row++) {
        for (var col = 1; col < data.getNumberOfColumns(); col++) {
          var point = chartLayout.getBoundingBox('point#' + (col - 1) + '#' + row);
          if (((point.left >= (x3 - point.width)) && ((point.left + point.width) <= (x4 + point.width))) &&
              ((point.top >= (y3 - point.height)) && ((point.top + point.height) <= (y4 + point.height)))) {
            selection.push({row: row, column: col});
          }
        }
      }
      chart.setSelection(selection);
    }
    window.addEventListener('mousedown', function (e) {
      divSelect.className = '';
      x1 = e.pageX;
      y1 = e.pageY;
      reCalc();
    }, false);
    window.addEventListener('mousemove', function (e) {
      x2 = e.pageX;
      y2 = e.pageY;
      reCalc();
    }, false);
    window.addEventListener('mouseup', function (e) {
      divSelect.className = 'hidden';
      selectPoints();
    }, false);
  });

  chart.draw(data, options);
});
html, body {
  height: 100%;
  margin: 0px 0px 0px 0px;
  overflow: hidden;
  padding: 0px 0px 0px 0px;
}

#select_div {
  border: 1px dashed #3366cc;
  position: absolute;
  z-index: 1000;
}

.chart {
  height: 100%;
}

.hidden {
  display: none;
  visibility: hidden;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="hidden" id="select_div"></div>
<div class="chart" id="chart_div"></div>

注意:如果您的图表不在页面上的top = 0 & left = 0
你需要调整点的边界,
基于图表在页面上的位置...


编辑 - 更新多个图表...

google.charts.load('current', {
  packages: ['controls', 'corechart']
}).then(function () {
  var data = google.visualization.arrayToDataTable([
    ['x', 'y'],
    [10, 15],
    [15, 13],
    [18, 20],
    [24, 26],
    [34, 30],
    [40, 43],
    [49, 48],
    [50, 55],
    [65, 67],
    [70, 70],
    [72, 70],
    [73, 70],
    [80, 85]
  ]);

  var options = {
    chartArea: {
      height: '100%',
      width: '100%',
      top: 32,
      left: 32,
      right: 16,
      bottom: 32
    },
    height: '100%',
    width: '100%',
    legend: {
      position: 'top'
    },
    selectionMode: 'multiple'
  };

  var charts = [];
  var container = document.getElementById('charts');
  for (var i = 0; i < 4; i++) {
    var chartContainer = container.appendChild(document.createElement('div'));
    chartContainer.id = 'chart_' + i;
    var chart = new google.visualization.ChartWrapper({
      chartType: 'ScatterChart',
      containerId: chartContainer.id,
      dataTable: data,
      options: options
    });
    google.visualization.events.addListener(chart, 'ready', function () {
      charts.push(chart);
    });
    chart.draw();
  }

  var divSelect = document.getElementById('select');
  var x1 = 0;
  var y1 = 0;
  var x2 = 0;
  var y2 = 0;
  var x3 = 0;
  var y3 = 0;
  var x4 = 0;
  var y4 = 0;

  window.addEventListener('mousedown', function (e) {
    divSelect.className = '';
    x1 = e.pageX;
    y1 = e.pageY;
    reCalc();
  }, false);
  window.addEventListener('mousemove', function (e) {
    x2 = e.pageX;
    y2 = e.pageY;
    reCalc();
  }, false);
  window.addEventListener('mouseup', function (e) {
    divSelect.className = 'hidden';
    selectPoints();
  }, false);

  function reCalc() {
    x3 = Math.min(x1,x2);
    x4 = Math.max(x1,x2);
    y3 = Math.min(y1,y2);
    y4 = Math.max(y1,y2);
    divSelect.style.left = x3 + 'px';
    divSelect.style.top = y3 + 'px';
    divSelect.style.width = x4 - x3 + 'px';
    divSelect.style.height = y4 - y3 + 'px';
  }

  function selectPoints() {
    charts.forEach(function (chart, index) {
      var chartLayout = chart.getChart().getChartLayoutInterface();
      var chartContainer = document.getElementById(chart.getContainerId());
      var chartBounds = chartContainer.getBoundingClientRect();
      if ((((chartBounds.left + window.pageXOffset) <= x3) &&
           ((chartBounds.left + chartBounds.width + window.pageXOffset) >= x4)) &&
          (((chartBounds.top + window.pageYOffset) <= y3) &&
           ((chartBounds.top + chartBounds.height + window.pageYOffset) >= y4))) {
        var selection = [];
        var dataTable = chart.getDataTable();
        for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
          for (var col = 1; col < dataTable.getNumberOfColumns(); col++) {
            var point = chartLayout.getBoundingBox('point#' + (col - 1) + '#' + row);
            if ((((chartBounds.left + point.left + window.pageXOffset) >= (x3 - point.width)) &&
                 ((chartBounds.left + point.left + point.width + window.pageXOffset) <= (x4 + point.width))) &&
                (((chartBounds.top + point.top + window.pageYOffset) >= (y3 - point.height)) &&
                 ((chartBounds.top + point.top + point.height + window.pageYOffset) <= (y4 + point.height)))) {
              selection.push({row: row, column: col});
            }
          }
        }
        chart.getChart().setSelection(selection);
      }
    });
  }
});
#select {
  border: 1px dashed #3366cc;
  position: absolute;
  z-index: 1000;
}

.hidden {
  display: none;
  visibility: hidden;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="hidden" id="select"></div>
<div id="charts"></div>

关于javascript - 需要通过鼠标拖动选择google散点图中点的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49849902/

相关文章:

javascript - 如何从 TypeScript 文件生成类型定义文件?

javascript - 作业未重新启动

用于音频控制的 Javascript 按钮切换

javascript - 为什么我的谷歌图表看起来不对

javascript - 使用 Google 图表自动合并值

javascript - Firestore 总是进行 3 次 api 调用,其中一次需要 60 秒

excel - 如何创建从多个工作表中提取数据的 Excel 图表?

r - 为什么以及何时 "Using size for a discrete variable is not advised"?

r - 如何在R中叠加散点图?

Python matplotlib散点图导入colormap列表