Related
i would like to draw a grouped bar from chart js using django which currently works fine. Actually i do manually. but i need to draw a grouped bar through for loop(data,label,background-color).
Actual
label_list=[2019,2020]
color_list=['#e75e72','#3396ff']
data_list=[[282,314,106,502,107,111],[86,350,411,340,635,809]]
datasets: [
{
label: {{label_list.0|safe}},
backgroundColor: '{{color_list.0|safe}}',
data:{{data_list.0|safe}} ,
},
{
label: {{label_list.1|safe}},
backgroundColor: '{{color_list.1|safe}}',
data: {{data_list.1|safe}} ,
},
]
i really do not have any idea to make it dynamically.
i need something like
{% for x in label_list %}
{{
label:label_list.forloop.counter[x],
background-color:color_list.forloop.counter[x],
data:data_list.forloop.counter[x]
}}//forloop.counter0,forloop.counter1
{% endfor %}
thanx in advance.
Rather than processing the values in template, why not you build the dataset in view and send it as context, like this:
datasets = list()
for label, color, data in zip(label_list, color_list, data_list):
value_dict = {
'label': label,
'backgroundColor' : color,
'data': data
}
datasets.append(value_dict)
context = {'datasets': json.dumps(datasets)} # use 'import json' on top of the file
return render('template.html', context)
Then use it directly in your template like this:
<script>
var dataset = {{ datasets }}
// rest of the code
</script>
I would like to use Flask to render a ChartJS graph. This is from my routes.py
#app.route("/graph")
def graph():
d = Eval.query.all()
labels = [i.date.strftime('%d.%m.%Y') for i in d]
data = [i.bw for i in d]
return render_template('chart.html', title='Charts', labels = labels, data = data)
I've the following code in the chart.html:
{% extends "base.html" %}
{% block content %}
<canvas id="myChart" height="400" width="800"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['16.07.2017', '23.07.2017', '30.07.2017', '06.08.2017', '13.08.2017'],
datasets: [{
label: "My First dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: {{ data }}
}]
},
options: {
responsive:false
}
});
</script>
{% endblock %}
with this code the chart is rendered with the correct labels.
Question:
However once I change the labels to
labels: {{ labels }}
the chart is not rendered at all.
I checked to make sure that the {{ labels }} expression is indeed also a list with the correct formating. Calling {{ labels }} above the script tag shows the following output in the html page:
['16.07.2017', '23.07.2017', '30.07.2017', '06.08.2017', '13.08.2017']
If you are not using safe filter special symbols would be escaped during template parsing process and would corrupt the variable value.
In the case above, final variable value without 'jinja safe' filter would be
["16.07.2017", "23.07.2017"] =>['16.07.2017','23.07.2017']
And that value (['16.07.2017','23.07.2017']) is illegal for JS and you'll be able to see the error in the browser console:
Uncaught SyntaxError: Unexpected token &
In the case above, final variable value with 'jinja safe' filter would be the same
["16.07.2017", "23.07.2017"] =>["16.07.2017", "23.07.2017"]
You can read more about escaping here.
var ctx = document.getElementById('myChart').getContext('2d');
var dates = {{labels|safe}};
var data1 = {{data|safe}}
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: dates,
datasets: [{
label: "My First dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: data1
I added the Jinja expressions as variables inside the script and now the chart renders as expected. Still not sure why ...
I'm attempting to generate an annotated LineChart using the google visualization API, and while I have it working, I would like to be able to have annotations have line-breaks if possible. Unfortunately, it seems like Google's API ignores any newline information and displays everything on a single line. Has anyone come up with a way around this?
Here's an example:
var data = new google.visualization.DataTable();
data.addColumn('string', 'Month');
data.addColumn('number', 'Sales');
data.addColumn({type:'string', role:'annotation'});
data.addColumn({type:'string', role:'annotationText'});
data.addRows([
['April',1000, 'A', "Stolen data\nSo-so month"],
['May', 1170, 'B', "Coffee spill\nAnother line\nA third line"],
['June', 660, 'C', "Wumpus attack"]
]);
I've tried \n, \\n, and <br /> and those aren't working.
Add p': {'html': true}} to your tooltip like this
data.addColumn({type:'string', role:'tooltip','p': {'html': true}});
then your add <br/> to your tooltip content
create a second annotation line.
var data = new google.visualization.DataTable();
data.addColumn('timeofday', 'Time');
data.addColumn('number', 'Temp');
data.addColumn({type:'string', role:'annotation'});
data.addColumn({type:'string', role:'annotation'});
data.addRows([
[[4, 56, 00], 0, '0', 'rain'], [[5, 56, 00], 10, '10', 'drizzle'], [[6, 56, 00], 23, '23', 'cats'], [[7, 56, 00], 17, '17', 'partly cloudy'], [[8, 56, 00], 18, '18', 'sunny'], [[9, 56, 00], 9, '9', 'sunny'], [[10, 56, 00], 11, '9', 'sunny'], ]);
Check this out https://jsfiddle.net/k6eocgLd/4/
I have implemented a simple example for you to implement multi-line annotation using Google Chart. Copy and paste the following example and run it.
<html>
<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() {
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', { role: 'annotation' }, 'Expenses', { role: 'annotation' }],
['2004', 1000, 1000, 400, 400],
['2005', 1170, 1170, 460, 460],
['2006', 660, 660, 1120, 1120],
['2007', 1030, 1030, 540, 540]
]);
var options = {
title: 'Company Performance',
vAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
After running this code, you will see the following screen.
You cannot do this with current functionality as asgallant points out in the comments. If this is an absolute must, then you can parse through the SVG to create line breaks (which have spotty functionality as well). You can see this answer for more information on how to add line breaks in SVG:
How to linebreak an svg text within javascript?
What I've found is that while it isn't possible to have multi-line annotations, you can make html tooltips and annotations: https://developers.google.com/chart/interactive/docs/customizing_tooltip_content. So it is possible to have multi-line annotations.
I implemented the following:
<div id="b1xy" class="dot-graph"></div>
<script type="text/javascript" language="javascript">
var r = Raphael("b1xy","100%","100%");
r.dotchart(10, 0, 400,200, [76, 70, 67, 71, 69], [0, 1, 2, 3, 4], [100, 120, 140, 160, 500], {max: 10, axisylabels: ['Mexico', 'Argentina', 'Cuba', 'Canada', 'United States of America'], heat: true, axis: '0 0 1 1'});
</script>
But this gave the javascript error Error: Problem parsing d="M,0,0". Does anyone know what's wrong? How do I print a dot chart?
I've included the jquery library, raphael.js, g.raphael.js and g.dot.js, so i know I have all the tools necessary.
I figured out the problem. My jQuery was version 1.4 and was too old, so raphael couldn't work with it. I upgraded my jQuery to 1.8 and everything was fine.
I have the following code in a simple, html file:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.0-beta2.js"> </script>
<script>
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var redLine = new Kinetic.Line({
points: [0, 0, 75, 75, 150, 150],
stroke: 'red',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(redLine);
stage.add(layer);
</script>
This code is supposed to draw a very simple, single line, from the top, left of the browser space, to 150, 150.
However, when I test this, nothing is drawn on the page.
I'm on Windows Vista Business, up to date, I'm using Google Chrome Version 23.0.1271.97 m.
Now, if I add another set of points in the points array - to look like this:
points: [0, 0, 75, 75, 150, 150, 300, 300],
when I reload the page including this change, the code works as expected.
Now, further play and research, turned that, if I want to keep this array:
points: [0, 0, 75, 75, 150, 150],
I have to add the following, in the line configuration code:
dashArray: [1, 1]
with the "dashArray" property, the line is correctly drawn with the initial array problem.
var redLine = new Kinetic.Line({
points: [0, 0, 75, 75, 150, 150],
stroke: 'red',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round',
dashArray: [1, 1]
});
Is this a bug?
Is this expected behavior? I cannot find any documentation about this.
Thank you!
If certain elements are not being drawn on the screen you should call:
.draw()
on either the stage or the layer containing the item. For example:
stage.draw(); or layer.draw();
This redraws the stage or layer.
More info:
The way that javascript execution works is not always the way we think, basically, your code is not executing at the time you think it should be. You need something to trigger the drawing after the stage is created. Simply put, you could add a window.onload function or document.onready function to draw the stage when the page loads. A different solution would be to have the draw triggered by a different event, such as click. So you could create a button, with an onclick attribute and have it trigger stage drawing.
Like so:
html:
<button onclick='javascript:myRedraw()'>Redraw</button>
javascript:
function myRedraw(){
stage.draw();
}
Here is an update: http://jsfiddle.net/ff4sD/2/