I have not been shy in my love of MongoDB. The honeymoon is not over. Now I want to graph and visualize my data from MongoDB. I just started looking at D3 – I’m coming to the party a bit late – and it is perfect for this task. I have thrown together a super simple, absurd even, example using a DB I had already populated and some left over CherryPy code. Let me say that reusing code is a good idea – when I can find what I’m looking for. It allows me to throw something together quickly. These are not production samples, but just for me to see that I can get it to work. Enough already. Here is a bar chart using D3 and MongoDB.
I have not put this on OpenShift yet, but may. This bar chart is a simple python script using CherryPy and committing my favorite sin – passing HTML as a variable in a return. One reason to put it on OpenShift is so I can template it in Jinja. Here is the code:
import cherrypy
from pymongo import Connectionclass mongocherry(object):
def index(self):
db=Connection().geo
output =[]
output.append(‘<HTML><HEAD><TITLE>D3 and MONGODB</TITLE><script type=”text/javascript” src=”http://d3js.org/d3.v2.min.js”></script><style type=”text/css”>div.bar {display: inline-block;width: 20px;height: 75px;margin-right: 2px;background-color: teal;}</style></HEAD><BODY><h1>D3 and MongoDB</h1>’)
output.append(‘<script type=”text/javascript”>var dataset=[‘)for x in db.places.find():
output.append(str(x[“loc”][0])+’,’)
output.append(‘0];’+”\n”+’d3.select(“body”).selectAll(“div”).data(dataset).enter().append(“div”).attr(“class”, “bar”).style(“height”, function(d) {var barHeight = d * 5;return barHeight + “px”;});</script></body></html>’)i=0
html=””
while i<len(output):
html+=str(output[i])
i+=1return html
index.exposed = True
cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})cherrypy.quickstart(mongocherry())
The Python code prints out HTML that looks like this:
<HTML><HEAD><TITLE>D3 and MONGODB</TITLE> <script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script> <style type="text/css"> div.bar { display: inline-block; width: 20px; height: 75px; margin-right: 2px; background-color: teal;} </style> </HEAD><BODY> <h1>D3 and MongoDB</h1> <script type="text/javascript"> var dataset=[35,35.8,38,39,30,31,31,31,33,25,33,0]; d3.select("body") .selectAll("div") .data(dataset) .enter() .append("div") .attr("class", "bar") .style("height", function(d) {var barHeight = d * 5;return barHeight + "px";}); </script></body></html>
Not much going on here, just a simple D3.js bar chart – not even done in SVG. The MongoDB part is in the variable dataset[..]. While writing the HTML, the python code loops through my mongodb with for x in db.places.find(): and it grabs the latitude of the data I have with x[“loc”][0] prints it out in the JavaScript variable dataset[]. I add a 0 at the end because I get a trailing comma. Sloppy, but oh well.
I return all the HTML and you get the page displayed at the top of this post. The cool part of marrying D3.js and MongoDB is JSON. I have JSON in my DB and D3 takes JSON.
For the record, you can avoid the ‘trailing comma’ issue by doing this:
output.append(
‘,’.join(
[
x[“loc”][0] for x in db.places.find()
]
)
)
That takes each value and joins it together using commas, instead of printing each value and then a comma regardless.
Then at the end, instead of looping through output, you can do a few things differently:
First, you could do ‘for line in output: html += line’; secondly, you could do html += ”.join(output). Both of these will be more efficient, and are easier to read afterwards.
That is good to know. I will use the join a lot!
I am not entirely sure why you chose to give a python example using a blog style that doesn’t keep indentin information.
The blog formatted the code poorly. I put it out there for me to remember as much as to show others. If it didn’t help you, sorry.