read data from datastore into Google Charts Datatable to plot Graphs - sql

I'm trying to read data from the datastore of my Google App Engine Application, populate the google charts Datatable with it then visualize the whole thing into a graph using the source code from the google charts example which uses Javascript code embedded on the web page.
My issue is with fetching the data. I thought of two ways of doing this: either run the query directly inside the javascript code or run the query from the python code , send the results of that query as a template value to the html code, filter it to get the values I'm interested in and somehow passing the whole thing to the javascript code then diplay the data (looks more complicated). I've tried the first option but it doesn't seem to work. Since i wasn't sure what the URL of my datastore was, I though it was the same as the server which uses it so I passed the URL of my appengine application as a parameter to the query function. I tried to run an SQL query on this but I got an error.
Below are the corresponding JS code (alone) and the whole HTML code
function drawVisualization() {
var query = new google.visualization.Query('http://davidfirstapp.appspot.com');
query.setQuery('SELECT ac_current1, ac_voltage1 ORDER BY ac_current1 LIMIT 10');
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
visualization = new google.visualization.LineChart(document.getElementById('visualization'));
visualization.draw(data, {legend: 'bottom'});
}
<!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>
Google Visualization API Sample
</title>
<script type="text/javascript" src="//www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1', {packages: ['linechart']});
</script>
<script type="text/javascript">
var visualization;
function drawVisualization() {
var query = new google.visualization.Query('http://davidfirstapp.appspot.com');
query.setQuery('SELECT ac_current1, ac_voltage1 ORDER BY ac_current1 LIMIT 10');
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
visualization = new google.visualization.LineChart(document.getElementById('visualization'));
visualization.draw(data, {legend: 'bottom'});
}
google.setOnLoadCallback(drawVisualization);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="visualization" style="height: 400px; width: 400px;"></div>
</body>
</html>
​

You cant query your own webpage and somehow expect it to connect to the datastore. Your webpage contains your own html output that you defined. Read more about appengine / web applications and how the datastore works.
You need to do the datastore query from the frontend, not the browsers js. Build a table and pass it to the browser where it builds the datatable and chart.

Related

Context Dictionary isn't being passed with render in view

Alright, I've been poking around the internet for a solution to that there's something obvious that I'm missing but so far no good.
I'm currently having trouble with passing a context dictionary to a template in Django via my view. So far everything else seems to return, except for the dictionary that I'm passing to the template.
def search_subjects(request):
"""
This is our search view, at present it collects queries relating to:
- Subject ID
- Study Name
- Date Range Start
- Date Range Start
Then validates these entries, after which it redirects to the search
results view.
:param request:
:return: Redirect to search results if search button is pressed and form fields
are valid or renders this view again if this request is not POST
"""
if request.method == 'POST':
form = SearchForm(request.POST)
if form.is_valid():
search_dict = {}
search = form.save(commit=False)
search.subject_search = request.POST['subject_search']
search.study_search = request.POST['subject_search']
if request.POST['date_range_alpha'] and \
dateparse.parse_datetime(request.POST['date_range_alpha']):
search.date_range_alpha = request.POST['date_ranch_alpha']
else:
search.date_range_alpha = EPOCH_TIME
if request.POST['date_range_omega'] and \
dateparse.parse_datetime(request.POST['date_range_omega']):
with_tz = dateparse.parse_datetime(request.POST['date_range_omega'])
search.date_range_omega = with_tz
else:
search.date_range_omega = timezone.now()
search.save()
for k, v in form.data.items():
search_dict[k] = v
print(search_dict)
return render(request, 'dicoms/search_results.html', search_dict)
else:
form = SearchForm()
return render(request, 'dicoms/search.html', {'form': form})
And my template here:
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search Results</title>
</head>
<body>
Here's what you searched for:
<div>{{ search_dict }}</div>
</body>
</html>
The page that I'm getting back:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Search Results</title>
</head>
<body>
Here's what you searched for:
<div></div>
</body>
</html>
What on earth am I missing here?
Ok, so I walked away from this for a bit and managed to solve it. I wasn't passing a context dictionary correctly. Fix can be seen below.:
search.save()
context = {'search': search}
return render(request, 'dicoms/search_results.html', context)
Adjusting the template accordingly:
Here's what you searched for:
<div>{{ search.subject_search }}</div>
<div>{{ search.study_search }}</div>
<div>{{ search.date_range_alpha }}</div>
<div>{{ search.date_range_omega }}</div>
Results in:
Here's what you searched for:
<div>herp </div>
<div>herp </div>
<div>Jan. 1, 1970, midnight</div>
<div>Feb. 26, 2019, 11:05 p.m.</div>
Had I trusted in django and simply passed the whole search object in the beginning I wouldn't have ended up here. But you live and learn.

Orchard: Displaying only a single content item

I want to be able to display a content item of a certain type and only that content item i.e. no shapes that are not part of said item.
I have tried creating a controller method with a {Themed(false)] attribute, or returning a partial view. Both of these do almost exactly what I want, except that these don't include any scripts or styles associated with the View I'm trying to display.
My current attempt look like this:
Controller method:
[Themed(false)]
public ActionResult DisplayBare(int id) {
var contentItem = _contentManager.Get(id, VersionOptions.Published);
dynamic model = _contentManager.BuildDisplay(contentItem);
return View( (object)model);
}
The DisplayBare view:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
#Display(Model)
</body>
</html>
The problem is that when the display View of an item includes Script.Require, Script.Include and Script.Foot directives, the scripts do not show up in the Html.
How would I achieve this?
Found a solution by snooping around Orchard sources:
Using this view to display my content item gives me exactly what i want:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
#{
Style.Include("Site.css");
var content = Display(Model);
}
#Display.Metas()
#Display.HeadScripts()
#Display.HeadLinks()
#Display.StyleSheetLinks()
</head>
<body>
#content
#Display.FootScripts()
</body>
</html>

