How can I grab Google Visualization DataTable data after chart is loaded?
Asked Answered
M

2

13

I want to grab Google Chart data from a page, convert it to CSV, and then hand it off to a downloader.

In chartpage.js

function downloadCSV(args) {
  var csvData, filename, link;
  var action = args.action_name;
  var csv = convertArrayOfObjectsToCSV({
    action_name: action
  });
  filename = args.filename || 'export.csv';

  csvData = encodeURI(csv);

  link = document.createElement('a');
  link.setAttribute('href', 'data:text/csv;charset=utf-8,' + csvData);
  link.setAttribute('type', 'data:text/csv;charset=utf-8');
  link.setAttribute('download', filename);
  link.click();
 }

Then in chart.coffee:

 init_chart = ->
   chart = new google.visualization.BarChart(document.getElementById('chart_div'));  //#chart_div in chart.html.haml

render_chart = (items, year)->
  @data = new google.visualization.DataTable()
  data.addColumn 'string', I18n.t('charts.name')

  // Other logic for building chart from Rails DB Data

  for key_item in items
  label = []
  [key, item] = key_item.split(':')

  if key == 'competitor_meded_involvement'
    label.push I18n.t('charts.competitor')

  label.push I18n.t("kol_items.#{item}")

  data.addColumn 'number', label.join(' - ')

// and so on.

google.charts.load 'current', 'packages': ['corechart']

google.visualization.events.addListener(@data, 'ready', setData) // I read this was a solution but it doesn't seem to help

google.charts.setOnLoadCallback ->

init_chart()

render_chart()

$(setData(@data)) //I tried passing this to a setter method over in chartpage.js which takes @data and tries to set it globally but that makes no difference at page load time.

In chart.html.haml:

 %h5{id: "downloadCSV"}= link_to '<i class="fa fa-file-excel-o"></i> Download CSV'.html_safe, "#"

 #chart_div

So I am trying both the above and the following in the main JS:

case 'chart_kol_comparison':
        google.setOnLoadCallback(function() {
          str = google.visualization.dataTableToCsv(window.data); //This builds the CSV string and returns it to the download JS for output
        });

But the data variable from the page's JS (HAML):

 @data = new google.visualization.DataTable()

Seems to only be available after the page loads–not when the JS above loads and tries to grab the data.

It works when I run the following in a console, but not when the page loads. This is in a Rails app.

 str = google.visualization.dataTableToCsv(data); //var data is populated after page loads (available from console) but not from the JS at page load time.

How can I go about this?

Montymonument answered 3/6, 2018 at 0:51 Comment(3)
@WhiteHat Thanks. I updated the question. Please let me know if this clarifies the question.Montymonument
@WhiteHat I updated the question again. Chart is drawn in chart.html.haml, during the render_chart method in chart.coffee, in the google.charts.setOnLoadCallback.Montymonument
Any feedback on the existing answer?Biogeochemistry
M
0

For me, the event binding never worked. So what I had to do was, in chart page.js:

function setData(data) {
  after_data = data;
}

google.visualization.dataTableToCsv(window.after_data);

And in chart.coffee:

setData(data)

Where data is the Google dataTable object.

So basically I had to create a setter outside of the page's google js file.

Montymonument answered 12/6, 2018 at 12:29 Comment(0)
S
2

The thing that seems to happen here is that you are not waiting for the chart/datatable to be completely rendered after calling draw. So the best way to achieve this is create an event handler that waits for the ready event of the chart/datatable.

google.visualization.events.addListener(tableChart, 'ready', myReadyHandler);

and you add the function that populate your variable, but after the chart/datatable is ready.

function myReadyHandler(){
  // fill variables here or call directly your other methods, 
  // this will ensure, you can grab data from the chart/datatable
  // because is completely rendered and you can play with that
}
Sorel answered 7/6, 2018 at 13:43 Comment(0)
M
0

For me, the event binding never worked. So what I had to do was, in chart page.js:

function setData(data) {
  after_data = data;
}

google.visualization.dataTableToCsv(window.after_data);

And in chart.coffee:

setData(data)

Where data is the Google dataTable object.

So basically I had to create a setter outside of the page's google js file.

Montymonument answered 12/6, 2018 at 12:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.