Search code examples
google-visualization

How to add vertical lines and annotations Google timeline chart


I am using a google timeline similar to the code snippet below. I want my chart to look like the one below. I have managed to get everything to work expect how to add the dashed lines and text notation. Unfortunately, when I am searching for annotations I keep getting the AnnotatedTimeline, which is a different google chart.

Is there a simple way to do this?

enter image description here

       <html>
      <head>
        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
        <script type="text/javascript">
          google.charts.load('current', {'packages':['timeline']});
          google.charts.setOnLoadCallback(drawChart);
          function drawChart() {
            var container = document.getElementById('timeline');
            var chart = new google.visualization.Timeline(container);
            var dataTable = new google.visualization.DataTable();
    
            dataTable.addColumn({ type: 'string', id: 'President' });
            dataTable.addColumn({ type: 'date', id: 'Start' });
            dataTable.addColumn({ type: 'date', id: 'End' });
            dataTable.addRows([
              [ 'Washington', new Date(1789, 3, 30), new Date(1797, 2, 4) ],
              [ 'Adams',      new Date(1797, 2, 4),  new Date(1801, 2, 4) ],
              [ 'Jefferson',  new Date(1801, 2, 4),  new Date(1809, 2, 4) ]]);
    
            chart.draw(dataTable);
          }
        </script>
      </head>
      <body>
        <div id="timeline" style="height: 180px;"></div>
      </body>
    </html>


Solution

  • I was able to get this to work by finding the position of the rects. I started by drawing divs for each line I would want to show. Then after the timeline is draw I repositions those divs based on the location of the rectangle. I was not able to get a good minimal working snippet here because of the window positions used in the snippet code, but I got pretty close. In my own code I have it working perfectly.

    .hline {
                border-left: 5px solid black;
                height: 100px;
                position:absolute;
                visibility:hidden;
                top:144px;
            }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <html>
          <head>
            <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
            
          </head>
          <body>
            <div id="timeline" style="height: 180px;"></div>
            
            
            <div id = "Hline1" class= "hline" > <div style = "position: relative; top:-18px">HLine1</div>
            <div id = "Hline2" class= "hline" > <div style = "position: relative; top:-18px">HLine2</div>
            <div id = "Hline3" class= "hline" > <div style = "position: relative; top:-18px">HLine3</div>
            
            </div>
          </body>
          
          <script>
            var options = {
                              timeline: { showRowLabels: false }
                            };
            const lime="#00ff00" //color for average time
              google.charts.load('current', {'packages':['timeline']});
              google.charts.setOnLoadCallback(drawChart);
              function drawChart() {
                var container = document.getElementById('timeline');
                var chart = new google.visualization.Timeline(container);
                var dataTable = new google.visualization.DataTable();
        
                dataTable.addColumn({ type: 'string', id: 'Project Stage',  });
                    dataTable.addColumn({  type: 'string', id: 'Bar'});
                    dataTable.addColumn({  type: 'string', role: 'style'});
                    dataTable.addColumn({ type: 'date', id: 'Start' });
                    dataTable.addColumn({ type: 'date', id: 'End' });
                  dataTable.addRows([
                              [ 'Washington','Washington',lime, new Date(1789, 3, 30), new Date(1797, 2, 4) ],
                              [ 'Adams', 'Adams',lime,     new Date(1797, 2, 4),  new Date(1801, 2, 4) ],
                              [ 'Jefferson','Jefferson',lime,  new Date(1801, 2, 4),  new Date(1809, 2, 4) ]]);
                    
                            chart.draw(dataTable,options);
                          
              
              
              function redraw (){
                var rects = $('rect') //get all rectangles on plot.
                
                function checkColor(arr){
                    var results = [];
                    for (let i of arr){
                    var colorCheck=$(i).attr('fill')
                    var x =$(i).attr('x')
                    var width = $(i).attr('width')  
                    var x2 =parseFloat(x)+parseFloat(width)
                        
                        if(colorCheck == lime){results.push(x2)}
                        };
                        return results
                    };
                    
                var linPositions = checkColor(rects) //get x coordinates for vertical lines
    
                var yStart = $('rect')
                //console.log(linPositions)
                yStart = $(yStart[0]).offset().top;
                xMargin=$("#timeline").offset().left;
    
        
                
                var yHeight = $('rect')
                yHeight = $(yHeight[0]).attr('height');
                
    
                var lineNames=['Hline1','Hline2','Hline3']
    
                
                for (let i = 0; i < linPositions.length; i++) {
                    var position = linPositions[i]+xMargin+"px"
                    var newTop = i*yHeight + yStart
                    
                    /* set line information based on current chart positions */
                    document.getElementById(lineNames[i]).style.left = position;
                    document.getElementById(lineNames[i]).style.visibility = "visible";
                    document.getElementById(lineNames[i]).style.top = newTop;
                    document.getElementById(lineNames[i]).style.height = yHeight;
    
                
                };
                
            };  
    
            redraw()    
            
            function resizeChart () {
                chart.draw(dataTable, options);
    
            }
            if (document.addEventListener) {
                window.addEventListener('resize', resizeChart);
                window.addEventListener('resize', redraw)
            }
            else if (document.attachEvent) {
                window.attachEvent('onresize', resizeChart);
                window.attachEvent('onresize', redraw);
            }
            else {
                window.resize = resizeChart;
                window.resize = redraw;
            }
        
            
            }
              
            </script>
          
        </html>