Reputation: 87
I've been struggling three weeks for now and I'm at the dead end. Sysadmins are s*tty developers :)
I'm trying to build lightweight cgi-bin python scripts to collect data and convert it into json format. Then I use plain html page to make ajax query to python scripts to get data and draw my charts (periodically, people love real-time stuff)
These should be as light as possible, because they work on raspberry.
One of my python scripts that collects the data
#!/usr/bin/python
import sqlite3
import gviz_api
# enable debugging
import cgitb
cgitb.enable()
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
connection = sqlite3.connect("templog.db")
connection.row_factory = dict_factory
cursor = connection.cursor()
cursor.execute("select temp, status from data where ID = (select MAX(ID) from data)")
# fetch all or one we'll go for all.
results = cursor.fetchall()
connection.close()
schema = {"temp": ("number", "temp"),"status": ("number", "status")}
data = results
# Loading it into gviz_api.DataTable
data_table = gviz_api.DataTable(schema)
data_table.LoadData(data)
json = data_table.ToJSon(columns_order=("temp", "status"),order_by="temp")
#print results
#print "Content-type: application/json\n\n"
print "Content-type: application/json"
print
print json
This works like a charm when I open it up on my browser and it gives me what I need in corrent format for Google jsapi
{"rows":[{"c":[{"v":21.062},{"v":0}]}],"cols":[{"type":"number","id":"temp","label":"temp"},{"type":"number","id":"status","label":"status"}]}
Below is my html that needs the json data from python script to draw the chart
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.load('visualization', '1', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawTable);
function drawTable() {
var jsonData = $.ajax({
type: "GET",
url: "http://192.168.1.123:8099/cgi-bin/test.py",
dataType:"json",
async: false
}).responseText;
alert(jsonData);
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
Unfortunately I got "undefined" alert when html is making ajax query directly to python script.
Then I copied json output 1:1 to plain static html file and replaced ajax URL to .html instead of dynamic .py, and it works.
My question is - are there some limitations for what I'm trying to do or is there something wrong with my code?
My code is based on examples https://developers.google.com/chart/interactive/docs/php_example https://developers.google.com/chart/interactive/docs/dev/gviz_api_lib
Upvotes: 0
Views: 366
Reputation: 309929
If I'm reading your javascript correctly, the responseText property is only set after the request has completed. Normally, these things execute asynchronously, so you register a function to be called after the data has been received. e.g.
function drawTable() {
var drawChart = function(jsonData) {
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {width: 400, height: 240});
};
$.ajax({
type: "GET",
url: "http://192.168.1.123:8099/cgi-bin/test.py",
dataType:"json",
async: false
}).done(drawChart);
}
More examples can be found on in the jquery ajax documentation.
Upvotes: 1