artdaq_node_server  v1_01_01b
JSRootInterface.js
1 // JSRootInterface.js
2 //
3 // default user interface for JavaScript ROOT Web Page.
4 //
5 
6 function ResetUI() {
7  if (JSROOT.H('root') != null) {
8  JSROOT.H('root').clear();
9  JSROOT.DelHList('root');
10  }
11  $('#browser').get(0).innerHTML = '';
12 }
13 
14 function guiLayout() {
15  var res = 'collapsible';
16  var selects = document.getElementById("layout");
17  if (selects)
18  res = selects.options[selects.selectedIndex].text;
19  return res;
20 }
21 
22 function setGuiLayout(value) {
23  var selects = document.getElementById("layout");
24  if (!selects) return;
25 
26  for (var i in selects.options) {
27  var s = selects.options[i].text;
28  if (typeof s == 'undefined') continue;
29  if ((s == value) || (s.replace(/ /g,"") == value)) {
30  selects.selectedIndex = i;
31  break;
32  }
33  }
34 }
35 
36 function BuildNoBrowserGUI(online) {
37  var itemsarr = [];
38  var optionsarr = [];
39  var running_request = {};
40 
41  var filename = null;
42  if (!online) {
43  filename = JSROOT.GetUrlOption("file");
44  var filesdir = JSROOT.GetUrlOption("path");
45  if (filesdir!=null) filename = filesdir + filename;
46  }
47 
48  var itemname = JSROOT.GetUrlOption("item");
49  if (itemname) itemsarr.push(itemname);
50  var opt = JSROOT.GetUrlOption("opt");
51  if (opt) optionsarr.push(opt);
52 
53  var items = JSROOT.GetUrlOption("items");
54  if (items != null) {
55  items = JSON.parse(items);
56  for (var i in items) itemsarr.push(items[i]);
57  }
58 
59  var opts = JSROOT.GetUrlOption("opts");
60  if (opts!=null) {
61  opts = JSON.parse(opts);
62  for (var i in opts) optionsarr.push(opts[i]);
63  }
64 
65 
66  var layout = JSROOT.GetUrlOption("layout");
67  if (layout=="") layout = null;
68 
69  var monitor = JSROOT.GetUrlOption("monitoring");
70  if (monitor == "") monitor = 3000; else
71  if (monitor != null) monitor = parseInt(monitor);
72 
73  var divid = online ? "onlineGUI" : "simpleGUI";
74 
75  $('#'+divid).empty();
76 
77  $('html').css('height','100%');
78  $('body').css('min-height','100%').css('margin','0px').css("overflow", "hidden");
79 
80  $('#'+divid).css("position", "absolute")
81  .css("left", "1px")
82  .css("top", "1px")
83  .css("bottom", "1px")
84  .css("right", "1px");
85 
86  var objpainter = null;
87  var mdi = null;
88 
89  function file_error(str) {
90  if ((objpainter == null) && (mdi==null))
91  $('#'+divid).append("<h4>" + str + "</h4>");
92  }
93 
94  if ((filename == null) && !online) {
95  return file_error('filename not specified');
96  }
97 
98  if (itemsarr.length == 0) {
99  return file_error('itemname not specified');
100  }
101 
102  var title = online ? "Online" : ("File: " + filename);
103  if (itemsarr.length == 1) title += " item: " + itemsarr[0];
104  else title += " items: " + itemsarr.toString();
105  document.title = title;
106 
107  function draw_object(indx, obj) {
108  document.body.style.cursor = 'wait';
109  if (obj==null) {
110  file_error("object " + itemsarr[indx] + " not found");
111  } else
112  if (mdi) {
113  var frame = mdi.FindFrame(itemsarr[indx], true);
114  mdi.ActivateFrame(frame);
115  JSROOT.redraw($(frame).attr('id'), obj, optionsarr[indx]);
116  } else {
117  objpainter = JSROOT.redraw(divid, obj, optionsarr[indx]);
118  }
119  document.body.style.cursor = 'auto';
120  running_request[indx] = false;
121  }
122 
123  function read_object(file, indx) {
124 
125  if (itemsarr[indx]=="StreamerInfo")
126  draw_object(indx, file.fStreamerInfos);
127 
128  file.ReadObject(itemsarr[indx], function(obj) {
129  draw_object(indx, obj);
130  });
131  }
132 
133  function request_object(indx) {
134 
135  if (running_request[indx]) return;
136 
137  running_request[indx] = true;
138 
139  var url = itemsarr[indx] + "/root.json.gz?compact=3";
140 
141  var itemreq = JSROOT.NewHttpRequest(url, 'object', function(obj) {
142  if ((obj != null) && (itemsarr[indx] === "StreamerInfo")
143  && (obj['_typename'] === 'TList'))
144  obj['_typename'] = 'TStreamerInfoList';
145 
146  draw_object(indx, obj);
147  });
148 
149  itemreq.send(null);
150  }
151 
152  function read_all_objects() {
153 
154  if (online) {
155  for (var i in itemsarr)
156  request_object(i);
157  return;
158  }
159 
160  for (var i in itemsarr)
161  if (running_request[i]) {
162  console.log("Request for item " + itemsarr[i] + " still running");
163  return;
164  }
165 
166  new JSROOT.TFile(filename, function(file) {
167  if (file==null) return file_error("file " + filename + " cannot be opened");
168 
169  for (var i in itemsarr) {
170  running_request[i] = true;
171  read_object(file, i);
172  }
173  });
174  }
175 
176  if (itemsarr.length > 1) {
177  if ((layout==null) || (layout=='collapsible') || (layout == "")) {
178  var divx = 2; divy = 1;
179  while (divx*divy < itemsarr.length) {
180  if (divy<divx) divy++; else divx++;
181  }
182  layout = 'grid' + divx + 'x' + divy;
183  }
184 
185  if (layout=='tabs')
186  mdi = new JSROOT.TabsDisplay(divid);
187  else
188  mdi = new JSROOT.GridDisplay(divid, layout);
189 
190  // Than create empty frames for each item
191  for (var i in itemsarr)
192  mdi.CreateFrame(itemsarr[i]);
193  }
194 
195  read_all_objects();
196 
197  if (monitor>0)
198  setInterval(read_all_objects, monitor);
199 
200  JSROOT.RegisterForResize(function() { if (objpainter) objpainter.CheckResize(); if (mdi) mdi.CheckResize(); });
201 }
202 
203 function ReadFile(filename, checkitem) {
204  var navigator_version = navigator.appVersion;
205  if (typeof ActiveXObject == "function") { // Windows
206  // detect obsolete browsers
207  if ((navigator_version.indexOf("MSIE 8") != -1) ||
208  (navigator_version.indexOf("MSIE 7") != -1)) {
209  alert("You need at least MS Internet Explorer version 9.0. Note you can also use any other web browser");
210  return;
211  }
212  }
213  else {
214  // Safari 5.1.7 on MacOS X doesn't work properly
215  if ((navigator_version.indexOf("Windows NT") == -1) &&
216  (navigator_version.indexOf("Safari") != -1) &&
217  (navigator_version.indexOf("Version/5.1.7") != -1)) {
218  alert("There are know issues with Safari 5.1.7 on MacOS X. It may become unresponsive or even hangs. You can use any other web browser");
219  return;
220  }
221  }
222 
223  if (filename==null) {
224  filename = $("#urlToLoad").val();
225  filename.trim();
226  } else {
227  $("#urlToLoad").val(filename);
228  }
229  if (filename.length == 0) return;
230 
231  var layout = null;
232  var itemsarr = [];
233  var optionsarr = [];
234  if (checkitem) {
235  var itemname = JSROOT.GetUrlOption("item");
236  if (itemname) itemsarr.push(itemname);
237  var items = JSROOT.GetUrlOption("items");
238  if (items!=null) {
239  items = JSON.parse(items);
240  for (var i in items) itemsarr.push(items[i]);
241  }
242 
243  layout = JSROOT.GetUrlOption("layout");
244  if (layout=="") layout = null;
245 
246  var opt = JSROOT.GetUrlOption("opt");
247  if (opt) optionsarr.push(opt);
248  var opts = JSROOT.GetUrlOption("opts");
249  if (opts!=null) {
250  opts = JSON.parse(opts);
251  for (var i in opts) optionsarr.push(opts[i]);
252  }
253  }
254 
255  if (layout==null)
256  layout = guiLayout();
257  else
258  setGuiLayout(layout);
259 
260  var painter = new JSROOT.HierarchyPainter('root', 'browser');
261 
262  painter.SetDisplay(layout, 'right-div');
263 
264  painter.OpenRootFile(filename, function() {
265  painter.displayAll(itemsarr, optionsarr);
266  });
267 }
268 
269 function ProcessResize(direct)
270 {
271  if (direct) document.body.style.cursor = 'wait';
272 
273  JSROOT.H('root').CheckResize();
274 
275  if (direct) document.body.style.cursor = 'auto';
276 }
277 
278 function AddInteractions() {
279  var drag_sum = 0;
280 
281  var drag_move = d3.behavior.drag()
282  .origin(Object)
283  .on("dragstart", function() {
284  d3.event.sourceEvent.preventDefault();
285  // console.log("start drag");
286  drag_sum = 0;
287  })
288  .on("drag", function() {
289  d3.event.sourceEvent.preventDefault();
290  drag_sum += d3.event.dx;
291  // console.log("dx = " + d3.event.dx);
292  d3.event.sourceEvent.stopPropagation();
293  })
294  .on("dragend", function() {
295  d3.event.sourceEvent.preventDefault();
296  // console.log("stop drag " + drag_sum);
297 
298  var width = d3.select("#left-div").style('width');
299  width = (parseInt(width.substr(0, width.length - 2)) + Number(drag_sum)).toString() + "px";
300  d3.select("#left-div").style('width', width);
301 
302  var left = d3.select("#separator-div").style('left');
303  left = parseInt(left.substr(0, left.length - 2)) + Number(drag_sum);
304  d3.select("#separator-div").style('left',left.toString() + "px");
305  d3.select("#right-div").style('left',(left+6).toString() + "px");
306 
307  ProcessResize(true);
308  });
309 
310  d3.select("#separator-div").call(drag_move);
311 
312  JSROOT.RegisterForResize(ProcessResize);
313 
314  // specify display kind every time selection done
315  // will be actually used only for first drawing or after reset
316  document.getElementById("layout").onchange = function() {
317  if (JSROOT.H('root'))
318  JSROOT.H('root').SetDisplay(guiLayout(), "right-div");
319  }
320 }
321 
322 
323 function BuildOnlineGUI() {
324  var myDiv = $('#onlineGUI');
325  if (!myDiv) {
326  alert("You have to define a div with id='onlineGUI'!");
327  return;
328  }
329 
330  JSROOT.Painter.readStyleFromURL();
331 
332  if (JSROOT.GetUrlOption("nobrowser")!=null)
333  return BuildNoBrowserGUI(true);
334 
335  var guiCode = "<div id='overlay'><font face='Verdana' size='1px'>&nbspJSROOT version " + JSROOT.version + "&nbsp</font></div>"
336 
337  guiCode += '<div id="left-div" class="column"><br/>'
338  + ' <h1><font face="Verdana" size="4">ROOT online server</font></h1>'
339  + ' Hierarchy in <a href="h.json">json</a> and <a href="h.xml">xml</a> format<br/><br/>'
340  + ' <input type="checkbox" name="monitoring" id="monitoring"/> Monitoring '
341  + ' <select style="padding:2px; margin-left:10px; margin-top:5px;" id="layout">'
342  + ' <option>collapsible</option><option>grid 2x2</option><option>grid 3x3</option><option>grid 4x4</option><option>tabs</option>'
343  + ' </select>'
344  + ' <div id="browser"></div>'
345  + '</div>'
346  + '<div id="separator-div" class="column"></div>'
347  + '<div id="right-div" class="column"></div>';
348 
349  $('#onlineGUI').empty();
350  $('#onlineGUI').append(guiCode);
351 
352  var layout = JSROOT.GetUrlOption("layout");
353  if ((layout=="") || (layout==null))
354  layout = guiLayout();
355  else
356  setGuiLayout(layout);
357 
358  var monitor = JSROOT.GetUrlOption("monitoring");
359 
360  var itemsarr = [], optionsarr = [];
361  var itemname = JSROOT.GetUrlOption("item");
362  if (itemname) itemsarr.push(itemname);
363  var items = JSROOT.GetUrlOption("items");
364  if (items!=null) {
365  items = JSON.parse(items);
366  for (var i in items) itemsarr.push(items[i]);
367  }
368 
369  var opt = JSROOT.GetUrlOption("opt");
370  if (opt) optionsarr.push(opt);
371  var opts = JSROOT.GetUrlOption("opts");
372  if (opts!=null) {
373  opts = JSON.parse(opts);
374  for (var i in opts) optionsarr.push(opts[i]);
375  }
376 
377  var h = new JSROOT.HierarchyPainter("root", "browser");
378 
379  h.SetDisplay(layout, 'right-div');
380 
381  h.EnableMonitoring(monitor!=null);
382  $("#monitoring")
383  .prop('checked', monitor!=null)
384  .click(function() {
385  h.EnableMonitoring(this.checked);
386  if (this.checked) h.updateAll();
387  });
388 
389  h.OpenOnline("", function() {
390  h.displayAll(itemsarr, optionsarr);
391  });
392 
393  setInterval(function() { if (h.IsMonitoring()) h.updateAll(); }, h.MonitoringInterval());
394 
395  AddInteractions();
396 }
397 
398 function BuildSimpleGUI() {
399 
400  if (document.getElementById('onlineGUI')) return BuildOnlineGUI();
401 
402  var myDiv = $('#simpleGUI');
403  if (!myDiv) return;
404 
405  JSROOT.Painter.readStyleFromURL();
406 
407  if (JSROOT.GetUrlOption("nobrowser")!=null)
408  return BuildNoBrowserGUI(false);
409 
410  var files = JSROOT.GetUrlOption("files");
411  if (files==null) files = myDiv.attr("files");
412  var filesdir = JSROOT.GetUrlOption("path");
413  if (filesdir==null) filesdir = myDiv.attr("path");
414 
415  if (files==null) files = "files/hsimple.root";
416  if (filesdir==null) filesdir = "";
417  var arrFiles = files.split(';');
418 
419  var guiCode = "<div id='overlay'><font face='Verdana' size='1px'>&nbspJSROOT version " + JSROOT.version + "&nbsp</font></div>"
420 
421  guiCode += "<div id='left-div' class='column'>\n"
422  +"<h1><font face='Verdana' size='4'>Read a ROOT file with Javascript</font></h1>\n"
423  +"<p><b>Select a ROOT file to read, or enter a url (*): </b><br/>\n"
424  +'<small><sub>*: Other URLs might not work because of cross site scripting protection, see e.g. <a href="https://developer.mozilla.org/en/http_access_control">developer.mozilla.org/http_access_control</a> on how to avoid it.</sub></small></p>'
425  +'<form name="ex">'
426  +'<div style="margin-left:10px;">'
427  + '<input type="text" name="state" value="" size="30" id="urlToLoad"/><br/>'
428  +'<select name="s" size="1" '
429  +'onchange="document.ex.state.value = document.ex.s.options[document.ex.s.selectedIndex].value;document.ex.s.selectedIndex=0;document.ex.s.value=\'\'">'
430  +'<option value = " " selected = "selected">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</option>';
431  for (var i=0; i<arrFiles.length; i++) {
432  guiCode += '<option value = "' + filesdir + arrFiles[i] + '">' + arrFiles[i] + '</option>';
433  }
434  guiCode += '</select>'
435  +'</div>'
436  +'<input style="padding:2px; margin-left:10px; margin-top:5px;"'
437  +' onclick="ReadFile()" type="button" title="Read the Selected File" value="Load"/>'
438  +'<input style="padding:2px; margin-left:10px;"'
439  +' onclick="ResetUI()" type="button" title="Clear All" value="Reset"/>'
440  +'<select style="padding:2px; margin-left:10px; margin-top:5px;" id="layout">'
441  +' <option>collapsible</option><option>grid 2x2</option><option>grid 3x3</option><option>grid 4x4</option><option>tabs</option>'
442  +'</select>'
443  +'</form>'
444  +'<br/>'
445  +'<div id="browser"></div>'
446  +'</div>'
447  +'<div id="separator-div" class="column"></div>'
448  +'<div id="right-div" class="column"></div>';
449 
450  $('#simpleGUI').empty();
451  $('#simpleGUI').append(guiCode);
452  // $("#layout").selectmenu();
453 
454  AddInteractions();
455 
456  var filename = JSROOT.GetUrlOption("file");
457  if ((typeof filename == 'string') && (filename.length>0))
458  ReadFile(filename, true);
459 }