pass form data to a new window

I'm trying to figure out how to pass form data collected from sql database to a new window. The idea is when the user click 'Rediger' (edit), that a new small window will open up with the current data and an input field for the user to change the data, and then hit the save button for the data to be written to the database. Then the window must close and the original page being updated with the new data. Is this possible? Can anyone please help me with this? Thank you.
Check out the page here: http://kristoff.it/onlinecoaching/coach/
Here is my dummy code:
<!DOCTYPE html>
<html>
<head>
<script>
function getValue()
  {
var txtfield=document.getElementById(this.id);
//alert(txtfield.innerHTML);
newWindow.document.write(txtfield.innerHTML);
return newWindow;
//windowsize(640, 480)
  }
</script>
</head>
<body>
<form method="POST" id="submitform">
<label id="name">John Smith</label><input type="button" id="button" onclick="getValue()" value="Edit">
<br>
<label id="title">Director</label><input type="button" id="button" onclick="getValue()" value="Edit">
</form>
</body>
</html>
You'll need some AJAX for this.
First follow this discussion, to be able to detect when the windows was closed.
Then make an ajaxRequest like this:
$.ajax({
url: "someUrlWhereYouCanFindTheUpdatedRecords.html",
cache: false
}).done(function( html ) {
//Some code that updates your webpage
});
Note that this code is using JQuery
Good luck!

How to add id using dojo.query to search element

I'm trying to add id to a element using dojo.query. I'm not sure if it's possible though. I trying to use the code below to add the id but it's not working.
dojo.query('div[style=""]').attr("id","main-body");
<div style="">
content
</div>
If this is not possible, is there another way to do it? Using javascript or jquery? Thanks.
Your way of adding an id to an element is correct.
The code runs fine for me in Firefox 17 and Chrome 23 but I have an issue in IE9. I suspect you may have the same issue.
In IE9 the query div[style=""] returns no results. The funny thing is,it works fine in compatibility mode!
t seems that in IE9 in normal mode if an HTML element has an inline empty style attribute, that attribute is not being preserved when the element is added to the DOM.
So a solution would be to use a different query to find the divs you want.
You could try to find the divs with an empty style attributes OR with no style attribute at all.
A query like this should work:
div[style=""], div:not([style])
Take a look at the following example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.8.2/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.NodeList-manipulate");//just for the innerHTML() function
dojo.addOnLoad(function () {
var nodeListByAttr = dojo.query('div[style=""], div:not([style])');
alert('Search by attribute nodeList length:' + nodeListByAttr.length);
nodeListByAttr.attr("id", "main-body");
var nodeListByID = dojo.query('#main-body');
alert('Search by id nodeList length:' + nodeListByID.length);
nodeListByID.innerHTML('Content set after finding the element by ID');
});
</script>
</head>
<body>
<div style="">
</div>
</body>
</html>
Hope this helps
#Nikanos' answer covers the query issue, I would like to add, that any query returns an array of elements, in case of Dojo it is dojo/NodeList.
The problem is you are about to assign the same id to multiple DOM nodes, especially with query containing div:not([style]). I recommend to use more specific query like first div child of body:
var nodes = dojo.query('body > div:first-child');
nodes.attr("id", "main-body");
To make it more robust, do not manipulate all the nodes, just the first node (even through there should be just one):
dojo.query('body > div:first-child')[0].id = "main-body";
This work also in IE9, see it in action: http://jsfiddle.net/phusick/JN4cz/
The same example written in Modern Dojo: http://jsfiddle.net/phusick/BReda/

maps v3 api kml layer change transparency on click

The final goal is to display a few kml overlays on one map and set the transparency value by clicking on a control button for each kml layer (depending on how much layers there are).
My first idea was changing opacity/transparency directly by the div layer.. but I can't find any way to address the div where the kml layer is shown in the map.
Does someone know a way to address the div where the KML is inserted by the KmlLayer(..)?
Now I'm trying to find a way to do it via the KmlLayer Object..
but so far no luck either..
Any ideas how to handle this?
The Code is:
(function() {
window.onload = function(){
var myLatlng = new google.maps.LatLng(48.1497, 11.5795);
var myOptions = {
zoom: 10,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var georssLayer = new google.maps.KmlLayer('somemap.kml',({'suppressInfoWindows': true}));
georssLayer.setMap(map);
}
})();
To the best of my knowledge it is not possible via standard google api but you can do this using jquery or some other library. KML images are just part of the DOM so if you can find the nodes you can manipulate their properties.
If you have multiple KML files you will probably need to name your images so that the name reflects which KML image belongs to. so if you have KML1 prepend KML1 to all your image names in that KML and search for that string using jQuery selector.
Here is an example using jquery which targets all images (for searches on substrings see http://api.jquery.com/attribute-contains-selector/):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: KmlLayer KML</title>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".b_opacity").click(function(){
//this will find all the images in the map canvas container. Normally you would want to target specific images by the value of src
$("#map_canvas").find("img").css("opacity","0.4")
})
})
function initialize() {
var chicago = new google.maps.LatLng(41.875696,-87.624207);
var myOptions = {
zoom: 11,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var ctaLayer = new google.maps.KmlLayer('http://code.google.com/apis/kml/documentation/KML_Samples.kml');
ctaLayer.setMap(map);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width: 600px;height: 600px;"></div>
<input type="button" value="dim the lights" class="b_opacity">
</body>
</html>
NOTE: please bear in mind that the css property opacity does not work in IE you have to use filter:alpha(opacity=40) for IE or you can use jQuery .fade() method.