Flask and great looking charts using Chart.js


Flask piechart
Flask webapp with pie chart
In this article you will learn how to create great looking charts using Chart.js and Flask.

Chart.js is a javascript library to create simple and clean charts. All of them are HTML5 based, responsive, modular, interactive and there are in total 6 charts.

If you are not familiar with Flask, read the getting started tutorial here.

 

Creating a bar chart app with Flask

We will start by creating a web application that displays a bar chart from a Python array. Create a directory /templates/ and add the file chart.html with this content:

<!DOCTYPE html><html lang="en"><head>   <meta charset="utf-8" />   <title>Chart.js </title>      <!-- import plugin script -->   <script src='static/Chart.min.js'></script>   </head><body>
<h1>Flask Chart.js</h1><!-- bar chart canvas element --><canvas id="chart" width="600" height="400"></canvas>
<script>
   // bar chart data
   var barData = {
   labels : [{% for item in labels %}
                  "{{item}}",
              {% endfor %}],
   datasets : [
      {
            fillColor: "rgba(151,187,205,0.2)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
         data : [{% for item in values %}
                      {{item}},
                    {% endfor %}]
      }
      ]
   }
 
   // get bar chart canvas
   var mychart = document.getElementById("chart").getContext("2d");
 
   steps = 10
   max = 10
   // draw bar chart
   new Chart(mychart).Bar(barData, {
        scaleOverride: true,
        scaleSteps: steps,
        scaleStepWidth: Math.ceil(max / steps),
        scaleStartValue: 0,
        scaleShowVerticalLines: true,
        scaleShowGridLines : true,
        barShowStroke : true,
        scaleShowLabels: true
   });
 
</script>
</body></html>

Create the directory /static/ and add the file Chart.min.js to it. You can get it either from the Chart.js website or use the link. Finally go into the home directory and create app.py with this contents:

from flask import Flask
from flask import Markup
from flask import Flask
from flask import render_template
app = Flask(__name__)
 
@app.route("/")
def chart():
    labels = ["January","February","March","April","May","June","July","August"]
    values = [10,9,8,7,6,4,7,8]
    return render_template('chart.html', values=values, labels=labels)
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5001)

Finally run:

python app.py
Open http://127.0.0.1:5001/ and you will see the array values[] plotted with the data in labels[].
We simply pass these two arrays to render_template(). This means that most of the magic occurs in the template. Chart.js is a client-side javascript library which is why our app.py is very minimal.
Result:
Flask barchart
Flask barchart

Create a line chart with Chart.js and Flask

To create a line chart, we can simply modify the chart.html template. Change it to:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <title>Chart.js </title>
 
   <!-- import plugin script -->
   <script src='static/Chart.min.js'></script>
 
</head>
<body>
 
<h1>Flask Chart.js</h1>
<!-- bar chart canvas element -->
<canvas id="chart" width="600" height="400"></canvas>
 
<script>
 
   // bar chart data
   var barData = {
   labels : [{% for item in labels %}
                  "{{item}}",
              {% endfor %}],
   datasets : [
      {
            fillColor: "rgba(151,187,205,0.2)",
            strokeColor: "rgba(151,187,205,1)",
            pointColor: "rgba(151,187,205,1)",
            pointStrokeColor: "#fff",
            pointHighlightFill: "#fff",
            pointHighlightStroke: "rgba(151,187,205,1)",
            bezierCurve : false,
            data : [{% for item in values %}
                      {{item}},
                    {% endfor %}]
      }]
   }
 
    Chart.defaults.global.animationSteps = 50;
    Chart.defaults.global.tooltipYPadding = 16;
    Chart.defaults.global.tooltipCornerRadius = 0;
    Chart.defaults.global.tooltipTitleFontStyle = "normal";
    Chart.defaults.global.tooltipFillColor = "rgba(0,0,0,0.8)";
    Chart.defaults.global.animationEasing = "easeOutBounce";
    Chart.defaults.global.responsive = false;
    Chart.defaults.global.scaleLineColor = "black";
    Chart.defaults.global.scaleFontSize = 16;
 
   // get bar chart canvas
   var mychart = document.getElementById("chart").getContext("2d");
 
   steps = 10
   max = 10
   // draw bar chart
   var LineChartDemo = new Chart(mychart).Line(barData, {
        scaleOverride: true,
        scaleSteps: steps,
        scaleStepWidth: Math.ceil(max / steps),
        scaleStartValue: 0,
        scaleShowVerticalLines: true,
        scaleShowGridLines : true,
        barShowStroke : true,
        scaleShowLabels: true,
        bezierCurve: false,
 
   });
 
 
</script>
 
</body>
</html>

Output:

Flask line-chart
Flask line-chart

Creating a pie chart

To create a pie chart, we must modify the application code slightly. We need 3 arrays: values, labels and colors. Colors are defined in hexadecimal, as usual in HTML. To iterate them in one loop, we zip them.

from flask import Flask
from flask import Markup
from flask import Flask
from flask import render_template
app = Flask(__name__)
 
@app.route("/")
def chart():
    labels = ["January","February","March","April","May","June","July","August"]
    values = [10,9,8,7,6,4,7,8]
    colors = [ "#F7464A", "#46BFBD", "#FDB45C", "#FEDCBA","#ABCDEF", "#DDDDDD", "#ABCABC"  ]
    return render_template('chart.html', set=zip(values, labels, colors))
 
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5001)

Secondly we modify the template to:

<!DOCTYPE html><html lang="en"><head>   <meta charset="utf-8" />   <title>Chart.js </title>      <!-- import plugin script -->   <script src='static/Chart.min.js'></script>   </head><body>
<h1>Flask Chart.js</h1><!-- bar chart canvas element --><canvas id="chart" width="600" height="400"></canvas>
<script>
   var pieData = [
            {% for item,label,colors in set %}
                {
                    value: {{item}},
                    label: "{{label}}",
                    color : "{{colors}}"
                },
                {% endfor %}
 
 
         ];
 
   // get bar chart canvas
   var mychart = document.getElementById("chart").getContext("2d");
 
   steps = 10
   max = 10
   // draw pie chart
   new Chart(document.getElementById("chart").getContext("2d")).Pie(pieData);
 
</script>
</body></html>

Result:

Flask piechart
Flask piechart

 


5 thoughts on “Flask and great looking charts using Chart.js

  1. Gary C. - August 10, 2015

    I’m hoping that Misha sees my reply, but in the interim and as I mentioned in my reply to him, I was able to further simplify the template by using the tojson filter. Simply replace your loops with, for example:

    labels: {{ labels|tojson|safe }},

    data: {{ values|tojson|safe }},

    Thoughts?

  2. Misha - July 27, 2015

    It’s a bad idea to use templating for passing data into js code (aka filling gaps). Maybe it’s easier to implement but you should make some ajax call to corresponding route on the server to fetch the data. That gives you more flexibility when switching backend/frontend to other technology and avoids mixing jinja2/javascript.

    1. Frank - July 27, 2015

      Thanks Misha! That would be more flexible.

    2. Gary C. - August 8, 2015

      I just stumbled across this post a couple weeks ago and thought the method seemed sane (as a JS initiate). Why do you call it filling gaps? I was able to further improve the code (IMHO) by removing the loops from the template by using the tojson filter on the variables directly. It seems to be a fairly straightforward and clean application of that method for use on mostly static data.

    3. Andrew - October 8, 2015

      Can anyone point to an example or provide some demo code that will do this ajax call? Sorry I am very new to javascript.