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