souffle  2.0.2-371-g6315b36
htmlJsMain.h
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2017, The Souffle Developers. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 #include <string>
10 
11 namespace souffle {
12 namespace profile {
13 namespace html {
14 std::string jsMain = R"___(
15 function changeSelectedRel(id) {
16  selected.rel = id;
17  highlightRow();
18  genRulesOfRelations();
19 }
20 
21 function changeSelectedRul(id) {
22  selected.rul = id;
23  highlightRow();
24  genRulVer();
25  genAtomVer();
26 }
27 
28 function highlightRow() {
29  var i;
30  for (i=0;i<document.getElementsByClassName("rel_row").length;i++) {
31  document.getElementsByClassName("rel_row")[i].style.background = "rgba(255,255,0,0)";
32  }
33  for (i=0;i<document.getElementsByClassName("rul_row").length;i++) {
34  document.getElementsByClassName("rul_row")[i].style.background = "rgba(255,255,0,0)";
35  }
36  if (selected.rul) {
37  document.getElementById(selected.rul).style.background = "rgba(255,255,0,0.2)";
38  }
39  if (selected.rel) {
40  document.getElementById(selected.rel).style.background = "rgba(255,255,0,0.2)";
41  }
42 }
43 
44 
45 function graphRel() {
46  if (!selected.rel) {
47  alert("please select a relation to graph");
48  return;
49  }
50 
51  graph_vals.labels = [];
52  graph_vals.tot_t = [];
53  graph_vals.tuples = [];
54  for (j = 0; j < data.rel[selected.rel][9].tot_t.length; j++) {
55  graph_vals.labels.push(j.toString());
56  graph_vals.tot_t.push(
57  data.rel[selected.rel][9].tot_t[j]
58  );
59  graph_vals.tuples.push(
60  data.rel[selected.rel][9].tuples[j]
61  )
62  }
63 
64  document.getElementById('chart_tab').click();
65  drawGraph();
66 }
67 
68 function graphIterRul() {
69  if (!selected.rul || selected.rul[0]!='C') {
70  alert("Please select a recursive rule (ID starts with C) to graph.");
71  return;
72  }
73 
74  came_from = "rul";
75 
76  graph_vals.labels = [];
77  graph_vals.tot_t = [];
78  graph_vals.tuples = [];
79  for (j = 0; j < data.rul[selected.rul][9].tot_t.length; j++) {
80  graph_vals.labels.push(j.toString());
81  graph_vals.tot_t.push(
82  data.rul[selected.rul][9].tot_t[j]
83  );
84  graph_vals.tuples.push(
85  data.rul[selected.rul][9].tuples[j]
86  )
87  }
88 
89  document.getElementById('chart_tab').click();
90  drawGraph();
91 }
92 
93 
94 function graphUsages() {
95  graph_vals.labels = [];
96  graph_vals.cpu = [];
97  graph_vals.rss = [];
98  var interval = Math.ceil(data.usage.length / 8);
99  for (j = 0; j < data.usage.length; j++) {
100  graph_vals.labels.push(
101  j % interval == 0 ? data.usage[j][0] : "");
102  graph_vals.cpu.push(
103  {meta: data.usage[j][4], value: (data.usage[j][1] + data.usage[j][2]).toString()});
104  graph_vals.rss.push(
105  {meta: data.usage[j][4], value: data.usage[j][3].toString()});
106  }
107 
108  var options = {
109  height: "calc((100vh - 167px) / 2)",
110  axisY: {
111  labelInterpolationFnc: function (value) {
112  return value.toFixed(0) + '%';
113  }
114  },
115  axisX: {
116  labelInterpolationFnc: function (value) {
117  if (!value) {
118  return "";
119  }
120  return humanise_time(value);
121  }
122  },
123  plugins: [Chartist.plugins.tooltip({tooltipFnc: function (meta, value) {
124  value = Number(value);
125  return meta + '<br/>' + value.toFixed(0) + '%';}})]
126  };
127 
128  new Chartist.Bar(".ct-chart-cpu", {
129  labels: graph_vals.labels,
130  series: [graph_vals.cpu],
131  }, options);
132 
133  options.axisY = {
134  labelInterpolationFnc: function (value) {
135  return minify_memory(value);
136  },
137  };
138 
139  options.plugins = [Chartist.plugins.tooltip({tooltipFnc: function(meta, value) {
140  return meta + '<br/>' + minify_memory(value);}})]
141  new Chartist.Bar(".ct-chart-rss", {
142  labels: graph_vals.labels,
143  series: [graph_vals.rss],
144  }, options)
145 }
146 
147 function drawGraph() {
148  var options = {
149  height: "calc((100vh - 167px) / 2)",
150  axisY: {
151  labelInterpolationFnc: function (value) {
152  return humanise_time(value);
153  }
154  },
155  axisX: {
156  labelInterpolationFnc: function (value) {
157  var n = Math.floor(graph_vals.labels.length/15);
158  if (n>1) {
159  if (value%n == 0) {
160  return value;
161  }
162  return null;
163  }
164  return value;
165  }
166  },
167  plugins: [Chartist.plugins.tooltip()]
168  };
169 
170  new Chartist.Bar(".ct-chart1", {
171  labels: graph_vals.labels,
172  series: [graph_vals.tot_t],
173  }, options);
174 
175  options.axisY = {
176  labelInterpolationFnc: function (value) {
177  return minify_numbers(value);
178  }
179  };
180 
181  new Chartist.Bar(".ct-chart2", {
182  labels: graph_vals.labels,
183  series: [graph_vals.tuples],
184  }, options)
185 }
186 
187 
188 function changeTab(event, change_to) {
189  if (change_to === "Chart") {
190  document.getElementById("chart-tab").style.display = "block";
191  } else {
192  document.getElementById("chart-tab").style.display = "none";
193  }
194  var c, d, e;
195  d = document.getElementsByClassName("tabcontent");
196  for (c = 0; c < d.length; c++) {
197  d[c].style.display = "none";
198  }
199 
200  e = document.getElementsByClassName("tablinks");
201  for (c = 0; c < e.length; c++) {
202  e[c].className = e[c].className.replace(" active", "");
203  }
204 
205  document.getElementById(change_to).style.display = "block";
206  event.currentTarget.className += " active"
207 }
208 
209 
210 function toggle_precision() {
211  precision=!precision;
212  flip_table_values(document.getElementById("Rel_table"));
213  flip_table_values(document.getElementById("Rul_table"));
214  flip_table_values(document.getElementById("rulesofrel_table"));
215  flip_table_values(document.getElementById("rulvertable"));
216 }
217 
218 function flip_table_values(table) {
219  var i,j,cell;
220  for (i in table.rows) {
221  if (!table.rows.hasOwnProperty(i)) continue;
222  for (j in table.rows[i].cells) {
223  if (! table.rows[i].cells.hasOwnProperty(j)) continue;
224  cell = table.rows[i].cells[j];
225  if (cell.className === "time_cell") {
226  val = cell.getAttribute('data-sort');
227  cell.innerHTML = humanise_time(parseFloat(val));
228  } else if (cell.className === "int_cell") {
229  val = cell.getAttribute('data-sort');
230  cell.innerHTML = minify_numbers(parseInt(val));
231  }
232  }
233  }
234 }
235 
236 function create_cell(type, value, perc_total) {
237  cell = document.createElement("td");
238 
239  if (type === "text") {
240  cell.className = "text_cell";
241  text_span = document.createElement("span");
242  text_span.innerHTML = value;
243  cell.appendChild(text_span);
244  } else if (type === "code_loc") {
245  cell.className = "text_cell";
246  text_span = document.createElement("span");
247  text_span.innerHTML = value;
248  cell.appendChild(text_span);
249  if (data.hasOwnProperty("code"))
250  text_span.onclick = function() {view_code_snippet(value);}
251  } else if (type === "id") {
252  cell.innerHTML = value;
253  } else if (type === "time") {
254  cell.innerHTML = humanise_time(value);
255  cell.setAttribute('data-sort', value);
256  cell.className = "time_cell";
257  } else if (type === "int") {
258  cell.innerHTML = minify_numbers(value);
259  cell.setAttribute('data-sort', value);
260  cell.className = "int_cell";
261  } else if (type === "perc") {
262  div = document.createElement("div");
263  div.className = "perc_time";
264  if (perc_total == 0) {
265  div.style.width = "0%";
266  div.innerHTML = "0";
267  } else if (isNaN(value)) {
268  div.style.width = "0%";
269  div.innerHTML = "NaN";
270  } else {
271  div.style.width = parseFloat(value) / perc_total * 100 + "%";
272  div.innerHTML = clean_percentages(parseFloat(value) / perc_total * 100);
273  }
274  cell.appendChild(div);
275  }
276  return cell;
277 }
278 
279 
280 function generate_table(data_format,body_id,data_key) {
281  var item,i;
282  var perc_totals = [];
283 
284  for (i in data_format) {
285  if (!data_format.hasOwnProperty(i)) continue;
286  if (data_format[i][0] === "perc") {
287  perc_totals.push([data_format[i][1],data_format[i][2],0]);
288  }
289  }
290 
291  for (item in data[data_key]) {
292  if (data[data_key].hasOwnProperty(item)) {
293  for (i in perc_totals) {
294  if (!isNaN(data[data_key][item][perc_totals[i][1]])) {
295  perc_totals[i][2] += data[data_key][item][perc_totals[i][1]];
296  }
297  }
298  }
299  }
300 
301 
302  table_body = document.getElementById(body_id);
303  table_body.innerHTML = "";
304  for (item in data[data_key]) {
305  if (data[data_key].hasOwnProperty(item)) {
306  row = document.createElement("tr");
307  row.id = item;
308 
309  if (data_key === "rel") {
310  row.className = "rel_row";
311  row.onclick = function () {
312  changeSelectedRel(this.id);
313  };
314  } else if (data_key === "rul") {
315  row.className = "rul_row";
316  row.onclick = function () {
317  changeSelectedRul(this.id);
318  };
319  }
320  perc_counter = 0;
321  for (i in data_format) {
322  if (!data_format.hasOwnProperty(i)) continue;
323  if (data_format[i][0] === "perc") {
324  cell = create_cell(data_format[i][0], data[data_key][item][data_format[i][2]], perc_totals[perc_counter++][2]);
325  } else {
326  cell = create_cell(data_format[i][0], data[data_key][item][data_format[i][1]]);
327  }
328  row.appendChild(cell);
329  }
330  table_body.appendChild(row);
331  }
332  }
333 }
334 
335 function gen_rel_table() {
336  generate_table([["text",0],["id",1],["time",2],["time",3],["time",4],
337  ["time",5],["int",6],["int", 7],["perc","float",2],["perc","int",6],["code_loc",8]],
338  "Rel_table_body",
339  "rel");
340 }
341 
342 function gen_rul_table() {
343  generate_table([["text",0],["id",1],["time",2],["time",3],["time",4],
344  ["int",5],["perc","float",2],["perc","int",5],["code_loc",6]],
345  "Rul_table_body",
346  "rul");
347 }
348 
349 function gen_top_rel_table() {
350  generate_table([["text",0],["id",1],["time",2],["time",3],["time",4],
351  ["time",5],["int",6],["int",7],["perc","float",2],["perc","int",6],["code_loc",8]],
352  "top_rel_table_body",
353  "topRel");
354 }
355 
356 function gen_top_rul_table() {
357  generate_table([["text",0],["id",1],["time",2],["time",3],["time",4],
358  ["int",5],["perc","float",2],["perc","int",5],["code_loc",6]],
359  "top_rul_table_body",
360  "topRul");
361 }
362 
363 
364 function genRulesOfRelations() {
365  var data_format = [["text",0],["id",1],["time",2],["time",3],["time",4],
366  ["int",5],["perc","float",2],["perc","int",5],["code_loc",6]];
367  var rules = data.rel[selected.rel][9];
368  var perc_totals = [];
369  var row, cell, perc_counter, table_body, i, j;
370  table_body = document.getElementById("rulesofrel_body");
371  table_body.innerHTML = "";
372 
373  for (i in data_format) {
374  if (!data_format.hasOwnProperty(i)) continue;
375  if (data_format[i][0] === "perc") {
376  perc_totals.push([data_format[i][1],data_format[i][2],0]);
377  }
378  }
379 
380  for (item in rules) {
381  if (data.rul[rules[item]].hasOwnProperty(item)) {
382  for (i in perc_totals) {
383  if (!isNaN(data.rul[rules[item]][perc_totals[i][1]])) {
384  perc_totals[i][2] += data.rul[rules[item]][perc_totals[i][1]];
385  }
386  }
387  }
388  }
389 
390  for (j=0; j<rules.length; j++) {
391  row = document.createElement("tr");
392  perc_counter=0;
393  for (i in data_format) {
394  if (!data_format.hasOwnProperty(i)) continue;
395  if (data_format[i][0] === "perc") {
396  cell = create_cell(data_format[i][0], data.rul[rules[j]][data_format[i][2]], perc_totals[perc_counter++][2]);
397  } else {
398  cell = create_cell(data_format[i][0], data.rul[rules[j]][data_format[i][1]]);
399  }
400  row.appendChild(cell);
401  }
402  table_body.appendChild(row);
403  }
404 
405  document.getElementById("rulesofrel").style.display = "block";
406 }
407 
408 function genRulVer() {
409  var data_format = [["text",0],["id",1],["time",2],["time",3],["time",4],
410  ["int",5],["int",7],["perc","float",2],["perc","int",5],["code_loc",6]];
411  var rules = data.rul[selected.rul][7];
412  var perc_totals = [];
413  var row, cell, perc_counter, table_body, i, j;
414  table_body = document.getElementById("rulver_body");
415  table_body.innerHTML = "";
416 
417  for (i in data_format) {
418  if (!data_format.hasOwnProperty(i)) continue;
419  if (data_format[i][0] === "perc") {
420  if (!isNaN(data.rul[selected.rul][data_format[i][2]])) {
421  perc_totals.push([data_format[i][1], data_format[i][2], data.rul[selected.rul][data_format[i][2]]]);
422  }
423  }
424  }
425 
426  row = document.createElement("tr");
427  for (i in data_format) {
428  if (!data_format.hasOwnProperty(i)) continue;
429  if (data_format[i][1] == 7) {
430  cell = create_cell("text","-")
431  } else if (data_format[i][0] === "perc") {
432  cell = create_cell(data_format[i][0], 1, 1);
433  } else {
434  cell = create_cell(data_format[i][0], data.rul[selected.rul][data_format[i][1]]);
435  }
436  row.appendChild(cell);
437  }
438  table_body.appendChild(row);
439 
440  for (j=0; j<rules.length; j++) {
441  row = document.createElement("tr");
442  perc_counter=0;
443  for (i in data_format) {
444  if (!data_format.hasOwnProperty(i)) continue;
445  if (data_format[i][0] === "perc") {
446  cell = create_cell(data_format[i][0], rules[j][data_format[i][2]], perc_totals[perc_counter++][2]);
447  } else {
448  cell = create_cell(data_format[i][0], rules[j][data_format[i][1]]);
449  }
450  row.appendChild(cell);
451  }
452  table_body.appendChild(row);
453  }
454 
455  document.getElementById("rulver").style.display = "block";
456 }
457 
458 function genAtomVer() {
459  var atoms = data.atoms[selected.rul];
460  var table_body = document.getElementById('atoms_body');
461  table_body.innerHTML = "";
462 
463  for (i = 0; i < atoms.length; ++i) {
464  var row = document.createElement("tr");
465  row.appendChild(create_cell("text", atoms[i][1]));
466  if (atoms[i][2] === undefined) {
467  row.appendChild(create_cell("text", '--'));
468  } else {
469  row.appendChild(create_cell("int", atoms[i][2]));
470  }
471  row.appendChild(create_cell("int", atoms[i][3]));
472  table_body.appendChild(row);
473  }
474  document.getElementById("atoms").style.display = "block";
475 }
476 
477 function genConfig() {
478  var table = document.createElement("table");
479  {
480  var header = document.createElement("thead");
481  var headerRow = document.createElement("tr");
482  var headerName = document.createElement("th");
483  headerName.textContent = "Key";
484  var headerValue = document.createElement("th");
485  headerValue.textContent = "Value";
486 
487  headerRow.appendChild(headerName);
488  headerRow.appendChild(headerValue);
489  header.appendChild(headerRow);
490  table.appendChild(header);
491  }
492  var body = document.createElement("tbody");
493  for (i in data["configuration"]) {
494  var row = document.createElement("tr");
495  var name = document.createElement("td");
496  if (i === "") {
497  name.textContent = "Datalog input file";
498  } else {
499  name.textContent = i;
500  }
501  var value = document.createElement("td");
502  value.textContent = data["configuration"][i];
503 
504  row.appendChild(name);
505  row.appendChild(value);
506  body.appendChild(row);
507  }
508  table.appendChild(body);
509  return table;
510 }
511 
512 function gen_top() {
513  var statsElement, line1, line2;
514  statsElement = document.getElementById("top-stats");
515  line1 = document.createElement("p");
516  line1.textContent = "Total runtime: " + humanise_time(data.top[0]) + " (" + data.top[0] + " seconds)";
517  line2 = document.createElement("p");
518  line2.textContent = "Total tuples: " + minify_numbers(data.top[1]) + " (" + data.top[1] + ")";
519  line3 = document.createElement("p");
520  line3.textContent = "Total loadtime: " + humanise_time(data.top[2]) + " (" + data.top[2] + " seconds)";
521  line4 = document.createElement("p");
522  line4.textContent = "Total savetime: " + humanise_time(data.top[3]) + " (" + data.top[3] + " seconds)";
523  statsElement.appendChild(line1);
524  statsElement.appendChild(line2);
525  statsElement.appendChild(line3);
526  statsElement.appendChild(line4);
527  graphUsages();
528 
529  document.getElementById("top-config").appendChild(genConfig());
530  gen_top_rel_table();
531  gen_top_rul_table();
532 }
533 
534 function view_code_snippet(value) {
535  value = value.split(" ");
536  value = value[value.length-1]; // get [num:num]
537  value = value.slice(1); // cut out "["
538  value = value.split(":");
539  value = value[0];
540  var targetLi = gen_code(parseInt(value));
541  document.getElementById("code_tab").click();
542 
543  var list = document.getElementById("code-view");
544 
545  list.scrollTop = Math.max(21*parseInt(value) - 100, 0);
546 
547 }
548 
549 
550 function gen_code(highlight_row) {
551  var list, row, text, target_row;
552  list = document.getElementById("code-list");
553  list.innerHTML = "";
554  for (var i=0; i<data.code.length; i++) {
555  row = document.createElement("li");
556  row.className = "code-li";
557  if (i+1 == highlight_row) {
558  target_row = row;
559  row.style.background = "#E0FFFF";
560  }
561  row.style.marginBottom = "0";
562  text = document.createElement("span");
563  text.className = "text-span";
564  text.textContent = data.code[i];
565  row.appendChild(text);
566  list.appendChild(row);
567  }
568  document.getElementById("code-view").appendChild(list);
569  return target_row;
570 }
571 
572 
573 var precision = !1;
574 var selected = {rel: !1, rul: !1};
575 var came_from = !1;
576 var graph_vals = {
577  labels:[],
578  tot_t:[],
579  tuples:[]
580 };
581 
582 
583 function init() {
584  gen_top();
585  gen_rel_table();
586  gen_rul_table();
587  gen_code(-1)
588  Tablesort(document.getElementById('Rel_table'),{descending: true});
589  Tablesort(document.getElementById('Rul_table'),{descending: true});
590  Tablesort(document.getElementById('rulesofrel_table'),{descending: true});
591  Tablesort(document.getElementById('rulvertable'),{descending: true});
592  document.getElementById("default").click();
593  //document.getElementById("default").classList['active'] = !0;
594 
595 }
596 
597 init();
598  )___";
599 }
600 } // namespace profile
601 } // namespace souffle
souffle::profile::html::jsMain
std::string jsMain
Definition: htmlJsMain.h:14
souffle
Definition: AggregateOp.h:25