javascript - 检测 Google 折线图的缩放事件?

标签 javascript charts google-visualization

是否可以使用 Google 折线图 API 检测缩放/范围更改事件? 如果我使用带注释的时间线,我可以做到,但不能使用折线图。

如您所见,我正在尝试同步两个图表。它工作正常,但是当我放大上图时,我也想放大下图。

我使用以下代码:

  google.charts.load('current', {
  callback: function () {

    var chart1;
    var chart2;

    var data1 = new google.visualization.DataTable();
    var data2 = new google.visualization.DataTable();

    var outDiv1 = document.getElementById('mcs-chart-event');
    var outDiv2 = document.getElementById('snr-chart-event');

    var options1 = {title:'Wot',
      height:300,
      displayAnnotations: false,
      displayZoomButtons: false,
      chartArea: { width:'95%',height:'90%'},
      lineWidth: 1.5,
      legend: { position: 'none' },
      crosshair: {
        trigger: 'both',
        orientation: 'vertical'
      },
      explorer: {
          actions: ['dragToZoom', 'rightClickToReset'],
          axis: 'horizontal',
          keepInBounds: true,
          maxZoomIn: 10.0
      },
    };

    var options2 = {
      displayZoomButtons: false,
      displayRangeSelector: false,
      title:'rsi typ',
      chartArea: { width:'95%',height:'90%'},
      height:100,
      lineWidth: 1.5,
      colors: ['red'],
      legend: { position: 'none' },
      crosshair: {
        trigger: 'both',
        orientation: 'vertical'
      },
      explorer: {
          actions: ['dragToZoom', 'rightClickToReset'],
          axis: 'horizontal',
          keepInBounds: true,
          maxZoomIn: 10.0
      },
    };


    drawChartOne(data1);
    drawChartTwo(data2);

    google.visualization.events.addListener(chart1, 'onmouseover', function(selection) {
        chart1.setSelection(selection);
         chart2.setSelection([{ row: selection.row, column: null }]);
     });
		
    //Only works when using AnnotatedTimeLine...
     google.visualization.events.addListener(chart1, 'rangechange', function(data) {
     //Only works when using AnnotatedTimeLine...
          chart2.setVisibleChartRange(data.start,data.end);
      });

     google.visualization.events.addListener(chart2, 'onmouseover', function(selection) {
          chart2.setSelection(selection);
          chart1.setSelection([{ row: selection.row, column: null }]);
      });

    chart1.draw(data1, options1);
    chart2.draw(data2, options2);

    function drawChartOne(data) {
      data.addColumn('date', 'Date');
      data.addColumn('number', 'Sessions');
      data.addColumn({type: 'string', role: 'style'});
      data.addColumn({type:'string', role:'annotation'});

      var sessions = [786, 450, 866, 814, 192, 466, 984, 780, 922, 458, 786, 758, 701, 831, 901, 557, 114, 393, 689, 658, 103, 837, 164, 727, 593, 193, 945, 583, 948, 338];
      var start = new Date(1458345600 * 1000);
      var date;

      var dates = [];

      for(var i = 0; i < sessions.length; i++) {
        var newDate = start.setDate(start.getDate() + 1);
        if(i == 10){
            data.addRow([new Date(newDate), sessions[i],'point { size: 6; shape-type: circle; fill-color: green;','Buy']);

        }else{
          data.addRow([new Date(newDate), sessions[i],null,null]);
        }

      }

      chart1 = new google.visualization.LineChart(document.getElementById('mcs-chart'));
    }

    function drawChartTwo(data) {
      data.addColumn('date', 'Date');
      data.addColumn('number', 'Other Sessions');

      var rsi = [100, 450, 200, 333, 192, 466, 984, 77, 922, 458, 200, 758, 701, 831, 901, 557, 114, 393, 500, 658, 103, 837, 300, 727, 593, 193, 945, 583, 948, 338];

      var start = new Date(1458345600 * 1000);
      var date;

      for(var i = 0; i < rsi.length; i++) {
        var newDate = start.setDate(start.getDate() + 1);
        data.addRow([new Date(newDate), rsi[i]]);
      }

      chart2 = new google.visualization.LineChart(document.getElementById('snr-chart'));
    }
  },
  packages: ['corechart','annotatedtimeline']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="mcs-chart"></div>
<div id="snr-chart"></div>
<div id="mcs-chart-event"></div>
<div id="snr-chart-event"></div>

最佳答案

首先,使用MutationObserver 了解何时交互,包括缩放,发生在图1

    // sync chart2
    var observer = new MutationObserver(function () {
      setRange(getCoords());
    });

    // start observing on 'ready'
    google.visualization.events.addListener(chart1, 'ready', function() {
      observer.observe(container1, {
        childList: true,
        subtree: true
      });
    });

接下来,从chart1中抓取各个轴的坐标,并在chart2上设置viewWindow

坐标是使用下面的methods ...获得的

getChartLayoutInterface() --> Returns an object containing information about the onscreen placement of the chart and its elements.

getChartAreaBoundingBox() --> Returns an object containing the left, top, width, and height of the chart content (i.e., excluding labels and legend)

请参阅下面的 getCoordssetRange 函数...


请参阅以下工作代码段,运行一次,然后选择“整页”以获得“完整效果”...

google.charts.load('current', {
  callback: function () {
    var chart1;
    var chart2;

    var data1 = new google.visualization.DataTable();
    var data2 = new google.visualization.DataTable();

    var container1 = document.getElementById('mcs-chart');
    var container2 = document.getElementById('snr-chart');

    var outDiv1 = document.getElementById('mcs-chart-event');
    var outDiv2 = document.getElementById('snr-chart-event');

    var options1 = {title:'Wot',
      height:300,
      displayAnnotations: false,
      displayZoomButtons: false,
      chartArea: { width:'95%',height:'90%'},
      lineWidth: 1.5,
      legend: { position: 'none' },
      crosshair: {
        trigger: 'both',
        orientation: 'vertical'
      },
      explorer: {
          actions: ['dragToZoom', 'rightClickToReset'],
          axis: 'horizontal',
          keepInBounds: true,
          maxZoomIn: 10.0
      },
    };

    var options2 = {
      displayZoomButtons: false,
      displayRangeSelector: false,
      title:'rsi typ',
      chartArea: { width:'95%',height:'90%'},
      height:100,
      lineWidth: 1.5,
      colors: ['red'],
      legend: { position: 'none' },
      crosshair: {
        trigger: 'both',
        orientation: 'vertical'
      },
      explorer: {
          actions: ['dragToZoom', 'rightClickToReset'],
          axis: 'horizontal',
          keepInBounds: true,
          maxZoomIn: 10.0
      },
    };

    drawChartOne(data1);
    drawChartTwo(data2);

    google.visualization.events.addListener(chart1, 'onmouseover', function(selection) {
      chart1.setSelection(selection);
      chart2.setSelection([{ row: selection.row, column: null }]);
    });

    // sync chart2
    var observer = new MutationObserver(function () {
      setRange(getCoords());
    });

    // start observing on 'ready'
    google.visualization.events.addListener(chart1, 'ready', function() {
      observer.observe(container1, {
        childList: true,
        subtree: true
      });
    });

    google.visualization.events.addListener(chart2, 'onmouseover', function(selection) {
      chart2.setSelection(selection);
      chart1.setSelection([{ row: selection.row, column: null }]);
    });

    drawCharts();
    window.addEventListener('resize', drawCharts, false);
    function drawCharts() {
      chart1.draw(data1, options1);
      chart2.draw(data2, options2);
    }

    function drawChartOne(data) {
      data.addColumn('date', 'Date');
      data.addColumn('number', 'Sessions');
      data.addColumn({type: 'string', role: 'style'});
      data.addColumn({type:'string', role:'annotation'});

      var sessions = [786, 450, 866, 814, 192, 466, 984, 780, 922, 458, 786, 758, 701, 831, 901, 557, 114, 393, 689, 658, 103, 837, 164, 727, 593, 193, 945, 583, 948, 338];
      var start = new Date(1458345600 * 1000);
      var date;

      var dates = [];

      for(var i = 0; i < sessions.length; i++) {
        var newDate = start.setDate(start.getDate() + 1);
        if(i == 10){
            data.addRow([new Date(newDate), sessions[i],'point { size: 6; shape-type: circle; fill-color: green;','Buy']);

        }else{
          data.addRow([new Date(newDate), sessions[i],null,null]);
        }

      }

      chart1 = new google.visualization.LineChart(container1);
    }

    function drawChartTwo(data) {
      data.addColumn('date', 'Date');
      data.addColumn('number', 'Other Sessions');

      var rsi = [100, 450, 200, 333, 192, 466, 984, 77, 922, 458, 200, 758, 701, 831, 901, 557, 114, 393, 500, 658, 103, 837, 300, 727, 593, 193, 945, 583, 948, 338];

      var start = new Date(1458345600 * 1000);
      var date;

      for(var i = 0; i < rsi.length; i++) {
        var newDate = start.setDate(start.getDate() + 1);
        data.addRow([new Date(newDate), rsi[i]]);
      }

      chart2 = new google.visualization.LineChart(container2);
    }

    // get axis coordinates from chart1
    function getCoords() {
      var chartLayout = chart1.getChartLayoutInterface();
      var chartBounds = chartLayout.getChartAreaBoundingBox();
      return {
        x: {
          min: chartLayout.getHAxisValue(chartBounds.left),
          max: chartLayout.getHAxisValue(chartBounds.width + chartBounds.left)
        },
        y: {
          min: chartLayout.getVAxisValue(chartBounds.top),
          max: chartLayout.getVAxisValue(chartBounds.height + chartBounds.top)
        }
      };
    }

    // set axis coordinates on chart2
    function setRange(coords) {
      options2.hAxis = {};
      options2.vAxis = {};
      options2.hAxis.viewWindow = {};
      options2.vAxis.viewWindow = {};
      if (coords) {
        options2.hAxis.viewWindow.min = coords.x.min;
        options2.hAxis.viewWindow.max = coords.x.max;
        options2.vAxis.viewWindow.min = coords.y.min;
        options2.vAxis.viewWindow.max = coords.y.max;
      }
      chart2.draw(data2, options2);
    }
  },
  packages: ['corechart','annotatedtimeline']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="mcs-chart"></div>
<div id="snr-chart"></div>
<div id="mcs-chart-event"></div>
<div id="snr-chart-event"></div>

关于javascript - 检测 Google 折线图的缩放事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42235369/

相关文章:

javascript - 曲线类型为 : function changes vAxis values 的谷歌折线图

javascript - 将类添加到动态 Bootstrap 表行

javascript - 单击按钮即可洗牌阵列

javascript - Soundcloud 播放器小部件在轨道更改时触发事件

javascript - Cartesian3.distance - 返回 NaN?

javascript - 将 y 刻度扩展到 d3 条形图中所需数字的方法

java - Apache poi Excel折线图点

javascript - 如何使用 javascript 突出显示 jqplot 条形图

javascript - 在 Google 图表中从第一个点到最后一个点绘制一条线

javascript - Google 图表连续轴上的数据差距