Add a google chart to a FusionTableLayer infowindow

I'm trying to display chart (Google Chart API) inside InfoWindow (Fusion Table layer), but the problem is with container "Uncaught Error: The container is null or not defined." whenever I try to include div inside InfoWindow.

I was trying to solve the problem based on this solution, but it's not working with fusion table Add a google chart to a infowindow using google maps api

Please help

<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});
    function drawVisualization() {
      var queryText = encodeURIComponent("SELECT Year, Austria, Bulgaria, Denmark, Greece FROM 641716");
      google.visualization.drawChart({
        "containerId": 'visualization_div',
        "dataSourceUrl": 'https://www.google.com/fusiontables/gvizdata?tq=',
        "query":"SELECT Year, Austria, Bulgaria, Denmark, Greece FROM 641716",
        "refreshInterval": 5,
        "chartType": "PieChart",
        "options": {
          "title":"Yearly Coffee Consumption by Country",
          "vAxis": {"title": "Year"},
          "hAxis": {"title": "Cups"}
        }
      });
    }
      function initialize() {
        var map = new google.maps.Map(document.getElementById('map-canvas'), {
          center: new google.maps.LatLng(29.296435107347698, -29.54822280000008),
          zoom: 2,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });

        var layer = new google.maps.FusionTablesLayer({
          query: {
            select: 'col0',
            from: '1PoUAVtdJKOKnJT_ZYkoM7yDpGw-wNJMHXakPeC0'
          },
          map: map
        });
        google.maps.event.addListener(layer, 'click', function(e) {
        drawVisualization(this);
          e.infoWindowHtml += "<div id='visualization_div'></div>";{
          }
        });
      }

      google.maps.event.addDomListener(window, 'load', initialize);

    </script>

PS.

One more thing ! It's possible to display chart from data from one row. In my example for one country that is clicked ?

Answers:

Answer

It's a bit more difficult.

The infowindow of a FTLayer doesn't open immediately, because the data for the infowindow will be requested asynchronously.

When you call drawVisualization immediately there is no guarantee that the infowindow-content is already available in the DOM, the #visualization_div will not be available yet.

The problem: there is no domready-event for the infowindow of the FTLayer, you'll never know when the infowindow is ready.

Another problem: the chart will also be drawn asynchronously, the result would be a undesirable look of the infowindow(the chart will be drawn under the infowindow, not inside)

Possible solution(there may be others): use a custom infowindow instead:

<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});

  //pass the infowindow as argument, we need it later
function drawVisualization(infowindow) {
  var queryText = encodeURIComponent("SELECT Year, Austria, Bulgaria, \
                                      Denmark, Greece FROM 641716");

    /*note:      we don't need the ContainerId here, 
                 we use the node-reference with draw
     *also note: we use ChartWrapper here, because we need 
                 the ready-event of the chart to redraw the infowindow
    */
  var chart=new google.visualization.ChartWrapper({
    "dataSourceUrl": 'https://www.google.com/fusiontables/gvizdata?tq=',
    "query":"SELECT Year, Austria, Bulgaria, Denmark, Greece FROM 641716",
    "refreshInterval": 5,
    "chartType": "PieChart",
    "options": {
      "title":"Yearly Coffee Consumption by Country",
      "vAxis": {"title": "Year"},
      "hAxis": {"title": "Cups"}
    }
  });


  var ready=google.visualization.events.addListener(chart, 'ready', function(){
      //re-assign the map-property to redraw the 
      //infowindow when the chart has been drawn
    infowindow.setMap(infowindow.getMap());
      //remove the ready-listener
    google.visualization.events.removeListener(ready);
   });

    //draw the chart
  chart.draw(infowindow.getContent().lastChild);

}

