GSI Object Oriented Online Offline (Go4)  GO4-6.1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
go4.js
Go to the documentation of this file.
1 (function(){
2 
3  if (typeof JSROOT != "object") {
4  var e1 = new Error("go4.js requires JSROOT to be already loaded");
5  e1.source = "go4.js";
6  throw e1;
7  }
8 
9  if (typeof GO4 == "object") {
10  var e1 = new Error("GO4 already defined when loading go4.js");
11  e1.source = "go4.js";
12  throw e1;
13  }
14 
15  GO4 = {};
16 
17  GO4.version = "6.1.x";
18 
19  // use location to load all other scripts when required
20  GO4.source_dir = function() {
21  var scripts = document.getElementsByTagName('script');
22 
23  for (var n in scripts) {
24  if (scripts[n]['type'] != 'text/javascript') continue;
25 
26  var src = scripts[n]['src'];
27  if ((src == null) || (src.length == 0)) continue;
28 
29  var pos = src.indexOf("html/go4.js");
30  if (pos<0) continue;
31  if ((src.indexOf("JSRootCore") >= 0) || (src.indexOf("JSRoot.core") >= 0)) continue;
32  console.log('Set GO4.source_dir to ' + src.substr(0, pos));
33  return src.substr(0, pos);
34  }
35  return "";
36  }();
37 
38  let BasePainter = JSROOT.BasePainter || JSROOT.TBasePainter;
39 
40  if (!BasePainter.prototype.get_main_id) {
41  GO4.id_counter = 1;
42  // method removed from JSROOT v6, is not required there, therefore reintroduce it here
43  BasePainter.prototype.get_main_id = function() {
44  var elem = this.selectDom();
45  if (elem.empty()) return "";
46  var id = elem.attr("id");
47  if (!id) {
48  id = "go4_element_" + GO4.id_counter++;
49  elem.attr("id", id);
50  }
51  return id;
52  }
53  }
54 
55  if (!BasePainter.prototype.getItemName)
56  BasePainter.prototype.getItemName = BasePainter.prototype.GetItemName;
57 
58  if (typeof JSROOT.httpRequest == 'function')
59  GO4.httpRequest = JSROOT.httpRequest;
60  else
61  GO4.httpRequest = function(url, kind, post_data) {
62  return new Promise((resolveFunc,rejectFunc) => {
63  let req = JSROOT.NewHttpRequest(url,kind, (res) => {
64  if (res === null)
65  rejectFunc(Error(`Fail to request ${url}`));
66  else
67  resolveFunc(res);
68  });
69 
70  req.send(post_data || null);
71  });
72  }
73 
74  GO4.ExecuteMethod = function(item, method, options, callback) {
75  var prefix = "";
76  if (item.getItemName())
77  prefix = item.getItemName() + "/"; // suppress / if item name is empty
78  prefix += "exe.json\?method=";
79 
80  var fullcom = prefix + method + (options || "&"); // send any arguments otherwise ROOT refuse to process it
81 
82  GO4.httpRequest(fullcom, 'text')
83  .then(() => callback(true))
84  .catch(() => callback(false))
85  .finally(() => console.log('Command is completed ' + prefix + method));
86  }
87 
88  // ==================================================================================
89 
90  GO4.DrawAnalysisRatemeter = function(divid, itemname) {
91 
92  function CreateHTML() {
93  var elem = d3.select('#'+divid);
94 
95  if (elem.size() == 0) return null;
96  if (elem.select(".event_rate").size() > 0) return elem;
97 
98  var html = "<div style='padding-top:2px'>";
99  html += "<img class='go4_logo' style='vertical-align:middle;margin-left:5px;margin-right:5px;' src='go4sys/icons/go4logorun4.gif' alt='logo'></img>";
100  html += "<label class='event_source' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>file.lmd</label> ";
101  html += "<label class='event_rate' style='border: 1px solid gray; font-size:large; vertical-align:middle; background-color: grey'; padding-left:3px; padding-right:3px;>---</label> Ev/s ";
102  html += "<label class='aver_rate' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>---</label> Ev/s ";
103  html += "<label class='run_time' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>---</label> s ";
104  html += "<label class='total_events' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>---</label> Events ";
105  html += "<label class='analysis_time' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>time</label>";
106  html += "</div>";
107 
108  elem.style('overflow','hidden')
109  .style('padding-left','5px')
110  .style('display', 'inline-block')
111  .style('white-space', 'nowrap')
112  .html(html);
113 
114  // use height of child element
115  var brlayout = JSROOT.hpainter ? JSROOT.hpainter.brlayout : null,
116  sz = $('#'+divid + " div").height() + 4; // use jquery to get height
117 
118  if (brlayout)
119  if (JSROOT._)
120  brlayout.adjustSeparators(null, sz, true);
121  else
122  brlayout.AdjustSeparator(null, sz, true);
123  return elem;
124  }
125 
126  var xreq = false, was_running = null;
127 
128  function UpdateRatemeter() {
129  if (xreq) return;
130 
131  let elem = CreateHTML();
132  if (!elem) return;
133 
134  xreq = true;
135  GO4.httpRequest(itemname+"/root.json.gz", 'object').then(res => {
136  elem.select(".event_rate").style('background-color', res.fbRunning ? 'lightgreen' : 'red');
137  if (was_running != res.fbRunning)
138  elem.select(".go4_logo").attr("src", res.fbRunning ? 'go4sys/icons/go4logorun4.gif' : 'go4sys/icons/go4logo_t.png');
139 
140  was_running = res.fbRunning;
141 
142  elem.select(".event_source").text(res.fxEventSource == "" ? "<source>" : res.fxEventSource);
143  elem.select(".event_rate").text(res.fdRate.toFixed(1));
144  elem.select(".aver_rate").text((res.fdTime > 0 ? res.fuCurrentCount / res.fdTime : 0).toFixed(1));
145  elem.select(".run_time").text(res.fdTime.toFixed(1));
146  elem.select(".total_events").text(res.fuCurrentCount);
147  elem.select(".analysis_time").text(res.fxDateString == "" ? "<datime>" : res.fxDateString);
148  }).catch(() => {
149  elem.select(".event_rate").style('background-color','grey');
150  }).finally(() => {
151  xreq = false;
152  });
153  }
154 
155  CreateHTML();
156 
157  setInterval(UpdateRatemeter, 2000);
158  }
159 
160 
161  GO4.MakeMsgListRequest = function(hitem, item) {
162  var arg = "&max=2000";
163  if ('last-id' in item) arg+= "&id="+item['last-id'];
164  return 'exe.json.gz?method=Select' + arg;
165  }
166 
167  GO4.AfterMsgListRequest = function(hitem, item, obj) {
168  if (!item) return;
169 
170  if (!obj) {
171  delete item['last-id'];
172  return;
173  }
174  // ignore all other classes
175  if (obj._typename != 'TList') return;
176 
177  obj._typename = "TGo4MsgList";
178 
179  if (obj.arr.length>0) {
180  var duplicate = (('last-id' in item) && (item['last-id'] == obj.arr[0].fString));
181 
182  item['last-id'] = obj.arr[0].fString;
183 
184  // workaround for snapshot, it sends always same messages many times
185  if (duplicate) obj.arr.length = 1;
186 
187  // add clear function for item
188  if (!('clear' in item))
189  item['clear'] = function() { delete this['last-id']; }
190  }
191  }
192 
193 
194  GO4.MsgListPainter = function(divid, lst) {
195  BasePainter.call(this, divid);
196  if (this.SetDivId) this.SetDivId(divid); // old
197  this.lst = lst;
198  return this;
199  }
200 
201  GO4.MsgListPainter.prototype = Object.create( BasePainter.prototype );
202 
203  GO4.MsgListPainter.prototype.redrawObject = function(obj) {
204  // if (!obj._typename != 'TList') return false;
205  this.lst = obj;
206  this.Draw();
207  return true;
208  }
209 
210  if (!JSROOT._)
211  GO4.MsgListPainter.prototype.RedrawObject = GO4.MsgListPainter.prototype.redrawObject;
212 
213  GO4.MsgListPainter.prototype.Draw = function() {
214  if (!this.lst) return;
215 
216  var frame = JSROOT._ ? this.selectDom() : this.select_main();
217 
218  var main = frame.select("div");
219  if (main.empty())
220  main = frame.append("div")
221  .style('max-width','100%')
222  .style('max-height','100%')
223  .style('overflow','auto');
224 
225  var old = main.selectAll("pre");
226  var newsize = old.size() + this.lst.arr.length - 1;
227 
228  // in the browser keep maximum 2000 entries
229  if (newsize > 2000)
230  old.select(function(d,i) { return i < newsize - 2000 ? this : null; }).remove();
231 
232  for (var i=this.lst.arr.length-1;i>0;i--)
233  main.append("pre").style('margin','3px').html(this.lst.arr[i].fString);
234 
235  }
236 
237  GO4.DrawMsgList = function(divid, lst, opt) {
238 
239  var painter = new GO4.MsgListPainter(divid, lst);
240 
241  painter.Draw();
242 
243  if (JSROOT._) {
244  painter.setTopPainter();
245  return Promise.resolve(painter);
246  }
247  // (re) set painter to first child element
248  painter.SetDivId(divid); // old
249  return painter.DrawingReady();
250  }
251 
252  GO4.drawAnalysisTerminal = function(hpainter, itemname) {
253  var url = "", mdi, frame;
254  // FIXME: only for short backward compatibility with jsroot5
255  if (JSROOT._) {
256  url = hpainter.getOnlineItemUrl(itemname);
257  mdi = hpainter.getDisplay();
258  if (mdi) frame = mdi.findFrame(itemname, true);
259  } else {
260  url = hpainter.GetOnlineItemUrl(itemname);
261  mdi = hpainter.GetDisplay();
262  if (mdi) frame = mdi.FindFrame(itemname, true);
263  }
264 
265  if (!url || !frame) return null;
266 
267  var divid = d3.select(frame).attr('id');
268 
269  var h = $("#"+divid).height(), w = $("#"+divid).width();
270  if ((h<10) && (w>10)) $("#"+divid).height(w*0.7);
271 
272  var player = new BasePainter(divid);
273  player.url = url;
274  player.hpainter = hpainter;
275  player.itemname = itemname;
276  player.draw_ready = true;
277  player.needscroll = false;
278 
279  player.LogReady = function(p) {
280  if (p) this.log_painter = p;
281  if(this.needscroll) {
282  this.ClickScroll();
283  this.needscroll = false;
284  }
285  this.draw_ready = true;
286  }
287 
288  if (JSROOT._)
289  player.cleanup = function() {
290  if (this.log_painter) {
291  this.log_painter.cleanup();
292  delete this.log_painter;
293  }
294  if (this.interval) {
295  clearInterval(this.interval);
296  delete this.interval;
297  }
298  BasePainter.prototype.cleanup.call(this);
299  }
300  else
301  player.Cleanup = function() {
302  if (this.log_painter) {
303  this.log_painter.Cleanup();
304  delete this.log_painter;
305  }
306  if (this.interval) {
307  clearInterval(this.interval);
308  delete this.interval;
309  }
310  BasePainter.prototype.Cleanup.call(this);
311  }
312 
313 
314  player.ProcessTimer = function() {
315  var subid = "anaterm_output_container";
316  if ($("#" + subid).length == 0) {
317  // detect if drawing disappear
318  return JSROOT._ ? this.cleanup() : this.Cleanup();
319  }
320  if (!this.draw_ready) return;
321 
322  var msgitem = this.itemname.replace("Control/Terminal", "Status/Log");
323 
324  this.draw_ready = false;
325 
326  if (this.log_painter)
327  this.hpainter.display(msgitem, "update:divid:" + subid).then(() => this.LogReady());
328  else if (JSROOT._)
329  this.hpainter.display(msgitem, "divid:" + subid).then(p => this.LogReady(p));
330  else
331  this.hpainter.display(msgitem, "divid:" + subid, () => this.LogReady());
332  }
333 
334  player.ClickCommand = function(kind) {
335  var pthis = this;
336  var command = this.itemname.replace("Terminal", "CmdExecute");
337  if (JSROOT._)
338  this.hpainter.executeCommand(command, null, kind). then(() => { pthis.needscroll = true; });
339  else
340  this.hpainter.ExecuteCommand(command, function() { pthis.needscroll = true; }, kind);
341  }
342 
343  player.ClickClear = function() {
344  document.getElementById("anaterm_output_container").firstChild.innerHTML = "";
345  }
346 
347  player.ClickScroll = function() {
348  // inner frame created by hpainter has the scrollbars, i.e. first child
349  var disp = $("#anaterm_output_container").children(":first");
350  disp.scrollTop(disp[0].scrollHeight - disp.height());
351  }
352 
353 
354  player.fillDisplay = function(id) {
355  if (JSROOT._) {
356  this.setTopPainter();
357  } else {
358  this.SetDivId(id); // old
359  }
360  this.interval = setInterval(this.ProcessTimer.bind(this), 2000);
361 
362  id = "#" + id; // to use in jQuery
363 
364  $(id + " .go4_clearterm")
365  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
366  .click(this.ClickClear.bind(this))
367  .children(":first") // select first button element, used for images
368  .css('background-image', "url(" + GO4.source_dir + "icons/clear.png)");
369 
370  $(id + " .go4_endterm")
371  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
372  .click(this.ClickScroll.bind(this))
373  .children(":first") // select first button element, used for images
374  .css('background-image', "url(" + GO4.source_dir + "icons/shiftdown.png)");
375 
376  $(id + " .go4_printhistos")
377  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
378  .click(this.ClickCommand.bind(this,"@PrintHistograms()"))
379  .children(":first") // select first button element, used for images
380  .css('background-image', "url(" + GO4.source_dir + "icons/hislist.png)");
381 
382  $(id + " .go4_printcond")
383  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
384  .click(this.ClickCommand.bind(this,"@PrintConditions()"))
385  .children(":first") // select first button element, used for images
386  .css('background-image', "url(" + GO4.source_dir + "icons/condlist.png)");
387 
388  var pthis = this;
389 
390  $("#go4_anaterm_cmd_form").submit(
391  function(event) {
392  var command = pthis.itemname.replace("Terminal", "CmdExecute");
393  var cmdpar = document.getElementById("go4_anaterm_command").value;
394  console.log("submit command - " + cmdpar);
395  if (JSROOT._)
396  pthis.hpainter.executeCommand(command, null, cmdpar).then(() => { pthis.needscroll = true; });
397  else
398  pthis.hpainter.ExecuteCommand(command, function() { pthis.needscroll = true; }, cmdpar);
399  event.preventDefault();
400  });
401 
402  $(id + " .go4_executescript")
403  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
404  .children(":first") // select first button element, used for images
405  .css('background-image', "url(" + GO4.source_dir + "icons/macro_t.png)");
406  }
407 
408  player.CheckResize = player.checkResize = function() {}
409 
410  $("#"+divid).load(GO4.source_dir + "html/terminal.htm", "", () => player.fillDisplay(divid));
411 
412  return player;
413  }
414 
415 
416  // ==============================================================================
417 
418  var canvsrc = GO4.source_dir + 'html/go4canvas.js;';
419  var jsrp = JSROOT._ ? JSROOT.Painter : JSROOT;
420 
421  jsrp.addDrawFunc({ name: "TGo4WinCond", script: canvsrc + GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond', opt: ";editor" });
422  jsrp.addDrawFunc({ name: "TGo4PolyCond", script: canvsrc + GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond', opt: ";editor" });
423  jsrp.addDrawFunc({ name: "TGo4ShapedCond", script: canvsrc + GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond', opt: ";editor" });
424  jsrp.addDrawFunc({ name: "TGo4CondArray", script: canvsrc + GO4.source_dir + 'html/condition.js', func: 'GO4.drawCondArray', opt: ";editor" });
425  jsrp.addDrawFunc({ name: "TGo4Marker", script: canvsrc, func: 'GO4.drawGo4Marker' });
426 
427  jsrp.addDrawFunc({ name: "TGo4AnalysisWebStatus", script: GO4.source_dir + 'html/analysiseditor.js', func: 'GO4.drawGo4AnalysisStatus', opt: "editor" });
428 
429  jsrp.addDrawFunc({ name: "TGo4MsgList", func: GO4.DrawMsgList });
430 
431  jsrp.addDrawFunc({ name: "TGo4MbsEvent", noinspect: true });
432  jsrp.addDrawFunc({ name: "TGo4EventElement", noinspect: true });
433 
434 })(); // factory
var jsrp
Definition: go4.js:419
function JSROOT
Definition: go4canvas.js:17
int main(int argc, char **argv)
GO4 MsgListPainter prototype Draw
Definition: go4.js:213
function GO4
Definition: go4canvas.js:17
let BasePainter
Definition: go4.js:38