GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 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  GO4 = {};
10 
11  GO4.version = "5.3.x";
12 
13  // use location to load all other scripts when required
14  GO4.source_dir = function() {
15  var scripts = document.getElementsByTagName('script');
16 
17  for (var n in scripts) {
18  if (scripts[n]['type'] != 'text/javascript') continue;
19 
20  var src = scripts[n]['src'];
21  if ((src == null) || (src.length == 0)) continue;
22 
23  var pos = src.indexOf("html/go4.js");
24  if (pos<0) continue;
25  if (src.indexOf("JSRootCore")>=0) continue;
26  console.log('Set GO4.source_dir to ' + src.substr(0, pos));
27  return src.substr(0, pos);
28  }
29  return "";
30  }();
31 
32 
33  if (!JSROOT.TBasePainter.prototype.get_main_id)
34  JSROOT.TBasePainter.prototype.get_main_id = function() {
35  var elem = this.select_main();
36  return elem.empty() ? "" : elem.attr("id");
37  }
38 
39  // ==================================================================================
40 
41  GO4.DrawAnalysisRatemeter = function(divid, itemname) {
42 
43  var html = "<div style='padding-top:2px'>";
44  html += "<img class='go4_logo' style='vertical-align:middle;margin-left:5px;margin-right:5px;' src='go4sys/icons/go4logorun4.gif' alt='logo'></img>";
45  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> ";
46  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 ";
47  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 ";
48  html += "<label class='run_time' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>---</label> s ";
49  html += "<label class='total_events' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>---</label> Events ";
50  html += "<label class='analysis_time' style='border: 1px solid gray; font-size:large; vertical-align:middle; padding-left:3px; padding-right:3px;'>time</label>";
51  html += "</div>";
52 
53  $('#'+divid).css('overflow','hidden')
54  .css('padding-left','5px')
55  .css('display', 'inline-block')
56  .css('white-space', 'nowrap')
57  .html(html);
58 
59  // use height of child element
60  JSROOT.Painter.AdjustLayout(null, $('#'+divid+' div').height()+4, false);
61 
62  var xreq = null, was_running = null;
63 
64  function UpdateRatemeter() {
65  if (xreq!=null) return;
66 
67  xreq = JSROOT.NewHttpRequest(itemname+"/root.json.gz", 'object', function(res) {
68  xreq = null;
69 
70  if (res==null)
71  return $('#'+divid + " .event_rate").css('background-color','grey');
72 
73  $('#'+divid + " .event_rate").css('background-color', res.fbRunning ? 'lightgreen' : 'red');
74  if (was_running != res.fbRunning)
75  $('#'+divid + " .go4_logo").attr("src", res.fbRunning ? 'go4sys/icons/go4logorun4.gif' : 'go4sys/icons/go4logo_t.png');
76  was_running = res.fbRunning;
77 
78  $('#'+divid + " .event_source").text(res.fxEventSource == "" ? "<source>" : res.fxEventSource);
79  $('#'+divid + " .event_rate").text(res.fdRate.toFixed(1));
80  $('#'+divid + " .aver_rate").text((res.fdTime > 0 ? res.fuCurrentCount / res.fdTime : 0).toFixed(1));
81  $('#'+divid + " .run_time").text(res.fdTime.toFixed(1));
82  $('#'+divid + " .total_events").text(res.fuCurrentCount);
83  $('#'+divid + " .analysis_time").text(res.fxDateString == "" ? "<datime>" : res.fxDateString);
84  });
85 
86  xreq.send(null);
87  }
88 
89  setInterval(UpdateRatemeter, 2000);
90  }
91 
92 
93  GO4.MakeMsgListRequest = function(hitem, item) {
94  var arg = "&max=2000";
95  if ('last-id' in item) arg+= "&id="+item['last-id'];
96  return 'exe.json.gz?method=Select' + arg;
97  }
98 
99  GO4.AfterMsgListRequest = function(hitem, item, obj) {
100  if (!item) return;
101 
102  if (!obj) {
103  delete item['last-id'];
104  return;
105  }
106  // ignore all other classes
107  if (obj._typename != 'TList') return;
108 
109  obj._typename = "TGo4MsgList";
110 
111  if (obj.arr.length>0) {
112  var duplicate = (('last-id' in item) && (item['last-id'] == obj.arr[0].fString));
113 
114  item['last-id'] = obj.arr[0].fString;
115 
116  // workaround for snapshot, it sends always same messages many times
117  if (duplicate) obj.arr.length = 1;
118 
119  // add clear function for item
120  if (!('clear' in item))
121  item['clear'] = function() { delete this['last-id']; }
122  }
123  }
124 
125 
126  GO4.MsgListPainter = function(lst) {
127  JSROOT.TBasePainter.call(this);
128 
129  this.lst = lst;
130 
131  return this;
132  }
133 
134  GO4.MsgListPainter.prototype = Object.create( JSROOT.TBasePainter.prototype );
135 
136  GO4.MsgListPainter.prototype.RedrawObject = function(obj) {
137  this.lst = obj;
138  this.Draw();
139  return true;
140  }
141 
142  GO4.MsgListPainter.prototype.Draw = function() {
143  if (!this.lst) return;
144 
145  var frame = this.select_main();
146 
147  var main = frame.select("div");
148  if (main.empty())
149  main = frame.append("div")
150  .style('max-width','100%')
151  .style('max-height','100%')
152  .style('overflow','auto');
153 
154  var old = main.selectAll("pre");
155  var newsize = old.size() + this.lst.arr.length - 1;
156 
157  // in the browser keep maximum 2000 entries
158  if (newsize > 2000)
159  old.select(function(d,i) { return i < newsize - 2000 ? this : null; }).remove();
160 
161  for (var i=this.lst.arr.length-1;i>0;i--)
162  main.append("pre").style('margin','3px').html(this.lst.arr[i].fString);
163 
164  // (re) set painter to first child element
165  this.SetDivId(this.divid);
166 
167  }
168 
169  GO4.DrawMsgList = function(divid, lst, opt) {
170  var painter = new GO4.MsgListPainter(lst);
171  painter.SetDivId(divid);
172  painter.Draw();
173  return painter.DrawingReady();
174  }
175 
176  GO4.drawAnalysisTerminal = function(hpainter, itemname) {
177  var url = hpainter.GetOnlineItemUrl(itemname);
178  var frame = hpainter.GetDisplay().FindFrame(itemname, true);
179  if (!url || !frame) return null;
180 
181  var divid = d3.select(frame).attr('id');
182 
183  var h = $("#"+divid).height(), w = $("#"+divid).width();
184  if ((h<10) && (w>10)) $("#"+divid).height(w*0.7);
185 
186  var player = new JSROOT.TBasePainter();
187  player.url = url;
188  player.hpainter = hpainter;
189  player.itemname = itemname;
190  player.draw_ready = true;
191  player.needscroll = false;
192 
193  player.DrawReady = function() {
194  if(this.needscroll) {
195  this.ClickScroll();
196  this.needscroll = false;
197  }
198  this.draw_ready = true;
199  }
200 
201  player.ProcessTimer = function() {
202  var subid = "anaterm_output_container";
203  if ($("#" + subid).length == 0) {
204  // detect if drawing disappear
205  clearInterval(this.interval);
206  this.interval = null;
207  return;
208  }
209  if (!this.draw_ready)
210  return;
211 
212  var msgitem = this.itemname.replace("Control/Terminal", "Status/Log");
213 
214  this.draw_ready = false;
215 
216  this.hpainter.display(msgitem, "divid:" + subid, this.DrawReady.bind(this));
217  }
218 
219  player.ClickCommand = function(kind) {
220  var pthis = this;
221  this.hpainter.ExecuteCommand(this.itemname.replace("Terminal",
222  "CmdExecute"), function() {
223  pthis.needscroll = true
224  }, kind);
225  }
226 
227  player.ClickClear = function() {
228  // console.log("Clear terminal");
229  document.getElementById("anaterm_output_container").firstChild.innerHTML = "";
230  }
231 
232  player.ClickScroll = function() {
233  // inner frame created by hpainter has the scrollbars, i.e. first child
234  var disp = $("#anaterm_output_container").children(":first");
235  disp.scrollTop(disp[0].scrollHeight - disp.height());
236  }
237 
238 
239  player.fillDisplay = function(id) {
240  this.SetDivId(id);
241  this.interval = setInterval(this.ProcessTimer.bind(this), 2000);
242 
243  $(id + " .go4_clearterm")
244  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
245  .click(this.ClickClear.bind(this))
246  .children(":first") // select first button element, used for images
247  .css('background-image', "url(" + GO4.source_dir + "icons/clear.png)");
248 
249 
250  $(id + " .go4_endterm")
251  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
252  .click(this.ClickScroll.bind(this))
253  .children(":first") // select first button element, used for images
254  .css('background-image', "url(" + GO4.source_dir + "icons/shiftdown.png)");
255 
256 
257 
258  $(id + " .go4_printhistos")
259  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
260  .click(this.ClickCommand.bind(this,"@PrintHistograms()"))
261  .children(":first") // select first button element, used for images
262  .css('background-image', "url(" + GO4.source_dir + "icons/hislist.png)");
263 
264  $(id + " .go4_printcond").button()
265  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
266  .click(this.ClickCommand.bind(this,"@PrintConditions()"))
267  .children(":first") // select first button element, used for images
268  .css('background-image', "url(" + GO4.source_dir + "icons/condlist.png)");
269 
270  var pthis = this;
271 
272  $("#go4_anaterm_cmd_form").submit(
273  function(event) {
274  var command = pthis.itemname.replace("Terminal", "CmdExecute");
275  var cmdpar=document.getElementById("go4_anaterm_command").value;
276  console.log("submit command - " + cmdpar);
277  pthis.hpainter.ExecuteCommand(command, function(){pthis.needscroll=true}, cmdpar);
278  event.preventDefault();
279  });
280 
281 
282  $(id + " .go4_executescript").button()
283  .button({text: false, icons: { primary: "ui-icon-blank MyTermButtonStyle"}})
284  .children(":first") // select first button element, used for images
285  .css('background-image', "url(" + GO4.source_dir + "icons/macro_t.png)");
286  }
287 
288 
289  player.CheckResize = function(force) {
290  // console.log("CheckResize..., force=" + force);
291  }
292 
293  $("#"+divid).load(GO4.source_dir + "html/terminal.htm", "", player.fillDisplay.bind(player, divid));
294 
295  return player;
296  }
297 
298 
299  // ==============================================================================
300 
301  JSROOT.addDrawFunc("TGo4WinCond", { script: GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond' }, ";editor");
302  JSROOT.addDrawFunc("TGo4PolyCond", { script: GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond' }, ";editor");
303  JSROOT.addDrawFunc("TGo4ShapedCond", { script: GO4.source_dir + 'html/condition.js', func: 'GO4.drawGo4Cond' }, ";editor");
304 
305  JSROOT.addDrawFunc("TGo4AnalysisWebStatus", { script: GO4.source_dir + 'html/analysiseditor.js', func: 'GO4.drawGo4AnalysisStatus' }, "editor");
306 
307  JSROOT.addDrawFunc("TGo4MsgList", GO4.DrawMsgList, "");
308 
309  JSROOT.addDrawFunc({ name: "TGo4MbsEvent", noinspect: true });
310  JSROOT.addDrawFunc({ name: "TGo4EventElement", noinspect: true });
311 
312 })();
int main(int argc, char **argv)