Time Series Data Visualization 2

Prerequisite : tornado , c3.js , influxDB

Time Series Data Visualization

I would like to create a realtime time series chart and pulling data from influxDB, but barely found a suitable websocket soulation with django.

So,I changed from django to tornado easily achieved websocket.

Based on Ubuntu 14.04 64bit
tornado
pip3 install tornado

views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# -*- coding: utf-8 -*-
import os
import json, time, datetime
import tornado.options
#import tornado.httpclient
from tornado import gen
from tornado import web, ioloop, websocket
##
import timeSeriesDB
import pe
##
tornado.options.define("port", default=8888, help="message...", type=int)

class getData:
def __init__(self):
pass

def i(self):
tsDB = timeSeriesDB.tsDB()
x1,d1,x2,d2=tsDB.read_data()
#print("Result: ", d1 )
chart = [ x1,x2,d1,d2 ]
return chart

class graphHandler(tornado.web.RequestHandler):
@gen.coroutine
def i(self):
gd = getData()
chart = gd.i()
return chart

@gen.coroutine
def get(self):
response = yield self.i()
self.render("index.html", chart_columns=json.dumps(response),a=23.53,b=1,c=12.8,
d=26.075,e=72.325,f=1,
g=1.7,h=0,i=30.8)

class calaHandler(tornado.web.RequestHandler):
@gen.coroutine
def i(self,X,y):
return pe.Online_One_PE(X,y)

@gen.coroutine
def get(self):
a = self.get_argument('a')
b = self.get_argument('b')
c = self.get_argument('c')
d = self.get_argument('d')
e = self.get_argument('e')
f = self.get_argument('f')
g = self.get_argument('g')
h = self.get_argument('h')
i = self.get_argument('i')
a = float(a)
b = float(b)
c = float(c)
d = float(d)
e = float(e)
f = float(f)
g = float(g)
h = float(h)
i = float(i)
X = [a, b, c, d, e, f, g, h, i]
y = [1]
Xy_predict = yield self.i(X,y)
self.write(str(Xy_predict[0]))

class websocketManager(object):
users = []
@classmethod
def add_user(cls, websocket):
cls.users.append(websocket)

@classmethod
def remove_user(cls, websocket):
cls.users.remove(websocket)

class Socket(websocket.WebSocketHandler):
def open(self):
websocketManager.add_user(self)
tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(seconds=1), self.start)

def on_close(self):
websocketManager.remove_user(self)

def on_message(self, message):
pass

def start(self):
chart = getData().i()
chart_cols=json.dumps(chart)
for user in websocketManager.users:
user.write_message(chart_cols)
tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(seconds=10), self.start)

settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
"template_path": os.path.join(os.path.dirname(__file__), "templates"),
"autoreload": True
}

def main():
tornado.options.parse_command_line()
application = tornado.web.Application([
(r"/", graphHandler),
(r"/q/", calaHandler),
(r"/socket", Socket),
], **settings)
application.listen(tornado.options.options.port)
tornado.ioloop.IOLoop.current().start()

if __name__ == "__main__":
main()

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>C3 DataTable</title>
<script src="/static/js/jquery-1.12.2.min.js"></script>
<!-- Load c3.css -->
<link href="/static/css/c3.min.css" rel="stylesheet" type="text/css">
<!-- Load d3.js and c3.js -->
<script src="/static/js/d3.min.js" charset="utf-8"></script>
<script src="/static/js/c3.min.js"></script>
</head>
<body>
<div id="chart"></div>

<p>INPUT</p>
<form action="/q/" method="get">
Mean cooling tower leaving water temperture: <input type="text" id="a" name="a" value=> <br>
Zone pumps number: <input type="text" id="b" name="b" value=> <br>
Mean zone pumps leaving water temperture: <input type="text" id="c" name="c" value=> <br>
Mean cooling container temperture: <input type="text" id="d" name="d" value=> <br>
Mean cooling container humidity: <input type="text" id="e" name="e" value=> <br>
Chiller DPS: <input type="text" id="f" name="f" value=> <br>
Chiller DPT01: <input type="text" id="g" name="g" value=> <br>
Chiller compressor number: <input type="text" id="h" name="h" value=> <br>
Total it pw: <input type="text" id="i" name="i" value=> <br>
<p>RESULT: <span id='result'></span></p>
<button type="button" id='sum'>Submit</button>
</form>

<script>
$(document).ready(function(){
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val();
var c = $("#c").val();
var d = $("#d").val();
var e = $("#e").val();
var f = $("#f").val();
var g = $("#g").val();
var h = $("#h").val();
var i = $("#i").val();
$.get("/q/",{'a':a,'b':b,'c':c,'d':d,'e':e,'f':f,'g':g,'h':h,'i':i}, function(ret){
$('#result').html(ret)
})
});
});

var columns = {% raw chart_columns %}

var chart = c3.generate({
bindto: '#chart',
data: {
xs: {
'ori': 'x1',
'pred': 'x2',
},
xFormat: '%Y-%m-%dT%H:%M:%SZ',
columns: columns,
onclick: function (d, i) { /* ... */ }
},
axis: {
x: {
type: 'timeseries',
localtime: true,
tick: {
format: '%Y-%m-%d %H:%M:%S'
}
}
}
});

function chartUpdateFun(cols){
var colsArray = JSON.parse(cols);
chart.load({
columns: colsArray
});
}

var chatObj = {
host: location.host,
socket: null,
init: function(){
var url = "ws://" + chatObj.host + "/socket";
chatObj.socket = new WebSocket(url);
chatObj.socket.onmessage = function(event){
chartUpdateFun(event.data);
},
chatObj.socket.onclose = function(event){
console.log("on close");
},
chatObj.socket.onerror = function(event){
console.log("on error");
}
}
};
chatObj.init();
</script>

</body>
</html>

Show

 show result