Tony Frame Tony Frame - 1 month ago 19
Javascript Question

Issues with Google Visualization API on App Engine

I have been working on a front end to my App Engine app kind of based on this codelab. I have a text box where you enter in a stock ticker symbol (like say, AMZN or GOOG), which it uses as criteria to run a query to Google BigQuery in the background and then it's supposed display the tweet count over several days in a Google Visualization API line chart.

But, based on what I've seen in the source code from the page, it's not pulling the query results from BigQuery into the data template variable {{ data }}. Here's my HTML code (called index1.html), which for the most part is like the codelab's:

<!--
You are free to copy and use this sample in accordance with the terms of the
Apache license (http://www.apache.org/licenses/LICENSE-2.0.html)
-->

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>
Jibdan Analytics
</title>
<script type="text/javascript" src="//www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['corechart']});
</script>
<script type="text/javascript">

countdata = {{ data }}

function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.DataTable(query_response);

// Create and draw the visualization.
var chart = new google.visualization.LineChart(document.getElementById('visualization'));
chart.draw(data, {title: "Tweets by Day by Ticker",
curveType: "function",
width: 800, height: 600}
);
}


google.setOnLoadCallback(drawVisualization);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="visualization" style="width: 800px; height: 640px;"></div>
</body>
</html>


I messed with the html and Javascript after looking at the Google Code Playground code for the line chart, but really it seems like the issue is with that template variable.

Here's the pertinent Python code, too. The first method is supposed to take the BigQuery response and put it in a format that should be ingested by the Visualization API to produce a line chart. The get method has the query string to run and renders the results into the template, index1.html. Pretty much like the codelab:

class QueryHandler(webapp2.RequestHandler):

def _bq2line(self, bqdata):
logging.info(bqdata)
columnNameDate = bqdata['schema']['fields'][0]['name']
columnNameVal = bqdata['schema']['fields'][1]['name']
logging.info("Column Names=%s, %s" % (columnNameDate, columnNameVal))
countdata = { 'cols': ({'id':columnNameDate, 'label':columnNameDate, 'type':'string'},
{'id':columnNameVal, 'label':columnNameVal, 'type':'number'})}
countdata['rows'] = [];
logging.info(countdata)
for row in bqdata['rows']:
newrow = ({'c':[]})
newrow['c'].append({'v': row['f'][0]['v']})
newrow['c'].append({'v':row['f'][1]['v']})
countdata['rows'].append(newrow)
logging.info('FINAL COUNTDATA---')
logging.info(countdata)
self.response.out.write(countdata)
return json.dumps(countdata)

def get(self):

QUERY = """
SELECT STRFTIME_UTC_USEC(querydate, "%Y-%m-%d") AS tweet_date, COUNT(tweet_id) AS tweet_count
FROM [jibdantweetstream.tweetdata_09_21_2013]
WHERE gcs_load = true AND (REGEXP_MATCH(ticker, '""" + self.request.get('stock') + """'))
GROUP BY tweet_date
ORDER BY tweet_date
"""

try:
query_request = bigquery_service.jobs()
query = {'data': self._bq2line(bq.Query(QUERY, BILLING_ID)),
'query': QUERY}
query_response = query_request.query(projectId=BILLING_ID,
body=query).execute()
template = os.path.join(os.path.dirname(__file__), 'result1.html')
self.response.out.write(render(template, query_response))

finally:
self.response.out.write('<a href="/">Click here</a> to go back to the Search page. ')


So, that's what I have. You'll see I have a couple of
self.response.out.write
statements in there, because I wanted to see if I was getting a response back with query results. I am getting results, so I know it's not an OAuth2 issue. I just don't know what else it could be.

Many Thanks in Advance.

Answer

"View Source", coupled with something (Firebug, Chrome Developer Tools) that'll tell you about syntax errors in your JavaScript are your friends. Looking at what you've provided, I'm guessing that expanding {{ data }} will result in a syntax error. And as asgallant noted, you're setting up countdata but referencing query_response instead.

Since your data is a date and a count, you're not going to run into entity escaping issues, but if you expand the query to include something else, you'll run into the problem of {{ data }} being escaped for HTML, where it needs to be escaping for JS. To handle that, you'll need the escapejs filter.

Comments