I want to draw a chart using ChartJS and Flask.
I can draw the chart when I set my variables directly into the JS part (i.e. when data: [1.03, 380.31, 0.0, 18.69, 400.02]), but not when I pass the data using Flask.
I have checked the variable passed to Flask, and I can show in the browser (with a p tag) that the content of the array is fine: [1.03, 380.31, 0.0, 18.69, 400.02]
The JS code is below, t_gamme and t_badge are both arrays (build in Python using append method):
new Chart(document.getElementById("chart-tps"), {
type: 'bar',
data: {
labels: ["A", "B", "C", "D", "TOTAL"],
datasets: [{
label: "Temps gamme (h)",
backgroundColor: "#3e95cd",
data: "{{ t_gamme }}"
}, {
label: "Temps badgé (h)",
backgroundColor: "#8e5ea2",
data: "{{ t_badge }}"
}]
},
options: {
legend: {
display: false
},
title: {
display: true,
text: 'Temps badgé versus temps gamme en heures'
}
}
});
I would like avoiding to make an AJAX call to an endpoint for getting these arrays because I have already.
I removed " character and it works, but I have errors in Javascript code in Visual Studio Code:
Related to ChesskoWarrior's answer:
I tried that solution, but still, get the red error on double brackets.
Here is an example that works for me:
1.) Python function in routes.py as part of the Flask-App:
def index():
data = {"labels": ['a', 'b', 'c', 'd'],
"data_1": [1, 2, 3, 4],
"data_2": [5, 6, 7, 8]}
return render_template('template.html', data=data)
2.) You can access this variable in template.html as {{ variable }}. This works in JS too. However, you need to create a new JS variable and make sure the data is formatted in the right way. Fortunately, there is a Jinja "tojson"-filter which converts the data into a proper JSON (https://flask.palletsprojects.com/en/1.1.x/templating/#standard-filters). Knowing this, this code snippet works for me inside the template.html:
{% block javascripts %}
<script>
var data_js = {{ data|tojson }};
...
});
</script>
{% endblock javascripts %}
Now you can access the data using the original keys:
datasets: [{
label: data_js["labels"],
data: data_js["data_1"]
}, {
label: data_js["labels"],
data: data_js["data_2"]
}]
Related
So I have a python flask application that routes to a site and passes along two lists:
def chart():
labels = ['x', 'y', 'z']
values = [100, 150, 100]
return render_template('chart.html',
labels=labels, values=values)
I use Chart.min.js and I can then use the lists in rendering a graph in my chart.html:
{% block body %}
<h1>Test chart</h1>
<canvas id="myChart" width="800" height="400"></canvas>
<p id="caption">chart displaying labels n' values</p>
<script type=text/javascript>
var ctx = document.getElementById('myChart');
var names = [
{% for item in labels %}
"{{ item }}",
{% endfor %}
];
var numbers = [
{% for item in values %}
{{ item }},
{% endfor %}
];
var chartData = {
labels: names,
datasets: [{
label: 'values',
data: numbers
}]
};
var myChart = new Chart(ctx, {
type: 'line',
data: chartData
});
</script>
{% endblock %}
Now this works fine and I get a nice pretty graph.
Then I wanted to put my JavaScript in a seperate file in the static folder for my flask application but I cannot find how I'm supposed to access the lists passed along to chart.htlm. I can render a graph just fine if I hardcode some data into the JS file but I can't seem to get the data provided by the python code..
var ctx = document.getElementById('myChart');
// var names = ['x', 'y', 'z'];
// var numbers = [100, 150, 100];
var chartData = {
labels: names,
datasets: [{
label: 'values',
data: numbers
}]
};
var myChart = new Chart(ctx, {
type: 'line',
data: chartData
});
I have tried to loop the contents of the lists from my python file into different containers such as <div>, <ol> and <ul>and access those through document.getElementById("") among some other attempts, can't really remember them all.
I have tried to find the answer on google but to no avail.
Any help is appreciated and I should mention that I'm new to these coding languages and frameworks so please have some oversight if what I am missing is obvious.
=== NEW WORKING VERSION ===
chart.html :
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', (event) => {
const myChart2 = document.getElementById('ChartOne');
drawChart(ChartOne, {{ labels| tojson }}, {{ values| tojson }}, ChartType.LINE);
});
</script>
<div>
<canvas id="ChartOne" width="800" height="400"></canvas>
<p id="caption">line chart displaying labels n' values</p>
</div>
script.js:
const ChartType = {
LINE: "line" // add more variables for more chart options
}
function drawEmployeeChart(ctx, labels, values, chartType) {
var chartData = {
labels: labels,
datasets: [{
label: 'values',
data: values,
}]
};
var myChart = new Chart(ctx, {
type: chartType,
data: chartData
});
}
Now that you've separated your javascript into a new js file, you have to get your variables there.
What you could do is define a javascript function in your .js file that takes two arrays:
function render_chart(labels, values)
{
var ctx = document.getElementById('myChart');
var chartData = {
labels: names,
datasets: [{
label: 'values',
data: values
}]
};
var myChart = new Chart(ctx, {
type: 'line',
data: chartData
});
}
Then call the function from your chart.html page, but you have to convert the variables you pass from Flask to json. To do that do this, using the special tojson Jinja2 filters:
<script type="text/javascript">render_chart({{ labels|tojson }}, {{ values|tojson }})'></script>
The problem I am facing is that in my web server I am sending a JSON as argument via render_template to my website where I want to use that JSON to show a google pie chart.
The problem is that if I assign the google pie chart data statically like this:
var data = new google.visualization.DataTable({
cols: [
{ id: "", label: "objeto", type: "string" },
{ id: "", label: "quantidade", type: "number" }
],
rows: [
{ c: [{ v: "Caixa 2" }, { v: 3 }] },
{ c: [{ v: "Caixa 3" }, { v: 3 }] },
{ c: [{ v: "Caixa 4" }, { v: 3 }] }
]
});
It works perfectly. On the other hand if I assign it dynamically with the JSON that I am receiving from my server like this:
var data = new google.visualization.DataTable({{json}});
It stops showing the google pie chart in my website.
The things I tried until now was litteraly adapting the JSON to the desired format by google charts because I thought that was the only problem, but now that it is in the required format and it works statically I do not know any way of assigning my received JSON to the data var.
This is my ideal function that I would like to work.
function drawChart() {
var data = new google.visualization.DataTable({{json}});
var options = {
title: 'gráfico Objeto/Quantidade',
is3D: true
};
var chart = new google.visualization.PieChart(
document.getElementById('piechart')
);
chart.draw(data, options);
}
Desired result:
http://prntscr.com/oejojv
Actual result:
http://prntscr.com/oejooe
The JSON string is being HTML-escaped. Assuming that you're using Flask (guessing based on your mention of render_template), you need to do something like {{json | safe}}.
Also, this assumes that you have total control over the content of this JSON, because you are otherwise susceptible to cross-site scripting attacks.
I am using laravel 5.1 PHP framework and a sign chart from a javascript, But when i send data from controller with ' (single quote) but JavaScript Parse as some undefined value
$data_B_Temp = "{x : new Date('".$piecesTime[$dataLength]."'), y :".$pieces[$dataLength]."}";
this variable will make a graph point input
as
$(function () {
var chart = new CanvasJS.Chart("TempChart",
{
axisX:{
title: "time",
gridThickness: 2,
interval:1,
intervalType: "hour",
valueFormatString: "hh TT K",
labelAngle: -10
},
axisY:{
title: "distance"
},
data: [
{
type: "line",
dataPoints:[{{$data_B_Temp }}]
}
]
});
$("#TempChart").CanvasJSChart(chart.render());
});
But the javascript executes as :
dataPoints:[{x : new Date('2015-10-30 18:16:08'), y :38.5}]
I'm confused ' is coming? how to solve it?
According to the Laravel Blade documentation, using {{ }} results in an escaped string, which would cause the behavior that you're seeing.
Try using {!! !!} instead; using that syntax will tell Blade to not escape the string.
...
dataPoints: [{!! $data_B_Temp !!}]
...
I'm trying to use Google GeoChart library to display a map, and if I do it on a local HTML file or somewhere like JSFiddle, it works perfectly.
However, when I embed it in a JSP on my project and deploy it (using JBoss), calling chart.draw results in a JSON error:
Invalid JSON string: {":",":",":{":[",","]},":",":{":true}}
My complete Javascript method is as follows:
var data2 = google.visualization.arrayToDataTable([
[{label: 'Country', type: 'string'},
{label: 'description', type: 'string'},
{label: 'consistency', type: 'number'},
{type: 'string', role: 'tooltip'}],
['Canada', "CANADA", 2, "OK"],
['France', "FRANCE", 0, "KO"],
['USA', "USA", 1, "Other"]
]);
var options = {
displayMode: 'region',
backgroundColor: '#81d4fa',
colorAxis: {
colors: ['red', 'orange', 'green']
},
legend: 'none',
tooltip: {
showColorCode: true
}
};
var chart = new google.visualization.GeoChart(document.getElementById('chart_div'));
chart.draw(data2, options);
So it's clearly picking up the "structure" of the JSON object (two simple objects, another object with an array inside, another simple object, another object with an array inside), but for some reason is not picking up the content, except for the 'true' value, so it looks like a problem with quotes...
In any case, I have tried simple and double quotes, removing the quotes from the identifiers, reducing the options object to a simple
var options = {
"legend": "none"
};
... but to no avail. Everything results in a Invalid JSON string error (in this last case, a Invalid JSON string: {":"} error, since there is only one object).
Last note: if I just use
var options = {};
it shows the map (but with the default options).
Any ideas as to why is this happening and/or how to solve it?
Thanks!
I'm using the Highchart charting library with AngularJS, using Pablojim's 'Highchart-ng' module.
Everything is set up properly, and the following code works as intended:
<highchart config="{
type : 'line',
series : [{
name : 'Visitors',
data : [1, 4, 10, 3]
}]
}"></highchart>
But
<highchart config="{
type : 'line',
series : [{
name : 'Visitors',
data : {{visitors}}
}]
}"></highchart>
does not. (notice the difference at 'data')
I keep getting the following error:
Error: [$parse:syntax] Syntax Error: Token 'visitors' is unexpected, expecting [:] at column 122 of the expression [{
type : 'line',
series : [{
name : 'Visitors',
data : {{visitors}}
}]
}] starting at [visitors}}
}]
}].
Note: The variable {{visitors}} is set up properly in my controller, and when using it in my template, the data works fine. It also used to work with my previous charting library, Flot.
I've tried multiple workarounds:
Normally I can work around this (initialization) problem by adding something like ng-repeat="data in visitors | limitTo: 1" to the directive, so it inits only when the variable becomes available (this works with Flot and EasyPieCharts).
Adding ui-refresh="visitors" doesn't work,
and data: {{visitors || 0}} doesn't work either.
So, how can I add variables inline, within my template files?
you can try with:
<highchart config="{
type : 'line',
series : [{
name : 'Visitors',
data : visitors
}]
}"></highchart>
like a var
OR
in your ng-controller
$scope.config = {
options: {
chart: { type: 'bar' }
},
series: [{
data: visitors
}],
title: { text: 'Hello' },
loading: false }
and then in your html
<highchart config="config"></highchart>