Uncaught SyntaxError: Unexpected token & while rendering a Django template - javascript

I'm trying to draw a line chart using "https://www.google.com/jsapi", and passing data from a Django view;
this is my template
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
data = {{analytics_data}}
var data = google.visualization.arrayToDataTable(data);
var options = {
title: 'Facebook Analytics'
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
views.py
def show_fb_analytics(request):
analytics_data = [["Day", "Likes", "Share", "Comments"]]
data = FbAnalytics.objects.all()
for item in data:
date = item.date
likes = item.likes
comments = item.comments
shares = item.shares
lst = [date, likes, comments, shares]
analytics_data.append(lst)
return render(request, 'fbchart.html', {'analytics_data':analytics_data})
The analytics_data should return data in format
[['Day', 'Likes', 'Share', 'Comments'],
['31 Aug', 5, 8, 10 ],
['01 Sep', 10, 5, 13 ]]
but during render of the html template it gives data it given format
[['Day', 'Likes', 'Share', 'Comments'],
[u'01Sep', 2, 2, 2]]
means it is adding u'&#39 in every string due to which I'm getting the error "Uncaught Syntax Error: Unexpected token &" and my temlate is not returning the line chart.
How I can remove this error?

You should convert your list to proper JSON first, like this:
import json
def show_fb_analytics(request):
...
return render(request, 'fbchart.html', {'analytics_data': json.dumps(analytics_data)})
Then output it with "safe" filter, so Django's escaping engine doesn't intervene:
{{analytics_data|safe}}
Converting to JSON will output your list as JavaScript Array literal (instead of Python List literal; although the two are pretty similar, they are in fact different, in your case Python has u prefixes which JS doesn't, etc.), and using safe filter will prevent Django's template engine from converting ' to '

#Spc_555's answer is correct but you can mark the JSON as safe in the view too:
import json
from django.utils.safestring import marksafe
def show_fb_analytics(request):
...
return render(request, 'fbchart.html', {'analytics_data': mark_safe(json.dumps(analytics_data))})

Related

Locale language for google charts not working

In my page I load the chart as described in the docs. It's a view in asp.net that renders the output. The view checks if a class called Avstemning is populated then puts strings from that class into the chart as data. But if I use Norwegian letters like ø,æ, å. The chart data can't read it even as I specify the language option to use. What is going on here?
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
#if (Model.Avstemning != null)
{
<script type="text/javascript">
google.charts
.load('current', { 'packages': ['corechart'], 'language':'no' });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Avstemning', '#Model.Avstemning.Tittel'],
['#Model.Avstemning.Option1', #Model.Avstemning.One],
['#Model.Avstemning.Option2', #Model.Avstemning.Two],
['#Model.Avstemning.Option3', #Model.Avstemning.Three]
]);
var options = {
title: '#Model.Avstemning.Tittel'};
var chart = new
google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
}
If I change the data variable to take hard coded options with norwegian letters it works. But that's not exactly ideal. Any ideas on how to solve this? Inject javascript from controller?
I solved the encoding issue by using Html.Raw(). Not recommended if these are later to be stored in db, but works for displaying the data as I intended:
var data = google.visualization.arrayToDataTable([
['Avstemning', '#Html.Raw(Model.Avstemning.Tittel)'],
['#Html.Raw(Model.Avstemning.Option1)', #Model.Avstemning.One],
['#Html.Raw(Model.Avstemning.Option2)', #Model.Avstemning.Two],
['#Html.Raw(Model.Avstemning.Option3)', #Model.Avstemning.Three]
]);
var options = {
title: '#Html.Raw(Model.Avstemning.Tittel)',
};

How to properly pass json to a view

I have a view with some javascript code for a pie chart in it. This view has an action method, where I am running some queries an converting the results to json in order to fill the pie chart with something.
The problem is that I don't know (and couldn't understand from another questions here) how to properly return a json from action to view and actually work with the data in some way in the view.
Currently, what I have give me a json string in my browser instead of a view.
I do not have a model in my project for the data that's in in the json.
Here's all the code from my view :
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Language', 'Speakers (in millions)'],
['German', 5.85],
['French', 1.66],
['Italian', 0.316],
['Romansh', 0.0791]
]);
var options = {
legend: 'none',
pieSliceText: 'label',
title: 'Accumulated experience',
pieStartAngle: 100,
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
<div id="piechart" style="width: 1000px; height: 600px;"></div>
And here is my controller :
public ActionResult experiencePieChart()
{
//some queries
var json = JsonConvert.SerializeObject(perclist);
return Json(json, JsonRequestBehavior.AllowGet);
}
your controller method should return JsonResult, just change it's signature in following way:
public JsonResult experiencePieChart()
{
var perclist = ...
//some queries
return Json(perclist, JsonRequestBehavior.AllowGet);
}
then in your js code you could call it
$(document).ready(function()
{
$.get("/YourController/experiencePieChart",ShowPieChart,"json").fail(ShowPieChartFail);
});
of course then you need define ShowPieChart function which will render that graph
function ShowPieChart(chartData){
// this code will be executed after result is returned asynchronously
// chartData contains JSON representation of perclist variable
}
In case you'd like to do that data-transfer just on each refresh of page, you could store data required for chart. In your .cshtml you'd just add
<script type="text/javascript">
var ChartData = #Html.Raw(Json.Encode(#Model.MyData))
</script>
then during execution of js on client side you'd have ChartData variable initialized. Anyway this way have multiple downside and is not scalable at all. Going with ajax call seems much better to me.

instead of ready data how can i read from csv?

i have this code and i want to change the static data with data from csv
the csv is look like:
GPA,Total Distance,id
3.27,22.0,20032202
2,64.0,20038107
2.81,10.0,20051566
2.33,66.5,20060382
i want to add the GPA in y axis
and total distance in the X axis
when i try to add code from d3 library it does not works
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart', 'line']
});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'GPA');
data.addRows([
[0, 0],
[1, 10],
[2, 23],
[3, 17],
[4, 18],
]);
var options = {
hAxis: {
title: 'Total Distance'
},
vAxis: {
title: 'GPA'
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="curve_chart" style="width: 900px; height: 500px"></div>
</body>
</html>
Here is the best answer I can come up with to help you.
In your question, you have to tackle different topics in javascript
get content of a local file in javascript
parse this content as a csv file (and make it a multidimensional array)
prepare the values to put in the chart
First, add the following two libraries : jQuery for the simplified ajax calls to the file and jquery-csv for an also simplified way to parse the content.
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
Then, you have to re-route the charts callback : you have to point to a function that get asynchronously the file content (getFileContent in the example below).
Only in case of success, you can format the csv data into array.
And only then, you can serve the data to the chart by passing your formatted and sorted array to your drawbasic method.
Finally, you end up with that script
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart', 'line']
});
google.charts.setOnLoadCallback(getFileContent);
function getFileContent() {
var filePath = 'file:///path/to/file.csv';
// 1. Get local file content asynchronously
$.get(filePath, {}, function (data) {
console.log(arguments);
var lines = $.csv.toArrays(data); // 2. Parse the csv as a multidimensional array
var header = lines.shift(); // 3. Remove the header of the file
// 4. Sort the lines by the second column
lines.sort(function (a, b) {
if (a[1] === b[1]) {
return 0;
}
else {
return (a[1] < b[1]) ? -1 : 1;
}
});
// 5. Pass your lines to the draw method
drawBasic(lines);
}, 'text')
.fail(function () {
console.log(arguments);
})
;
}
function drawBasic(lines) {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'GPA');
for (i = 0; i < lines.length; i++) {
// 6. Don't forget to parse as float the numbers in the array, they are strings at this point
// You'll get a 'Type mismatch. Value 3,27 does not match type number' error if you don't
var xValue = parseFloat(lines[i][1]);
var yValue = parseFloat(lines[i][0]);
data.addRow([xValue, yValue]);
}
var options = {
hAxis: {
title: 'Total Distance'
},
vAxis: {
title: 'GPA'
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
Don't forget to change the filepath in getFileContent, preceded by file://
I give credit to the answers in SO that helped me create this answer:
Javascript - read local text file
How to sort 2 dimensional array by column value?
Side note
In different conditions, it's much more common if you get csv (or, better with Javascript, JSON) via an HTTP call when working with Javascript to display data.
Local file reading may be reserved for server-side processing, that make this content available through HTTP.

Google guage chart give Unknown Header Type : 24

Here is my code which is right as per my knowledge. Because I created similar PIE chart successfully,
Error is : Unknown Header Type : 24
I think error is in parsing data from csv file. But it parsed correctly in string & int form.
Can someone tell what is the issue here.
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="http://jquery-csv.googlecode.com/files/jquery.csv-0.71.js"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["gauge"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
// grab the CSV
$.get("Chart2-data.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
//alert(arrayData);
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// this view can select a subset of the data at a time
var view = new google.visualization.DataView(data);
view.setColumns([0,1]);
// set chart options
var options = {
title: "A Chart from a CSV!",
hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
legend: 'none'
};
var chart = new google.visualization.Gauge(document.getElementById('gauge'));
chart.draw(data, options);
});
}
</script>
</head>
<body>
<div id="gauge" style="width: 900px; height: 500px;"></div>
</body>
</html
>
csv data:
Engine,24
min,34
max,0
yellowFrom,10
yellowTo,6
redFrom,6
redTo,0
I was having the same problem.
Using Firebug on my DB result I was able to identify that the problem was that the google library threating a numeric value as an array header.
My array is the following
[['234 234 - ',234.00],['234 234 - ',234.00],['cuarta zzzzzzzzz prueba htmlzzzzzzz - ',654999.00],['fulanita de tal - ',150.00],['fulanita de tal - ',133.00],['Mario Alvarez Alvarez - tony',125143.20],['otra5555 prueba5555 - ',1866.00],['prieba de insert actualizando - ',1101.00],['prueba 888 - ',987.00],['prueba con html - ',854.00],['prueba de guardado - ',123.00],['prueba de insert - ',369.00],['prueba insert actualizando 02 - ',753.00],['prueba666 7777 - ',1547.00],['prueba666 7777 - ',1547.00],['prueba88888 de guardado8888 - ',1576.00],['tercera prueba - ',98765.00]]
My javascript error was:
Error: Unknown header type: 234
The solution is explained in the Google Visualization API Reference:
google.visualization.arrayToDataTable(twoDArray, opt_firstRowIsData)
Check this link for detailed info
You have to explicit tell the library that the first row is data, not a header. I add the second parameter true like this:
var data = google.visualization.arrayToDataTable(vArray, true);
PD: My web app was working fine until a few days ago. I guess google did some change to the library.
Hope my explain will help you

create Google Chart through AJAX call with JSON/JS

CI'm having an issue creating a chart. I've read number of tutorials and basically wrote a code according to them. However, the problem is that the chart won't be displayed at all.
I want on AJAX call to retrieve data from SQLite3 and then draw a chart based on that data.
It could be Column or Pie chart, doesnt matter.
I'm pretty sure there is some kind of problem with the way I work on JSON, and I would like someone to help me. Thanks!
#test.html
-------------------------------------------------------------------------
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<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">
function drawChart() {
var jsonData = $.ajax({
url: "test-return.php",
dataType: "json",
async: false
}).responseText;
document.getElementById('rightDiv').innerHTML = jsonData;
var jsonData2 = [["FC Internazionale ",24],["AS Roma ",24],["Milan AC ",20],["UC Sampdoria ",19],["US Citt\u00e0 di Palermo",18],["SSC Napoli ",15],["Juventus FC ",16],["Parma FC ",14],["Genoa CFC ",14],["AS Bari ",13],["AC Fiorentina ",13],["SS Lazio ",11],["Calcio Catania ",10],["Cagliari Calcio ",11],["Udinese Calcio ",11],["AC Chievo Verona ",12],["Bologna FC ",10],["Atalanta BC ",9],["AC Siena ",7],["AS Livorno Calcio ",7]];
var data = google.visualization.arrayToDataTable(jsonData2,true);
var options = {
title: 'table 1'
};
var chart = new google.visualization.ColumnChart(
document.getElementById('chart_div'));
chart.draw(data, options);
}
google.load('visualization', '1', {packages:['corechart'], callback: drawChart});
</script>
</head>
<body>
<div id="chart_div" style="width: 400px; height: 500px;"></div>
<div id="rightDiv">query results</div>
</body>
</html>
#test-return.php
-----------------------------------------------------------------------------
<?php
sqlite code here
................
echo json_encode($row_array);
?>
$row_array output => [["FC Internazionale ",24],["AS Roma ",24],["Milan AC ",20],["UC Sampdoria ",19]......
You have to match your data format to format expected by your chosen chart type. As-is, you will have 3 columns of data: one numeric, one string, and one numeric. The PieChart expects two columns of data: the first should be type "string" and the second should be type "number". ColumnCharts can have any number of columns: the first can be either type "number", "date", "datetime", "timeofday", or "string", but all of the following columns should be type "number" (usually, that is - there are some exceptions that have to do with using column roles which are outside the scope of what you are doing here).
Looking at your data, I am speculating that the first column (the 1, 2, 3, 4... in your sample data) is a row number and not something you intend to plot. If this is the case, you need to adjust your server-side code to remove it. If this is not the case, can you provide information about it so I can help you figure out how to use it?
Also, your data is missing column headers. As structured, the arrayToDataTable method will take the first row of data and use it as the column headers, so you would get three columns with the labels "1", "FC Internazionale ", and "24", which you probably don't want. Either amend your server-side code to make the first row of data contain column labels, or set the second argument in the arrayToDataTable call to true.
By using jsonData = $.ajax(...).responseText;, you are bypassing the JSON conversion that jQuery does and passing the raw text of the response to jsonData. Since you need a javascript array to use the arrayToDataTable method, you need to call JSON.parse on jsonData to convert it to an array:
var data = google.visualization.arrayToDataTable(JSON.parse(jsonData), true);

Categories

Resources