Guest User

Untitled

a guest
Aug 20th, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.27 KB | None | 0 0
  1. // Define the margin, radius, and color scale. Colors are assigned lazily, so
  2. // if you want deterministic behavior, define a domain for the color scale.
  3. var m = 10
  4. , r = 100
  5. , no = +top.location.hash.slice(1)
  6. , arc = d3.svg.arc().innerRadius(r / 2).outerRadius(r)
  7. , donut = d3.layout.pie()
  8. .value(function(d) { return +d.count; })
  9. .sort(function(a, b) { return a.time - b.time; })
  10. , color = d3.scale.category20c()
  11. , dates =
  12. [ '2011-10-26'
  13. , '2011-10-27'
  14. , '2011-10-28'
  15. , '2011-10-29'
  16. , '2011-10-30'
  17. ]
  18. , files, buts, data, arcs, pages, svg; // for page inspection in dev tools
  19.  
  20. load(dates.map(function(f) { return f + '.csv'; }), d3.csv, loaded);
  21.  
  22. // Store the currently-displayed angles in this._current.
  23. // Then, interpolate from this._current to the new angles.
  24. function arcTween(a) {
  25. var i = d3.interpolate(this._current, a);
  26. this._current = i(0);
  27. return function(t) { return arc(i(t)); };
  28. }
  29.  
  30. function setData(d) {
  31. // Nest the page load time data by page. Our data has page load time in
  32. // 2-second resolution, upper bound, but we want to group counts by page.
  33. pages = d3.nest()
  34. .key(function(d) { return d.page; })
  35. .entries(data = d);
  36.  
  37. svg = d3.select('body').selectAll('div.page').data(pages);
  38. svg.selectAll('g.slice').data(pages)
  39. .selectAll('path').data(function(d) { return donut(d.values); });
  40. return svg;
  41. }
  42.  
  43. function loaded(_files) {
  44. var ul = d3.select('ul.date'), w = 0;
  45. buts = ul.selectAll('li')
  46. .data(files = _files)
  47. .enter().append('li').append('button')
  48. .attr('class', function(d, i) {
  49. return (i === no ? 'active ' : '') +
  50. (i === files.length - 1 ? 'last' : i ? '' : 'first');
  51. })
  52. .text(function(d) { return d.url.split('.')[0]; })
  53. .each(function(d) { w += parseInt(d3.select(this).style('width'), 10); })
  54. .on('click', function(d, i) {
  55. top.location.hash = '#' + (no = i); // clicked data set #no
  56. buts.classed('active', function(d, j) { return no === j; });
  57. setData(data = d.data);
  58. arcs.selectAll('text').remove(); // remove the arc labels
  59. arcs = svg.selectAll('g.slice') // recompute angles and rebind the data
  60. .data(pages);
  61. arcs.selectAll('path')
  62. .transition().duration(750).attrTween("d", arcTween) // redraw arcs
  63. .each('end', function() {
  64. // label larger arcs, translated&rotated to the arc centroid
  65. arcs.filter(function(d) { return d.endAngle - d.startAngle > 0.2; })
  66. .append('svg:text')
  67. .attr('dy', '.35em')
  68. .attr('text-anchor', 'middle')
  69. .attr('transform', function(d) {
  70. return 'translate(' + arc.centroid(d) +')'+
  71. 'rotate(' + angle(d) + ')';
  72. })
  73. .text(function(d) { return '<' + d.data.time; });
  74. });
  75. });
  76. ul.style('width', w + 'px');
  77. console.log(w);
  78.  
  79. // Insert an svg element (with margin) for each page in our dataset.
  80. // A child g element translates the origin to the donut center.
  81. svg = setData(data = files[no].data);
  82.  
  83. svg.exit().remove();
  84.  
  85. svg = svg.enter().append('div')
  86. .classed('page', true)
  87. .style('display', 'inline-block')
  88. .style('width', (r + m) * 2 + 'px')
  89. .style('height', (r + m) * 2 + 'px')
  90. .append('svg:svg')
  91. .attr('width', (r + m) * 2)
  92. .attr('height', (r + m) * 2)
  93. .append('svg:g')
  94. .classed('donut', true)
  95. .attr('transform', 'translate(' + (r + m) + ',' + (r + m) + ')');
  96.  
  97. // Add a label for the page. The `key` comes from the nest operator.
  98. svg.append('svg:text')
  99. .attr('dy', '.35em')
  100. .attr('text-anchor', 'middle')
  101. .text(function(d) { return d.key; });
  102.  
  103. // Pass the nested per-page values to the pie layout. The layout computes
  104. // the angles for each arc. Another g element will hold the arc and its label.
  105. arcs = svg.selectAll('g.slice')
  106. .data(function(d) { return donut(d.values); })
  107. .enter().append('svg:g').classed('slice', true);
  108.  
  109. // Add a colored arc path, with a mouseover title showing the count.
  110. arcs.append('svg:path')
  111. .style('fill', function(d) { return color(d.data.time); })
  112. .attr('d', arc)
  113. .each(function(d) { this._current = d; })
  114. .append('svg:title')
  115. .text(function(d) { return '<' + d.data.time + ': ' + d.data.count; });
  116.  
  117. // Add a label to the larger arcs, translated to the arc centroid and rotated.
  118. arcs.filter(function(d) { return d.endAngle - d.startAngle > 0.2; })
  119. .append('svg:text')
  120. .attr('dy', '.35em')
  121. .attr('text-anchor', 'middle')
  122. .attr('transform', function(d) {
  123. return 'translate(' + arc.centroid(d) + ')rotate(' + angle(d) + ')';
  124. })
  125. .text(function(d) { return '<' + d.data.time; });
  126.  
  127. d3.select(self.frameElement).style('height', document.body.offsetHeight+'px');
  128. }
  129.  
  130. // Computes the label angle of an arc, converting from radians to degrees.
  131. function angle(d) {
  132. var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
  133. return a > 90 ? a - 180 : a;
  134. }
  135.  
  136. function load(urls, loader, cb) {
  137. function fetch(url, n) {
  138. function loaded(data) {
  139. all[n] = { url: url, data: data };
  140. if (!--left) cb(all);
  141. }
  142. loader(url, loaded);
  143. }
  144. var all = [], left = urls.length;
  145. urls.forEach(fetch);
  146. }
  147.  
  148. function I(i) { return i; }
Add Comment
Please, Sign In to add comment