tripalFeature.adminChart.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. Drupal.behaviors.tripalFeature_adminSummaryChart = {
  2. attach: function (context, settings) {
  3. // First add the container after the view header.
  4. var container = d3.select('#tripal-feature-admin-summary');
  5. if (container.empty) {
  6. container = d3.select('.view-header').append('div')
  7. .attr('id', 'tripal-feature-admin-summary')
  8. .classed('tripal-admin-summary',true);
  9. container.append('div')
  10. .attr('id', 'tripal-feature-admin-summary-chart')
  11. .classed('tripal-admin-chart',true);
  12. container.append('div')
  13. .attr('id', 'tripal-feature-admin-summary-figure-desc')
  14. .classed('tripal-admin-figure-desc',true);
  15. }
  16. // Set-up the dimensions for our chart canvas.
  17. // Note: these are adjusted below so think of these are your minimum size.
  18. var margin = {top: 20, right: 20, bottom: 140, left: 100},
  19. width = 960 - margin.left - margin.right,
  20. height = 500 - margin.top - margin.bottom;
  21. var color = d3.scale.ordinal()
  22. .range(["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"]);
  23. var formatNum = d3.format("0,000");
  24. // The data was parsed and saved into tripalFeature.admin.summary
  25. // in the preprocess function for this template.
  26. if (Drupal.settings.tripalFeature.admin.summary) {
  27. // Determine the max number of characters in both the type name
  28. // and the total number of features per bar for use in width/magin adjustments.
  29. var maxTypeLength = 0;
  30. var maxTotalLength = 0;
  31. var numBars = Drupal.settings.tripalFeature.admin.summary.length;
  32. for(var i=0; i < numBars; i++){
  33. var element = Drupal.settings.tripalFeature.admin.summary[i];
  34. if(element.name.length > maxTypeLength){
  35. maxTypeLength = element.name.length;
  36. }
  37. if(element.total_features.length > maxTypeLength){
  38. maxTotalLength = element.total_features.length;
  39. }
  40. }
  41. // Adjust our bottom margin based on the length of type names in the data.
  42. // Assume 4px/character based on the slope of the label.
  43. margin.bottom = maxTypeLength * 4;
  44. // Adjust the width of the chart based on the number or bars (types)
  45. // and the length of the bar totals which need to fit on the top of the bar.
  46. // Assume 9px/character since it's not rotated.
  47. width = numBars * (maxTotalLength * 9);
  48. // Set-up the scales of the chart.
  49. var x0 = d3.scale.ordinal()
  50. .rangeRoundBands([0, width], .1);
  51. var x1 = d3.scale.ordinal();
  52. var y = d3.scale.linear()
  53. .range([height, 0]);
  54. // Now set-up the axis functions.
  55. var xAxis = d3.svg.axis()
  56. .scale(x0)
  57. .orient('bottom');
  58. var yAxis = d3.svg.axis()
  59. .scale(y)
  60. .orient('left')
  61. .ticks(10, '');
  62. // Create our chart canvas.
  63. var svg = d3.select('#tripal-feature-admin-summary-chart').append('svg')
  64. .attr('width', width + margin.left + margin.right)
  65. .attr('height', height + margin.top + margin.bottom)
  66. .append('g')
  67. .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
  68. // map the data to the x & y axis' of our chart.
  69. data = Drupal.settings.tripalFeature.admin.summary;
  70. x0.domain(data.map(function(d) { return d.name; }));
  71. x1.domain(Drupal.settings.tripalFeature.admin.organisms).rangeRoundBands([0, x0.rangeBand()]);
  72. y.domain([0, Drupal.settings.tripalFeature.admin.maxBarHeight]);
  73. // Create the x-axis.
  74. var xaxis = svg.append('g')
  75. .attr('class', 'x axis')
  76. .attr('transform', 'translate(0,' + height + ')')
  77. .call(xAxis);
  78. xaxis.selectAll("text")
  79. .style("text-anchor", "end")
  80. .attr("dx", "-.8em")
  81. .attr("dy", ".15em")
  82. .attr("transform", function(d) { return "rotate(-25)"; });
  83. // Label the x-axis.
  84. xaxis.append('g')
  85. .attr('class', 'axis-label')
  86. .attr('transform', 'translate(' + width/2 + ',' + (margin.bottom - 20) + ')')
  87. .append('text')
  88. .attr('font-size', '16px')
  89. .attr('dy', '.71em')
  90. .style('text-anchor', 'middle')
  91. .text('Types of Features');
  92. // Create the y-axis.
  93. var yaxis = svg.append('g')
  94. .attr('class', 'y axis')
  95. .call(yAxis);
  96. // Label the y-axis.
  97. yaxis.append('g')
  98. .attr('class', 'axis-label')
  99. .attr('transform', 'translate(-70,' + height/2 + ')')
  100. .append('text')
  101. .attr('transform', 'rotate(-90)')
  102. .attr('font-size', '16px')
  103. .attr('dy', '.71em')
  104. .style('text-anchor', 'middle')
  105. .text('Total Number of Features');
  106. // Add a g element to contain each set of bars (1 per type).
  107. var type = svg.selectAll(".type")
  108. .data(data)
  109. .enter().append("g")
  110. .attr("class", "g")
  111. .attr("transform", function(d) { return "translate(" + x0(d.name) + ",0)"; });
  112. // Now add the bars :)
  113. // Keep in mind some processing was done in the preprocess function to
  114. // generate the bars array based on the organisms array
  115. // and pre-calculated the y0 & y1 used here.
  116. type.selectAll("rect")
  117. .data(function(d) { return d.bars; })
  118. .enter().append("rect")
  119. .attr("width", x0.rangeBand())
  120. .attr("y", function(d) { return y(d.y1); })
  121. .attr("height", function(d) { return y(d.y0) - y(d.y1); })
  122. .style("fill", function(d) { return color(d.name); })
  123. .append("svg:title")
  124. .text(function(d) { return formatNum(d.y1 - d.y0); });
  125. // Add the total to the top of the bar.
  126. svg.selectAll("g.bar-totals")
  127. .data(data)
  128. .enter().append('g')
  129. .classed('bar-totals', true)
  130. .append("text")
  131. .attr("class", "bar-label")
  132. .attr("text-anchor", "middle")
  133. .attr('font-size', '10px')
  134. .attr("x", function(d) { return x0(d.name) + x0.rangeBand()/2; })
  135. .attr("y", function(d) { return y(d.total_features) -5; })
  136. .text(function(d) { return formatNum(d.total_features); });
  137. // Finally add in a simple legend.
  138. var legend = svg.selectAll(".legend")
  139. .data(Drupal.settings.tripalFeature.admin.organisms.slice().reverse())
  140. .enter().append("g")
  141. .attr("class", "legend")
  142. .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
  143. legend.append("rect")
  144. .attr("x", width - 18)
  145. .attr("width", 18)
  146. .attr("height", 18)
  147. .style("fill", color);
  148. legend.append("text")
  149. .attr("x", width - 24)
  150. .attr("y", 9)
  151. .attr("dy", ".35em")
  152. .style("text-anchor", "end")
  153. .attr('font-style','italic')
  154. .text(function(d) { return d; });
  155. // Add a small blurb mentioning this is from an mview and you should update ;).
  156. d3.selectAll('#tripal-feature-admin-summary-figure-desc')
  157. .html(Drupal.settings.tripalFeature.admin.figureDesc);
  158. }
  159. }
  160. };