4

I'm using a Google Annotated Timeline chart and the mouse scrollwheel zooming of the time scale is getting annoying. I want to be able to scroll down my page of charts with my scroll wheel, but the timeline chart is intercepting the scroll wheel events. It prevents me from scrolling down the page and changes my timeline zoom to an unusable range.

Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229

1 Answers1

2

I wrote a solution for your problem. I have applied my solution to the example annotated timeline from google and furthermore I have used the mouse wheel event capture technique from here.

To reproduce the problem:

  1. Demo of graph if you do not apply the solution code below.

  2. Another demo of the graph if you do apply the solution code.

To see the difference scroll your mouse wheel while your mouse pointer is on the graph.

The code below detects if the mouse wheel is moved. If that is the case the variable scrolled is set to 1 for the next 1.5 seconds and normal page scrolling behaviour is applied.

If during the next 1.5 second the rangechange event is fired by the annotatedtimeline object the change in range is undone. In that way your original graphs zoom level is restored.

If the users changes the zoom level in any other way, e.g. by dragging some of the controls on the graph, the new state is saved in the variable chartRange, which is read at the moment a range change has to be undone.

Below the solution code:

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
        // source: https://developers.google.com/chart/interactive/docs/
        //          gallery/annotatedtimeline
      google.load('visualization', '1', {packages: ['annotatedtimeline']});
      function drawVisualization() {
        var data = new google.visualization.DataTable();
        data.addColumn('date', 'Date');
        data.addColumn('number', 'Sold Pencils');
        data.addColumn('string', 'title1');
        data.addColumn('string', 'text1');
        data.addColumn('number', 'Sold Pens');
        data.addColumn('string', 'title2');
        data.addColumn('string', 'text2');
        data.addRows([
          [new Date(2008, 1 ,1), 30000, null, null, 40645, null, null],
          [new Date(2008, 1 ,2), 14045, null, null, 20374, null, null],
          [new Date(2008, 1 ,3), 55022, null, null, 50766, null, null],
          [new Date(2008, 1 ,4), 75284, null, null, 14334, 'Out of Stock', 
            'Ran out of stock on pens at 4pm'],
          [new Date(2008, 1 ,5), 41476, 'Bought Pens', 'Bought 200k pens', 
            66467, null, null],
          [new Date(2008, 1 ,6), 33322, null, null, 39463, null, null]
        ]);    
        var annotatedtimeline = new google.visualization.AnnotatedTimeLine(
            document.getElementById('visualization'));
        annotatedtimeline.draw(data, {'displayAnnotations': true, 
          'wmode': 'transparent'});

        // In the lines below the default scroll when the mouse is on the 
        // AnnotatedTimeLine graph is disabled and normal page scroll  
        // behaviour is enabled.
        var chartRange, scrolled, mySetInterval                
        google.visualization.events.addListener(annotatedtimeline , 'ready', 
         function() {        
            //save the zoom state in chartRange after graph has been rendered
            chartRange = annotatedtimeline.getVisibleChartRange();
        });      
        google.visualization.events.addListener(annotatedtimeline , 
         'rangechange',function() {        
          if (scrolled) {
            // document was scrolled during last 1.5 seconds, therefore undo 
            // zooming. The 1.5 second delay is needed because rangechange is 
            // fired one 1 second after scroll event
            annotatedtimeline.setVisibleChartRange(chartRange.start, 
             chartRange.end);
          }else{
            // document was not scrolled during last 1.5 seconds, therefore
            // save the zoom state in chartRange
            chartRange = annotatedtimeline.getVisibleChartRange();
          }
        });

        // source: http://help.dottoro.com/ljqeknfl.php
        // for mouse scrolling in Firefox
        var elem = document.getElementById ("visualization");
        if (elem.addEventListener) {//all browsers except IE before version 9
              // Internet Explorer, Opera, Google Chrome and Safari
          elem.addEventListener ("mousewheel", MouseScroll, false);
              // Firefox
          elem.addEventListener ("DOMMouseScroll", MouseScroll, false);
        }
        else {
          if (elem.attachEvent) { // IE before version 9
              elem.attachEvent ("onmousewheel", MouseScroll);
          }
        }   

        //original from:http://help.dottoro.com/ljqeknfl.php and edited by me
        function MouseScroll (event) {
            // set scrolled to 1 for the next 1.5 second, and via 
            // mySetInterval make sure when multiple scroll event in 1.5 
            //  second appear, everything wroks correctly
            clearInterval(mySetInterval);
            scrolled=1;mySetInterval=setInterval(function(){scrolled=0},1500);

            //determine distance to be rolled
            var rolled = 0;
            if ('wheelDelta' in event) {
            rolled = event.wheelDelta;
            }
            else {  // Firefox
                    // The measurement units of the detail and wheelDelta 
                    // properties are different.
            rolled = -40 * event.detail;
            }
            //apply normal page scroll behaviour
            document.body.scrollTop -=rolled;
        }
      }    
      google.setOnLoadCallback(drawVisualization);
    </script>
  </head>
  <body style="font-family: Arial;border: 0 none;">
    <div id="visualization" style="width: 800px; height: 400px;"></div>
    <div style="height:1200px; background-color:#a08080;"></div>
  </body>
</html>
Ruut
  • 1,091
  • 1
  • 16
  • 29
  • I'm likely missing something obvious but I can't seem to see a difference when scrolling the graph. – Ren Nov 12 '12 at 11:18
  • If you scroll with your mouse on (1) [this graph](https://developers.google.com/chart/interactive/docs/gallery/annotatedtimeline#Example), you will zoom in and your page will not scroll. This is standard google api behaviour. If you scroll with your mouse on (2)[this graph](http://www.allepeilingen.com/index.php/peilingen-politieke-partijen-maurice-de-hond.html), the graph will not zoom and the web page will scroll down, this is the behaviour requested in the question. – Ruut Nov 12 '12 at 12:17
  • I was testing it on Firefox 16 - it isn't working. It works fine on Chrome though. – Ren Nov 12 '12 at 12:22
  • 1
    It is indeed not working in FF 16. I could not solve it easily. I will look into it later – Ruut Nov 12 '12 at 13:01
  • @Ren, I managed to fix it in FF 16 by adding `,'wmode': 'transparent'` to line starting with `annotatedtimeline.draw`. I updated the code above. Please confirm if it now works on your end. – Ruut Nov 12 '12 at 14:24