检测Google Line图表的缩放事件?

时间:2017-02-14 20:14:32

标签: javascript charts google-visualization

是否可以使用Google Line Chart api检测缩放/范围更改事件? 如果我使用带注释的时间线,我可以这样做,但不能使用LineChart。

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

我使用以下代码:

  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>

1 个答案:

答案 0 :(得分:4)

首先,使用 MutationObserver 来了解{{1>发生交互的时间,包括 zoom }}

chart1

下一步,从 // 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上设置viewWindow

使用以下methods ...

获得坐标
  

chart2 - &gt;返回一个对象,其中包含有关图表及其元素的屏幕位置信息。

     

getChartLayoutInterface() - &gt;返回包含图表内容的左侧,顶部,宽度和高度的对象(即,不包括标签和图例)

查看以下getChartAreaBoundingBox()getCoords的功能......

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

setRange
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']
});