Skip to content

Instantly share code, notes, and snippets.

@IgorDePaula
Forked from mbostock/.block
Created August 26, 2014 15:38
Show Gist options
  • Save IgorDePaula/f378783d495f5d6e96d6 to your computer and use it in GitHub Desktop.
Save IgorDePaula/f378783d495f5d6e96d6 to your computer and use it in GitHub Desktop.

This example demonstrates how to display the progress of an asynchronous request. Rather than saying d3.json(url, callback), use d3.json(url) to first create the request object, then register a "progress" event listener with xhr.on before starting the request with xhr.get.

You can also use this pattern to listen to "load" and "success" events separately. For example:

var xhr = d3.json(url)
    .on("progress", function() { console.log("progress", d3.event.loaded); })
    .on("load", function(json) { console.log("success!", json); })
    .on("error", function(error) { console.log("failure!", error); })
    .get();

This pattern also lets you cancel in-progress requests using xhr.abort, register custom headers with xhr.header, and even change the HTTP method and request body using xhr.send.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.progress-meter .background {
fill: #ccc;
}
.progress-meter .foreground {
fill: #000;
}
.progress-meter text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 24px;
font-weight: bold;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
twoPi = 2 * Math.PI,
progress = 0,
total = 1308573, // must be hard-coded if server doesn't report Content-Length
formatPercent = d3.format(".0%");
var arc = d3.svg.arc()
.startAngle(0)
.innerRadius(180)
.outerRadius(240);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var meter = svg.append("g")
.attr("class", "progress-meter");
meter.append("path")
.attr("class", "background")
.attr("d", arc.endAngle(twoPi));
var foreground = meter.append("path")
.attr("class", "foreground");
var text = meter.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em");
d3.json("https://api.github.com/repos/mbostock/d3/git/blobs/2e0e3b6305fa10c1a89d1dfd6478b1fe7bc19c1e?" + Math.random())
.on("progress", function() {
var i = d3.interpolate(progress, d3.event.loaded / total);
d3.transition().tween("progress", function() {
return function(t) {
progress = i(t);
foreground.attr("d", arc.endAngle(twoPi * progress));
text.text(formatPercent(progress));
};
});
})
.get(function(error, data) {
meter.transition().delay(250).attr("transform", "scale(0)");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment