CodingGraphs

WebApplication, Database manipulation with dynamic charts

Dynamic charts with Highcharts, SQLite and Python

Sources :

https://github.com/salhina/Flask-Database

Objective :

Plot data logs form Database.

Technologies :

– Store data : SQLite
– Serve content : Python with Flask
– Plot data : Hightcharts / Highstock

1 Database

1.1 Create database

A quick python script to create our SQLite database:

 #File_name : create_db.py
 import sqlite3
  
 sqlite_file = 'db.sqlite'
 conn = sqlite3.connect(sqlite_file)
 c = conn.cursor()
 conn.execute("CREATE TABLE measures (timestamp DATETIME, measure INTEGER)")
 conn.commit()
 conn.close() 

N.B.:

  • Creates ‘db.sqlite’ file?!!
  • Database structure created :
  • Files generated
Files generated

1.2 Populate database

A quick python script to fill up our SQLite database with random data (0 to 9):

 #File_name : populate_db.py
 import sqlite3          # for DB
 import time             # for timestamp
 from random import randint
  
 sqlite_file     = 'db.sqlite'
 timestamp_begin = 1388534400  # 01/01/14 00:00
 #timestamp_end  = timestamp_begin +  60*100
 timestamp_end   = 1451520000
 pitch = 3600
  
 try:
     conn = sqlite3.connect(sqlite_file)
     c = conn.cursor()
     timestamp = timestamp_begin
     while timestamp <= timestamp_end:
         print("Iterations left :", (timestamp_end-timestamp)/pitch)
         measure = randint(0, 9)
         conn.execute("INSERT INTO measures ( timestamp         , measure ) 
                             VALUES   ({timestamp}        ,{measure}) "
                             .format  (timestamp=timestamp, measure=measure))
         conn.commit()
         timestamp += pitch
 except Exception as e:
     conn.rollback()
     raise e
 finally:
     conn.close() 

N.B.:

  •  Timestamp:
Timestamp_begin 1388534400   01/01/14 00:00
Pitch 3600  
timestamp_end 1451520000 timestamp_begin +  60*100
Iteration left   timestamp_end- timestamp      )/pitch
n: total iterations   timestamp_end- timestamp_begin)/pitch
  • Timestamp summary:
  36000       timestamp_begin +  60*100
timestamp_begin + Pitch + Pitch + Pitch …. timestamp_end
Sx0:         xn: x0 + n*pitch
1388534400 timestamp= x0+1*pitch timestamp= x0+2*pitch timestamp= x0+2*pitch timestamp= x0+n*pitch 1451520000
Timestamp calculation

  • Graphical illustration :
  • Files generated

2. Front-end

2.1 Data fetching (server side)

We’ll use only one python script to :
– Generate the json file from the SQLite database
– Serve the webpage with the chart

 #File_name : web.py
 from flask import Flask, render_template, request
 import sqlite3
 import json
  
 app = Flask(__name__)
  
 @app.route("/data.json")
 def data():
     connection = sqlite3.connect("db.sqlite")
     cursor = connection.cursor()
     cursor.execute("SELECT 1000*timestamp, measure from measures")
     results = cursor.fetchall()
     print results
     return json.dumps(results)
  
 @app.route("/graph")
 def graph():
     return render_template('graph.html')
  
 if __name__ == '__main__':
     app.run(
     debug=True,
     threaded=True,
     host='0.0.0.0', port=5000
 ) 

2.2 Web page

In the root folder, create the following folders :
– Templates : for your HTML templates
– Static : for static content (images, js files…)

  • Generated Files :

2.2.1 templates/graph.html

Then create a templates/graph.html with the following content:

File_name : templates/graph.html
  <!DOCTYPE HTML>
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Highstock Example</title>
         <script src="{{ url_for('static', filename='jquery-1.8.3.min.js') }}"></script>
 <script type="text/javascript">
 $(function () {
     $.getJSON('/data.json', function (data) {
         // Create the chart
         $('#container').highcharts('StockChart', {
             rangeSelector : {
                 selected : 1
             },
             title : {
                 text : 'My Sensor'
             },
             series : [{
                 name : 'Value',
                 data : data,
                 tooltip: {
                     valueDecimals: 2
                 }
             }]
         });
     });
 });
 </script>
 </head>
 <body>
 <script src="{{ url_for('static', filename='highstock.js') }}"></script>
 <script src="{{ url_for('static', filename='highcharts-more.js') }}"></script>
 <script src="{{ url_for('static', filename='exporting.js') }}"></script>
 <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
  
 </body>
 </html> 

 2.2.2 static content

On this repository youwill find the static folder with the files used in this example.

Testing

Your graph should be available here : http://<Raspberry_IP>:5000/graph

Final Outcome :

Enjoy zooming, panning and automatic data grouping !

Code Source :

Synthesis

Data flow:

  • Browser: <Raspberry_iP>:5000/graph  
  • à   web.py  à   templates/graph.html à Ajax request(/data.json)
  • à   web.py  à   json from DB
  • à Ajax return  (templates/graph.html) à Hightcharts / Highstock

Leave a Reply

Your email address will not be published. Required fields are marked *