Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Define the margin, radius, and color scale. Colors are assigned lazily, so
- // if you want deterministic behavior, define a domain for the color scale.
- var m = 10
- , r = 100
- , no = +top.location.hash.slice(1)
- , arc = d3.svg.arc().innerRadius(r / 2).outerRadius(r)
- , donut = d3.layout.pie()
- .value(function(d) { return +d.count; })
- .sort(function(a, b) { return a.time - b.time; })
- , color = d3.scale.category20c()
- , dates =
- [ '2011-10-26'
- , '2011-10-27'
- , '2011-10-28'
- , '2011-10-29'
- , '2011-10-30'
- ]
- , files, buts, data, arcs, pages, svg; // for page inspection in dev tools
- load(dates.map(function(f) { return f + '.csv'; }), d3.csv, loaded);
- // Store the currently-displayed angles in this._current.
- // Then, interpolate from this._current to the new angles.
- function arcTween(a) {
- var i = d3.interpolate(this._current, a);
- this._current = i(0);
- return function(t) { return arc(i(t)); };
- }
- function setData(d) {
- // Nest the page load time data by page. Our data has page load time in
- // 2-second resolution, upper bound, but we want to group counts by page.
- pages = d3.nest()
- .key(function(d) { return d.page; })
- .entries(data = d);
- svg = d3.select('body').selectAll('div.page').data(pages);
- svg.selectAll('g.slice').data(pages)
- .selectAll('path').data(function(d) { return donut(d.values); });
- return svg;
- }
- function loaded(_files) {
- var ul = d3.select('ul.date'), w = 0;
- buts = ul.selectAll('li')
- .data(files = _files)
- .enter().append('li').append('button')
- .attr('class', function(d, i) {
- return (i === no ? 'active ' : '') +
- (i === files.length - 1 ? 'last' : i ? '' : 'first');
- })
- .text(function(d) { return d.url.split('.')[0]; })
- .each(function(d) { w += parseInt(d3.select(this).style('width'), 10); })
- .on('click', function(d, i) {
- top.location.hash = '#' + (no = i); // clicked data set #no
- buts.classed('active', function(d, j) { return no === j; });
- setData(data = d.data);
- arcs.selectAll('text').remove(); // remove the arc labels
- arcs = svg.selectAll('g.slice') // recompute angles and rebind the data
- .data(pages);
- arcs.selectAll('path')
- .transition().duration(750).attrTween("d", arcTween) // redraw arcs
- .each('end', function() {
- // label larger arcs, translated&rotated to the arc centroid
- arcs.filter(function(d) { return d.endAngle - d.startAngle > 0.2; })
- .append('svg:text')
- .attr('dy', '.35em')
- .attr('text-anchor', 'middle')
- .attr('transform', function(d) {
- return 'translate(' + arc.centroid(d) +')'+
- 'rotate(' + angle(d) + ')';
- })
- .text(function(d) { return '<' + d.data.time; });
- });
- });
- ul.style('width', w + 'px');
- console.log(w);
- // Insert an svg element (with margin) for each page in our dataset.
- // A child g element translates the origin to the donut center.
- svg = setData(data = files[no].data);
- svg.exit().remove();
- svg = svg.enter().append('div')
- .classed('page', true)
- .style('display', 'inline-block')
- .style('width', (r + m) * 2 + 'px')
- .style('height', (r + m) * 2 + 'px')
- .append('svg:svg')
- .attr('width', (r + m) * 2)
- .attr('height', (r + m) * 2)
- .append('svg:g')
- .classed('donut', true)
- .attr('transform', 'translate(' + (r + m) + ',' + (r + m) + ')');
- // Add a label for the page. The `key` comes from the nest operator.
- svg.append('svg:text')
- .attr('dy', '.35em')
- .attr('text-anchor', 'middle')
- .text(function(d) { return d.key; });
- // Pass the nested per-page values to the pie layout. The layout computes
- // the angles for each arc. Another g element will hold the arc and its label.
- arcs = svg.selectAll('g.slice')
- .data(function(d) { return donut(d.values); })
- .enter().append('svg:g').classed('slice', true);
- // Add a colored arc path, with a mouseover title showing the count.
- arcs.append('svg:path')
- .style('fill', function(d) { return color(d.data.time); })
- .attr('d', arc)
- .each(function(d) { this._current = d; })
- .append('svg:title')
- .text(function(d) { return '<' + d.data.time + ': ' + d.data.count; });
- // Add a label to the larger arcs, translated to the arc centroid and rotated.
- arcs.filter(function(d) { return d.endAngle - d.startAngle > 0.2; })
- .append('svg:text')
- .attr('dy', '.35em')
- .attr('text-anchor', 'middle')
- .attr('transform', function(d) {
- return 'translate(' + arc.centroid(d) + ')rotate(' + angle(d) + ')';
- })
- .text(function(d) { return '<' + d.data.time; });
- d3.select(self.frameElement).style('height', document.body.offsetHeight+'px');
- }
- // Computes the label angle of an arc, converting from radians to degrees.
- function angle(d) {
- var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
- return a > 90 ? a - 180 : a;
- }
- function load(urls, loader, cb) {
- function fetch(url, n) {
- function loaded(data) {
- all[n] = { url: url, data: data };
- if (!--left) cb(all);
- }
- loader(url, loaded);
- }
- var all = [], left = urls.length;
- urls.forEach(fetch);
- }
- function I(i) { return i; }
Add Comment
Please, Sign In to add comment