function initialize() {
    map = new google.maps.Map(document.getElementById('map-canvas'), {
      center: new google.maps.LatLng(29.296435107347698, -29.54822280000008),
      zoom: 2,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var layer = new google.maps.FusionTablesLayer({
      query: {
        select: 'col0',
        from: '1PoUAVtdJKOKnJT_ZYkoM7yDpGw-wNJMHXakPeC0'
      },
      map: map,
        //don't use the infowindows of the FTLayer
      suppressInfoWindows:true
    });
      //a custom infowindow
    infowindow=new google.maps.InfoWindow();


    google.maps.event.addListener(layer, 'click', function(e) {
      //call drawVisualization when the infowindow is ready
      google.maps.event.addListenerOnce(infowindow,'domready',function(){
        drawVisualization(infowindow);
      });
        //create the content for the infowindow
      var node=document.createElement('div');
      node.innerHTML=e.infoWindowHtml;
        //create the node where the chart will be drawn
      node.appendChild(document.createElement('div'));
        //open the infowindow
      infowindow.setOptions({position:e.latLng,content:node,map:map});
     });
  }

  google.maps.event.addDomListener(window, 'load', initialize);

</script>
Answer

I found also second way, maybe not so sophisticated but working
1. Create chart in Fusion Table
2. Copy link from Publish tab
3. Paste the link inside iframe. I made some tabs for this

'<div id="tab-2">' + //firts tab content 
    '<iframe src="https://www.google.com/fusiontables/embedviz?containerId=googft-gviz-canvas&q=select+col2%2C+col3+from+1NLk1HStpHzzSedbjQioau_7fSxeVlmb4G4A46MM+order+by+col3+desc+limit+6&viz=GVIZ&t=PIE&uiversion=2&gco_forceIFrame=true&gco_hasLabelsColumn=true&gco_useFirstColumnAsDomain=true&gco_is3D=false&gco_pieHole=0.5&gco_booleanRole=certainty&gco_colors=%5B%22%233366CC%22%2C%22%23DC3912%22%2C%22%23FF9900%22%2C%22%23109618%22%2C%22%23990099%22%2C%22%230099C6%22%2C%22%23DD4477%22%2C%22%2366AA00%22%2C%22%23B82E2E%22%2C%22%23316395%22%2C%22%23994499%22%2C%22%2322AA99%22%2C%22%23AAAA11%22%2C%22%236633CC%22%2C%22%23E67300%22%2C%22%238B0707%22%2C%22%23651067%22%2C%22%23329262%22%2C%22%235574A6%22%2C%22%233B3EAC%22%2C%22%23B77322%22%2C%22%2316D620%22%2C%22%23B91383%22%2C%22%23F4359E%22%2C%22%239C5935%22%2C%22%23A9C413%22%2C%22%232A778D%22%2C%22%23668D1C%22%2C%22%23BEA413%22%2C%22%230C5922%22%2C%22%23743411%22%5D&gco_hAxis=%7B%22useFormatFromData%22%3Atrue%2C+%22viewWindow%22%3A%7B%22max%22%3Anull%2C+%22min%22%3Anull%7D%2C+%22minValue%22%3Anull%2C+%22maxValue%22%3Anull%7D&gco_vAxes=%5B%7B%22useFormatFromData%22%3Atrue%2C+%22viewWindow%22%3A%7B%22max%22%3Anull%2C+%22min%22%3Anull%7D%2C+%22minValue%22%3Anull%2C+%22maxValue%22%3Anull%7D%2C%7B%22useFormatFromData%22%3Atrue%2C+%22viewWindow%22%3A%7B%22max%22%3Anull%2C+%22min%22%3Anull%7D%2C+%22minValue%22%3Anull%2C+%22maxValue%22%3Anull%7D%5D&gco_theme=maximized&gco_legend=none&width=00&height=150"frameborder="0"; scrolling="no"/>' +
    '</div>' +

DEMO

And we can also insert query into URL so just selected rows are in Google Chart

e.row['Country_Name'].value

'<div id="tab-2">' + //firts tab content 
    '<iframe src="https://www.google.com/fusiontables/embedviz?containerId=googft-gviz-canvas&q=select+col0%2C+col1%2C+col2%2Ccol3+from+1r4egxlD-9QeK-4gBrdtTGQFrhdrBoxNhBwQbWUc+%20WHERE%20Country_Name=%27'+ e.row['Country_Name'].value +'%27+order+by+col1+asc+limit+10&viz=GVIZ&t=COLUMN&uiversion=2&gco_forceIFrame=true&gco_hasLabelsColumn=true&att=true&gco_theme=maximized&width=300&height=150"frameborder="0"; scrolling="no"/>' +

DEMO 2

Answer

I solved this by rendering the charts to PNG with gnuplot and serving them as static images from a column of URLs in the Fusion Table.

It's not a Google Chart/javascript solution, but we have more data points than we want to plot on the fly with Google Chart anyway.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.