5 if ( typeof define ===
"function" && define.amd ) {
6 define( [
'jquery',
'jquery-ui',
'd3',
'JSRootPainter',
'JSRootPainter.hierarchy'], factory );
9 if (typeof jQuery ==
'undefined')
10 throw new Error(
'jQuery not defined',
'JSRootPainter.jquery.js');
12 if (typeof jQuery.ui ==
'undefined')
13 throw new Error(
'jQuery-ui not defined',
'JSRootPainter.jquery.js');
15 if (typeof d3 !=
'object')
16 throw new Error(
'This extension requires d3.v3.js',
'JSRootPainter.jquery.js');
18 if (typeof JSROOT ==
'undefined')
19 throw new Error(
'JSROOT is not defined',
'JSRootPainter.jquery.js');
21 if (typeof JSROOT.Painter !=
'object')
22 throw new Error(
'JSROOT.Painter not defined',
'JSRootPainter.jquery.js');
24 factory(jQuery, jQuery.ui, d3, JSROOT);
26 } (
function($, myui, d3, JSROOT) {
30 JSROOT.sources.push(
"jq2d");
32 if ( typeof define ===
"function" && define.amd )
33 JSROOT.loadScript(
'$$$style/jquery-ui.css');
35 JSROOT.Painter.createMenu =
function(painter, maincallback) {
36 var menuname =
'root_ctx_menu';
38 if (!maincallback && typeof painter===
'function') { maincallback = painter; painter = null; }
40 var menu = { painter: painter, element: null, code:
"", cnt: 1, funcs: {}, separ:
false };
42 menu.add =
function(name, arg, func, title) {
43 if (name ==
"separator") { this.code +=
"<li>-</li>"; this.separ =
true;
return; }
45 if (name.indexOf(
"header:")==0) {
46 this.code +=
"<li class='ui-widget-header' style='padding:3px; padding-left:5px;'>"+name.substr(7)+
"</li>";
50 if (name==
"endsub:") { this.code +=
"</ul></li>";
return; }
52 var item =
"", close_tag =
"</li>";
53 title = title ?
" title='" + title +
"'" :
"";
54 if (name.indexOf(
"sub:")==0) { name = name.substr(4); close_tag =
"<ul>"; }
56 if (typeof arg ==
'function') { func = arg; arg = name; }
58 if (name.indexOf(
"chk:")==0) { item =
"<span class='ui-icon ui-icon-check' style='margin:1px'></span>"; name = name.substr(4); }
else
59 if (name.indexOf(
"unk:")==0) { item =
"<span class='ui-icon ui-icon-blank' style='margin:1px'></span>"; name = name.substr(4); }
62 if (($.ui.version.indexOf(
"1.10")==0) || ($.ui.version.indexOf(
"1.9")==0))
63 item =
'<a href="#">' + item + name +
'</a>';
64 else if ($.ui.version.indexOf(
"1.11")==0)
67 item =
"<div" + title +
">" + item + name +
"</div>";
69 this.code +=
"<li cnt='" + this.cnt + ((arg !== undefined) ?
"' arg='" + arg :
"") +
"'>" + item + close_tag;
70 if (typeof func ==
'function') this.funcs[this.cnt] = func;
75 menu.addchk =
function(flag, name, arg, func) {
76 return this.add((flag ?
"chk:" :
"unk:") + name, arg, func);
79 menu.size =
function() {
return this.cnt-1; }
81 menu.addDrawMenu =
function(menu_name, opts, call_back) {
83 if (opts.length==0) opts.push(
"");
85 var without_sub =
false;
86 if (menu_name.indexOf(
"nosub:")==0) {
88 menu_name = menu_name.substr(6);
91 if (opts.length === 1) {
92 if (opts[0]===
'inspect') menu_name = menu_name.replace(
"Draw",
"Inspect");
93 return this.add(menu_name, opts[0], call_back);
96 if (!without_sub) this.add(
"sub:" + menu_name, opts[0], call_back);
98 for (var i=0;i<opts.length;++i) {
100 if (name==
"") name =
'<dflt>';
103 if ((opts.length>5) && (name.length>0)) {
105 while ((group<opts.length) && (opts[group].indexOf(name)==0)) group++;
108 if (without_sub) name = menu_name +
" " + name;
111 this.add(name, opts[i], call_back);
113 this.add(
"sub:" + name, opts[i], call_back);
114 for (var k=i+1;k<group;++k)
115 this.add(opts[k], opts[k], call_back);
120 if (!without_sub) this.add(
"endsub:");
123 menu.remove =
function() {
124 if (this.element!==null) {
125 this.element.remove();
126 if (this.close_callback) this.close_callback();
127 document.body.removeEventListener(
'click', this.remove_bind);
132 menu.remove_bind = menu.remove.bind(menu);
134 menu.show =
function(event, close_callback) {
137 if (typeof close_callback ==
'function') this.close_callback = close_callback;
139 document.body.addEventListener(
'click', this.remove_bind);
141 var oldmenu = document.getElementById(menuname);
142 if (oldmenu) oldmenu.parentNode.removeChild(oldmenu);
144 $(document.body).append(
'<ul class="jsroot_ctxmenu">' + this.code +
'</ul>');
146 this.element = $(
'.jsroot_ctxmenu');
151 .attr(
'id', menuname)
152 .css(
'left', event.clientX + window.pageXOffset)
153 .css(
'top', event.clientY + window.pageYOffset)
155 .css(
'position',
'absolute')
157 items:
"> :not(.ui-widget-header)",
158 select:
function( event, ui ) {
159 var arg = ui.item.attr(
'arg'),
160 cnt = ui.item.attr(
'cnt'),
161 func = cnt ? pthis.funcs[cnt] : null;
163 if (typeof func ==
'function') {
164 if (
'painter' in menu)
165 func.bind(pthis.painter)(arg);
172 var newx = null, newy = null;
174 if (event.clientX +
this.element.width() > $(window).width()) newx = $(window).width() - this.element.width() - 20;
175 if (event.clientY +
this.element.height() > $(window).height()) newy = $(window).height() - this.element.height() - 20;
177 if (newx!==null) this.element.css(
'left', (newx>0 ? newx : 0) + window.pageXOffset);
178 if (newy!==null) this.element.css(
'top', (newy>0 ? newy : 0) + window.pageYOffset);
181 JSROOT.CallBack(maincallback, menu);
188 var BrowserLayout = JSROOT.BrowserLayout;
192 BrowserLayout.prototype.SetBrowserTitle =
function(title) {
193 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser");
195 main.select(
".jsroot_browser_title").text(title);
198 BrowserLayout.prototype.ToggleBrowserKind =
function(kind) {
200 if (!this.gui_div)
return;
203 if (!this.browser_kind)
return;
204 kind = (this.browser_kind ===
"float") ?
"fix" :
"float";
207 var main = d3.select(
"#"+this.gui_div+
" .jsroot_browser"),
208 jmain = $(main.node()),
209 area = jmain.find(
".jsroot_browser_area"),
212 if (this.browser_kind ===
"float") {
213 area.css(
'bottom',
'0px')
215 .css(
'width',
'').css(
'height',
'')
216 .toggleClass(
'jsroot_float_browser',
false)
217 .resizable(
"destroy")
218 .draggable(
"destroy");
219 }
else if (this.browser_kind ===
"fix") {
220 main.select(
".jsroot_v_separator").remove();
221 area.css(
'left',
'0px');
222 d3.select(
"#"+this.gui_div+
"_drawing").style(
'left',
'0px');
223 main.select(
".jsroot_h_separator").style(
'left',
'0px');
224 d3.select(
"#"+this.gui_div+
"_status").style(
'left',
'0px');
228 this.browser_kind = kind;
229 this.browser_visible =
true;
231 if (kind===
"float") {
232 area.css(
'bottom',
'40px')
233 .toggleClass(
'jsroot_float_browser',
true)
235 containment:
"parent",
237 resize:
function( event, ui ) {
238 pthis.SetButtonsPosition();
240 stop:
function( event, ui ) {
241 var bottom = $(
this).parent().innerHeight() - ui.position.top - ui.size.height;
242 if (bottom<7) $(
this).css(
'height',
"").css(
'bottom', 0);
246 containment:
"parent",
247 handle : $(
"#"+this.gui_div).find(
".jsroot_browser_title"),
251 drag:
function( event, ui ) {
252 pthis.SetButtonsPosition();
254 stop:
function( event, ui ) {
255 var bottom = $(
this).parent().innerHeight() - $(
this).offset().top - $(
this).outerHeight();
256 if (bottom<7) $(
this).css(
'height',
"").css(
'bottom', 0);
259 this.AdjustBrowserSize();
263 area.css(
'left',0).css(
'top',0).css(
'bottom',0).css(
'height',
'');
267 .classed(
"jsroot_separator",
true).classed(
'jsroot_v_separator',
true)
268 .style(
'position',
'absolute').style(
'top',0).style(
'bottom',0);
270 $(vsepar.node()).draggable({
271 axis:
"x" , cursor:
"ew-resize",
272 containment:
"parent",
273 helper :
function() {
return $(
this).clone().css(
'background-color',
'grey'); },
274 drag:
function(event,ui) {
275 pthis.SetButtonsPosition();
276 pthis.AdjustSeparator(ui.position.left, null);
278 stop:
function(event,ui) {
283 this.AdjustSeparator(250, null,
true,
true);
286 this.SetButtonsPosition();
289 BrowserLayout.prototype.SetButtonsPosition =
function() {
290 if (!this.gui_div)
return;
292 var jmain = $(
"#"+this.gui_div+
" .jsroot_browser"),
293 btns = jmain.find(
".jsroot_browser_btns"),
296 if (!btns.length)
return;
298 if (this.browser_visible) {
299 var area = jmain.find(
".jsroot_browser_area"),
300 off0 = jmain.offset(), off1 = area.offset();
301 top = off1.top - off0.top + 7;
302 left = off1.left - off0.left + area.innerWidth() - 27;
305 btns.css(
'left', left+
'px').css(
'top', top+
'px');
308 BrowserLayout.prototype.AdjustBrowserSize =
function(onlycheckmax) {
309 if (!this.gui_div || (this.browser_kind !==
"float"))
return;
311 var jmain = $(
"#" + this.gui_div +
" .jsroot_browser");
312 if (!jmain.length)
return;
314 var area = jmain.find(
".jsroot_browser_area"),
315 cont = jmain.find(
".jsroot_browser_hierarchy"),
316 chld = cont.children(
":first");
319 if (area.parent().innerHeight() - 10 < area.innerHeight())
320 area.css(
'bottom',
'0px').css(
'top',
'0px');
324 if (!chld.length)
return;
326 var h1 = cont.innerHeight(),
327 h2 = chld.innerHeight();
329 if ((h2!==undefined) && (h2<h1*0.7)) area.css(
'bottom',
'');
332 BrowserLayout.prototype.ToggleBrowserVisisbility =
function(fast_close) {
333 if (!this.gui_div || (typeof this.browser_visible===
'string'))
return;
335 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser"),
336 area = main.select(
'.jsroot_browser_area');
338 if (area.empty())
return;
340 var vsepar = main.select(
".jsroot_v_separator"),
341 drawing = d3.select(
"#" + this.gui_div +
"_drawing"),
342 tgt = area.property(
'last_left'),
343 tgt_separ = area.property(
'last_vsepar'),
344 tgt_drawing = area.property(
'last_drawing');
346 if (!this.browser_visible) {
347 if (fast_close)
return;
348 area.property(
'last_left', null).property(
'last_vsepar',null).property(
'last_drawing', null);
350 area.property(
'last_left', area.style(
'left'));
351 if (!vsepar.empty()) {
352 area.property(
'last_vsepar', vsepar.style(
'left'));
353 area.property(
'last_drawing', drawing.style(
'left'));
355 tgt = (-$(area.node()).outerWidth(
true)-10).toString() +
"px";
356 var mainw = $(main.node()).outerWidth(
true);
358 if (vsepar.empty() && ($(area.node()).offset().left > mainw/2)) tgt = (mainw+10) +
"px";
364 var pthis =
this, visible_at_the_end = !this.browser_visible, _duration = fast_close ? 0 : 700;
366 this.browser_visible =
'changing';
368 area.transition().style(
'left', tgt).duration(_duration).on(
"end",
function() {
369 if (fast_close)
return;
370 pthis.browser_visible = visible_at_the_end;
371 if (visible_at_the_end) pthis.SetButtonsPosition();
374 if (!visible_at_the_end)
375 main.select(
".jsroot_browser_btns").transition().style(
'left',
'7px').style(
'top',
'7px').duration(_duration);
377 if (!vsepar.empty()) {
378 vsepar.transition().style(
'left', tgt_separ).duration(_duration);
379 drawing.transition().style(
'left', tgt_drawing).duration(_duration).on(
"end", this.CheckResize.bind(
this));
382 if (this.status_layout && (this.browser_kind ==
'fix')) {
383 main.select(
".jsroot_h_separator").transition().style(
'left', tgt_drawing).duration(_duration);
384 main.select(
".jsroot_status_area").transition().style(
'left', tgt_drawing).duration(_duration);
389 BrowserLayout.prototype.Toggle =
function(browser_kind) {
390 if (this.browser_visible!==
'changing') {
391 if (browser_kind === this.browser_kind) this.ToggleBrowserVisisbility();
392 else this.ToggleBrowserKind(browser_kind);
396 BrowserLayout.prototype.DeleteContent =
function() {
397 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser");
398 if (main.empty())
return;
400 this.CreateStatusLine(
"delete");
401 var vsepar = main.select(
".jsroot_v_separator");
403 $(vsepar.node()).draggable(
'destroy');
405 this.ToggleBrowserVisisbility(
true);
407 main.selectAll(
"*").remove();
408 delete this.browser_visible;
409 delete this.browser_kind;
415 BrowserLayout.prototype.CreateStatusLine =
function(height, mode) {
416 var main = d3.select(
"#"+this.gui_div+
" .jsroot_browser");
417 if (main.empty())
return '';
419 var
id = this.gui_div +
"_status",
420 line = d3.select(
"#"+
id), skip_height_check =
false,
421 is_visible = !line.empty();
423 if (mode===
"toggle") { mode = !is_visible; skip_height_check = (height === this.last_hsepar_height); }
else
424 if (height===
"delete") { mode =
false; height = 0;
delete this.status_layout; }
else
425 if (mode===undefined) { mode =
true; this.status_layout =
"app"; }
428 if ((mode ===
true) || (this.status_layout===
"app"))
return id;
430 var hsepar = main.select(
".jsroot_h_separator");
432 $(hsepar.node()).draggable(
"destroy");
437 delete this.status_layout;
439 if (this.status_handler && (JSROOT.Painter.ShowStatus ===
this.status_handler)) {
440 delete JSROOT.Painter.ShowStatus;
441 delete this.status_handler;
444 this.AdjustSeparator(null, 0,
true);
448 if (mode ===
false)
return "";
450 var left_pos = d3.select(
"#" + this.gui_div +
"_drawing").style(
'left');
452 line = main.insert(
"div",
".jsroot_browser_area").attr(
"id",
id)
453 .classed(
"jsroot_status_area",
true)
454 .style(
'position',
"absolute").style(
'left',left_pos).style(
'height',
"20px").style(
'bottom',0).style(
'right',0)
455 .style(
'margin',0).style(
'border',0);
457 var hsepar = main.insert(
"div",
".jsroot_browser_area")
458 .classed(
"jsroot_separator",
true).classed(
"jsroot_h_separator",
true)
459 .style(
'position',
'absolute').style(
'left',left_pos).style(
'right',0).style(
'bottom',
'20px').style(
'height',
'5px');
463 $(hsepar.node()).draggable({
464 axis:
"y" , cursor:
"ns-resize", containment:
"parent",
465 helper:
function() {
return $(
this).clone().css(
'background-color',
'grey'); },
466 drag:
function(event,ui) {
467 pthis.AdjustSeparator(null, -ui.position.top);
469 stop:
function(event,ui) {
474 if (!height || (typeof height ===
'string')) height = this.last_hsepar_height || 20;
476 this.AdjustSeparator(null, height,
true);
478 if (this.status_layout ==
"app")
return id;
480 this.status_layout =
new JSROOT.GridDisplay(
id,
'horizx4_1213');
482 var frame_titles = [
'object name',
'object title',
'mouse coordinates',
'object info'];
483 for (var k=0;k<4;++k)
484 d3.select(
this.status_layout.GetFrame(k)).attr(
'title', frame_titles[k]).style(
'overflow',
'hidden')
485 .append(
"label").attr(
"class",
"jsroot_status_label");
487 this.status_handler = this.ShowStatus.bind(
this);
489 JSROOT.Painter.ShowStatus = this.status_handler;
494 BrowserLayout.prototype.AdjustSeparator =
function(vsepar, hsepar, redraw, first_time) {
496 if (!this.gui_div)
return;
498 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser"), w = 5;
500 if ((hsepar===null) && first_time && !main.select(
".jsroot_h_separator").empty()) {
502 hsepar = main.select(
".jsroot_h_separator").style(
'bottom');
503 if ((typeof hsepar==
'string') && (hsepar.indexOf(
'px')==hsepar.length-2))
504 hsepar = hsepar.substr(0,hsepar.length-2);
510 hsepar = parseInt(hsepar);
511 var elem = main.select(
".jsroot_h_separator"), hlimit = 0;
514 if (hsepar<0) hsepar += ($(main.node()).outerHeight(
true) - w);
515 if (hsepar<5) hsepar = 5;
516 this.last_hsepar_height = hsepar;
517 elem.style(
'bottom', hsepar+
'px').style(
'height', w+
'px');
518 d3.select(
"#" + this.gui_div +
"_status").style(
'height', hsepar+
'px');
519 hlimit = (hsepar+w) +
'px';
522 d3.select(
"#" + this.gui_div +
"_drawing").style(
'bottom',hlimit);
526 vsepar = parseInt(vsepar);
527 if (vsepar<50) vsepar = 50;
528 main.select(
".jsroot_browser_area").style(
'width',(vsepar-5)+
'px');
529 d3.select(
"#" + this.gui_div +
"_drawing").style(
'left',(vsepar+w)+
'px');
530 main.select(
".jsroot_h_separator").style(
'left', (vsepar+w)+
'px');
531 d3.select(
"#" + this.gui_div +
"_status").style(
'left',(vsepar+w)+
'px');
532 main.select(
".jsroot_v_separator").style(
'left',vsepar+
'px').style(
'width',w+
"px");
535 if (redraw) this.CheckResize();
538 BrowserLayout.prototype.ShowStatus =
function(name, title, info, coordinates) {
539 if (!this.status_layout)
return;
541 $(this.status_layout.GetFrame(0)).children(
'label').text(name ||
"");
542 $(this.status_layout.GetFrame(1)).children(
'label').text(title ||
"");
543 $(this.status_layout.GetFrame(2)).children(
'label').text(coordinates ||
"");
544 $(this.status_layout.GetFrame(3)).children(
'label').text(info ||
"");
546 if (!this.status_layout.first_check) {
547 this.status_layout.first_check =
true;
549 for (var n=0;n<4;++n)
550 maxh = Math.max(maxh, $(
this.status_layout.GetFrame(n)).children(
'label').outerHeight());
551 if ((maxh>5) && ((maxh>this.last_hsepar_height) || (maxh<this.last_hsepar_height+5)))
552 this.AdjustSeparator(null, maxh,
true);
558 var HierarchyPainter = JSROOT.HierarchyPainter;
560 HierarchyPainter.prototype.isLastSibling =
function(hitem) {
561 if (!hitem || !hitem._parent || !hitem._parent._childs)
return false;
562 var chlds = hitem._parent._childs, indx = chlds.indexOf(hitem);
563 if (indx<0)
return false;
564 while (++indx < chlds.length)
565 if (!(
'_hidden' in chlds[indx]))
return false;
569 HierarchyPainter.prototype.addItemHtml =
function(hitem, d3prnt, arg) {
571 if (!hitem || (
'_hidden' in hitem))
return true;
573 var isroot = (hitem === this.h),
574 has_childs = (
'_childs' in hitem),
575 handle = JSROOT.getDrawHandle(hitem._kind),
576 img1 =
"", img2 =
"", can_click =
false, break_list =
false,
577 d3cont, itemname = this.itemFullName(hitem);
579 if (handle !== null) {
580 if (
'icon' in handle) img1 = handle.icon;
581 if (
'icon2' in handle) img2 = handle.icon2;
582 if ((img1.length==0) && (typeof handle.icon_get ==
'function'))
583 img1 = handle.icon_get(hitem,
this);
584 if ((
'func' in handle) || (
'execute' in handle) || (
'aslink' in handle) ||
585 ((
'expand' in handle) && (hitem._more !==
false))) can_click =
true;
588 if (
'_icon' in hitem) img1 = hitem._icon;
589 if (
'_icon2' in hitem) img2 = hitem._icon2;
590 if ((img1.length==0) && (
'_online' in hitem))
591 hitem._icon = img1 =
"img_globe";
592 if ((img1.length==0) && isroot)
593 hitem._icon = img1 =
"img_base";
595 if (hitem._more || (
'_expand' in hitem) || (
'_player' in hitem))
598 var can_menu = can_click;
599 if (!can_menu && (typeof hitem._kind ==
'string') && (hitem._kind.indexOf(
"ROOT.")==0))
600 can_menu = can_click =
true;
602 if (img2.length==0) img2 = img1;
603 if (img1.length==0) img1 = (has_childs || hitem._more) ?
"img_folder" :
"img_page";
604 if (img2.length==0) img2 = (has_childs || hitem._more) ?
"img_folderopen" :
"img_page";
606 if (arg ===
"update") {
607 d3prnt.selectAll(
"*").remove();
610 d3cont = d3prnt.append(
"div");
611 if (arg && (arg >= (hitem._parent._show_limit || JSROOT.gStyle.HierarchyLimit))) break_list =
true;
614 hitem._d3cont = d3cont.node();
615 d3cont.attr(
"item", itemname);
618 var d3line = d3cont.append(
"div").attr(
'class',
'h_line');
621 var prnt = isroot ? null : hitem._parent;
622 while (prnt && (prnt !== this.h)) {
623 d3line.insert(
"div",
":first-child")
624 .attr(
"class", this.isLastSibling(prnt) ?
"img_empty" :
"img_line");
628 var icon_class =
"", plusminus =
false;
633 if (has_childs && !break_list) {
634 icon_class = hitem._isopen ?
"img_minus" :
"img_plus";
641 icon_class =
"img_join";
646 if (icon_class.length > 0) {
647 if (break_list || this.isLastSibling(hitem)) icon_class +=
"bottom";
648 var d3icon = d3line.append(
"div").attr(
'class', icon_class);
649 if (plusminus) d3icon.style(
'cursor',
'pointer')
650 .on(
"click",
function() { h.tree_click(
this,
"plusminus"); });
655 if (this.with_icons && !break_list) {
656 var icon_name = hitem._isopen ? img2 : img1;
660 if (icon_name.indexOf(
"img_")==0)
661 d3img = d3line.append(
"div")
662 .attr(
"class", icon_name)
663 .attr(
"title", hitem._kind);
665 d3img = d3line.append(
"img")
666 .attr(
"src", icon_name)
668 .attr(
"title", hitem._kind)
669 .style(
'vertical-align',
'top').style(
'width',
'18px').style(
'height',
'18px');
671 if ((
'_icon_click' in hitem) || (handle && (
'icon_click' in handle)))
672 d3img.on(
"click",
function() { h.tree_click(
this,
"icon"); });
675 var d3a = d3line.append(
"a");
676 if (can_click || has_childs || break_list)
677 d3a.attr(
"class",
"h_item")
678 .on(
"click",
function() { h.tree_click(
this); });
681 hitem._break_point =
true;
682 d3a.attr(
'title',
'there are ' + (hitem._parent._childs.length-arg) +
' more items')
687 if (
'disp_kind' in h) {
688 if (JSROOT.gStyle.DragAndDrop && can_click)
689 this.enable_dragging(d3a.node(), itemname);
690 if (JSROOT.gStyle.ContextMenu && can_menu)
691 d3a.on(
'contextmenu',
function() { h.tree_contextmenu(
this); });
693 d3a.on(
"mouseover",
function() { h.tree_mouseover(
true,
this); })
694 .on(
"mouseleave",
function() { h.tree_mouseover(
false,
this); });
696 if (hitem._direct_context && JSROOT.gStyle.ContextMenu)
697 d3a.on(
'contextmenu',
function() { h.direct_contextmenu(
this); });
699 var element_name = hitem._name, element_title =
"";
701 if (
'_realname' in hitem)
702 element_name = hitem._realname;
704 if (
'_title' in hitem)
705 element_title = hitem._title;
707 if (
'_fullname' in hitem)
708 element_title +=
" fullname: " + hitem._fullname;
711 element_title = element_name;
713 d3a.attr(
'title', element_title)
714 .text(element_name + (
'_value' in hitem ?
":" :
""))
715 .style(
'background', hitem._background ? hitem._background : null);
717 if (
'_value' in hitem) {
718 var d3p = d3line.append(
"p");
719 if (
'_vclass' in hitem) d3p.attr(
'class', hitem._vclass);
720 if (!hitem._isopen) d3p.html(hitem._value);
723 if (has_childs && (isroot || hitem._isopen)) {
724 var d3chlds = d3cont.append(
"div").attr(
"class",
"h_childs");
725 for (var i=0; i< hitem._childs.length; ++i) {
726 var chld = hitem._childs[i];
727 chld._parent = hitem;
728 if (!this.addItemHtml(chld, d3chlds, i))
break;
735 HierarchyPainter.prototype.toggleOpenState =
function(isopen, h) {
736 var hitem = h ? h : this.h;
738 if (!(
'_childs' in hitem)) {
739 if (!isopen || this.with_icons || (!hitem._expand && (hitem._more !==
true)))
return false;
740 this.expand(this.itemFullName(hitem));
741 if (hitem._childs) hitem._isopen =
true;
745 if ((hitem != this.h) && isopen && !hitem._isopen) {
747 hitem._isopen =
true;
751 var change_child =
false;
752 for (var i=0; i < hitem._childs.length; ++i)
753 if (this.toggleOpenState(isopen, hitem._childs[i])) change_child =
true;
755 if ((hitem != this.h) && !isopen && hitem._isopen && !change_child) {
757 delete hitem._isopen;
761 if (!h) this.RefreshHtml();
766 HierarchyPainter.prototype.RefreshHtml =
function(callback) {
768 if (!this.divid)
return JSROOT.CallBack(callback);
770 var d3elem = this.select_main();
773 .style(
'overflow',
'hidden')
774 .style(
'display',
'flex')
775 .style(
'flex-direction',
'column');
777 var h =
this, factcmds = [], status_item = null;
778 this.ForEach(
function(item) {
780 if ((
'_fastcmd' in item) && (item._kind ==
'Command')) factcmds.push(item);
781 if ((
'_status' in item) && !status_item) status_item = item;
784 if (!this.h || d3elem.empty())
785 return JSROOT.CallBack(callback);
787 if (factcmds.length) {
788 var fastbtns = d3elem.append(
"div").attr(
"class",
"jsroot");
789 for (var n=0;n<factcmds.length;++n) {
790 var btn = fastbtns.append(
"button")
792 .attr(
"class",
'fast_command')
793 .attr(
"item", this.itemFullName(factcmds[n]))
794 .attr(
"title", factcmds[n]._title)
795 .on(
"click",
function() { h.ExecuteCommand(d3.select(
this).attr(
"item"),
this); } );
797 if (
'_icon' in factcmds[n])
798 btn.append(
'img').attr(
"src", factcmds[n]._icon);
802 var d3btns = d3elem.append(
"p").attr(
"class",
"jsroot").style(
"margin-bottom",
"3px").style(
"margin-top",0);
803 d3btns.append(
"a").attr(
"class",
"h_button").text(
"open all")
804 .attr(
"title",
"open all items in the browser").on(
"click", h.toggleOpenState.bind(h,
true));
805 d3btns.append(
"text").text(
" | ");
806 d3btns.append(
"a").attr(
"class",
"h_button").text(
"close all")
807 .attr(
"title",
"close all items in the browser").on(
"click", h.toggleOpenState.bind(h,
false));
809 if (typeof h.removeInspector ==
'function') {
810 d3btns.append(
"text").text(
" | ");
811 d3btns.append(
"a").attr(
"class",
"h_button").text(
"remove")
812 .attr(
"title",
"remove inspector").on(
"click", h.removeInspector.bind(h));
815 if (
'_online' in this.h) {
816 d3btns.append(
"text").text(
" | ");
817 d3btns.append(
"a").attr(
"class",
"h_button").text(
"reload")
818 .attr(
"title",
"reload object list from the server").on(
"click", h.reload.bind(h));
821 if (
'disp_kind' in
this) {
822 d3btns.append(
"text").text(
" | ");
823 d3btns.append(
"a").attr(
"class",
"h_button").text(
"clear")
824 .attr(
"title",
"clear all drawn objects").on(
"click", h.clear.bind(h,
false));
829 .attr(
"class",
"jsroot")
830 .style(
'font-size', this.with_icons ?
"12px" :
"15px")
831 .style(
"overflow",
"auto")
835 maindiv.style(
"background-color", this.background)
836 .style(
'margin',
'2px').style(
'padding',
'2px');
838 this.addItemHtml(this.h, maindiv.append(
"div").attr(
"class",
"h_tree"));
840 if (status_item && !this.status_disabled && (JSROOT.GetUrlOption(
'nostatus')===null)) {
841 var func = JSROOT.findFunction(status_item._status);
842 var hdiv = (typeof func ==
'function') ? this.CreateStatusLine() : null;
843 if (hdiv) func(hdiv, this.itemFullName(status_item));
846 JSROOT.CallBack(callback);
849 HierarchyPainter.prototype.UpdateTreeNode =
function(hitem, d3cont) {
850 if ((d3cont===undefined) || d3cont.empty()) {
851 d3cont = d3.select(hitem._d3cont ? hitem._d3cont : null);
852 var name = this.itemFullName(hitem);
854 d3cont = this.select_main().select(
"[item='" + name +
"']");
855 if (d3cont.empty() && (
'_cycle' in hitem))
856 d3cont = this.select_main().select(
"[item='" + name +
";" + hitem._cycle +
"']");
857 if (d3cont.empty())
return;
860 this.addItemHtml(hitem, d3cont,
"update");
862 if (this.brlayout) this.brlayout.AdjustBrowserSize(
true);
865 HierarchyPainter.prototype.UpdateBackground =
function(hitem, scroll_into_view) {
867 if (!hitem || !hitem._d3cont)
return;
869 var d3cont = d3.select(hitem._d3cont);
871 if (d3cont.empty())
return;
873 var d3a = d3cont.select(
".h_item");
875 d3a.style(
'background', hitem._background ? hitem._background : null);
877 if (scroll_into_view && hitem._background)
878 d3a.node().scrollIntoView(
false);
882 HierarchyPainter.prototype.tree_click =
function(node, place) {
885 var d3cont = d3.select(node.parentNode.parentNode),
886 itemname = d3cont.attr(
'item'),
887 hitem = itemname ? this.Find(itemname) : null;
890 if (hitem._break_point) {
893 delete hitem._break_point;
896 this.addItemHtml(hitem, d3cont,
"update");
898 var prnt = hitem._parent, indx = prnt._childs.indexOf(hitem),
899 d3chlds = d3.select(d3cont.node().parentNode);
901 if (indx<0)
return console.error(
'internal error');
903 prnt._show_limit = (prnt._show_limit || JSROOT.gStyle.HierarchyLimit) * 2;
905 for (var n=indx+1;n<prnt._childs.length;++n) {
906 var chld = prnt._childs[n];
908 if (!this.addItemHtml(chld, d3chlds, n))
break;
914 var prnt = hitem, dflt = undefined;
916 if ((dflt = prnt._click_action) !== undefined)
break;
920 if (!place || (place==
"")) place =
"item";
922 var sett = JSROOT.getDrawSettings(hitem._kind), handle = sett.handle;
924 if (place ==
"icon") {
926 if (typeof hitem._icon_click ==
'function') func = hitem._icon_click;
else
927 if (handle && typeof handle.icon_click ==
'function') func = handle.icon_click;
928 if (func && func(hitem,
this))
929 this.UpdateTreeNode(hitem, d3cont);
934 if ((place==
"item") && (
'_expand' in hitem) && !d3.event.ctrlKey && !d3.event.shiftKey) place =
"plusminus";
937 if (((place ==
"plusminus") && !(
'_childs' in hitem) && hitem._more) ||
938 ((place ==
"item") && (dflt ===
"expand"))) {
939 return this.expand(itemname, null, d3cont);
942 if (place ==
"item") {
944 if (
'_player' in hitem)
945 return this.player(itemname);
947 if (handle && handle.aslink)
948 return window.open(itemname +
"/");
950 if (handle && handle.execute)
951 return this.ExecuteCommand(itemname, node.parentNode);
953 if (handle && handle.ignore_online &&
this.isOnlineItem(hitem))
return;
955 var can_draw = hitem._can_draw,
956 can_expand = hitem._more,
957 dflt_expand = (this.default_by_click ===
"expand"),
960 if (d3.event.shiftKey) {
961 drawopt = (handle && handle.shift) ? handle.shift :
"inspect";
962 if ((drawopt===
"inspect") && handle && handle.noinspect) drawopt =
"";
964 if (handle && handle.ctrl && d3.event.ctrlKey) drawopt = handle.ctrl;
967 for (var pitem = hitem._parent; !!pitem; pitem = pitem._parent) {
968 if (pitem._painter) { can_draw =
false;
if (can_expand===undefined) can_expand =
false;
break; }
972 if (hitem._childs) can_expand =
false;
974 if (can_draw === undefined) can_draw = sett.draw;
975 if (can_expand === undefined) can_expand = sett.expand;
977 if (can_draw && can_expand && !drawopt) {
979 if (dflt_expand || (handle && (handle.dflt ===
'expand'))) can_draw =
false;
else
980 if (this.isItemDisplayed(itemname)) can_draw =
false;
984 return this.display(itemname, drawopt);
986 if (can_expand || dflt_expand)
987 return this.expand(itemname, null, d3cont);
990 if ((typeof hitem._kind ===
"string") && (hitem._kind.indexOf(
"ROOT.")===0) && sett.inspect && (can_draw!==
false))
991 return this.display(itemname,
"inspect");
993 if (!hitem._childs || (hitem ===
this.h))
return;
997 delete hitem._isopen;
999 hitem._isopen =
true;
1001 this.UpdateTreeNode(hitem, d3cont);
1004 HierarchyPainter.prototype.tree_mouseover =
function(on, elem) {
1005 var itemname = d3.select(elem.parentNode.parentNode).attr(
'item');
1007 var hitem = this.Find(itemname);
1010 var painter, prnt = hitem;
1011 while (prnt && !painter) {
1012 painter = prnt._painter;
1013 prnt = prnt._parent;
1016 if (painter && typeof painter.MouseOverHierarchy ===
'function')
1017 painter.MouseOverHierarchy(on, itemname, hitem);
1020 HierarchyPainter.prototype.direct_contextmenu =
function(elem) {
1023 d3.event.preventDefault();
1024 var itemname = d3.select(elem.parentNode.parentNode).attr(
'item');
1025 var hitem = this.Find(itemname);
1028 if (typeof this.fill_context !==
'function')
return;
1030 JSROOT.Painter.createMenu(
this,
function(menu) {
1032 menu.painter.fill_context(menu, hitem);
1034 if (menu.size() > 0) {
1035 menu.tree_node = elem.parentNode;
1036 menu.show(d3.event);
1041 HierarchyPainter.prototype.tree_contextmenu =
function(elem) {
1044 d3.event.preventDefault();
1046 var itemname = d3.select(elem.parentNode.parentNode).attr(
'item');
1048 var hitem = this.Find(itemname);
1052 onlineprop = painter.GetOnlineProp(itemname),
1053 fileprop = painter.GetFileProp(itemname);
1055 function qualifyURL(url) {
1056 function escapeHTML(s) {
1057 return s.split(
'&').join(
'&').split(
'<').join(
'<').split(
'"').join(
'"');
1059 var el = document.createElement(
'div');
1060 el.innerHTML =
'<a href="' + escapeHTML(url) +
'">x</a>';
1061 return el.firstChild.href;
1064 JSROOT.Painter.createMenu(painter,
function(menu) {
1066 if ((itemname ==
"") && !(
'_jsonfile' in hitem)) {
1067 var addr =
"", cnt = 0;
1068 function separ() {
return cnt++ > 0 ?
"&" :
"?"; }
1071 painter.ForEachRootFile(
function(item) { files.push(item._file.fFullURL); });
1073 if (!painter.GetTopOnlineItem())
1074 addr = JSROOT.source_dir +
"index.htm";
1076 if (painter.IsMonitoring())
1077 addr += separ() +
"monitoring=" + painter.MonitoringInterval();
1079 if (files.length==1)
1080 addr += separ() +
"file=" + files[0];
1083 addr += separ() +
"files=" + JSON.stringify(files);
1085 if (painter[
'disp_kind'])
1086 addr += separ() +
"layout=" + painter.disp_kind.replace(/ /g,
"");
1091 painter.disp.ForEachPainter(
function(p) {
1092 if (p.GetItemName()!=null)
1093 items.push(p.GetItemName());
1096 if (items.length == 1) {
1097 addr += separ() +
"item=" + items[0];
1098 }
else if (items.length > 1) {
1099 addr += separ() +
"items=" + JSON.stringify(items);
1102 menu.add(
"Direct link",
function() { window.open(addr); });
1103 menu.add(
"Only items",
function() { window.open(addr +
"&nobrowser"); });
1104 }
else if (onlineprop) {
1105 painter.FillOnlineMenu(menu, onlineprop, itemname);
1107 var sett = JSROOT.getDrawSettings(hitem._kind,
'nosame');
1110 if (hitem._can_draw) {
1111 if (!sett.opts) sett.opts = [
""];
1112 if (sett.opts.indexOf(
"")<0) sett.opts.unshift(
"");
1116 menu.addDrawMenu(
"Draw", sett.opts,
function(arg) {
this.display(itemname, arg); });
1118 if (fileprop && sett.opts && !fileprop.localfile) {
1119 var filepath = qualifyURL(fileprop.fileurl);
1120 if (filepath.indexOf(JSROOT.source_dir) == 0)
1121 filepath = filepath.slice(JSROOT.source_dir.length);
1122 filepath = fileprop.kind +
"=" + filepath;
1123 if (fileprop.itemname.length > 0) {
1124 var name = fileprop.itemname;
1125 if (name.search(/\+| |\,/)>=0) name =
"\'" + name +
"\'";
1126 filepath +=
"&item=" + name;
1129 menu.addDrawMenu(
"Draw in new tab", sett.opts,
function(arg) {
1130 window.open(JSROOT.source_dir +
"index.htm?nobrowser&"+filepath +
"&opt="+arg);
1134 if (sett.expand && !(
'_childs' in hitem) && (hitem._more || !(
'_more' in hitem)))
1135 menu.add(
"Expand",
function() { painter.expand(itemname); });
1137 if (hitem._kind ===
"ROOT.TStyle")
1138 menu.add(
"Apply",
function() { painter.ApplyStyle(itemname); });
1141 if (typeof hitem._menu ==
'function')
1142 hitem._menu(menu, hitem, painter);
1144 if (menu.size() > 0) {
1145 menu.tree_node = elem.parentNode;
1146 if (menu.separ) menu.add(
"separator");
1148 menu.show(d3.event);
1161 HierarchyPainter.prototype.CreateDisplay =
function(callback) {
1163 if (
'disp' in
this) {
1164 if (this.disp.NumDraw() > 0)
return JSROOT.CallBack(callback,
this.disp);
1170 if (document.getElementById(
this.disp_frameid) == null)
1171 return JSROOT.CallBack(callback, null);
1173 if (this.disp_kind ==
"tabs")
1174 this.disp =
new TabsDisplay(this.disp_frameid);
1176 if (this.disp_kind.indexOf(
"flex")==0)
1177 this.disp =
new FlexibleDisplay(this.disp_frameid);
1179 if (this.disp_kind.indexOf(
"coll")==0)
1180 this.disp =
new CollapsibleDisplay(this.disp_frameid);
1182 this.disp =
new JSROOT.GridDisplay(this.disp_frameid, this.disp_kind);
1185 this.disp.CleanupFrame = this.CleanupFrame.bind(
this);
1187 JSROOT.CallBack(callback, this.disp);
1190 HierarchyPainter.prototype.enable_dragging =
function(element, itemname) {
1191 $(element).draggable({ revert:
"invalid", appendTo:
"body", helper:
"clone" });
1194 HierarchyPainter.prototype.enable_dropping =
function(frame, itemname) {
1196 $(frame).droppable({
1197 hoverClass :
"ui-state-active",
1198 accept:
function(ui) {
1199 var dropname = ui.parent().parent().attr(
'item');
1200 if ((dropname == itemname) || !dropname)
return false;
1202 var ditem = h.Find(dropname);
1203 if (!ditem || (!(
'_kind' in ditem)))
return false;
1205 return ditem._kind.indexOf(
"ROOT.")==0;
1207 drop:
function(event, ui) {
1208 var dropname = ui.draggable.parent().parent().attr(
'item');
1209 if (!dropname)
return false;
1210 return h.dropitem(dropname, $(
this).attr(
"id"));
1215 HierarchyPainter.prototype.CreateBrowser =
function(browser_kind, update_html, call_back) {
1217 if (!this.gui_div || this.exclude_browser || !this.brlayout)
return false;
1219 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser"),
1220 jmain = $(main.node());
1223 if (main.empty())
return false;
1225 if ((browser_kind===
"float") && this.float_browser_disabled) browser_kind =
"fix";
1227 if (!main.select(
'.jsroot_browser_area').empty()) {
1231 if (update_html) this.brlayout.Toggle(browser_kind);
1233 JSROOT.CallBack(call_back);
1238 var guiCode =
"<p class='jsroot_browser_version'><a href='https://root.cern/js/'>JSROOT</a> version <span style='color:green'><b>" + JSROOT.version +
"</b></span></p>";
1240 if (this.is_online) {
1241 guiCode +=
'<p> Hierarchy in <a href="h.json">json</a> and <a href="h.xml">xml</a> format</p>'
1242 +
'<div style="display:flex;flex-direction:row;">'
1243 +
'<label style="margin-right:5px; vertical-align:middle;">'
1244 +
'<input style="vertical-align:middle;" type="checkbox" name="monitoring" class="gui_monitoring"/>'
1245 +
'Monitoring</label>';
1246 }
else if (!this.no_select) {
1247 var myDiv = d3.select(
"#"+this.gui_div),
1248 files = myDiv.attr(
"files") ||
"../files/hsimple.root",
1249 path = JSROOT.GetUrlOption(
"path") || myDiv.attr(
"path") ||
"",
1250 arrFiles = files.split(
';');
1253 '<input type="text" value="" style="width:95%; margin:5px;border:2px;" class="gui_urlToLoad" title="input file name"/>'
1254 +
'<div style="display:flex;flex-direction:row;padding-top:5px">'
1255 +
'<select class="gui_selectFileName" style="flex:1;padding:2px;" title="select file name"'
1256 +
'<option value="" selected="selected"></option>';
1257 for (var i in arrFiles)
1258 guiCode +=
'<option value = "' + path + arrFiles[i] +
'">' + arrFiles[i] +
'</option>';
1259 guiCode +=
'</select>'
1260 +
'<input type="file" class="gui_localFile" accept=".root" style="display:none"/><output id="list" style="display:none"></output>'
1261 +
'<input type="button" value="..." class="gui_fileBtn" style="min-width:3em;padding:3px;margin-left:5px;margin-right:5px;" title="select local file for reading"/><br/>'
1263 +
'<p id="gui_fileCORS"><small><a href="https://github.com/root-project/jsroot/blob/master/docs/JSROOT.md#reading-root-files-from-other-servers">Read docu</a>'
1264 +
' how to open files from other servers.</small></p>'
1265 +
'<div style="display:flex;flex-direction:row">'
1266 +
'<input style="padding:3px;margin-right:5px;"'
1267 +
' class="gui_ReadFileBtn" type="button" title="Read the Selected File" value="Load"/>'
1268 +
'<input style="padding:3px;margin-right:5px;"'
1269 +
' class="gui_ResetUIBtn" type="button" title="Close all opened files and clear drawings" value="Reset"/>'
1270 }
else if (this.no_select ==
"file") {
1271 guiCode +=
'<div style="display:flex;flex-direction:row">';
1274 if (this.is_online || !this.no_select || this.no_select==
"file")
1275 guiCode +=
'<select style="padding:2px;margin-right:5px;" title="layout kind" class="gui_layout"></select>'
1278 guiCode +=
'<div id="' + this.gui_div+
'_browser_hierarchy" class="jsroot_browser_hierarchy"></div>';
1280 this.brlayout.SetBrowserContent(guiCode);
1282 this.brlayout.SetBrowserTitle(this.is_online ?
'ROOT online server' :
'Read a ROOT file');
1284 var hpainter =
this, localfile_read_callback = null;
1286 if (!this.is_online && !this.no_select) {
1288 this.ReadSelectedFile =
function() {
1289 var filename = main.select(
".gui_urlToLoad").property(
'value').trim();
1290 if (!filename)
return;
1292 if ((filename.toLowerCase().lastIndexOf(
".json") == filename.length-5))
1293 this.OpenJsonFile(filename);
1295 this.OpenRootFile(filename);
1298 jmain.find(
".gui_selectFileName").val(
"").change(
function() {
1299 jmain.find(
".gui_urlToLoad").val($(
this).val());
1301 jmain.find(
".gui_fileBtn").button().click(
function() {
1302 jmain.find(
".gui_localFile").click();
1305 jmain.find(
".gui_ReadFileBtn").button().click(
function(){
1306 hpainter.ReadSelectedFile();
1309 jmain.find(
".gui_ResetUIBtn").button().click(
function(){
1310 hpainter.clear(
true);
1313 jmain.find(
".gui_urlToLoad").keyup(
function(e) {
1314 if (e.keyCode == 13) hpainter.ReadSelectedFile();
1317 jmain.find(
".gui_localFile").change(
function(evnt) {
1318 var files = evnt.target.files;
1320 for (var n=0;n<files.length;++n) {
1322 main.select(
".gui_urlToLoad").property(
'value', f.name);
1323 if (hpainter) hpainter.OpenRootFile(f, localfile_read_callback);
1326 localfile_read_callback = null;
1329 this.SelectLocalFile =
function(read_callback) {
1330 localfile_read_callback = read_callback;
1331 $(
"#" + this.gui_div +
" .jsroot_browser").find(
".gui_localFile").click();
1335 var jlayout = jmain.find(
".gui_layout");
1336 if (jlayout.length) {
1337 var lst = [
'simple',
'vert2',
'vert3',
'vert231',
'horiz2',
'horiz32',
'flex',
1338 'grid 2x2',
'grid 1x3',
'grid 2x3',
'grid 3x3',
'grid 4x4',
'collapsible',
'tabs'];
1340 for (var k=0;k<lst.length;++k){
1341 var opt = document.createElement(
'option');
1343 opt.innerHTML = lst[k];
1344 jlayout.get(0).appendChild(opt);
1347 jlayout.change(
function() {
1348 hpainter.SetDisplay($(
this).val() ||
'collapsible', hpainter.gui_div +
"_drawing");
1352 this.SetDivId(this.gui_div +
'_browser_hierarchy');
1356 this.InitializeBrowser();
1359 this.brlayout.ToggleBrowserKind(browser_kind ||
"fix");
1361 JSROOT.CallBack(call_back);
1366 HierarchyPainter.prototype.InitializeBrowser =
function() {
1368 var main = d3.select(
"#" + this.gui_div +
" .jsroot_browser");
1369 if (main.empty() || !this.brlayout)
return;
1370 var jmain = $(main.node()), hpainter =
this;
1372 if (this.brlayout) this.brlayout.AdjustBrowserSize();
1374 var selects = main.select(
".gui_layout").node();
1378 for (var i in selects.options) {
1379 var s = selects.options[i].text;
1380 if (typeof s !==
'string')
continue;
1381 if ((s == this.GetLayout()) || (s.replace(/ /g,
"") == this.GetLayout())) {
1382 selects.selectedIndex = i; found =
true;
1387 var opt = document.createElement(
'option');
1388 opt.innerHTML = opt.value = this.GetLayout();
1389 selects.appendChild(opt);
1390 selects.selectedIndex = selects.options.length-1;
1394 if (this.is_online) {
1395 if (this.h && this.h._toptitle)
1396 this.brlayout.SetBrowserTitle(this.h._toptitle);
1397 jmain.find(
".gui_monitoring")
1398 .prop(
'checked', this.IsMonitoring())
1400 hpainter.EnableMonitoring(this.checked);
1401 hpainter.updateAll(!this.checked);
1403 }
else if (!this.no_select) {
1405 this.ForEachRootFile(
function(item) {
if (!fname) fname = item._fullurl; });
1406 jmain.find(
".gui_urlToLoad").val(fname);
1410 HierarchyPainter.prototype.EnableMonitoring =
function(on) {
1411 this.SetMonitoring(undefined, on);
1413 var chkbox = d3.select(
"#" + this.gui_div +
" .jsroot_browser .gui_monitoring");
1414 if (!chkbox.empty() && (chkbox.property(
'checked') !== on))
1415 chkbox.property(
'checked', on);
1418 HierarchyPainter.prototype.CreateStatusLine =
function(height, mode) {
1419 if (this.status_disabled || !this.gui_div || !this.brlayout)
return '';
1420 return this.brlayout.CreateStatusLine(height, mode);
1423 JSROOT.BuildGUI =
function() {
1424 var myDiv = d3.select(
'#simpleGUI'), online =
false;
1426 if (myDiv.empty()) {
1427 myDiv = d3.select(
'#onlineGUI');
1428 if (myDiv.empty())
return alert(
'no div for gui found');
1432 if (myDiv.attr(
"ignoreurl") ===
"true")
1433 JSROOT.gStyle.IgnoreUrlOptions =
true;
1435 if ((JSROOT.GetUrlOption(
"nobrowser")!==null) || (myDiv.attr(
"nobrowser") && myDiv.attr(
"nobrowser")!==
"false"))
1436 return JSROOT.BuildNobrowserGUI();
1438 JSROOT.Painter.readStyleFromURL();
1440 var hpainter =
new JSROOT.HierarchyPainter(
'root', null);
1442 hpainter.is_online = online;
1444 hpainter.StartGUI(myDiv, hpainter.InitializeBrowser.bind(hpainter));
1449 function CollapsibleDisplay(frameid) {
1450 JSROOT.MDIDisplay.call(
this, frameid);
1454 CollapsibleDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
1456 CollapsibleDisplay.prototype.ForEachFrame =
function(userfunc, only_visible) {
1457 var topid = this.frameid +
'_collapsible';
1459 if (document.getElementById(topid) == null)
return;
1461 if (typeof userfunc !=
'function')
return;
1463 $(
'#' + topid +
' .collapsible_draw').each(
function() {
1466 if (only_visible && $(
this).is(
":hidden"))
return;
1468 userfunc($(
this).
get(0));
1472 CollapsibleDisplay.prototype.GetActiveFrame =
function() {
1473 var found = JSROOT.MDIDisplay.prototype.GetActiveFrame.call(
this);
1474 if (found && !$(found).is(
":hidden"))
return found;
1477 this.ForEachFrame(
function(frame) {
1478 if (!found) found = frame;
1484 CollapsibleDisplay.prototype.ActivateFrame =
function(frame) {
1485 if ($(frame).is(
":hidden")) {
1486 $(frame).prev().toggleClass(
"ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
1487 .find(
"> .ui-icon").toggleClass(
"ui-icon-triangle-1-e ui-icon-triangle-1-s").end()
1488 .next().toggleClass(
"ui-accordion-content-active").slideDown(0);
1490 $(frame).prev()[0].scrollIntoView();
1492 this.active_frame_title = d3.select(frame).attr(
'frame_title');
1495 CollapsibleDisplay.prototype.CreateFrame =
function(title) {
1497 this.BeforeCreateFrame(title);
1499 var topid = this.frameid +
'_collapsible';
1501 if (document.getElementById(topid) == null)
1502 $(
"#"+this.frameid).append(
'<div id="'+ topid +
'" class="jsroot ui-accordion ui-accordion-icons ui-widget ui-helper-reset" style="overflow:auto; overflow-y:scroll; height:100%; padding-left: 2px; padding-right: 2px"></div>');
1505 hid = topid +
"_sub" + this.cnt++,
1507 entryInfo =
"<h5 id=\"" + uid +
"\">" +
1508 "<span class='ui-icon ui-icon-triangle-1-e'></span>" +
1509 "<a> " + title +
"</a> " +
1510 "<button type='button' class='jsroot_collaps_closebtn' style='float:right; width:1.4em' title='close canvas'/>" +
1512 "<div class='collapsible_draw' id='" + hid +
"'></div>\n";
1514 $(
"#" + topid).append(entryInfo);
1517 .addClass(
"ui-accordion-header ui-helper-reset ui-state-default ui-corner-top ui-corner-bottom")
1518 .hover(
function() { $(
this).toggleClass(
"ui-state-hover"); })
1519 .click(
function() {
1520 $(
this).toggleClass(
"ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
1521 .find(
"> .ui-icon").toggleClass(
"ui-icon-triangle-1-e ui-icon-triangle-1-s")
1522 .end().next().toggleClass(
"ui-accordion-content-active").slideToggle(0);
1523 var sub = $(
this).next(), hide_drawing = sub.is(
":hidden");
1524 sub.css(
'display', hide_drawing ?
'none' :
'');
1525 if (!hide_drawing) JSROOT.resize(sub.get(0));
1528 .addClass(
"ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom")
1531 $(
'#' + uid).find(
" .jsroot_collaps_closebtn")
1532 .button({ icons: { primary:
"ui-icon-close" }, text:
false })
1534 mdi.CleanupFrame($(
this).parent().next().attr(
'id'));
1535 $(
this).parent().next().remove();
1536 $(
this).parent().remove();
1540 .toggleClass(
"ui-accordion-header-active ui-state-active ui-state-default ui-corner-bottom")
1541 .find(
"> .ui-icon").toggleClass(
"ui-icon-triangle-1-e ui-icon-triangle-1-s").end().next()
1542 .toggleClass(
"ui-accordion-content-active").slideToggle(0);
1544 return $(
"#" + hid).attr(
'frame_title', title).css(
'overflow',
'hidden')
1545 .attr(
'can_resize',
'height')
1546 .css(
'position',
'relative')
1552 function TabsDisplay(frameid) {
1553 JSROOT.MDIDisplay.call(
this, frameid);
1557 TabsDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
1559 TabsDisplay.prototype.ForEachFrame =
function(userfunc, only_visible) {
1560 var topid = this.frameid +
'_tabs';
1562 if (document.getElementById(topid) == null)
return;
1564 if (typeof userfunc !=
'function')
return;
1567 var active = $(
'#' + topid).tabs(
"option",
"active");
1569 $(
'#' + topid +
'> .tabs_draw').each(
function() {
1571 if (!only_visible || (cnt == active))
1572 userfunc($(
this).get(0));
1576 TabsDisplay.prototype.GetActiveFrame =
function() {
1578 this.ForEachFrame(
function(frame) {
1579 if (!found) found = frame;
1585 TabsDisplay.prototype.ActivateFrame =
function(frame) {
1586 var cnt = 0,
id = -1;
1587 this.ForEachFrame(
function(fr) {
1588 if ($(fr).attr(
'id') == $(frame).attr(
'id'))
id = cnt;
1591 $(
'#' + this.frameid +
"_tabs").tabs(
"option",
"active",
id);
1593 this.active_frame_title = d3.select(frame).attr(
'frame_title');
1596 TabsDisplay.prototype.CreateFrame =
function(title) {
1598 this.BeforeCreateFrame(title);
1601 topid = this.frameid +
'_tabs',
1602 hid = topid +
"_sub" + this.cnt++,
1603 li =
'<li><a href="#' + hid +
'">' + title
1604 +
'</a><span class="ui-icon ui-icon-close" style="float: left; margin: 0.4em 0.2em 0 0; cursor: pointer;" role="presentation">Remove Tab</span></li>',
1605 cont =
'<div class="tabs_draw" id="' + hid +
'"></div>';
1607 if (document.getElementById(topid) == null) {
1608 $(
"#" + this.frameid).append(
'<div id="' + topid +
'" class="jsroot">' +
' <ul>' + li +
' </ul>' + cont +
'</div>');
1610 var tabs = $(
"#" + topid)
1611 .css(
'overflow',
'hidden')
1613 heightStyle :
"fill",
1614 activate :
function (event,ui) {
1615 $(ui.newPanel).css(
'overflow',
'hidden');
1616 JSROOT.resize($(ui.newPanel).get(0));
1620 tabs.delegate(
"span.ui-icon-close",
"click",
function() {
1621 var panelId = $(
this).closest(
"li").remove().attr(
"aria-controls");
1622 mdi.CleanupFrame(panelId);
1623 $(
"#" + panelId).
remove();
1624 tabs.tabs(
"refresh");
1625 if ($(
'#' + topid +
'> .tabs_draw').length == 0)
1626 $(
"#" + topid).
remove();
1630 $(
"#" + topid).find(
"> .ui-tabs-nav").append(li);
1631 $(
"#" + topid).append(cont);
1632 $(
"#" + topid).tabs(
"refresh");
1633 $(
"#" + topid).tabs(
"option",
"active", -1);
1637 .css(
'overflow',
'hidden')
1638 .attr(
'frame_title', title);
1640 return $(
'#' + hid).
get(0);
1643 TabsDisplay.prototype.CheckMDIResize =
function(frame_id, size) {
1644 $(
"#" + this.frameid +
'_tabs').tabs(
"refresh");
1645 JSROOT.MDIDisplay.prototype.CheckMDIResize.call(
this, frame_id, size);
1650 function FlexibleDisplay(frameid) {
1651 JSROOT.MDIDisplay.call(
this, frameid);
1655 FlexibleDisplay.prototype = Object.create(JSROOT.MDIDisplay.prototype);
1657 FlexibleDisplay.prototype.ForEachFrame =
function(userfunc, only_visible) {
1658 var topid = this.frameid +
'_flex';
1660 if (document.getElementById(topid) == null)
return;
1661 if (typeof userfunc !=
'function')
return;
1663 $(
'#' + topid +
' .flex_draw').each(
function() {
1665 if (only_visible && $(
this).is(
":hidden"))
return;
1667 userfunc($(
this).
get(0));
1671 FlexibleDisplay.prototype.GetActiveFrame =
function() {
1672 var found = JSROOT.MDIDisplay.prototype.GetActiveFrame.call(
this);
1673 if (found && !$(found).is(
":hidden"))
return found;
1676 this.ForEachFrame(
function(frame) {
1677 if (!found) found = frame;
1683 FlexibleDisplay.prototype.ActivateFrame =
function(frame) {
1684 this.active_frame_title = d3.select(frame).attr(
'frame_title');
1687 FlexibleDisplay.prototype.CreateFrame =
function(title) {
1689 this.BeforeCreateFrame(title);
1691 var topid = this.frameid +
'_flex';
1693 if (document.getElementById(topid) == null)
1694 $(
"#" + this.frameid).append(
'<div id="'+ topid +
'" class="jsroot" style="overflow:none; height:100%; width:100%"></div>');
1697 top = $(
"#" + topid),
1700 subid = topid +
"_frame" + this.cnt;
1702 var entry =
'<div id="' + subid +
'" class="flex_frame" style="position:absolute">' +
1703 '<div class="ui-widget-header flex_header">'+
1704 '<p>'+title+
'</p>' +
1705 '<button type="button" style="float:right; width:1.4em"/>' +
1706 '<button type="button" style="float:right; width:1.4em"/>' +
1707 '<button type="button" style="float:right; width:1.4em"/>' +
1709 '<div id="' + subid +
'_cont" class="flex_draw"></div>' +
1714 function PopupWindow(div) {
1715 if (div ===
'first') {
1717 $(
'#' + topid +
' .flex_frame').each(
function() {
1718 if (!$(
this).is(
":hidden") && ($(
this).prop(
'state') !=
"minimal")) div = $(
this);
1723 div.appendTo(div.parent());
1725 if (div.prop(
'state') ==
"minimal")
return;
1727 div = div.find(
".flex_draw").get(0);
1728 var dummy =
new JSROOT.TObjectPainter();
1729 dummy.SetDivId(div, -1);
1730 JSROOT.Painter.SelectActivePad({ pp: dummy.canv_painter(), active:
true });
1735 function ChangeWindowState(main, state) {
1736 var curr = main.prop(
'state');
1737 if (!curr) curr =
"normal";
1738 main.prop(
'state', state);
1739 if (state==curr)
return;
1741 if (curr ==
"normal") {
1742 main.prop(
'original_height', main.height());
1743 main.prop(
'original_width', main.width());
1744 main.prop(
'original_top', main.css(
'top'));
1745 main.prop(
'original_left', main.css(
'left'));
1748 main.find(
".jsroot_minbutton").find(
'.ui-icon')
1749 .toggleClass(
"ui-icon-triangle-1-s", state!=
"minimal")
1750 .toggleClass(
"ui-icon-triangle-2-n-s", state==
"minimal");
1752 main.find(
".jsroot_maxbutton").find(
'.ui-icon')
1753 .toggleClass(
"ui-icon-triangle-1-n", state!=
"maximal")
1754 .toggleClass(
"ui-icon-triangle-2-n-s", state==
"maximal");
1758 main.height(main.find(
'.flex_header').height()).width(
"auto");
1759 main.find(
".flex_draw").css(
"display",
"none");
1760 main.find(
".ui-resizable-handle").css(
"display",
"none");
1763 main.height(
"100%").width(
"100%").css(
'left',
'').css(
'top',
'');
1764 main.find(
".flex_draw").css(
"display",
"");
1765 main.find(
".ui-resizable-handle").css(
"display",
"none");
1768 main.find(
".flex_draw").css(
"display",
"");
1769 main.find(
".ui-resizable-handle").css(
"display",
"");
1770 main.height(main.prop(
'original_height'))
1771 .width(main.prop(
'original_width'));
1772 if (curr!=
"minimal")
1773 main.css(
'left', main.prop(
'original_left'))
1774 .css(
'top', main.prop(
'original_top'));
1777 if (state !==
"minimal")
1780 PopupWindow(
"first");
1784 .css(
'left', parseInt(w * (this.cnt % 5)/10))
1785 .css(
'top', parseInt(h * (this.cnt % 5)/10))
1786 .width(Math.round(w * 0.58))
1787 .height(Math.round(h * 0.58))
1789 helper:
"jsroot-flex-resizable-helper",
1790 start:
function(event, ui) {
1792 PopupWindow($(
this));
1794 stop:
function(event, ui) {
1795 var rect = { width : ui.size.width-1, height : ui.size.height - $(
this).find(
".flex_header").height()-1 };
1796 JSROOT.resize($(
this).find(
".flex_draw").
get(0), rect);
1800 containment:
"parent",
1801 start:
function(event, ui) {
1803 PopupWindow($(
this));
1805 var ddd = $(
this).find(
".flex_draw");
1808 var elementMouseIsOver = document.elementFromPoint(event.clientX, event.clientY);
1809 var isparent =
false;
1810 $(elementMouseIsOver).parents().map(
function() {
if ($(
this).
get(0) === ddd.get(0)) isparent =
true; });
1811 if (isparent)
return false;
1814 .click(
function() { PopupWindow($(
this)); })
1815 .find(
'.flex_header')
1818 PopupWindow($(
this).parent());
1820 .dblclick(
function() {
1821 var main = $(
this).parent();
1822 if (main.prop(
'state') ==
"normal")
1823 ChangeWindowState(main,
"maximal");
1825 ChangeWindowState(main,
"normal");
1829 .attr(
'title',
'close canvas')
1830 .button({ icons: { primary:
"ui-icon-close" }, text:
false })
1832 var main = $(
this).parent().parent();
1833 mdi.CleanupFrame(main.find(
".flex_draw").get(0));
1835 PopupWindow(
'first');
1838 .attr(
'title',
'maximize canvas')
1839 .addClass(
'jsroot_maxbutton')
1840 .button({ icons: { primary:
"ui-icon-triangle-1-n" }, text:
false })
1842 var main = $(
this).parent().parent();
1843 var maximize = $(
this).find(
'.ui-icon').hasClass(
"ui-icon-triangle-1-n");
1844 ChangeWindowState(main, maximize ?
"maximal" :
"normal");
1847 .attr(
'title',
'minimize canvas')
1848 .addClass(
'jsroot_minbutton')
1849 .button({ icons: { primary:
"ui-icon-triangle-1-s" }, text:
false })
1851 var main = $(
this).parent().parent();
1852 var minimize = $(
this).find(
'.ui-icon').hasClass(
"ui-icon-triangle-1-s");
1853 ChangeWindowState(main, minimize ?
"minimal" :
"normal");
1857 $(
"#" + subid).find(
".ui-resizable-handle").css(
'z-index',
'');
1861 return $(
"#" + subid +
"_cont").attr(
'frame_title', title).get(0);
1866 JSROOT.GridDisplay.prototype.CreateSeparator =
function(handle, main, group) {
1867 var separ = $(main.append(
"div").node());
1869 separ.toggleClass(
'jsroot_separator',
true)
1870 .toggleClass(handle.vertical ?
'jsroot_hline' :
'jsroot_vline',
true)
1871 .prop(
'handle', handle)
1872 .attr(
'separator-id', group.id)
1873 .css(
'position',
'absolute')
1874 .css(handle.vertical ?
'top' :
'left',
"calc(" + group.position+
"% - 2px)")
1875 .css(handle.vertical ?
'width' :
'height', (handle.size || 100)+
"%")
1876 .css(handle.vertical ?
'height' :
'width',
'5px')
1877 .css(
'cursor', handle.vertical ?
"ns-resize" :
"ew-resize");
1879 separ.bind(
'changePosition',
function(e, drag_ui) {
1880 var handle = $(
this).prop(
'handle'),
1881 id = parseInt($(
this).attr(
'separator-id')),
1882 pos = handle.groups[id].position;
1884 if (drag_ui ===
'restore') {
1885 pos = handle.groups[id].position0;
1887 if (drag_ui && drag_ui.offset) {
1888 if (handle.vertical)
1889 pos = Math.round((drag_ui.offset.top+2-$(
this).parent().offset().top)/$(
this).parent().innerHeight()*100);
1891 pos = Math.round((drag_ui.offset.left+2-$(
this).parent().offset().left)/$(
this).parent().innerWidth()*100);
1894 var diff = handle.groups[id].position - pos;
1896 if (Math.abs(diff)<0.3)
return;
1899 if (Math.min(handle.groups[
id-1].size-diff, handle.groups[
id].size+diff) < 5)
return;
1901 handle.groups[
id-1].size -= diff;
1902 handle.groups[id].size += diff;
1903 handle.groups[id].position = pos;
1905 function SetGroupSize(prnt, grid) {
1906 var name = handle.vertical ?
'height' :
'width',
1907 size = handle.groups[grid].size+
'%';
1908 prnt.children(
"[groupid='"+grid+
"']").css(name, size)
1909 .children(
".jsroot_separator").css(name, size);
1912 $(
this).css(handle.vertical ?
'top' :
'left',
"calc("+pos+
"% - 2px)");
1914 SetGroupSize($(
this).parent(),
id-1);
1915 SetGroupSize($(
this).parent(),
id);
1917 if (drag_ui ===
'restore') {
1918 $(
this).trigger(
'resizeGroup',
id-1);
1919 $(
this).trigger(
'resizeGroup',
id);
1923 separ.bind(
'resizeGroup',
function(e, grid) {
1924 var sel = $(
this).parent().children(
"[groupid='"+grid+
"']");
1925 if (!sel.hasClass(
'jsroot_newgrid')) sel = sel.find(
".jsroot_newgrid");
1926 sel.each(
function() { JSROOT.resize($(
this).
get(0)); });
1929 separ.dblclick(
function() {
1930 $(
this).trigger(
'changePosition',
'restore');
1934 axis: handle.vertical ?
"y" :
"x",
1935 cursor: handle.vertical ?
"ns-resize" :
"ew-resize",
1936 containment:
"parent",
1937 helper :
function() {
return $(
this).clone().css(
'background-color',
'grey'); },
1938 start:
function(event,ui) {
1940 var handle = $(
this).prop(
'handle'),
1941 id = parseInt($(
this).attr(
'separator-id'));
1942 handle.groups[id].startpos = handle.groups[id].position;
1944 drag:
function(event,ui) {
1945 $(
this).trigger(
'changePosition', ui);
1947 stop:
function(event,ui) {
1949 var handle = $(
this).prop(
'handle'),
1950 id = parseInt($(
this).attr(
'separator-id'));
1951 if (Math.abs(handle.groups[
id].startpos - handle.groups[
id].position)<0.5)
return;
1953 $(
this).trigger(
'resizeGroup',
id-1);
1954 $(
this).trigger(
'resizeGroup',
id);
1961 JSROOT.CreateTreePlayer =
function(player) {
1963 player.draw_first =
true;
1965 player.ConfigureOnline =
function(itemname, url, askey, root_version, dflt_expr) {
1966 this.SetItemName(itemname,
"",
this);
1968 this.root_version = root_version;
1970 this.dflt_expr = dflt_expr;
1973 player.ConfigureTree =
function(tree) {
1974 this.local_tree = tree;
1977 player.KeyUp =
function(e) {
1978 if (e.keyCode == 13) this.PerformDraw();
1981 player.ShowExtraButtons =
function(args) {
1982 var main = $(this.select_main().node());
1984 main.find(
".treedraw_buttons")
1985 .append(
" Cut: <input class='treedraw_cut ui-corner-all ui-widget' style='width:8em;margin-left:5px' title='cut expression'></input>"+
1986 " Opt: <input class='treedraw_opt ui-corner-all ui-widget' style='width:5em;margin-left:5px' title='histogram draw options'></input>"+
1987 " Num: <input class='treedraw_number' style='width:7em;margin-left:5px' title='number of entries to process (default all)'></input>" +
1988 " First: <input class='treedraw_first' style='width:7em;margin-left:5px' title='first entry to process (default first)'></input>" +
1989 " <button class='treedraw_clear' title='Clear drawing'>Clear</button>");
1991 var page = 1000, numentries = undefined, p =
this;
1992 if (this.local_tree) numentries = this.local_tree.fEntries || 0;
1994 main.find(
".treedraw_cut").val(args && args.parse_cut ? args.parse_cut :
"").keyup(this.keyup);
1995 main.find(
".treedraw_opt").val(args && args.drawopt ? args.drawopt :
"").keyup(this.keyup);
1996 main.find(
".treedraw_number").val(args && args.numentries ? args.numentries :
"").spinner({ numberFormat:
"n", min: 0, page: 1000, max: numentries }).keyup(this.keyup);
1997 main.find(
".treedraw_first").val(args && args.firstentry ? args.firstentry :
"").spinner({ numberFormat:
"n", min: 0, page: 1000, max: numentries }).keyup(this.keyup);
1998 main.find(
".treedraw_clear").button().click(
function() { JSROOT.cleanup(p.drawid); });
2001 player.Show =
function(divid, args) {
2002 this.drawid = divid +
"_draw";
2004 this.keyup = this.KeyUp.bind(
this);
2006 var show_extra = args && (args.parse_cut || args.numentries || args.firstentry);
2008 var main = $(
"#" + divid);
2010 main.html(
"<div class='treedraw_buttons' style='padding-left:0.5em'>" +
2011 "<button class='treedraw_exe' title='Execute draw expression'>Draw</button>" +
2012 " Expr:<input class='treedraw_varexp ui-corner-all ui-widget' style='width:12em;margin-left:5px' title='draw expression'></input> " +
2013 (show_extra ?
"" :
"<button class='treedraw_more'>More</button>") +
2016 "<div id='" + this.drawid +
"' style='width:100%'></div>");
2019 this.SetDivId(divid);
2023 if (this.local_tree)
2024 main.find(
'.treedraw_buttons').attr(
'title',
"Tree draw player for: " + this.local_tree.fName);
2025 main.find(
'.treedraw_exe').button().click(
function() { p.PerformDraw(); });
2026 main.find(
'.treedraw_varexp')
2027 .val(args && args.parse_expr ? args.parse_expr : (
this.dflt_expr ||
"px:py"))
2031 this.ShowExtraButtons(args);
2033 main.find(
'.treedraw_more').button().click(
function() {
2035 p.ShowExtraButtons();
2042 player.PerformLocalDraw =
function() {
2043 if (!this.local_tree)
return;
2045 var frame = $(this.select_main().node()),
2046 args = { expr: frame.find(
'.treedraw_varexp').val() };
2048 if (frame.find(
'.treedraw_more').length==0) {
2049 args.cut = frame.find(
'.treedraw_cut').val();
2050 if (!args.cut)
delete args.cut;
2052 args.drawopt = frame.find(
'.treedraw_opt').val();
2053 if (args.drawopt ===
"dump") { args.dump =
true; args.drawopt =
""; }
2054 if (!args.drawopt)
delete args.drawopt;
2056 args.numentries = parseInt(frame.find(
'.treedraw_number').val());
2057 if (isNaN(args.numentries))
delete args.numentries;
2059 args.firstentry = parseInt(frame.find(
'.treedraw_first').val());
2060 if (isNaN(args.firstentry))
delete args.firstentry;
2065 if (args.drawopt) JSROOT.cleanup(p.drawid);
2067 p.local_tree.Draw(args,
function(histo, hopt, intermediate) {
2068 JSROOT.redraw(p.drawid, histo, hopt);
2072 player.PerformDraw =
function() {
2074 if (this.local_tree)
return this.PerformLocalDraw();
2076 var frame = $(this.select_main().node()),
2077 url = this.url +
'/exe.json.gz?compact=3&method=Draw',
2078 expr = frame.find(
'.treedraw_varexp').val(),
2079 hname =
"h_tree_draw", option =
"",
2080 pos = expr.indexOf(
">>");
2083 expr +=
">>" + hname;
2085 hname = expr.substr(pos+2);
2086 if (hname[0]==
'+') hname = hname.substr(1);
2087 var pos2 = hname.indexOf(
"(");
2088 if (pos2>0) hname = hname.substr(0, pos2);
2091 if (frame.find(
'.treedraw_more').length==0) {
2092 var cut = frame.find(
'.treedraw_cut').val(),
2093 nentries = frame.find(
'.treedraw_number').val(),
2094 firstentry = frame.find(
'.treedraw_first').val();
2096 option = frame.find(
'.treedraw_opt').val();
2098 url +=
'&prototype="const char*,const char*,Option_t*,Long64_t,Long64_t"&varexp="' + expr +
'"&selection="' + cut +
'"';
2101 if (nentries==
"") nentries = (this.root_version >= 394499) ?
"TTree::kMaxEntries":
"1000000000";
2102 if (firstentry==
"") firstentry =
"0";
2103 url +=
'&option="' + option +
'"&nentries=' + nentries +
'&firstentry=' + firstentry;
2105 url +=
'&prototype="Option_t*"&opt="' + expr +
'"';
2107 url +=
'&_ret_object_=' + hname;
2111 function SubmitDrawRequest() {
2112 JSROOT.NewHttpRequest(url,
'object',
function(res) {
2114 JSROOT.cleanup(player.drawid);
2115 JSROOT.draw(player.drawid, res, option);
2122 JSROOT.NewHttpRequest(this.url +
"/root.json",
'text', SubmitDrawRequest).send();
2124 SubmitDrawRequest();
2128 player.CheckResize =
function(arg) {
2129 var main = $(this.select_main().node());
2131 $(
"#" + this.drawid).width(main.width());
2132 var h = main.height(),
2133 h0 = main.find(
".treedraw_buttons").outerHeight(
true),
2134 h1 = main.find(
"hr").outerHeight(
true);
2136 $(
"#" + this.drawid).height(h - h0 - h1 - 2);
2138 JSROOT.resize(this.drawid);
2147 JSROOT.drawTreePlayer =
function(hpainter, itemname, askey, asleaf) {
2149 var item = hpainter.Find(itemname),
2150 top = hpainter.GetTopOnlineItem(item),
2151 draw_expr =
"", leaf_cnt = 0;
2152 if (!item || !top)
return null;
2155 draw_expr = item._name;
2156 while (item && !item._ttree) item = item._parent;
2157 if (!item)
return null;
2158 itemname = hpainter.itemFullName(item);
2161 var url = hpainter.GetOnlineItemUrl(itemname);
2162 if (!url)
return null;
2164 var root_version = top._root_version ? parseInt(top._root_version) : 396545;
2166 var mdi = hpainter.GetDisplay();
2167 if (!mdi)
return null;
2169 var frame = mdi.FindFrame(itemname,
true);
2170 if (!frame)
return null;
2172 var divid = d3.select(frame).attr(
'id'),
2173 player =
new JSROOT.TBasePainter();
2175 if (item._childs && !asleaf)
2176 for (var n=0;n<item._childs.length;++n) {
2177 var leaf = item._childs[n];
2178 if (leaf && leaf._kind && (leaf._kind.indexOf(
"ROOT.TLeaf")==0) && (leaf_cnt<2)) {
2179 if (leaf_cnt++ > 0) draw_expr+=
":";
2180 draw_expr+=leaf._name;
2184 JSROOT.CreateTreePlayer(player);
2185 player.ConfigureOnline(itemname, url, askey, root_version, draw_expr);
2193 JSROOT.drawTreePlayerKey =
function(hpainter, itemname) {
2194 return JSROOT.drawTreePlayer(hpainter, itemname,
true);
2199 JSROOT.drawLeafPlayer =
function(hpainter, itemname) {
2200 return JSROOT.drawTreePlayer(hpainter, itemname,
false,
true);
2205 JSROOT.Painter.ConfigureVSeparator =
function(handle) {
2209 JSROOT.Painter.AdjustLayout =
function(left, height, firsttime) {
2211 if (JSROOT.hpainter && JSROOT.hpainter.brlayout)
2212 JSROOT.hpainter.brlayout.AdjustSeparator(left, height,
true);
2215 JSROOT.Painter.ConfigureHSeparator =
function(height) {
2217 if (!JSROOT.hpainter)
return "";
2219 return JSROOT.hpainter.CreateStatusLine(height);