realtime-graph-flask-rickshaw
所属分类:后台框架
开发工具:JavaScript
文件大小:1060KB
下载次数:0
上传日期:2015-06-01 00:10:07
上 传 者:
sh-1993
说明: 如何使用Flask、Rickshaw和服务器端事件在浏览器中工作的实时图表的示例。
(An example of how to get real time charts working in the browser, using Flask, Rickshaw, and Server Side Events.)
文件列表:
LICENSE (1075, 2015-06-01)
webserver (0, 2015-06-01)
webserver\app.py (1463, 2015-06-01)
webserver\bower.json (242, 2015-06-01)
webserver\static (0, 2015-06-01)
webserver\static\bower_components (0, 2015-06-01)
webserver\static\bower_components\jquery (0, 2015-06-01)
webserver\static\bower_components\jquery\.bower.json (771, 2015-06-01)
webserver\static\bower_components\jquery\MIT-LICENSE.txt (1099, 2015-06-01)
webserver\static\bower_components\jquery\bower.json (451, 2015-06-01)
webserver\static\bower_components\jquery\src (0, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax.js (21168, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax (0, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\jsonp.js (2516, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\load.js (1669, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\parseJSON.js (222, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\parseXML.js (485, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\script.js (1271, 2015-06-01)
webserver\static\bower_components\jquery\src\ajax\xhr.js (3488, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes.js (200, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes (0, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes\attr.js (3320, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes\classes.js (4155, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes\prop.js (1854, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes\support.js (893, 2015-06-01)
webserver\static\bower_components\jquery\src\attributes\val.js (3839, 2015-06-01)
webserver\static\bower_components\jquery\src\callbacks.js (5506, 2015-06-01)
webserver\static\bower_components\jquery\src\core.js (11790, 2015-06-01)
webserver\static\bower_components\jquery\src\core (0, 2015-06-01)
webserver\static\bower_components\jquery\src\core\access.js (1210, 2015-06-01)
webserver\static\bower_components\jquery\src\core\init.js (3401, 2015-06-01)
webserver\static\bower_components\jquery\src\core\parseHTML.js (938, 2015-06-01)
webserver\static\bower_components\jquery\src\core\ready.js (2381, 2015-06-01)
webserver\static\bower_components\jquery\src\css.js (12346, 2015-06-01)
webserver\static\bower_components\jquery\src\css (0, 2015-06-01)
webserver\static\bower_components\jquery\src\css\addGetHookIf.js (509, 2015-06-01)
webserver\static\bower_components\jquery\src\css\curCSS.js (1452, 2015-06-01)
... ...
# Server Sent Events, Rickshaw, and Flask for Real Time Graphing
Use a handful of relatively robust frameworks to graph streams of data in your
web browser.
Inspired by the fact that I needed to check some sensor readings on my robots,
even when they won't stay still for long enough for me to connect an HDMI cable.
# Running The Demo
Tested with Python3, on a MacBook running Chrome, and using whatever's in the `bower.json` file for the JavaScript parts.
```sh
$ python webserver/app.py
```
Then, visit `localhost:8000` or equivalent to see the magic take place.
# Contributing
If I've made a major mistake, don't hesitate to inform me, but if it's an
aesthetic issue, just fork the repo and make your own modifications.
# Neutral Summary
This isn't particularly hard to do in and of itself, it's just that there's a labryinth of features, framesworks, and technologies to contend with that all seem to drown each other out.
So after trying to use a couple of things that seemed to promise "all-in-one" functionality, I found it was just easier to glue a few things together, and it seems to work reasonably well.
## Flask
Flask supports what I'm trying to do, and is very fast to prototype with.
http://flask.pocoo.org/
## Rickshaw
Rickshaw allows you to make and animate graphs in the browser, and there are a
number of examples out there that *almost* did what I wanted to do
http://code.shutterstock.com/rickshaw/
### New Rickshaw Series
I created a subclass of `Rickshaw.Series` in order to better understand what's going on,
and also because I wanted to make a few small modifications.
In particular, it no longer requires specifying `timeInterval` or `timeBase` when
creating the `Series`, because perhaps what you are plotting is not a function of time.
The downside is that your graph may thrash about resizing itself as data comes
in, but this can be fixed by filling in default values yourself before starting
the stream.
## Server Side Events
An experimental yet well-supported feature that allows for streaming data
without having to rely on still more frameworks.
https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events
# Opinionated Writeup
## Remarks
### Why is there an opinionated writeup?
Well, I originally wrote a bunch of stuff down for future-me while I was trying
to get this to work, and then after it was working, I wanted to just get this out
there to maybe save other people time.
Most of my frustration was due to the fact that despite there being such a
vibrant ecosystem of web software, such an obvious use of that software was
so tedious to actually implement.
In the end, it's not *that* opinionated, but there are parts where frustration
or confusion might be taken as an invitation to start a flame war.
Additionally, I am not 100% certain about the licensing situation, so if you're
planning to use this demo as the basis of a globe-spanning realtime graphing
corporate juggernaut, you should probably reimplement
everything from scratch while imagining Larry Ellison and Nathan Myhrvold
standing behind you wearing biker leathers and cradling lead pipes in a
menacing fashion.
Or at least check that this repo doesn't inadvertantly include code which is
someone else's intellectual property.
### Obligatory Comments on JavaScript as a Language
This is my first time working with JavaScript, and while previously I found it
unappealing, I now can see why people really, really like aspects of the
language... but the parts that are terrible are truly something to behold.
But, in the end, I got everything working, and it seems to work.
That feels dangerous, because I don't understand what's going on in depth, and
so I am probably writing code that is less than perfectly safe and performant.
The fact that it runs even in spite of this is probably the best illustration
of why sites get pwned, or why my phone turns into a miniature space heater
when visiting otherwise unremarkable pages.
## Server Sent Events
[See the documentation](https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events) if you're curious, but basically there's some new HTML5 technology that you can use to stream data without having to use any modules.
You get events like:
```
data: 3.123
data: text works
data: {"also": "json_messages too"}
```
To actually implement it in your page, use something like
```js
// Create a new EventSource
var evtSrc = new EventSource("/stream");
// Handle messages which only have a 'data' field
evtSrc.onmessage = function(e) {
var obj = JSON.parse(e.data);
console.log(obj);
};
// Handle events, which have an 'event' field and probably a 'data' field too
source.addEventListener('message', function(e) {
console.log(e.data);
}, false);
```
## Rickshaw
Use Rickshaw to generate graphs and keep track of things.
I made use of the documentation and examples here:
- http://code.shutterstock.com/rickshaw/
- http://code.shutterstock.com/rickshaw/examples/
- https://github.com/shutterstock/rickshaw
You might have to actually peer into the source code in order to get things
working as you like them.
Under the hood it uses D3, and the guy who wrote that is pretty cool.
```js
// Generate a graph
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 540,
height: 240,
renderer: 'line',
series: new Rickshaw.Series.Sliding([{ name: 'mySeries'}], undefined, {
maxDataPoints: 100,
})
} );
// Render the graph
graph.render();
```
Rickshaw is nice, but like many things in JS-land, it's somewhat strange.
The `Rickshaw.Series` is not really a series, more like a series container, and
it supports adding new series on the fly, which is weird.
I am assuming that it was probably done this way because there's some hidden
coupling between it and the rest of the library that is not easy to expose, and
that having a complete separation would be cumbersome or slow.
... or that it's just a deliberate way of messing with programmers.
However, it's not especially tough to modify.
## Flask
[Flask](http://flask.pocoo.org/) is easy to get up and running, and it allows us to send data generated by Python processes to the browser.
We implement a mini class for encoding the SSEs properly:
```python
# Server sent events
class ServerSentEvent:
FIELDS = ('event', 'data', 'id')
def __init__(self, data, event=None, event_id=None):
self.data = data
self.event = event
self.id = event_id
def encode(self):
if not self.data:
return ""
ret = []
for field in self.FIELDS:
entry = getattr(self, field)
if entry is not None:
ret.extend(["%s: %s" % (field, line) for line in entry.split("\n")])
return "\n".join(ret) + "\n\n"
```
Using hyper-advanced routing, and implementing the server-sent events as a generator, we have our demo.
```python
@app.route("/", methods=['GET'])
def get_index():
return render_template('index.html')
@app.route("/stream")
def stream():
def gen():
while True:
data = json.dumps({'mySeries': random.random()})
ev = ServerSentEvent(data, 'new_data')
print(ev.encode())
yield ev.encode()
time.sleep(1.0)
return Response(gen(), mimetype="text/event-stream")
```
## Actually Using This
Consider changing how your event stream is managed in Python.
[One of the inspirations for this demo](http://flask.pocoo.org/snippets/116/)
used `gevent`, so something of a more asynchronous persuasion might be helpful.
Also, you're going to want to futz around with the HTML, and maybe swap out
the `onmessage()` function used for transporting the graph data for an event
handler if you plan on incorporating multiple graphs.
近期下载者:
相关文件:
收藏者: