Skip to content

Instantly share code, notes, and snippets.

@vogievetsky
Forked from mbostock/.block
Last active January 24, 2016 05:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vogievetsky/30b764fa39d178be423e to your computer and use it in GitHub Desktop.
Save vogievetsky/30b764fa39d178be423e to your computer and use it in GitHub Desktop.
Sized Donut Multiples

These 24 hour donut clocks represent the top 10 countries on wikipedia (by edits) showing which hours of the day are the most popular. The area of each donut is sized proportionately to the total edits of each country, such that the area of the arcs is comparable across countries.

The Plywood query to pull the data for this visualization is:

$('main')
  .filter($('time').in({ start: new Date('2015-11-01T00:00:00Z'), end: null }))
  .filter('$country != null')
  .split('$country', 'Country')
    .apply('TotalEdits', '$main.count()')
    .sort('$TotalEdits', 'descending')
    .limit(10)
    .apply('HoursOfDay',
      $('main').split($("time").timePart('HOUR_OF_DAY', 'Etc/UTC'), 'HourOfDay')
        .apply('Edits', '$main.count()')
        .sort('$HourOfDay', 'ascending')
    )

Inspired by http://bl.ocks.org/mbostock/4c5fad723c87d2fd8273

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
svg {
padding: 10px 0 0 10px;
}
.legend {
vertical-align: top;
}
.label {
text-anchor: middle;
}
.label-name {
font-weight: bold;
}
</style>
<body>
<script src="http://d3js.org/d3.v4.0.0-alpha.9.min.js"></script>
<script src="http://static.imply.io/plywood/plywood.js"></script>
<script>
// Query
var Dataset = plywood.Dataset;
var $ = plywood.$;
var countryByHourOfDay = $('main')
.filter($('time').in({ start: new Date('2015-11-01T00:00:00Z'), end: null }))
.filter('$country != null')
.split('$country', 'Country')
.apply('TotalEdits', '$main.count()')
.sort('$TotalEdits', 'descending')
.limit(10)
.apply('HoursOfDay',
$('main').split($("time").timePart('HOUR_OF_DAY', 'Etc/UTC'), 'HourOfDay')
.apply('Edits', '$main.count()')
.sort('$HourOfDay', 'ascending')
);
d3.request('http://plywood-proxy.imply.io/plywood')
.header("Content-Type", "application/json")
.response(function(xhr) { return Dataset.fromJS(JSON.parse(xhr.responseText)); })
.post(
JSON.stringify({
dataSource: 'wiki',
expression: countryByHourOfDay
}),
function(err, dataset) {
if (err) {
console.log(err);
return;
}
render(dataset);
}
);
// Rendering
function translate(x, y) {
return "translate(" + x + "," + y + ")";
}
var formatTotalEdits = d3.format(".1s");
var padding = 10;
var radius = d3.scaleSqrt()
.range([0, 200]);
var color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.arc()
.padRadius(50);
var pie = d3.pie()
.sort(null)
.padAngle(0.02)
.value(function(d) { return d.Edits; });
function render(dataset) {
var data = dataset.toJS();
radius.domain([0, d3.max(data, function(d) { return d.TotalEdits; })]);
var svg = d3.select("body").selectAll(".pie").data(data, function(d) { return d.Country })
.enter().append("svg")
.attr("class", "pie")
.each(multiple)
.select("g");
var label = svg.append("text")
.attr("class", "label");
label.append("tspan")
.attr("class", "label-name")
.attr("x", 0)
.attr("dy", "-.2em")
.text(function(d) { return d.Country; });
label.append("tspan")
.attr("class", "label-value")
.attr("x", 0)
.attr("dy", "1.1em")
.text(function(d) { return formatTotalEdits(d.TotalEdits); });
function multiple(d) {
var r = radius(d.TotalEdits);
var svg = d3.select(this)
.attr("width", r * 2)
.attr("height", r * 2)
.append("g")
.attr("transform", translate(r, r));
svg.selectAll(".arc")
.data(function(d) { return pie(d.HoursOfDay); })
.enter().append("path")
.attr("class", "arc")
.attr("d", arc.outerRadius(r).innerRadius(r * 0.6))
.style("fill", function(d, i) { return i % 2 ? '#E2B89F' : '#799888' });
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment