graph.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. module.exports = {
  19. durationFormatter:function(d) {
  20. if (d==0) { return "0" }
  21. var seconds = Math.floor(parseInt(d) / 1000);
  22. if ( seconds < 60 )
  23. return seconds + "s";
  24. var minutes = Math.floor(seconds / 60);
  25. if ( minutes < 60 ) {
  26. var x = seconds - 60*minutes;
  27. return minutes + "m" + (x==0 ? "" : " " + x + "s");
  28. }
  29. var hours = Math.floor(minutes / 60);
  30. if ( hours < 24 ) {
  31. var x = minutes - 60*hours;
  32. return hours + "h" + (x==0 ? "" : " " + x + "m");
  33. }
  34. var days = Math.floor(hours / 24);
  35. if ( days < 7 ) {
  36. var x = hours - 24*days;
  37. return days + "d " + (x==0 ? "" : " " + x + "h");
  38. }
  39. var weeks = Math.floor(days / 7);
  40. var x = days - 7*weeks;
  41. return weeks + "w " + (x==0 ? "" : " " + x + "d");
  42. },
  43. bytesFormatter:function(y) {
  44. if (y >= 1125899906842624) { return Math.floor(10 * y / 1125899906842624)/10 + " PB" }
  45. else if (y >= 1099511627776){ return Math.floor(10 * y / 1099511627776)/10 + " TB" }
  46. else if (y >= 1073741824) { return Math.floor(10 * y / 1073741824)/10 + " GB" }
  47. else if (y >= 1048576) { return Math.floor(10 * y / 1048576)/10 + " MB" }
  48. else if (y >= 1024) { return Math.floor(10 * y / 1024)/10 + " KB" }
  49. else { return y + " B"}
  50. },
  51. addSeries:function(svgg,series,color,xscale,yscale,margin,startTime,dotInfo) {
  52. if (series.length==0) return;
  53. var self = this;
  54. var g = svgg.append("svg:g").selectAll("g")
  55. .data(series)
  56. .enter().append("svg:g")
  57. .attr("transform", "translate(0,"+margin+")");
  58. g.append("svg:circle")
  59. .attr("r",function(d) {return d.r;})
  60. .attr("cx",function(d) {return xscale(d.x);})
  61. .attr("cy",function(d) {return yscale(d.y);})
  62. .style("fill",color)
  63. .style("fill-opacity",0.8)
  64. .style("stroke",d3.interpolateRgb(color, 'black')(0.125))
  65. .append("title")
  66. .text(function(d) { return dotInfo[Math.round(xscale(d.x))][Math.round(yscale(d.y))]; });
  67. g.append("svg:line")
  68. .attr("x1", function(d) { return xscale(d.x)+d.r; } )
  69. .attr("x2", function(d) { return xscale(d.x+d.y); } )
  70. .attr("y1", function(d) { return yscale(d.y); } )
  71. .attr("y2", function(d) { return yscale(d.y); } )
  72. .style("stroke",d3.interpolateRgb(color, 'black')(0.125))
  73. .style("stroke-width",2)
  74. .append("title")
  75. .text(function(d) { return dotInfo[Math.round(xscale(d.x))][Math.round(yscale(d.y))]; });
  76. },
  77. /**
  78. *
  79. * @param mapNodeLocal
  80. * @param mapRackLocal
  81. * @param mapOffSwitch
  82. * @param reduceOffSwitch
  83. * @param startTime
  84. * @param endTime
  85. * @param svgw
  86. * @param svgh
  87. * @param element
  88. */
  89. drawJobTasks:function (mapNodeLocal, mapRackLocal, mapOffSwitch, reduceOffSwitch, startTime, endTime, svgw, svgh, element) {
  90. var rmax = 24; // default value
  91. var axisHeight = 24;
  92. var margin = {"vertical":10, "horizontal":50};
  93. var w = svgw - 2*margin.horizontal;
  94. var h = svgh - 2*margin.vertical;
  95. var x = d3.time.scale.utc()
  96. .domain([startTime, endTime])
  97. .range([0, w]);
  98. var xrel = d3.time.scale()
  99. .domain([0, endTime-startTime])
  100. .range([0, w]);
  101. // create axes
  102. var topAxis = d3.svg.axis()
  103. .scale(x)
  104. .orient("bottom");
  105. var self = this;
  106. var bottomAxis = d3.svg.axis()
  107. .scale(xrel)
  108. .orient("bottom")
  109. .tickFormat(function(d) {return self.durationFormatter(d.getTime())});
  110. var svg = d3.select("div#" + element).append("svg:svg")
  111. .attr("width", svgw+"px")
  112. .attr("height", svgh+"px");
  113. var svgg = svg.append("g")
  114. .attr("transform", "translate("+margin.horizontal+","+margin.vertical+")");
  115. svgg.append("g")
  116. .attr("class", "x axis top")
  117. .call(topAxis);
  118. svgg.append("g")
  119. .attr("class", "x axis bottom")
  120. .call(bottomAxis)
  121. .attr("transform", "translate(0,"+(h-axisHeight)+")");
  122. var ymax = 0;
  123. if (mapNodeLocal.length > 0)
  124. ymax = Math.max(ymax, d3.max(mapNodeLocal, function(d) { return d.y; } ));
  125. if (mapRackLocal.length > 0)
  126. ymax = Math.max(ymax, d3.max(mapRackLocal, function(d) { return d.y; } ));
  127. if (mapOffSwitch.length > 0)
  128. ymax = Math.max(ymax, d3.max(mapOffSwitch, function(d) { return d.y; } ));
  129. if (reduceOffSwitch.length > 0)
  130. ymax = Math.max(ymax, d3.max(reduceOffSwitch, function(d) { return d.y; } ));
  131. var y = d3.scale.linear()
  132. .domain([0, ymax])
  133. .range([h-2*axisHeight-rmax, 0]);
  134. var yAxis = d3.svg.axis()
  135. .scale(y)
  136. .orient("left")
  137. .tickFormat(self.durationFormatter);
  138. svgg.append("svg:g")
  139. .attr("class", "y axis")
  140. .call(yAxis)
  141. .attr("transform", "translate(0,"+(axisHeight+rmax)+")")
  142. .append("text")
  143. .attr("transform", "rotate(-90)")
  144. .attr("x", -(h-2*axisHeight-rmax)/2)
  145. .attr("y", -margin.horizontal + 11)
  146. .attr("class", "axislabel")
  147. .text("Task Attempt Duration");
  148. var dotInfo = [];
  149. var mapDotInfo = function(d) {
  150. var thisx = Math.round(x(d.x));
  151. var thisy = Math.round(y(d.y));
  152. if (!(thisx in dotInfo))
  153. dotInfo[thisx] = [];
  154. var existing = dotInfo[thisx][thisy];
  155. var newInfo = d.label + " \n" +
  156. 'Run-time: ' + self.durationFormatter(d.y) + ' \nWait-time: ' + self.durationFormatter(d.x-startTime) +
  157. ' \nI/O: ' + self.bytesFormatter(d.io) + ' \nStatus: ' + d.status;
  158. if (existing)
  159. dotInfo[thisx][thisy] = existing + " \n" + newInfo;
  160. else
  161. dotInfo[thisx][thisy] = newInfo;
  162. };
  163. mapNodeLocal.forEach(mapDotInfo);
  164. mapRackLocal.forEach(mapDotInfo);
  165. mapOffSwitch.forEach(mapDotInfo);
  166. reduceOffSwitch.forEach(mapDotInfo);
  167. this.addSeries(svgg, mapNodeLocal, "green", x, y, axisHeight+rmax, startTime, dotInfo);
  168. this.addSeries(svgg, mapRackLocal,'#66B366', x, y, axisHeight+rmax, startTime, dotInfo);
  169. this.addSeries(svgg, mapOffSwitch, 'brown', x, y, axisHeight+rmax, startTime, dotInfo);
  170. this.addSeries(svgg, reduceOffSwitch, 'steelblue', x, y, axisHeight+rmax, startTime, dotInfo);
  171. }
  172. };