(function( factory ) { // this is code for web canvas to support Go4 classes like // TGo4Marker or TGo4Condition in the go4 gui // it is slightly different to go4.js which is dedicated with usage of THttpServer if (typeof JSROOT != "object") { var e1 = new Error("go4canvas.js requires JSROOT to be already loaded"); e1.source = "go4canvas.js"; throw e1; } var myGO4 = { version: "5.9.x", web_canvas: true }; factory(JSROOT, (typeof GO4 != 'undefined') ? GO4 : myGO4); } (function(JSROOT, GO4) { "use strict"; GO4.MarkerPainter = function(marker) { JSROOT.TObjectPainter.call(this, marker); this.pave = null; // drawing of stat } GO4.MarkerPainter.prototype = Object.create(JSROOT.TObjectPainter.prototype); GO4.MarkerPainter.prototype.moveDrag = function(dx,dy) { this.grx += dx; this.gry += dy; this.draw_g.select('path').attr("d",this.markeratt.create(this.grx, this.gry)); } GO4.MarkerPainter.prototype.moveEnd = function() { var marker = this.GetObject(); marker.fX = this.SvgToAxis("x", this.grx); marker.fY = this.SvgToAxis("y", this.gry); this.WebCanvasExec("SetXY(" + marker.fX + "," + marker.fY + ")"); this.drawLabel(); } GO4.MarkerPainter.prototype.drawMarker = function() { this.CreateG(); // can draw in complete pad var marker = this.GetObject(); this.createAttMarker({ attr: marker }); this.grx = this.AxisToSvg("x", marker.fX); this.gry = this.AxisToSvg("y", marker.fY); var path = this.markeratt.create(this.grx, this.gry); if (path) this.draw_g.append("svg:path") .attr("d", path) .call(this.markeratt.func); this.AddMove(); } GO4.MarkerPainter.prototype.fillLabels = function(marker) { var lbls = []; var main = this.main_painter(), hint = null; if (main && typeof main.ProcessTooltip == 'function') hint = main.ProcessTooltip({ enabled: false, x: this.grx - this.frame_x(), y: this.gry - this.frame_y() }); lbls.push(marker.fxName + ((hint && hint.name) ? (" : " + hint.name) : "")); if (marker.fbXDraw) lbls.push("X = " + JSROOT.FFormat(marker.fX, "6.4g")); if (marker.fbYDraw) lbls.push("Y = " + JSROOT.FFormat(marker.fY, "6.4g")); if (hint && hint.user_info) { if (marker.fbXbinDraw) { var bin = ""; if (hint.user_info.binx !== undefined) bin = hint.user_info.binx; else if (hint.user_info.bin !== undefined) bin = hint.user_info.bin; lbls.push("Xbin = " + bin); } if (marker.fbYbinDraw) { lbls.push("Ybin = " + ((hint.user_info.biny !== undefined) ? hint.user_info.biny : "")); } if (marker.fbContDraw) lbls.push("Cont = " + hint.user_info.cont); } return lbls; } GO4.MarkerPainter.prototype.drawLabel = function() { var marker = this.GetObject(); if (!marker.fbHasLabel) return; var pave_painter = this.FindPainterFor(this.pave); if (!pave_painter) { this.pave = JSROOT.Create("TPaveStats"); this.pave.fName = "stats_" + marker.fName; var px = this.grx / this.pad_width() + 0.02, py = this.gry / this.pad_height() - 0.02; JSROOT.extend(this.pave, { fX1NDC: px, fY1NDC: py - 0.15, fX2NDC: px + 0.2, fY2NDC: py, fBorderSize: 1, fFillColor: 0, fFillStyle: 1001 }); var st = JSROOT.gStyle; JSROOT.extend(this.pave, { fFillColor: st.fStatColor, fFillStyle: st.fStatStyle, fTextAngle: 0, fTextSize: st.fStatFontSize, fTextAlign: 12, fTextColor: st.fStatTextColor, fTextFont: st.fStatFont}); } else { this.pave.Clear(); } var lbls = this.fillLabels(marker); for (var k=0;k cond.fUp1)) return cond.fbFalse; if ((cond.fiDim==2) && ((y < cond.fLow2) || (y > cond.fUp2))) return cond.fbFalse; return cond.fbTrue; } GO4.ConditionPainter.prototype.isPolyCond = function() { return this.MatchObjectType("TGo4PolyCond") || this.MatchObjectType("TGo4ShapedCond"); } GO4.ConditionPainter.prototype.isEllipseCond = function() { return this.MatchObjectType("TGo4ShapedCond"); } GO4.ConditionPainter.prototype.afterCutDraw = function(p) { if (!p || !this.snapid || p._oldexec) return; p.snapid = this.snapid + "#member_fxCut"; // catch TCutG exec and mark condition as modified p._oldexec = p.WebCanvasExec; p._condpainter = this; p.WebCanvasExec = function(exec, arg) { this._oldexec(exec, arg); p._condpainter.WebCanvasExec("SetChanged()"); } } GO4.ConditionPainter.prototype.drawCondition = function(interactive) { var cond = this.GetObject(); if (!cond || !cond.fbVisible) return; if (this.isPolyCond()) { if (cond.fxCut) { // look here if cut is already drawn in divid: var cutpaint = this.FindPainterFor(null, cond.fName, 'TCutG'); if (cutpaint) { if (cutpaint.UpdateObject(cond.fxCut)) cutpaint.Redraw(); this.afterCutDraw(cutpaint); } else { cond.fxCut.fFillStyle = 3006; cond.fxCut.fFillColor = 2; JSROOT.draw(this.divid, cond.fxCut, "LF", this.afterCutDraw.bind(this)); } } return; } this.CreateG(true); // drawing performed inside frame if ((cond.fFillStyle==1001) && (cond.fFillColor==19)) { cond.fFillStyle = 3006; cond.fFillColor = 2; } this.createAttFill({attr: cond}); this.createAttLine({attr: cond}); this.grx1 = this.AxisToSvg("x", cond.fLow1); this.grx2 = this.AxisToSvg("x", cond.fUp1); if (cond.fiDim == 2) { this.gry1 = this.AxisToSvg("y", cond.fUp2); this.gry2 = this.AxisToSvg("y", cond.fLow2); this.candy = true; } else { this.gry1 = 0; this.gry2 = this.frame_height(); this.candy = false; } this.draw_g.append("svg:rect") .attr("x", this.grx1) .attr("y", this.gry1) .attr("width", this.grx2 - this.grx1) .attr("height", this.gry2 - this.gry1) .call(this.lineatt.func) .call(this.fillatt.func); this.AddMove(); } GO4.ConditionPainter.prototype.moveStart = function(x,y) { this.swapx = this.swapy = false; this.dx1 = Math.abs(x-this.grx1) < 5; this.dx2 = Math.abs(x-this.grx2) < 5; this.dy1 = Math.abs(y-this.gry1) < 5; this.dy2 = Math.abs(y-this.gry2) < 5; if (!this.dx1 && !this.dx2 && !this.dy1 && !this.dy2) this.dx1 = this.dx2 = this.dy1 = this.dy2 = true; if (!this.candy) this.dy1 = this.dy2 = false; } GO4.ConditionPainter.prototype.swap = function(n1,n2) { var d = this[n1]; this[n1] = this[n2]; this[n2] = d; } GO4.ConditionPainter.prototype.moveDrag = function(dx,dy) { if (this.dx1) this.grx1 += dx; if (this.dx2) this.grx2 += dx; if (this.grx1 > this.grx2) { this.swapx = true; this.swap('grx1', 'grx2'); this.swap('dx1', 'dx2'); } if (this.dy1) this.gry1 += dy; if (this.dy2) this.gry2 += dy; if (this.gry1 > this.gry2) { this.swapy = true; this.swap('gry1', 'gry2'); this.swap('dy1', 'dy2'); } this.draw_g.select('rect').attr("x",this.grx1).attr("y", this.gry1) .attr("width", this.grx2 - this.grx1).attr("height", this.gry2 - this.gry1); } GO4.ConditionPainter.prototype.moveEnd = function() { var cond = this.GetObject(), exec = ""; if (this.dx1 || this.swapx) { cond.fLow1 = this.SvgToAxis("x", this.grx1); exec += "SetXLow(" + cond.fLow1 + ");;"; } if (this.dx2 || this.swapx) { cond.fUp1 = this.SvgToAxis("x", this.grx2); exec += "SetXUp(" + cond.fUp1 + ");;"; } if (this.dy2 || this.swapy) { cond.fLow2 = this.SvgToAxis("y", this.gry2); exec += "SetYLow(" + cond.fLow2 + ");;"; } if (this.dy1 || this.swapy) { cond.fUp2 = this.SvgToAxis("y", this.gry1); exec += "SetYUp(" + cond.fUp2 + ");;"; } if (exec) { this.WebCanvasExec(exec + "SetChanged()"); this.drawLabel(); } } GO4.ConditionPainter.prototype.drawLabel = function() { var cond = this.GetObject(), painter = this; if (!cond.fbLabelDraw || !cond.fbVisible) return; var pave_painter = this.FindPainterFor(this.pave); if (!pave_painter) { this.pave = JSROOT.Create("TPaveStats"); this.pave.fName = "stats_" + cond.fName; JSROOT.extend(this.pave, { fX1NDC: 0.1, fY1NDC: 0.4, fX2NDC: 0.4, fY2NDC: 0.65, fBorderSize: 1, fFillColor: 0, fFillStyle: 1001 }); var st = JSROOT.gStyle; JSROOT.extend(this.pave, { fFillColor: st.fStatColor, fFillStyle: st.fStatStyle, fTextAngle: 0, fTextSize: st.fStatFontSize, fTextAlign: 12, fTextColor: st.fStatTextColor, fTextFont: st.fStatFont}); } else { this.pave.Clear(); } this.pave.AddText(cond.fName); this.pave.AddText("Counts = " + cond.fiCounts); if (cond.fbLimitsDraw) if (this.isPolyCond()) { var res = { xmin: 0, xmax: 0, ymin: 0, ymax: 0 }; if (cond.fxCut.fNpoints > 0) { res.xmin = res.xmax = cond.fxCut.fX[0]; res.ymin = res.ymax = cond.fxCut.fY[0]; for (var i=1; iHistogram name not specified"); var h = $("#"+divid).height(), w = $("#"+divid).width(); if ((h<10) && (w>10)) $("#"+divid).height(w*0.4); var editor = new GO4.ConditionEditor(cond); return editor.drawEditor(divid); } // $('#'+divid).append("
Histogram name is " + cond.fxHistoName); if (!JSROOT.hpainter) { $('#'+divid).append("
Error - did not found hierarchy painter"); return; } var histofullpath = null; JSROOT.hpainter.ForEach(function(h) { if ((h['_name'] == cond.fxHistoName) && (h['_kind'].indexOf("ROOT.TH")==0)) { histofullpath = JSROOT.hpainter.itemFullName(h); return true; } }); if (histofullpath == null) { $('#'+divid).append("
Error - did not found histogram " + cond.fxHistoName); histofullpath = "../../Histograms/" + cond.fxHistoName; JSROOT.hpainter.Find({ name: histofullpath, force: true})['_kind'] = "ROOT.TH1I"; console.log("Try histogram" + histofullpath); } $('#'+divid).append("
Drawing histogram " + histofullpath); $('#'+divid).empty(); var condpainter = new GO4.ConditionPainter(cond); JSROOT.hpainter.display(histofullpath, "divid:" + divid, function(res) { if (res==null) return console.log("fail to get histogram " + histofullpath); condpainter.SetDivId(divid); condpainter.drawCondition(); condpainter.drawLabel(); condpainter.DrawingReady(); }); return condpainter; } GO4.drawCondArray = function(divid, obj, option) { var arr = obj.condarr.arr; var num = obj.fiNumCond; for (var k=0;k