D3 and Ajax: Updating a Bar Chart With New Data

28 Dec

This is the site I will build.

I have been showing several examples of graphing – mostly using Matplolib. In this example, I will show a bar chart in a webpage using D3 and updated via Ajax requesting a text file with the data. I also have a simple python file that randomly generates 20 data points and feeds it to the text file – my host doesn’t allow me to run the python, but you can get the idea.

I took the code from examples by Scott Murray, and some standard Ajax code block off W3. Making a few changes I was able to get it to work. I like to modify existing code to get a feel for what affects what and how things work. This really helps it all sink in.

This draws the first bar chart when the page loads.

var dataset=[12, 10, 13, 19, 21, 25, 22, 18, 15, 13, 11, 12, 15, 20, 18, 17, 16, 18, 23, 25];
var w = 500;
var h = 100;
var barPadding = 1;

var svg = d3.select(“body”)
.append(“svg”)
.attr(“width”, w)
.attr(“height”, h);

svg.selectAll(“rect”)
.data(dataset)
.enter()
.append(“rect”)
.attr(“x”, function(d, i) {
return i * (w / dataset.length);
})
.attr(“y”, function(d) {
return h – (d * 4);
})
.attr(“width”, w / dataset.length – barPadding)
.attr(“height”, function(d) {
return d * 4;
})
.attr(“fill”, “teal”);

This is my onclick function that uses Ajax and updates the chart:

function clicked(url)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}
xmlhttp.open(“GET”,url,false);
xmlhttp.send(null);
var newd=xmlhttp.responseText;
var da=newd.split(‘,’);
for (var i in da){
da[i] = parseInt(da[i], 10)
}
document.getElementById(‘test’).innerHTML=xmlhttp.responseText;
svg.selectAll(“rect”)
.data(da)
.attr(“x”, function(d, i) {
return i * (w / da.length);
})
.attr(“y”, function(d) {
return h – (d * 4);
})
.attr(“width”, w / da.length – barPadding)
.attr(“height”, function(d) {
return d * 4;
})
.attr(“fill”, “teal”);
}

All I am doing is requesting a text file of data values (12,34,65,67,32,21,10…), then I split it in to numbers and convert to integers. I also print out the values, but that was just a check for me to see what was being returned. The rest is from an example by Scott Murray on clicking a paragraph to change the data – but with the variable hard coded in the JavaScript. I just passed the textfile to the variable and viola!

Connect the function to a button: <button type=”button” onclick=”clicked(‘data.txt’)”>Click
Me</button>.

My goal was to see how I could have a python file write out a data file and then load it in a webpage, but be able to update the data without refreshing everything on the page.  Could have done it all in Python, with Flask and Jinja but I don’t have a production setup for this. This was the most reasonable way to connect what I may be able to run in production.  Here is a python file that feeds random integers from 5 to 25 to a text file – the one that we will load in.

import random
data=open(“data2.txt”,”w+”)
x=0
for x in range(20):
i=random.randint(5,25)
if x==19:
data.write(str(i))
break
else:
data.write(str(i)+”,”)

data.close()

This could connect to MongoDB, SQLite, or generate data on the fly like it’s doing now. The principle is the same – do something and write it out to text.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: