/js-only/visualiser/main.js

http://github.com/hhughes/ocaml-frui · JavaScript · 327 lines · 271 code · 51 blank · 5 comment · 45 complexity · 8b0533107772e15d98a92251d3a54fe8 MD5 · raw file

  1. var visualiser_elt = $("div#visualiser");
  2. var timeline_elt = $("div#timeline");
  3. var pie_elt = $("div#pie");
  4. var cloud_elt = $("div#cloud");
  5. var messages = {};
  6. var functions = {};
  7. var threads = {};
  8. var pie_pieces = {};
  9. var total_msgs = 0;
  10. var cloud_words = {};
  11. var total_words = 0;
  12. var t_min = 0;
  13. var t_max = 0;
  14. function layout_div(msg) {
  15. var parent = $(msg.div).parent();
  16. var m_width = visualiser_elt.width();
  17. var t_width = t_max - t_min;
  18. var left = 0;
  19. var width = 0;
  20. var top = 0;
  21. var height = 20;
  22. var t_left = 0;
  23. if(msg.ty == "fn" || msg.ty == "msg") {
  24. var thread = threads[msg.tid];
  25. t_left = msg.ts - thread.ts;
  26. left = (t_left * m_width) / t_width;
  27. if(msg.ty == "fn") {
  28. var finish = (msg.finish || t_max) - thread.ts;
  29. width = ((finish - t_left) * m_width) / t_width;
  30. } else {
  31. width = 2;
  32. }
  33. } else {
  34. var finish = (msg.finish || t_max) - t_min;
  35. t_left = msg.ts - t_min;
  36. left = (t_left * m_width) / t_width;
  37. width = ((finish - t_left) * m_width) / t_width;
  38. top = msg.tid * 24;
  39. }
  40. msg.div.offset({left: left + parent.offset().left, top: top + parent.offset().top});
  41. msg.div.width(width);
  42. msg.div.height(height);
  43. }
  44. function _layout_all(ht) {
  45. for(m in ht) {
  46. var msg = ht[m];
  47. if(msg != null && (typeof msg) != "function") {
  48. layout_div(msg);
  49. }
  50. }
  51. }
  52. function layout_all() {
  53. _layout_all(threads);
  54. _layout_all(functions);
  55. _layout_all(messages);
  56. }
  57. function create_div(parent, msg) {
  58. var div = $(document.createElement("div")).addClass(msg.ty).attr("title", msg.desc);
  59. div.appendTo(parent);
  60. return div;
  61. }
  62. function set_t(t) {
  63. var layout = false;
  64. if(t_min == 0 || t < t_min) {
  65. t_min = t;
  66. $("div#min > input").val(t_min);
  67. layout = true;
  68. }
  69. if(t > t_max) {
  70. t_max = t;
  71. $("div#max > input").val(t_max);
  72. layout = true;
  73. }
  74. if(layout) {
  75. layout_all();
  76. }
  77. }
  78. function draw_slice(ctx, r, s) {
  79. ctx.beginPath();
  80. ctx.arc(60, 60, 50, r, r+s, false);
  81. ctx.lineTo(60,60);
  82. ctx.closePath();
  83. ctx.stroke();
  84. return r+s;
  85. }
  86. function draw_pie() {
  87. var canvas = pie_elt.find("canvas");
  88. var ctx = canvas[0].getContext("2d");
  89. ctx.clearRect(0, 0, 200, 200);
  90. ctx.strokeStyle = "black";
  91. ctx.beginPath();
  92. ctx.arc(60, 60, 55, 0, Math.PI * 2);
  93. ctx.closePath();
  94. ctx.stroke();
  95. ctx.strokeStyle = "red";
  96. var r = 0;
  97. for(p in pie_pieces) {
  98. var count = pie_pieces[p];
  99. if(count != null && (typeof count) != "function") {
  100. r = draw_slice(ctx, r, (count * 2 * Math.PI) / total_msgs);
  101. }
  102. }
  103. }
  104. function add_to_pie(ty) {
  105. if(!pie_pieces[ty]) {
  106. pie_pieces[ty] = 0;
  107. }
  108. pie_pieces[ty]++;
  109. draw_pie();
  110. }
  111. function draw_cloud() {
  112. var canvas = cloud_elt.find("canvas");
  113. var ctx = canvas[0].getContext("2d");
  114. ctx.clearRect(0, 0, 200, 200);
  115. ctx.strokeStyle = "red";
  116. var r = 50;
  117. for(c in cloud_words) {
  118. var count = cloud_words[c];
  119. if(count != null && (typeof count) != "function") {
  120. var height = Math.floor((count * 100) / total_words);
  121. ctx.font = height + "px serif";
  122. ctx.strokeText(c, 0, r);
  123. r+=height;
  124. }
  125. }
  126. }
  127. function _add_to_cloud(w) {
  128. total_words++;
  129. if(!cloud_words[w]) {
  130. cloud_words[w] = 0;
  131. }
  132. cloud_words[w]++;
  133. draw_cloud();
  134. }
  135. function add_to_cloud(msg) {
  136. w_name = msg.name.split(" ");
  137. w_desc = msg.desc.split(" ");
  138. for(w in w_name) {
  139. var word = w_name[w];
  140. if(word != null && (typeof word) != "function") {
  141. _add_to_cloud(word);
  142. }
  143. }
  144. for(w in w_desc) {
  145. var word = w_desc[w];
  146. if(word != null && (typeof word) != "function") {
  147. _add_to_cloud(word);
  148. }
  149. }
  150. }
  151. function load_msg_obj(o) {
  152. var msgs = eval(o);
  153. for(m in msgs) {
  154. var msg = msgs[m];
  155. total_msgs++;
  156. set_t(msg.ts);
  157. add_to_pie(msg.ty);
  158. add_to_cloud(msg);
  159. switch(msg.ty) {
  160. case "t_start":
  161. //create t
  162. msg.ty = "thread";
  163. msg.div = create_div(visualiser_elt, msg)
  164. threads[msg.tid] = msg
  165. layout_div(msg);
  166. break;
  167. case "t_finish":
  168. //close t
  169. threads[msg.tid].finish = msg.tid;
  170. layout_div(threads[msg.tid]);
  171. break;
  172. case "fn_start":
  173. //create fn
  174. msg.ty = "fn";
  175. msg.div = create_div(threads[msg.tid].div, msg)
  176. functions[msg.tid + msg.name] = msg
  177. layout_div(msg);
  178. break;
  179. case "fn_finish":
  180. //close fn
  181. var fn = functions[msg.tid + msg.name];
  182. fn.finish = msg.ts;
  183. layout_div(fn);
  184. break;
  185. case "msg":
  186. //create msg
  187. msg.div = create_div(threads[msg.tid].div, msg)
  188. functions[msg.ts] = msg
  189. layout_div(msg);
  190. break;
  191. }
  192. }
  193. }
  194. function next_msg() {
  195. $.get("http://localhost:8080/next_msg", load_msg_obj)
  196. }
  197. function start() {
  198. setInterval(next_msg, 500);
  199. }
  200. function create_spinner(id, f_up, f_down) {
  201. var spinner = $(document.createElement("div")).attr("id", id);
  202. var up = $(document.createElement("button")).addClass("up").text("^");
  203. var down = $(document.createElement("button")).addClass("down").text("v");
  204. var input = $(document.createElement("input")).addClass("spinner");
  205. up.click(f_up);
  206. down.click(f_down);
  207. spinner.append(up);
  208. spinner.append(down);
  209. spinner.append(input);
  210. timeline_elt.append(spinner);
  211. }
  212. function min_up() {
  213. t_min++;
  214. $("div#min > input").val(t_min);
  215. layout_all();
  216. }
  217. function min_down() {
  218. t_min--;
  219. $("div#min > input").val(t_min);
  220. layout_all();
  221. }
  222. function max_up() {
  223. t_max++;
  224. $("div#max > input").val(t_max);
  225. layout_all();
  226. }
  227. function max_down() {
  228. t_max--;
  229. $("div#max > input").val(t_max);
  230. layout_all();
  231. }
  232. function create_pie_canvas() {
  233. pie_elt.append($(document.createElement("canvas")));
  234. draw_pie();
  235. }
  236. function create_cloud_canvas() {
  237. cloud_elt.append($(document.createElement("canvas")));
  238. }
  239. function test1a() {
  240. $.get("http://localhost:8080/tests/test1a.json", load_msg_obj)
  241. }
  242. function test1b() {
  243. $.get("http://localhost:8080/tests/test1b.json", load_msg_obj)
  244. }
  245. function test1000() {
  246. $.get("http://localhost:8080/tests/test1000.json", load_msg_obj)
  247. }
  248. function test10000() {
  249. $.get("http://localhost:8080/tests/test10000.json", load_msg_obj)
  250. }
  251. function _test2(n) {
  252. function f(o) {
  253. load_msg_obj(o);
  254. _test2 (n+1);
  255. }
  256. if (n >= 100) { return }
  257. else $.get("http://localhost:8080/tests/test2-" + n + ".json", f)
  258. }
  259. function test2() {
  260. _test2(0);
  261. }
  262. function visualise () {
  263. $.get($("input#json_url").val(), load_msg_obj)
  264. }
  265. create_spinner("min", min_up, min_down);
  266. create_spinner("max", max_up, max_down);
  267. $("button#visualise").click(visualise);
  268. $("button#next_msg").click(next_msg);
  269. $("button#start").click(start);
  270. $("button#test1a").click(test1a);
  271. $("button#test1b").click(test1b);
  272. $("button#test2").click(test2);
  273. $("button#test1000").click(test1000);
  274. $("button#test10000").click(test10000);
  275. create_pie_canvas();
  276. create_cloud_canvas();