Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 193 | f9daq | 1 | /** @file JSRootCore.js |
| 2 | * Core methods of JavaScript ROOT */ |
||
| 3 | |||
| 4 | /** @namespace JSROOT |
||
| 5 | * Holder of all JSROOT functions and classes */ |
||
| 6 | |||
| 7 | (function( factory ) { |
||
| 8 | if ( typeof define === "function" && define.amd ) { |
||
| 9 | |||
| 10 | var jsroot = factory({}); |
||
| 11 | |||
| 12 | var dir = jsroot.source_dir + "scripts/", ext = jsroot.source_min ? ".min" : ""; |
||
| 13 | |||
| 14 | var paths = { |
||
| 15 | 'd3' : dir+'d3.v3.min', |
||
| 16 | 'jquery' : dir+'jquery.min', |
||
| 17 | 'jquery-ui' : dir+'jquery-ui.min', |
||
| 18 | 'jqueryui-mousewheel' : dir+'jquery.mousewheel.min', |
||
| 19 | 'jqueryui-touch-punch' : dir+'touch-punch.min', |
||
| 20 | 'rawinflate' : dir+'rawinflate.min', |
||
| 21 | 'MathJax' : 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG&delayStartupUntil=configured', |
||
| 22 | 'saveSvgAsPng' : dir+'saveSvgAsPng.min', |
||
| 23 | 'dat.gui' : dir+'dat.gui.min', |
||
| 24 | 'threejs' : dir+'three.min', |
||
| 25 | 'threejs_all' : dir+'three.extra.min', |
||
| 26 | 'JSRootCore' : dir+'JSRootCore'+ext, |
||
| 27 | 'JSRootMath' : dir+'JSRootMath'+ext, |
||
| 28 | 'JSRootInterface' : dir+'JSRootInterface'+ext, |
||
| 29 | 'JSRootIOEvolution' : dir+'JSRootIOEvolution'+ext, |
||
| 30 | 'JSRootPainter' : dir+'JSRootPainter'+ext, |
||
| 31 | 'JSRootPainter.more' : dir+'JSRootPainter.more'+ext, |
||
| 32 | 'JSRootPainter.jquery' : dir+'JSRootPainter.jquery'+ext, |
||
| 33 | 'JSRoot3DPainter' : dir+'JSRoot3DPainter'+ext, |
||
| 34 | 'ThreeCSG' : dir+'ThreeCSG'+ext, |
||
| 35 | 'JSRootGeoBase' : dir+'JSRootGeoBase'+ext, |
||
| 36 | 'JSRootGeoPainter' : dir+'JSRootGeoPainter'+ext |
||
| 37 | }; |
||
| 38 | |||
| 39 | var cfg_paths; |
||
| 40 | if ((requirejs.s!==undefined) && (requirejs.s.contexts !== undefined) && ((requirejs.s.contexts._!==undefined) && |
||
| 41 | requirejs.s.contexts._.config!==undefined)) cfg_paths = requirejs.s.contexts._.config.paths; |
||
| 42 | else console.warn("Require.js paths changed - please contact JSROOT developers"); |
||
| 43 | |||
| 44 | // check if modules are already loaded |
||
| 45 | for (var module in paths) |
||
| 46 | if (requirejs.defined(module) || (cfg_paths && (module in cfg_paths))) |
||
| 47 | delete paths[module]; |
||
| 48 | |||
| 49 | // configure all dependencies |
||
| 50 | requirejs.config({ |
||
| 51 | paths: paths, |
||
| 52 | shim: { |
||
| 53 | 'jqueryui-mousewheel': { deps: ['jquery-ui'] }, |
||
| 54 | 'jqueryui-touch-punch': { deps: ['jquery-ui'] }, |
||
| 55 | 'threejs_all': { deps: [ 'threejs'] }, |
||
| 56 | 'ThreeCSG' : { deps: [ 'threejs'] }, |
||
| 57 | 'MathJax': { |
||
| 58 | exports: 'MathJax', |
||
| 59 | init: function () { |
||
| 60 | MathJax.Hub.Config({ TeX: { extensions: ["color.js"] }, SVG: { mtextFontInherit: true } }); |
||
| 61 | MathJax.Hub.Register.StartupHook("SVG Jax Ready",function () { |
||
| 62 | var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT; |
||
| 63 | VARIANT["normal"].fonts.unshift("MathJax_SansSerif"); |
||
| 64 | VARIANT["bold"].fonts.unshift("MathJax_SansSerif-bold"); |
||
| 65 | VARIANT["italic"].fonts.unshift("MathJax_SansSerif"); |
||
| 66 | VARIANT["-tex-mathit"].fonts.unshift("MathJax_SansSerif"); |
||
| 67 | }); |
||
| 68 | MathJax.Hub.Startup.onload(); |
||
| 69 | return MathJax; |
||
| 70 | } |
||
| 71 | } |
||
| 72 | } |
||
| 73 | }); |
||
| 74 | |||
| 75 | // AMD. Register as an anonymous module. |
||
| 76 | define( jsroot ); |
||
| 77 | |||
| 78 | if (!require.specified("JSRootCore")) |
||
| 79 | define('JSRootCore', [], jsroot); |
||
| 80 | |||
| 81 | if (!require.specified("jsroot")) |
||
| 82 | define('jsroot', [], jsroot); |
||
| 83 | |||
| 84 | } else { |
||
| 85 | |||
| 86 | if (typeof JSROOT != 'undefined') |
||
| 87 | throw new Error("JSROOT is already defined", "JSRootCore.js"); |
||
| 88 | |||
| 89 | JSROOT = {}; |
||
| 90 | |||
| 91 | factory(JSROOT); |
||
| 92 | } |
||
| 93 | } (function(JSROOT) { |
||
| 94 | |||
| 95 | JSROOT.version = "4.8.0 2/12/2016"; |
||
| 96 | |||
| 97 | JSROOT.source_dir = ""; |
||
| 98 | JSROOT.source_min = false; |
||
| 99 | JSROOT.source_fullpath = ""; // full name of source script |
||
| 100 | JSROOT.bower_dir = ""; // when specified, use standard libs from bower location |
||
| 101 | |||
| 102 | JSROOT.id_counter = 0; |
||
| 103 | |||
| 104 | JSROOT.touches = false; |
||
| 105 | JSROOT.browser = { isOpera:false, isFirefox:true, isSafari:false, isChrome:false, isIE:false, isWin:false }; |
||
| 106 | |||
| 107 | if ((typeof document !== "undefined") && (typeof window !== "undefined")) { |
||
| 108 | var scripts = document.getElementsByTagName('script'); |
||
| 109 | for (var n = 0; n < scripts.length; ++n) { |
||
| 110 | var src = scripts[n].src; |
||
| 111 | if ((src===undefined) || (typeof src !== 'string')) continue; |
||
| 112 | |||
| 113 | var pos = src.indexOf("scripts/JSRootCore."); |
||
| 114 | if (pos<0) continue; |
||
| 115 | |||
| 116 | JSROOT.source_dir = src.substr(0, pos); |
||
| 117 | JSROOT.source_min = src.indexOf("scripts/JSRootCore.min.js") >= 0; |
||
| 118 | |||
| 119 | JSROOT.source_fullpath = src; |
||
| 120 | |||
| 121 | if ((console!==undefined) && (typeof console.log == 'function')) |
||
| 122 | console.log("Set JSROOT.source_dir to " + JSROOT.source_dir + ", " + JSROOT.version); |
||
| 123 | break; |
||
| 124 | } |
||
| 125 | |||
| 126 | JSROOT.touches = ('ontouchend' in document); // identify if touch events are supported |
||
| 127 | JSROOT.browser.isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0; |
||
| 128 | JSROOT.browser.isFirefox = typeof InstallTrigger !== 'undefined'; |
||
| 129 | JSROOT.browser.isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0; |
||
| 130 | JSROOT.browser.isChrome = !!window.chrome && !JSROOT.browser.isOpera; |
||
| 131 | JSROOT.browser.isIE = false || !!document.documentMode; |
||
| 132 | JSROOT.browser.isWin = navigator.platform.indexOf('Win') >= 0; |
||
| 133 | } |
||
| 134 | |||
| 135 | JSROOT.browser.isWebKit = JSROOT.browser.isChrome || JSROOT.browser.isSafari; |
||
| 136 | |||
| 137 | // default draw styles, can be changed after loading of JSRootCore.js |
||
| 138 | // this style also can be changed providing style=itemname in the URL |
||
| 139 | JSROOT.gStyle = { |
||
| 140 | Tooltip : 1, // 0 - off, 1 - on |
||
| 141 | ContextMenu : true, |
||
| 142 | Zooming : true, // global zooming flag, enable/disable any kind of interactive zooming |
||
| 143 | ZoomMouse : true, // Zooming with the mouse events |
||
| 144 | ZoomWheel : true, // Zooming with mouse wheel |
||
| 145 | ZoomTouch : true, // Zooming with the touch devices |
||
| 146 | MoveResize : true, // enable move and resize of elements like statbox, title, pave, colz |
||
| 147 | DragAndDrop : true, // enables drag and drop functionality |
||
| 148 | ToolBar : true, // show additional tool buttons on the canvas |
||
| 149 | OptimizeDraw : 1, // drawing optimization: 0 - disabled, 1 - only for large (>5000 1d bins, >50 2d bins) histograms, 2 - always |
||
| 150 | AutoStat : true, |
||
| 151 | FrameNDC : { fX1NDC: 0.07, fY1NDC: 0.12, fX2NDC: 0.95, fY2NDC: 0.88 }, |
||
| 152 | Palette : 57, |
||
| 153 | MathJax : 0, // 0 - never, 1 - only for complex cases, 2 - always |
||
| 154 | ProgressBox : true, // show progress box |
||
| 155 | Embed3DinSVG : 2, // 0 - no embed, only 3D plot, 1 - overlay over SVG (IE/WebKit), 2 - embed into SVG (only Firefox) |
||
| 156 | NoWebGL : false, // if true, WebGL will be disabled, |
||
| 157 | GeoGradPerSegm : 6, // amount of grads per segment in TGeo spherical shapes like tube |
||
| 158 | GeoCompressComp : true, // if one should compress faces after creation of composite shape, |
||
| 159 | IgnoreUrlOptions : false, // if true, ignore all kind of URL options in the browser URL |
||
| 160 | |||
| 161 | // these are TStyle attributes, which can be chenged via URL 'style' parameter |
||
| 162 | |||
| 163 | fPadBottomMargin : 0.1, |
||
| 164 | fPadTopMargin : 0.1, |
||
| 165 | fPadLeftMargin : 0.1, |
||
| 166 | fPadRightMargin : 0.1, |
||
| 167 | fPadGridX : false, |
||
| 168 | fPadGridY : false, |
||
| 169 | fPadTickX : 0, |
||
| 170 | fPadTickY : 0, |
||
| 171 | fStatColor : 0, |
||
| 172 | fStatTextColor : 1, |
||
| 173 | fStatBorderSize : 1, |
||
| 174 | fStatFont : 42, |
||
| 175 | fStatFontSize : 0, |
||
| 176 | fStatStyle : 1001, |
||
| 177 | fStatFormat : "6.4g", |
||
| 178 | fStatX : 0.98, |
||
| 179 | fStatY : 0.935, |
||
| 180 | fStatW : 0.2, |
||
| 181 | fStatH : 0.16, |
||
| 182 | fTitleAlign : 23, |
||
| 183 | fTitleColor : 0, |
||
| 184 | fTitleTextColor : 1, |
||
| 185 | fTitleBorderSize : 0, |
||
| 186 | fTitleFont : 42, |
||
| 187 | fTitleFontSize : 0.05, |
||
| 188 | fTitleStyle : 0, |
||
| 189 | fTitleX : 0.5, |
||
| 190 | fTitleY : 0.995, |
||
| 191 | fTitleW : 0, |
||
| 192 | fTitleH : 0, |
||
| 193 | fFitFormat : "5.4g", |
||
| 194 | fOptStat : 1111, |
||
| 195 | fOptFit : 0, |
||
| 196 | fNumberContours : 20, |
||
| 197 | fGridColor : 0, |
||
| 198 | fGridStyle : 11, |
||
| 199 | fGridWidth : 1, |
||
| 200 | fFrameFillColor : 0, |
||
| 201 | fFrameLineColor : 1, |
||
| 202 | fFrameFillStyle : 1001, |
||
| 203 | fFrameLineStyle : 1, |
||
| 204 | fFrameLineWidth : 1, |
||
| 205 | fFrameBorderSize : 1, |
||
| 206 | fFrameBorderMode : 0, |
||
| 207 | fEndErrorSize : 2, // size in pixels of end error for E1 draw options |
||
| 208 | fErrorX : 0.5, // X size of the error marks for the histogram drawings |
||
| 209 | fHistMinimumZero: false, // when true, BAR and LEGO drawing using base = 0 |
||
| 210 | fPaintTextFormat : "g", |
||
| 211 | fTimeOffset : 788918400, // UTC time at 01/01/95 |
||
| 212 | }; |
||
| 213 | |||
| 214 | JSROOT.BIT = function(n) { return 1 << (n); } |
||
| 215 | |||
| 216 | // TH1 status bits |
||
| 217 | JSROOT.TH1StatusBits = { |
||
| 218 | kNoStats : JSROOT.BIT(9), // don't draw stats box |
||
| 219 | kUserContour : JSROOT.BIT(10), // user specified contour levels |
||
| 220 | kCanRebin : JSROOT.BIT(11), // can rebin axis |
||
| 221 | kLogX : JSROOT.BIT(15), // X-axis in log scale |
||
| 222 | kIsZoomed : JSROOT.BIT(16), // bit set when zooming on Y axis |
||
| 223 | kNoTitle : JSROOT.BIT(17), // don't draw the histogram title |
||
| 224 | kIsAverage : JSROOT.BIT(18) // Bin contents are average (used by Add) |
||
| 225 | }; |
||
| 226 | |||
| 227 | JSROOT.EAxisBits = { |
||
| 228 | kTickPlus : JSROOT.BIT(9), |
||
| 229 | kTickMinus : JSROOT.BIT(10), |
||
| 230 | kAxisRange : JSROOT.BIT(11), |
||
| 231 | kCenterTitle : JSROOT.BIT(12), |
||
| 232 | kCenterLabels : JSROOT.BIT(14), |
||
| 233 | kRotateTitle : JSROOT.BIT(15), |
||
| 234 | kPalette : JSROOT.BIT(16), |
||
| 235 | kNoExponent : JSROOT.BIT(17), |
||
| 236 | kLabelsHori : JSROOT.BIT(18), |
||
| 237 | kLabelsVert : JSROOT.BIT(19), |
||
| 238 | kLabelsDown : JSROOT.BIT(20), |
||
| 239 | kLabelsUp : JSROOT.BIT(21), |
||
| 240 | kIsInteger : JSROOT.BIT(22), |
||
| 241 | kMoreLogLabels : JSROOT.BIT(23), |
||
| 242 | kDecimals : JSROOT.BIT(11) |
||
| 243 | }; |
||
| 244 | |||
| 245 | // wrapper for console.log, avoids missing console in IE |
||
| 246 | // if divid specified, provide output to the HTML element |
||
| 247 | JSROOT.console = function(value, divid) { |
||
| 248 | if ((divid!=null) && (typeof divid=='string') && ((typeof document.getElementById(divid))!='undefined')) |
||
| 249 | document.getElementById(divid).innerHTML = value; |
||
| 250 | else |
||
| 251 | if ((typeof console != 'undefined') && (typeof console.log == 'function')) |
||
| 252 | console.log(value); |
||
| 253 | } |
||
| 254 | |||
| 255 | /// Should be used to reintroduce objects references, produced by TBufferJSON |
||
| 256 | // Replace all references inside object, object should not be null |
||
| 257 | // Idea of the code taken from JSON-R code, found on |
||
| 258 | // https://github.com/graniteds/jsonr |
||
| 259 | // Only unref part was used, arrays are not accounted as objects |
||
| 260 | JSROOT.JSONR_unref = function(obj) { |
||
| 261 | |||
| 262 | var map = [], newfmt = undefined; |
||
| 263 | |||
| 264 | function unref_value(value) { |
||
| 265 | if (value===null) return; |
||
| 266 | |||
| 267 | if (typeof value === 'string') { |
||
| 268 | if (newfmt || (value.length < 6) || (value.indexOf("$ref:") !== 0)) return; |
||
| 269 | var ref = parseInt(value.substr(5)); |
||
| 270 | if (isNaN(ref) || (ref < 0) || (ref >= map.length)) return; |
||
| 271 | newfmt = false; |
||
| 272 | return map[ref]; |
||
| 273 | } |
||
| 274 | |||
| 275 | if (typeof value !== 'object') return; |
||
| 276 | |||
| 277 | var i, k, res, proto = Object.prototype.toString.apply(value); |
||
| 278 | |||
| 279 | // TODO: should we process here typed arrays??? |
||
| 280 | // are there special JSON syntax for typed arrays |
||
| 281 | if ((proto.indexOf('[object')==0) && (proto.indexOf('Array]')>0)) { |
||
| 282 | for (i = 0; i < value.length; ++i) { |
||
| 283 | res = unref_value(value[i]); |
||
| 284 | if (res) value[i] = res; |
||
| 285 | } |
||
| 286 | return; |
||
| 287 | } |
||
| 288 | |||
| 289 | var ks = Object.keys(value), len = ks.length; |
||
| 290 | |||
| 291 | if ((newfmt!==false) && (len===1) && (ks[0]==='$ref')) { |
||
| 292 | var ref = parseInt(value['$ref']); |
||
| 293 | if (isNaN(ref) || (ref < 0) || (ref >= map.length)) return; |
||
| 294 | newfmt = true; |
||
| 295 | return map[ref]; |
||
| 296 | } |
||
| 297 | |||
| 298 | // debug code, can be commented out later |
||
| 299 | if (map.indexOf(value) >= 0) { |
||
| 300 | JSROOT.console('should never happen - object already in the map'); |
||
| 301 | return; |
||
| 302 | } |
||
| 303 | |||
| 304 | // add object to object map |
||
| 305 | map.push(value); |
||
| 306 | |||
| 307 | // add methods to all objects, where _typename is specified |
||
| 308 | if ('_typename' in value) JSROOT.addMethods(value); |
||
| 309 | |||
| 310 | for (k = 0; k < len; ++k) { |
||
| 311 | i = ks[k]; |
||
| 312 | res = unref_value(value[i]); |
||
| 313 | if (res) value[i] = res; |
||
| 314 | } |
||
| 315 | } |
||
| 316 | |||
| 317 | unref_value(obj); |
||
| 318 | |||
| 319 | return obj; |
||
| 320 | } |
||
| 321 | |||
| 322 | JSROOT.debug = 0; |
||
| 323 | |||
| 324 | // This is simple replacement of jQuery.extend method |
||
| 325 | // Just copy (not clone) all fields from source to the target object |
||
| 326 | JSROOT.extend = function(tgt, src) { |
||
| 327 | if ((src === null) || (typeof src !== 'object')) return src; |
||
| 328 | if ((tgt === null) || (typeof tgt !== 'object')) tgt = {}; |
||
| 329 | |||
| 330 | for (var k in src) |
||
| 331 | tgt[k] = src[k]; |
||
| 332 | |||
| 333 | return tgt; |
||
| 334 | } |
||
| 335 | |||
| 336 | // Make deep clone of the object, including all sub-objects |
||
| 337 | JSROOT.clone = function(src, map, nofunc) { |
||
| 338 | if (src === null) return null; |
||
| 339 | |||
| 340 | if (!map) { |
||
| 341 | map = { obj:[], clones:[], nofunc: nofunc }; |
||
| 342 | } else { |
||
| 343 | var i = map.obj.indexOf(src); |
||
| 344 | if (i>=0) return map.clones[i]; |
||
| 345 | } |
||
| 346 | |||
| 347 | var proto = Object.prototype.toString.apply(src); |
||
| 348 | |||
| 349 | // process normal array |
||
| 350 | if (proto === '[object Array]') { |
||
| 351 | var tgt = []; |
||
| 352 | map.obj.push(src); |
||
| 353 | map.clones.push(tgt); |
||
| 354 | for (var i = 0; i < src.length; ++i) |
||
| 355 | if (typeof src[i] === 'object') |
||
| 356 | tgt.push(JSROOT.clone(src[i], map)); |
||
| 357 | else |
||
| 358 | tgt.push(src[i]); |
||
| 359 | |||
| 360 | return tgt; |
||
| 361 | } |
||
| 362 | |||
| 363 | // process typed array |
||
| 364 | if ((proto.indexOf('[object ') == 0) && (proto.indexOf('Array]') == proto.length-6)) { |
||
| 365 | var tgt = []; |
||
| 366 | map.obj.push(src); |
||
| 367 | map.clones.push(tgt); |
||
| 368 | for (var i = 0; i < src.length; ++i) |
||
| 369 | tgt.push(src[i]); |
||
| 370 | |||
| 371 | return tgt; |
||
| 372 | } |
||
| 373 | |||
| 374 | var tgt = {}; |
||
| 375 | map.obj.push(src); |
||
| 376 | map.clones.push(tgt); |
||
| 377 | |||
| 378 | for (var k in src) { |
||
| 379 | if (typeof src[k] === 'object') |
||
| 380 | tgt[k] = JSROOT.clone(src[k], map); |
||
| 381 | else |
||
| 382 | if (!map.nofunc || (typeof src[k]!=='function')) |
||
| 383 | tgt[k] = src[k]; |
||
| 384 | } |
||
| 385 | |||
| 386 | return tgt; |
||
| 387 | } |
||
| 388 | |||
| 389 | // method can be used to delete all functions from objects |
||
| 390 | // only such objects can be cloned when transfer to Worker |
||
| 391 | JSROOT.clear_func = function(src, map) { |
||
| 392 | if (src === null) return src; |
||
| 393 | |||
| 394 | var proto = Object.prototype.toString.apply(src); |
||
| 395 | |||
| 396 | if (proto === '[object Array]') { |
||
| 397 | for (var n=0;n<src.length;n++) |
||
| 398 | if (typeof src[n] === 'object') |
||
| 399 | JSROOT.clear_func(src[n], map); |
||
| 400 | return src; |
||
| 401 | } |
||
| 402 | |||
| 403 | if ((proto.indexOf('[object ') == 0) && (proto.indexOf('Array]') == proto.length-6)) return src; |
||
| 404 | |||
| 405 | if (!map) map = []; |
||
| 406 | var nomap = (map.length == 0); |
||
| 407 | if ('__clean_func__' in src) return src; |
||
| 408 | |||
| 409 | map.push(src); |
||
| 410 | src['__clean_func__'] = true; |
||
| 411 | |||
| 412 | for (var k in src) { |
||
| 413 | if (typeof src[k] === 'object') |
||
| 414 | JSROOT.clear_func(src[k], map); |
||
| 415 | else |
||
| 416 | if (typeof src[k] === 'function') delete src[k]; |
||
| 417 | } |
||
| 418 | |||
| 419 | if (nomap) |
||
| 420 | for (var n=0;n<map.length;++n) |
||
| 421 | delete map[n]['__clean_func__']; |
||
| 422 | |||
| 423 | return src; |
||
| 424 | } |
||
| 425 | |||
| 426 | |||
| 427 | JSROOT.parse = function(arg) { |
||
| 428 | if ((arg==null) || (arg=="")) return null; |
||
| 429 | var obj = JSON.parse(arg); |
||
| 430 | if (obj!=null) obj = this.JSONR_unref(obj); |
||
| 431 | return obj; |
||
| 432 | } |
||
| 433 | |||
| 434 | /** @memberOf JSROOT */ |
||
| 435 | JSROOT.GetUrlOption = function(opt, url, dflt) { |
||
| 436 | // analyzes document.URL and extracts options after '?' mark |
||
| 437 | // following options supported ?opt1&opt2=3 |
||
| 438 | // In case of opt1 empty string will be returned, in case of opt2 '3' |
||
| 439 | // If option not found, null is returned (or provided default value) |
||
| 440 | |||
| 441 | if (dflt === undefined) dflt = null; |
||
| 442 | if ((opt===null) || (typeof opt != 'string') || (opt.length==0)) return dflt; |
||
| 443 | |||
| 444 | if (!url) { |
||
| 445 | if (JSROOT.gStyle.IgnoreUrlOptions || (typeof document === 'undefined')) return dflt; |
||
| 446 | url = document.URL; |
||
| 447 | } |
||
| 448 | |||
| 449 | var pos = url.indexOf("?"); |
||
| 450 | if (pos<0) return dflt; |
||
| 451 | url = url.slice(pos+1); |
||
| 452 | |||
| 453 | while (url.length>0) { |
||
| 454 | |||
| 455 | if (url==opt) return ""; |
||
| 456 | |||
| 457 | pos = url.indexOf("&"); |
||
| 458 | if (pos < 0) pos = url.length; |
||
| 459 | |||
| 460 | if (url.indexOf(opt) == 0) { |
||
| 461 | if (url.charAt(opt.length)=="&") return ""; |
||
| 462 | |||
| 463 | // replace several symbols which are known to make a problem |
||
| 464 | if (url.charAt(opt.length)=="=") |
||
| 465 | return url.slice(opt.length+1, pos).replace(/%27/g, "'").replace(/%22/g, '"').replace(/%20/g, ' ').replace(/%3C/g, '<').replace(/%3E/g, '>').replace(/%5B/g, '[').replace(/%5D/g, ']'); |
||
| 466 | } |
||
| 467 | |||
| 468 | url = url.slice(pos+1); |
||
| 469 | } |
||
| 470 | return dflt; |
||
| 471 | } |
||
| 472 | |||
| 473 | JSROOT.ParseAsArray = function(val) { |
||
| 474 | // parse string value as array. |
||
| 475 | // It could be just simple string: "value" |
||
| 476 | // or array with or without string quotes: [element], ['eleme1',elem2] |
||
| 477 | |||
| 478 | var res = []; |
||
| 479 | |||
| 480 | if (typeof val != 'string') return res; |
||
| 481 | |||
| 482 | val = val.trim(); |
||
| 483 | if (val=="") return res; |
||
| 484 | |||
| 485 | // return as array with single element |
||
| 486 | if ((val.length<2) || (val[0]!='[') || (val[val.length-1]!=']')) { |
||
| 487 | res.push(val); return res; |
||
| 488 | } |
||
| 489 | |||
| 490 | // try to split ourself, checking quotes and brackes |
||
| 491 | var nbr = 0, nquotes = 0, ndouble = 0, last = 1; |
||
| 492 | |||
| 493 | for (var indx = 1; indx < val.length; ++indx) { |
||
| 494 | if (nquotes > 0) { |
||
| 495 | if (val[indx]==="'") nquotes--; |
||
| 496 | continue; |
||
| 497 | } |
||
| 498 | if (ndouble > 0) { |
||
| 499 | if (val[indx]==='"') ndouble--; |
||
| 500 | continue; |
||
| 501 | } |
||
| 502 | switch (val[indx]) { |
||
| 503 | case "'" : nquotes++; break; |
||
| 504 | case '"' : ndouble++; break; |
||
| 505 | case "[" : nbr++; break; |
||
| 506 | case "]" : if (indx < val.length - 1) { nbr--; break; } |
||
| 507 | case "," : |
||
| 508 | if (nbr === 0) { |
||
| 509 | var sub = val.substring(last, indx).trim(); |
||
| 510 | if ((sub.length>1) && (sub[0]==sub[sub.length-1]) && ((sub[0]=='"') || (sub[0]=="'"))) |
||
| 511 | sub = sub.substr(1, sub.length-2); |
||
| 512 | res.push(sub); |
||
| 513 | last = indx+1; |
||
| 514 | } |
||
| 515 | break; |
||
| 516 | } |
||
| 517 | } |
||
| 518 | |||
| 519 | if (res.length === 0) |
||
| 520 | res.push(val.substr(1, val.length-2).trim()); |
||
| 521 | |||
| 522 | return res; |
||
| 523 | } |
||
| 524 | |||
| 525 | JSROOT.GetUrlOptionAsArray = function(opt, url) { |
||
| 526 | // special handling of URL options to produce array |
||
| 527 | // if normal option is specified ...?opt=abc, than array with single element will be created |
||
| 528 | // one could specify normal JSON array ...?opts=['item1','item2'] |
||
| 529 | // but also one could skip quotes ...?opts=[item1,item2] |
||
| 530 | // one could collect values from several options, specifying |
||
| 531 | // options names via semicolon like opt='item;items' |
||
| 532 | |||
| 533 | var res = []; |
||
| 534 | |||
| 535 | while (opt.length>0) { |
||
| 536 | var separ = opt.indexOf(";"); |
||
| 537 | var part = (separ>0) ? opt.substr(0, separ) : opt; |
||
| 538 | |||
| 539 | if (separ>0) opt = opt.substr(separ+1); else opt = ""; |
||
| 540 | |||
| 541 | var canarray = true; |
||
| 542 | if (part[0]=='#') { part = part.substr(1); canarray = false; } |
||
| 543 | |||
| 544 | var val = this.GetUrlOption(part, url, null); |
||
| 545 | |||
| 546 | if (canarray) res = res.concat(JSROOT.ParseAsArray(val)); |
||
| 547 | else if (val!==null) res.push(val); |
||
| 548 | } |
||
| 549 | return res; |
||
| 550 | } |
||
| 551 | |||
| 552 | JSROOT.findFunction = function(name) { |
||
| 553 | if (typeof name === 'function') return name; |
||
| 554 | if (typeof window[name] == 'function') return window[name]; |
||
| 555 | if ((typeof name !== 'string') || (name.indexOf(".") < 0)) return null; |
||
| 556 | |||
| 557 | var names = name.split('.'), elem = window; |
||
| 558 | for (var n=0;n<names.length;++n) { |
||
| 559 | if ((n==0) && (names[0]==='JSROOT')) |
||
| 560 | elem = this; |
||
| 561 | else |
||
| 562 | elem = elem[names[n]]; |
||
| 563 | if (!elem) return null; |
||
| 564 | } |
||
| 565 | |||
| 566 | return (typeof elem == 'function') ? elem : null; |
||
| 567 | } |
||
| 568 | |||
| 569 | JSROOT.CallBack = function(func, arg1, arg2) { |
||
| 570 | // generic method to invoke callback function |
||
| 571 | // func either normal function or container like |
||
| 572 | // { obj: object_pointer, func: name of method to call } |
||
| 573 | // arg1, arg2 are optional arguments of the callback |
||
| 574 | |||
| 575 | if (typeof func == 'string') func = JSROOT.findFunction(func); |
||
| 576 | |||
| 577 | if (func == null) return; |
||
| 578 | |||
| 579 | if (typeof func == 'function') return func(arg1,arg2); |
||
| 580 | |||
| 581 | if (typeof func != 'object') return; |
||
| 582 | |||
| 583 | if (('obj' in func) && ('func' in func) && |
||
| 584 | (typeof func.obj == 'object') && (typeof func.func == 'string') && |
||
| 585 | (typeof func.obj[func.func] == 'function')) { |
||
| 586 | alert('Old-style call-back, change code for ' + func.func); |
||
| 587 | return func.obj[func.func](arg1, arg2); |
||
| 588 | } |
||
| 589 | } |
||
| 590 | |||
| 591 | JSROOT.NewHttpRequest = function(url, kind, user_call_back) { |
||
| 592 | // Create asynchronous XMLHttpRequest object. |
||
| 593 | // One should call req.send() to submit request |
||
| 594 | // kind of the request can be: |
||
| 595 | // "bin" - abstract binary data, result as string (default) |
||
| 596 | // "buf" - abstract binary data, result as BufferArray (if supported) |
||
| 597 | // "text" - returns req.responseText |
||
| 598 | // "object" - returns JSROOT.parse(req.responseText) |
||
| 599 | // "xml" - returns res.responseXML |
||
| 600 | // "head" - returns request itself, uses "HEAD" method |
||
| 601 | // Result will be returned to the callback functions |
||
| 602 | // Request will be set as this pointer in the callback |
||
| 603 | // If failed, request returns null |
||
| 604 | |||
| 605 | var xhr = new XMLHttpRequest(); |
||
| 606 | |||
| 607 | function callback(res) { |
||
| 608 | // we set pointer on request when calling callback |
||
| 609 | if (typeof user_call_back == 'function') user_call_back.call(xhr, res); |
||
| 610 | } |
||
| 611 | |||
| 612 | var pthis = this; |
||
| 613 | |||
| 614 | if (window.ActiveXObject) { |
||
| 615 | |||
| 616 | xhr.onreadystatechange = function() { |
||
| 617 | if (xhr.readyState != 4) return; |
||
| 618 | |||
| 619 | if (xhr.status != 200 && xhr.status != 206) { |
||
| 620 | // error |
||
| 621 | return callback(null); |
||
| 622 | } |
||
| 623 | |||
| 624 | if (kind == "xml") return callback(xhr.responseXML); |
||
| 625 | if (kind == "text") return callback(xhr.responseText); |
||
| 626 | if (kind == "object") return callback(pthis.parse(xhr.responseText)); |
||
| 627 | if (kind == "head") return callback(xhr); |
||
| 628 | |||
| 629 | if ((kind == "buf") && ('responseType' in xhr) && |
||
| 630 | (xhr.responseType == 'arraybuffer') && ('response' in xhr)) |
||
| 631 | return callback(xhr.response); |
||
| 632 | |||
| 633 | var filecontent = new String(""); |
||
| 634 | var array = new VBArray(xhr.responseBody).toArray(); |
||
| 635 | for (var i = 0; i < array.length; ++i) |
||
| 636 | filecontent = filecontent + String.fromCharCode(array[i]); |
||
| 637 | delete array; |
||
| 638 | callback(filecontent); |
||
| 639 | } |
||
| 640 | |||
| 641 | xhr.open(kind == 'head' ? 'HEAD' : 'GET', url, true); |
||
| 642 | |||
| 643 | if (kind=="buf") { |
||
| 644 | if (('Uint8Array' in window) && ('responseType' in xhr)) |
||
| 645 | xhr.responseType = 'arraybuffer'; |
||
| 646 | } |
||
| 647 | |||
| 648 | } else { |
||
| 649 | |||
| 650 | xhr.onreadystatechange = function() { |
||
| 651 | if (xhr.readyState != 4) return; |
||
| 652 | |||
| 653 | if ((xhr.status != 200) && (xhr.status != 206) && |
||
| 654 | ((xhr.status !== 0) || (url.indexOf("file://")!==0))) { |
||
| 655 | return callback(null); |
||
| 656 | } |
||
| 657 | |||
| 658 | if (kind == "xml") return callback(xhr.responseXML); |
||
| 659 | if (kind == "text") return callback(xhr.responseText); |
||
| 660 | if (kind == "object") return callback(pthis.parse(xhr.responseText)); |
||
| 661 | if (kind == "head") return callback(xhr); |
||
| 662 | |||
| 663 | // if no response type is supported, return as text (most probably, will fail) |
||
| 664 | if (! ('responseType' in xhr)) |
||
| 665 | return callback(xhr.responseText); |
||
| 666 | |||
| 667 | if ((kind=="bin") && ('Uint8Array' in window) && ('byteLength' in xhr.response)) { |
||
| 668 | // if string representation in requested - provide it |
||
| 669 | |||
| 670 | var filecontent = "", u8Arr = new Uint8Array(xhr.response); |
||
| 671 | for (var i = 0; i < u8Arr.length; ++i) |
||
| 672 | filecontent += String.fromCharCode(u8Arr[i]); |
||
| 673 | delete u8Arr; |
||
| 674 | |||
| 675 | return callback(filecontent); |
||
| 676 | } |
||
| 677 | |||
| 678 | callback(xhr.response); |
||
| 679 | } |
||
| 680 | |||
| 681 | xhr.open(kind == 'head' ? 'HEAD' : 'GET', url, true); |
||
| 682 | |||
| 683 | if ((kind == "bin") || (kind == "buf")) { |
||
| 684 | if (('Uint8Array' in window) && ('responseType' in xhr)) { |
||
| 685 | xhr.responseType = 'arraybuffer'; |
||
| 686 | } else { |
||
| 687 | //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] |
||
| 688 | xhr.overrideMimeType("text/plain; charset=x-user-defined"); |
||
| 689 | } |
||
| 690 | } |
||
| 691 | |||
| 692 | } |
||
| 693 | return xhr; |
||
| 694 | } |
||
| 695 | |||
| 696 | JSROOT.loadScript = function(urllist, callback, debugout) { |
||
| 697 | // dynamic script loader using callback |
||
| 698 | // (as loading scripts may be asynchronous) |
||
| 699 | // one could specify list of scripts or style files, separated by semicolon ';' |
||
| 700 | // one can prepend file name with '$$$' - than file will be loaded from JSROOT location |
||
| 701 | // This location can be set by JSROOT.source_dir or it will be detected automatically |
||
| 702 | // by the position of JSRootCore.js file, which must be loaded by normal methods: |
||
| 703 | // <script type="text/javascript" src="scripts/JSRootCore.js"></script> |
||
| 704 | |||
| 705 | function completeLoad() { |
||
| 706 | if (debugout) |
||
| 707 | document.getElementById(debugout).innerHTML = ""; |
||
| 708 | else |
||
| 709 | JSROOT.progress(); |
||
| 710 | |||
| 711 | if ((urllist!=null) && (urllist.length>0)) |
||
| 712 | return JSROOT.loadScript(urllist, callback, debugout); |
||
| 713 | |||
| 714 | JSROOT.CallBack(callback); |
||
| 715 | } |
||
| 716 | |||
| 717 | if ((urllist==null) || (urllist.length==0)) |
||
| 718 | return completeLoad(); |
||
| 719 | |||
| 720 | var filename = urllist; |
||
| 721 | var separ = filename.indexOf(";"); |
||
| 722 | if (separ>0) { |
||
| 723 | filename = filename.substr(0, separ); |
||
| 724 | urllist = urllist.slice(separ+1); |
||
| 725 | } else { |
||
| 726 | urllist = ""; |
||
| 727 | } |
||
| 728 | |||
| 729 | var isrootjs = false, isbower = false; |
||
| 730 | if (filename.indexOf("$$$")===0) { |
||
| 731 | isrootjs = true; |
||
| 732 | filename = filename.slice(3); |
||
| 733 | if ((filename.indexOf("style/")==0) && JSROOT.source_min && |
||
| 734 | (filename.lastIndexOf('.css')==filename.length-3) && |
||
| 735 | (filename.indexOf('.min.css')<0)) |
||
| 736 | filename = filename.slice(0, filename.length-4) + '.min.css'; |
||
| 737 | } else |
||
| 738 | if (filename.indexOf("###")===0) { |
||
| 739 | isbower = true; |
||
| 740 | filename = filename.slice(3); |
||
| 741 | } |
||
| 742 | |||
| 743 | var font_suffix = filename.indexOf('.typeface.json'); |
||
| 744 | if (font_suffix > 0) { |
||
| 745 | var fontid = 'threejs_font_' + filename.slice(filename.lastIndexOf('/')+1, font_suffix); |
||
| 746 | if (typeof JSROOT[fontid] !== 'undefined') return completeLoad(); |
||
| 747 | |||
| 748 | if ((typeof THREE === 'undefined') || (typeof THREE.FontLoader === 'undefined')) { |
||
| 749 | console.log('fail to load',filename,'no (proper) three.js found'); |
||
| 750 | return completeLoad(); |
||
| 751 | } |
||
| 752 | |||
| 753 | JSROOT.progress("loading " + filename + " ..."); |
||
| 754 | |||
| 755 | var loader = new THREE.FontLoader(); |
||
| 756 | loader.load( filename, function ( response ) { |
||
| 757 | JSROOT[fontid] = response; |
||
| 758 | completeLoad(); |
||
| 759 | } ); |
||
| 760 | return; |
||
| 761 | } |
||
| 762 | |||
| 763 | var isstyle = filename.indexOf('.css') > 0; |
||
| 764 | |||
| 765 | if (isstyle) { |
||
| 766 | var styles = document.getElementsByTagName('link'); |
||
| 767 | for (var n = 0; n < styles.length; ++n) { |
||
| 768 | if ((styles[n].type != 'text/css') || (styles[n].rel !== 'stylesheet')) continue; |
||
| 769 | |||
| 770 | var href = styles[n].href; |
||
| 771 | if ((href == null) || (href.length == 0)) continue; |
||
| 772 | |||
| 773 | if (href.indexOf(filename)>=0) return completeLoad(); |
||
| 774 | } |
||
| 775 | |||
| 776 | } else { |
||
| 777 | var scripts = document.getElementsByTagName('script'); |
||
| 778 | |||
| 779 | for (var n = 0; n < scripts.length; ++n) { |
||
| 780 | // if (scripts[n].type != 'text/javascript') continue; |
||
| 781 | |||
| 782 | var src = scripts[n].src; |
||
| 783 | if ((src == null) || (src.length == 0)) continue; |
||
| 784 | |||
| 785 | if ((src.indexOf(filename)>=0) && (src.indexOf("load=")<0)) { |
||
| 786 | // avoid wrong decision when script name is specified as more argument |
||
| 787 | return completeLoad(); |
||
| 788 | } |
||
| 789 | } |
||
| 790 | } |
||
| 791 | |||
| 792 | if (isrootjs && (JSROOT.source_dir!=null)) filename = JSROOT.source_dir + filename; else |
||
| 793 | if (isbower && (JSROOT.bower_dir.length>0)) filename = JSROOT.bower_dir + filename; |
||
| 794 | |||
| 795 | var element = null; |
||
| 796 | |||
| 797 | if (debugout) |
||
| 798 | document.getElementById(debugout).innerHTML = "loading " + filename + " ..."; |
||
| 799 | else |
||
| 800 | JSROOT.progress("loading " + filename + " ..."); |
||
| 801 | |||
| 802 | if (isstyle) { |
||
| 803 | element = document.createElement("link"); |
||
| 804 | element.setAttribute("rel", "stylesheet"); |
||
| 805 | element.setAttribute("type", "text/css"); |
||
| 806 | element.setAttribute("href", filename); |
||
| 807 | } else { |
||
| 808 | element = document.createElement("script"); |
||
| 809 | element.setAttribute('type', "text/javascript"); |
||
| 810 | element.setAttribute('src', filename); |
||
| 811 | } |
||
| 812 | |||
| 813 | if (element.readyState) { // Internet Explorer specific |
||
| 814 | element.onreadystatechange = function() { |
||
| 815 | if (element.readyState == "loaded" || element.readyState == "complete") { |
||
| 816 | element.onreadystatechange = null; |
||
| 817 | completeLoad(); |
||
| 818 | } |
||
| 819 | } |
||
| 820 | } else { // Other browsers |
||
| 821 | element.onload = function() { |
||
| 822 | element.onload = null; |
||
| 823 | completeLoad(); |
||
| 824 | } |
||
| 825 | } |
||
| 826 | |||
| 827 | document.getElementsByTagName("head")[0].appendChild(element); |
||
| 828 | } |
||
| 829 | |||
| 830 | JSROOT.AssertPrerequisites = function(kind, callback, debugout) { |
||
| 831 | // one could specify kind of requirements |
||
| 832 | // 'io' for I/O functionality (default) |
||
| 833 | // '2d' for basic 2d graphic (TCanvas, TH1) |
||
| 834 | // 'more2d' for extra 2d graphic (TH2, TGraph) |
||
| 835 | // 'jq' jQuery and jQuery-ui |
||
| 836 | // 'jq2d' jQuery-dependend part of 2d graphic |
||
| 837 | // '3d' for histograms 3d graphic |
||
| 838 | // 'geom' for geometry drawing support |
||
| 839 | // 'simple' for basic user interface |
||
| 840 | // 'load:' list of user-specific scripts at the end of kind string |
||
| 841 | |||
| 842 | var jsroot = JSROOT; |
||
| 843 | |||
| 844 | if (jsroot.doing_assert === undefined) jsroot.doing_assert = []; |
||
| 845 | if (jsroot.ready_modules === undefined) jsroot.ready_modules = []; |
||
| 846 | |||
| 847 | if ((typeof kind !== 'string') || (kind == '')) |
||
| 848 | return jsroot.CallBack(callback); |
||
| 849 | |||
| 850 | if (kind === '__next__') { |
||
| 851 | if (jsroot.doing_assert.length==0) return; |
||
| 852 | var req = jsroot.doing_assert[0]; |
||
| 853 | if (req.running) return; |
||
| 854 | kind = req._kind; |
||
| 855 | callback = req._callback; |
||
| 856 | debugout = req._debug; |
||
| 857 | } else { |
||
| 858 | jsroot.doing_assert.push({_kind:kind, _callback:callback, _debug: debugout}); |
||
| 859 | if (jsroot.doing_assert.length > 1) return; |
||
| 860 | } |
||
| 861 | |||
| 862 | jsroot.doing_assert[0].running = true; |
||
| 863 | |||
| 864 | if (kind.charAt(kind.length-1)!=";") kind+=";"; |
||
| 865 | |||
| 866 | var ext = jsroot.source_min ? ".min" : "", |
||
| 867 | need_jquery = false, |
||
| 868 | use_bower = (jsroot.bower_dir.length > 0), |
||
| 869 | mainfiles = "", |
||
| 870 | extrafiles = "", // scripts for direct loadin |
||
| 871 | modules = []; // modules used for require.js |
||
| 872 | |||
| 873 | if (kind.indexOf('io;')>=0) { |
||
| 874 | mainfiles += "$$$scripts/rawinflate.min.js;" + |
||
| 875 | "$$$scripts/JSRootIOEvolution" + ext + ".js;"; |
||
| 876 | modules.push('JSRootIOEvolution'); |
||
| 877 | } |
||
| 878 | |||
| 879 | if (kind.indexOf('2d;')>=0) { |
||
| 880 | if (jsroot._test_d3_ === undefined) { |
||
| 881 | if (typeof d3 != 'undefined') { |
||
| 882 | jsroot.console('Reuse existing d3.js ' + d3.version + ", required 3.5.9", debugout); |
||
| 883 | jsroot._test_d3_ = 1; |
||
| 884 | } else { |
||
| 885 | mainfiles += use_bower ? '###d3/d3.min.js;' : '$$$scripts/d3.v3.min.js;'; |
||
| 886 | jsroot._test_d3_ = 2; |
||
| 887 | } |
||
| 888 | } |
||
| 889 | modules.push('JSRootPainter'); |
||
| 890 | mainfiles += '$$$scripts/JSRootPainter' + ext + ".js;"; |
||
| 891 | extrafiles += '$$$style/JSRootPainter' + ext + '.css;'; |
||
| 892 | } |
||
| 893 | |||
| 894 | if (kind.indexOf('savepng;')>=0) { |
||
| 895 | modules.push('saveSvgAsPng'); |
||
| 896 | mainfiles += '$$$scripts/saveSvgAsPng.min.js;'; |
||
| 897 | } |
||
| 898 | |||
| 899 | if (kind.indexOf('jq;')>=0) need_jquery = true; |
||
| 900 | |||
| 901 | if (kind.indexOf('math;')>=0) { |
||
| 902 | mainfiles += '$$$scripts/JSRootMath' + ext + ".js;"; |
||
| 903 | modules.push('JSRootMath'); |
||
| 904 | } |
||
| 905 | |||
| 906 | if (kind.indexOf('more2d;')>=0) { |
||
| 907 | mainfiles += '$$$scripts/JSRootPainter.more' + ext + ".js;"; |
||
| 908 | modules.push('JSRootPainter.more'); |
||
| 909 | } |
||
| 910 | |||
| 911 | if (kind.indexOf('jq2d;')>=0) { |
||
| 912 | mainfiles += '$$$scripts/JSRootPainter.jquery' + ext + ".js;"; |
||
| 913 | modules.push('JSRootPainter.jquery'); |
||
| 914 | need_jquery = true; |
||
| 915 | } |
||
| 916 | |||
| 917 | if ((kind.indexOf("3d;")>=0) || (kind.indexOf("geom;")>=0)) { |
||
| 918 | if (use_bower) { |
||
| 919 | mainfiles += "###threejs/build/three.min.js;" + |
||
| 920 | "###threejs/examples/js/renderers/Projector.js;" + |
||
| 921 | "###threejs/examples/js/renderers/CanvasRenderer.js;" + |
||
| 922 | "###threejs/examples/js/controls/OrbitControls.js;" + |
||
| 923 | "###threejs/examples/js/controls/TransformControls.js;" + |
||
| 924 | "###threejs/examples/js/shaders/CopyShader.js;" + |
||
| 925 | "###threejs/examples/js/postprocessing/EffectComposer.js;" + |
||
| 926 | "###threejs/examples/js/postprocessing/MaskPass.js;" + |
||
| 927 | "###threejs/examples/js/postprocessing/RenderPass.js;" + |
||
| 928 | "###threejs/examples/js/postprocessing/ShaderPass.js;" + |
||
| 929 | "###threejs/examples/js/shaders/SSAOShader.js;" |
||
| 930 | extrafiles += "###threejs/examples/fonts/helvetiker_regular.typeface.json;"; |
||
| 931 | } else { |
||
| 932 | mainfiles += "$$$scripts/three.min.js;" + |
||
| 933 | "$$$scripts/three.extra.min.js;"; |
||
| 934 | } |
||
| 935 | modules.push("threejs", "threejs_all"); |
||
| 936 | mainfiles += "$$$scripts/JSRoot3DPainter" + ext + ".js;"; |
||
| 937 | modules.push('JSRoot3DPainter'); |
||
| 938 | } |
||
| 939 | |||
| 940 | if (kind.indexOf("geom;")>=0) { |
||
| 941 | mainfiles += "$$$scripts/ThreeCSG" + ext + ".js;" + |
||
| 942 | "$$$scripts/JSRootGeoBase" + ext + ".js;" + |
||
| 943 | "$$$scripts/JSRootGeoPainter" + ext + ".js;" + |
||
| 944 | "$$$scripts/dat.gui.min.js;"; |
||
| 945 | extrafiles += "$$$style/JSRootGeoPainter" + ext + ".css;"; |
||
| 946 | modules.push('ThreeCSG', 'JSRootGeoBase', 'JSRootGeoPainter', 'dat.gui'); |
||
| 947 | } |
||
| 948 | |||
| 949 | if (kind.indexOf("mathjax;")>=0) { |
||
| 950 | if (typeof MathJax == 'undefined') { |
||
| 951 | mainfiles += (use_bower ? "###MathJax/MathJax.js" : "https://cdn.mathjax.org/mathjax/latest/MathJax.js") + |
||
| 952 | "?config=TeX-AMS-MML_SVG," + jsroot.source_dir + "scripts/mathjax_config.js;"; |
||
| 953 | } |
||
| 954 | if (jsroot.gStyle.MathJax == 0) jsroot.gStyle.MathJax = 1; |
||
| 955 | modules.push('MathJax'); |
||
| 956 | } |
||
| 957 | |||
| 958 | if (kind.indexOf("simple;")>=0) { |
||
| 959 | need_jquery = true; |
||
| 960 | mainfiles += '$$$scripts/JSRootInterface' + ext + ".js;"; |
||
| 961 | extrafiles += '$$$style/JSRootInterface' + ext + '.css;'; |
||
| 962 | modules.push('JSRootInterface'); |
||
| 963 | } |
||
| 964 | |||
| 965 | if (need_jquery && !jsroot.load_jquery) { |
||
| 966 | var has_jq = (typeof jQuery != 'undefined'), lst_jq = ""; |
||
| 967 | |||
| 968 | if (has_jq) |
||
| 969 | jsroot.console('Reuse existing jQuery ' + jQuery.fn.jquery + ", required 2.1.4", debugout); |
||
| 970 | else |
||
| 971 | lst_jq += (use_bower ? "###jquery/dist" : "$$$scripts") + "/jquery.min.js;"; |
||
| 972 | if (has_jq && typeof $.ui != 'undefined') |
||
| 973 | jsroot.console('Reuse existing jQuery-ui ' + $.ui.version + ", required 1.11.4", debugout); |
||
| 974 | else { |
||
| 975 | lst_jq += (use_bower ? "###jquery-ui" : "$$$scripts") + '/jquery-ui.min.js;'; |
||
| 976 | extrafiles += '$$$style/jquery-ui' + ext + '.css;'; |
||
| 977 | } |
||
| 978 | |||
| 979 | if (jsroot.touches) { |
||
| 980 | lst_jq += use_bower ? '###jqueryui-touch-punch/jquery.ui.touch-punch.min.js;' : '$$$scripts/touch-punch.min.js;'; |
||
| 981 | modules.push('jqueryui-touch-punch'); |
||
| 982 | } |
||
| 983 | |||
| 984 | modules.splice(0,0, 'jquery', 'jquery-ui', 'jqueryui-mousewheel'); |
||
| 985 | mainfiles = lst_jq + mainfiles; |
||
| 986 | |||
| 987 | jsroot.load_jquery = true; |
||
| 988 | } |
||
| 989 | |||
| 990 | var pos = kind.indexOf("user:"); |
||
| 991 | if (pos<0) pos = kind.indexOf("load:"); |
||
| 992 | if (pos>=0) extrafiles += kind.slice(pos+5); |
||
| 993 | |||
| 994 | function load_callback() { |
||
| 995 | var req = jsroot.doing_assert.shift(); |
||
| 996 | for (var n=0;n<req.modules.length;++n) |
||
| 997 | jsroot.ready_modules.push(req.modules[n]); |
||
| 998 | jsroot.CallBack(req._callback); |
||
| 999 | jsroot.AssertPrerequisites('__next__'); |
||
| 1000 | } |
||
| 1001 | |||
| 1002 | // check if modules already loaded |
||
| 1003 | for (var n=modules.length-1;n>=0;--n) |
||
| 1004 | if (jsroot.ready_modules.indexOf(modules[n])>=0) |
||
| 1005 | modules.splice(n,1); |
||
| 1006 | |||
| 1007 | // no modules means no main files |
||
| 1008 | if (modules.length===0) mainfiles = ""; |
||
| 1009 | |||
| 1010 | jsroot.doing_assert[0].modules = modules; |
||
| 1011 | |||
| 1012 | if ((modules.length>0) && (typeof define === "function") && define.amd) { |
||
| 1013 | jsroot.console("loading " + JSON.stringify(modules) + " with require.js", debugout); |
||
| 1014 | require(modules, function() { |
||
| 1015 | jsroot.loadScript(extrafiles, load_callback, debugout); |
||
| 1016 | }); |
||
| 1017 | } else { |
||
| 1018 | jsroot.loadScript(mainfiles + extrafiles, load_callback, debugout); |
||
| 1019 | } |
||
| 1020 | } |
||
| 1021 | |||
| 1022 | // function can be used to open ROOT file, I/O functionality will be loaded when missing |
||
| 1023 | JSROOT.OpenFile = function(filename, callback) { |
||
| 1024 | JSROOT.AssertPrerequisites("io", function() { |
||
| 1025 | new JSROOT.TFile(filename, callback); |
||
| 1026 | }); |
||
| 1027 | } |
||
| 1028 | |||
| 1029 | // function can be used to draw supported ROOT classes, |
||
| 1030 | // required functionality will be loaded automatically |
||
| 1031 | // if painter pointer required, one should load '2d' functionlity itself |
||
| 1032 | JSROOT.draw = function(divid, obj, opt) { |
||
| 1033 | JSROOT.AssertPrerequisites("2d", function() { |
||
| 1034 | JSROOT.draw(divid, obj, opt); |
||
| 1035 | }); |
||
| 1036 | } |
||
| 1037 | |||
| 1038 | JSROOT.redraw = function(divid, obj, opt) { |
||
| 1039 | JSROOT.AssertPrerequisites("2d", function() { |
||
| 1040 | JSROOT.redraw(divid, obj, opt); |
||
| 1041 | }); |
||
| 1042 | } |
||
| 1043 | |||
| 1044 | JSROOT.BuildSimpleGUI = function(user_scripts, andThen) { |
||
| 1045 | if (typeof user_scripts == 'function') { |
||
| 1046 | andThen = user_scripts; |
||
| 1047 | user_scripts = null; |
||
| 1048 | } |
||
| 1049 | |||
| 1050 | var debugout = null, |
||
| 1051 | nobrowser = JSROOT.GetUrlOption('nobrowser')!=null, |
||
| 1052 | requirements = "io;2d;", |
||
| 1053 | simplegui = document.getElementById('simpleGUI'); |
||
| 1054 | |||
| 1055 | if (simplegui) { |
||
| 1056 | debugout = 'simpleGUI'; |
||
| 1057 | if ((JSROOT.GetUrlOption('json')!=null) && |
||
| 1058 | (JSROOT.GetUrlOption('file')==null) && |
||
| 1059 | (JSROOT.GetUrlOption('files')==null)) requirements = "2d;"; |
||
| 1060 | if (simplegui.getAttribute('nobrowser') && (simplegui.getAttribute('nobrowser')!="false")) nobrowser = true; |
||
| 1061 | } else |
||
| 1062 | if (document.getElementById('onlineGUI')) { debugout = 'onlineGUI'; requirements = "2d;"; } else |
||
| 1063 | if (document.getElementById('drawGUI')) { debugout = 'drawGUI'; requirements = "2d;"; nobrowser = true; } |
||
| 1064 | |||
| 1065 | if (user_scripts == 'check_existing_elements') { |
||
| 1066 | user_scripts = null; |
||
| 1067 | if (debugout == null) return; |
||
| 1068 | } |
||
| 1069 | |||
| 1070 | if (!nobrowser) requirements += 'jq2d;simple;'; |
||
| 1071 | |||
| 1072 | if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("autoload"); |
||
| 1073 | if (user_scripts == null) user_scripts = JSROOT.GetUrlOption("load"); |
||
| 1074 | |||
| 1075 | if (user_scripts != null) |
||
| 1076 | requirements += "load:" + user_scripts + ";"; |
||
| 1077 | |||
| 1078 | JSROOT.AssertPrerequisites(requirements, function() { |
||
| 1079 | JSROOT.CallBack(JSROOT.findFunction(nobrowser ? 'JSROOT.BuildNobrowserGUI' : 'BuildSimpleGUI')); |
||
| 1080 | JSROOT.CallBack(andThen); |
||
| 1081 | }, debugout); |
||
| 1082 | }; |
||
| 1083 | |||
| 1084 | JSROOT.Create = function(typename, target) { |
||
| 1085 | var obj = target; |
||
| 1086 | if (obj == null) obj = { _typename: typename }; |
||
| 1087 | |||
| 1088 | switch (typename) { |
||
| 1089 | case 'TObject': |
||
| 1090 | JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008 }); |
||
| 1091 | break; |
||
| 1092 | case 'TNamed': |
||
| 1093 | JSROOT.extend(obj, { fUniqueID: 0, fBits: 0x3000008, fName: "", fTitle: "" }); |
||
| 1094 | break; |
||
| 1095 | case 'TList': |
||
| 1096 | case 'THashList': |
||
| 1097 | JSROOT.extend(obj, { name: typename, arr : [], opt : [] }); |
||
| 1098 | break; |
||
| 1099 | case 'TAttAxis': |
||
| 1100 | JSROOT.extend(obj, { fNdivisions: 510, fAxisColor: 1, |
||
| 1101 | fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.005, fLabelSize: 0.035, fTickLength: 0.03, |
||
| 1102 | fTitleOffset: 1, fTitleSize: 0.035, fTitleColor: 1, fTitleFont : 42 }); |
||
| 1103 | break; |
||
| 1104 | case 'TAxis': |
||
| 1105 | JSROOT.Create("TNamed", obj); |
||
| 1106 | JSROOT.Create("TAttAxis", obj); |
||
| 1107 | JSROOT.extend(obj, { fNbins: 0, fXmin: 0, fXmax: 0, fXbins : [], fFirst: 0, fLast: 0, |
||
| 1108 | fBits2: 0, fTimeDisplay: false, fTimeFormat: "", fLabels: null }); |
||
| 1109 | break; |
||
| 1110 | case 'TAttLine': |
||
| 1111 | JSROOT.extend(obj, { fLineColor: 1, fLineStyle : 1, fLineWidth : 1 }); |
||
| 1112 | break; |
||
| 1113 | case 'TAttFill': |
||
| 1114 | JSROOT.extend(obj, { fFillColor: 0, fFillStyle : 0 } ); |
||
| 1115 | break; |
||
| 1116 | case 'TAttMarker': |
||
| 1117 | JSROOT.extend(obj, { fMarkerColor: 1, fMarkerStyle : 1, fMarkerSize : 1. }); |
||
| 1118 | break; |
||
| 1119 | case 'TLine': |
||
| 1120 | JSROOT.Create("TObject", obj); |
||
| 1121 | JSROOT.Create("TAttLine", obj); |
||
| 1122 | JSROOT.extend(obj, { fX1: 0, fX2: 1, fY1: 0, fY2: 1 }); |
||
| 1123 | break; |
||
| 1124 | case 'TBox': |
||
| 1125 | JSROOT.Create("TObject", obj); |
||
| 1126 | JSROOT.Create("TAttLine", obj); |
||
| 1127 | JSROOT.Create("TAttFill", obj); |
||
| 1128 | JSROOT.extend(obj, { fX1: 0, fX2: 1, fY1: 0, fY2: 1 }); |
||
| 1129 | break; |
||
| 1130 | case 'TPave': |
||
| 1131 | JSROOT.Create("TBox", obj); |
||
| 1132 | JSROOT.extend(obj, { fX1NDC : 0., fY1NDC: 0, fX2NDC: 1, fY2NDC: 1, |
||
| 1133 | fBorderSize: 0, fInit: 1, fShadowColor: 1, |
||
| 1134 | fCornerRadius: 0, fOption: "blNDC", fName: "title" }); |
||
| 1135 | break; |
||
| 1136 | case 'TAttText': |
||
| 1137 | JSROOT.extend(obj, { fTextAngle: 0, fTextSize: 0, fTextAlign: 22, fTextColor: 1, fTextFont: 42}); |
||
| 1138 | break; |
||
| 1139 | case 'TPaveText': |
||
| 1140 | JSROOT.Create("TPave", obj); |
||
| 1141 | JSROOT.Create("TAttText", obj); |
||
| 1142 | JSROOT.extend(obj, { fLabel: "", fLongest: 27, fMargin: 0.05, fLines: JSROOT.Create("TList") }); |
||
| 1143 | break; |
||
| 1144 | case 'TPaveStats': |
||
| 1145 | JSROOT.Create("TPaveText", obj); |
||
| 1146 | JSROOT.extend(obj, { fOptFit: 0, fOptStat: 0, fFitFormat: "", fStatFormat: "", fParent: null }); |
||
| 1147 | break; |
||
| 1148 | case 'TLegend': |
||
| 1149 | JSROOT.Create("TPave", obj); |
||
| 1150 | JSROOT.Create("TAttText", obj); |
||
| 1151 | JSROOT.extend(obj, { fColumnSeparation: 0, fEntrySeparation: 0.1, fMargin: 0.25, fNColumns: 1, fPrimitives: JSROOT.Create("TList") }); |
||
| 1152 | break; |
||
| 1153 | case 'TLegendEntry': |
||
| 1154 | JSROOT.Create("TObject", obj); |
||
| 1155 | JSROOT.Create("TAttText", obj); |
||
| 1156 | JSROOT.Create("TAttLine", obj); |
||
| 1157 | JSROOT.Create("TAttFill", obj); |
||
| 1158 | JSROOT.Create("TAttMarker", obj); |
||
| 1159 | JSROOT.extend(obj, { fLabel: "", fObject: null, fOption: "" }); |
||
| 1160 | break; |
||
| 1161 | case 'TObjString': |
||
| 1162 | JSROOT.Create("TObject", obj); |
||
| 1163 | JSROOT.extend(obj, { fString: "" }); |
||
| 1164 | break; |
||
| 1165 | case 'TH1': |
||
| 1166 | JSROOT.Create("TNamed", obj); |
||
| 1167 | JSROOT.Create("TAttLine", obj); |
||
| 1168 | JSROOT.Create("TAttFill", obj); |
||
| 1169 | JSROOT.Create("TAttMarker", obj); |
||
| 1170 | |||
| 1171 | JSROOT.extend(obj, { |
||
| 1172 | fNcells : 0, |
||
| 1173 | fXaxis: JSROOT.Create("TAxis"), |
||
| 1174 | fYaxis: JSROOT.Create("TAxis"), |
||
| 1175 | fZaxis: JSROOT.Create("TAxis"), |
||
| 1176 | fBarOffset: 0, fBarWidth: 1000, fEntries: 0., |
||
| 1177 | fTsumw: 0., fTsumw2: 0., fTsumwx: 0., fTsumwx2: 0., |
||
| 1178 | fMaximum: -1111., fMinimum: -1111, fNormFactor: 0., fContour: [], |
||
| 1179 | fSumw2: [], fOption: "", |
||
| 1180 | fFunctions: JSROOT.Create("TList"), |
||
| 1181 | fBufferSize: 0, fBuffer: [], fBinStatErrOpt: 0 }); |
||
| 1182 | break; |
||
| 1183 | case 'TH1I': |
||
| 1184 | case 'TH1F': |
||
| 1185 | case 'TH1D': |
||
| 1186 | case 'TH1S': |
||
| 1187 | case 'TH1C': |
||
| 1188 | JSROOT.Create("TH1", obj); |
||
| 1189 | obj.fArray = []; |
||
| 1190 | break; |
||
| 1191 | case 'TH2': |
||
| 1192 | JSROOT.Create("TH1", obj); |
||
| 1193 | JSROOT.extend(obj, { fScalefactor: 1., fTsumwy: 0., fTsumwy2: 0, fTsumwxy : 0}); |
||
| 1194 | break; |
||
| 1195 | case 'TH2I': |
||
| 1196 | case 'TH2F': |
||
| 1197 | case 'TH2D': |
||
| 1198 | case 'TH2S': |
||
| 1199 | case 'TH2C': |
||
| 1200 | JSROOT.Create("TH2", obj); |
||
| 1201 | obj.fArray = []; |
||
| 1202 | break; |
||
| 1203 | case 'TGraph': |
||
| 1204 | JSROOT.Create("TNamed", obj); |
||
| 1205 | JSROOT.Create("TAttLine", obj); |
||
| 1206 | JSROOT.Create("TAttFill", obj); |
||
| 1207 | JSROOT.Create("TAttMarker", obj); |
||
| 1208 | JSROOT.extend(obj, { fFunctions: JSROOT.Create("TList"), fHistogram: null, |
||
| 1209 | fMaxSize: 0, fMaximum:-1111, fMinimum:-1111, fNpoints: 0, fX: [], fY: [] }); |
||
| 1210 | break; |
||
| 1211 | case 'TMultiGraph': |
||
| 1212 | JSROOT.Create("TNamed", obj); |
||
| 1213 | JSROOT.extend(obj, { fFunctions: JSROOT.Create("TList"), fGraphs: JSROOT.Create("TList"), |
||
| 1214 | fHistogram: null, fMaximum: -1111, fMinimum: -1111 }); |
||
| 1215 | break; |
||
| 1216 | case 'TPolyLine': |
||
| 1217 | JSROOT.Create("TObject", obj); |
||
| 1218 | JSROOT.Create("TAttLine", obj); |
||
| 1219 | JSROOT.Create("TAttFill", obj); |
||
| 1220 | JSROOT.extend(obj, { fLastPoint: -1, fN: 0, fOption: "", fX: null, fY: null }); |
||
| 1221 | break; |
||
| 1222 | case 'TGaxis': |
||
| 1223 | JSROOT.Create("TLine", obj); |
||
| 1224 | JSROOT.Create("TAttText", obj); |
||
| 1225 | JSROOT.extend(obj, { _fChopt: "", fFunctionName: "", fGridLength: 0, |
||
| 1226 | fLabelColor: 1, fLabelFont: 42, fLabelOffset: 0.005, fLabelSize: 0.035, |
||
| 1227 | fName: "", fNdiv: 12, fTickSize: 0.02, fTimeFormat: "", |
||
| 1228 | fTitle: "", fTitleOffset: 1, fTitleSize: 0.035, |
||
| 1229 | fWmax: 100, fWmin: 0 }); |
||
| 1230 | break; |
||
| 1231 | case 'TAttPad': |
||
| 1232 | JSROOT.extend(obj, { fLeftMargin: JSROOT.gStyle.fPadLeftMargin, |
||
| 1233 | fRightMargin: JSROOT.gStyle.fPadRightMargin, |
||
| 1234 | fBottomMargin: JSROOT.gStyle.fPadBottomMargin, |
||
| 1235 | fTopMargin: JSROOT.gStyle.fPadTopMargin, |
||
| 1236 | fXfile: 2, fYfile: 2, fAfile: 1, fXstat: 0.99, fYstat: 0.99, fAstat: 2, |
||
| 1237 | fFrameFillColor: JSROOT.gStyle.fFrameFillColor, |
||
| 1238 | fFrameLineColor: JSROOT.gStyle.fFrameLineColor, |
||
| 1239 | fFrameFillStyle: JSROOT.gStyle.fFrameFillStyle, |
||
| 1240 | fFrameLineStyle: JSROOT.gStyle.fFrameLineStyle, |
||
| 1241 | fFrameLineWidth: JSROOT.gStyle.fFrameLineWidth, |
||
| 1242 | fFrameBorderSize: JSROOT.gStyle.fFrameBorderSize, |
||
| 1243 | fFrameBorderMode: JSROOT.gStyle.fFrameBorderMode }); |
||
| 1244 | break; |
||
| 1245 | case 'TPad': |
||
| 1246 | JSROOT.Create("TObject", obj); |
||
| 1247 | JSROOT.Create("TAttLine", obj); |
||
| 1248 | JSROOT.Create("TAttFill", obj); |
||
| 1249 | JSROOT.Create("TAttPad", obj); |
||
| 1250 | JSROOT.extend(obj, { fX1: 0, fY1: 0, fX2: 1, fY2: 1, fXtoAbsPixelk: 1, fXtoPixelk: 1, |
||
| 1251 | fXtoPixel: 1, fYtoAbsPixelk: 1, fYtoPixelk: 1, fYtoPixel: 1, |
||
| 1252 | fUtoAbsPixelk: 1, fUtoPixelk: 1, fUtoPixel: 1, fVtoAbsPixelk: 1, |
||
| 1253 | fVtoPixelk: 1, fVtoPixel: 1, fAbsPixeltoXk: 1, fPixeltoXk: 1, |
||
| 1254 | fPixeltoX: 1, fAbsPixeltoYk: 1, fPixeltoYk: 1, fPixeltoY: 1, |
||
| 1255 | fXlowNDC: 0, fYlowNDC: 0, fXUpNDC: 0, fYUpNDC: 0, fWNDC: 1, fHNDC: 1, |
||
| 1256 | fAbsXlowNDC: 0, fAbsYlowNDC: 0, fAbsWNDC: 1, fAbsHNDC: 1, |
||
| 1257 | fUxmin: 0, fUymin: 0, fUxmax: 0, fUymax: 0, fTheta: 30, fPhi: 30, fAspectRatio: 0, |
||
| 1258 | fNumber: 0, fLogx: 0, fLogy: 0, fLogz: 0, |
||
| 1259 | fTickx: JSROOT.gStyle.fPadTickX, |
||
| 1260 | fTicky: JSROOT.gStyle.fPadTickY, |
||
| 1261 | fPadPaint: 0, fCrosshair: 0, fCrosshairPos: 0, fBorderSize: 2, |
||
| 1262 | fBorderMode: 0, fModified: false, |
||
| 1263 | fGridx: JSROOT.gStyle.fPadGridX, |
||
| 1264 | fGridy: JSROOT.gStyle.fPadGridY, |
||
| 1265 | fAbsCoord: false, fEditable: true, fFixedAspectRatio: false, |
||
| 1266 | fPrimitives: JSROOT.Create("TList"), fExecs: null, |
||
| 1267 | fName: "pad", fTitle: "canvas" }); |
||
| 1268 | |||
| 1269 | break; |
||
| 1270 | case 'TAttCanvas': |
||
| 1271 | JSROOT.extend(obj, { fXBetween: 2, fYBetween: 2, fTitleFromTop: 1.2, |
||
| 1272 | fXdate: 0.2, fYdate: 0.3, fAdate: 1 }); |
||
| 1273 | break; |
||
| 1274 | case 'TCanvas': |
||
| 1275 | JSROOT.Create("TPad", obj); |
||
| 1276 | JSROOT.extend(obj, { fDoubleBuffer: 0, fRetained: true, fXsizeUser: 0, |
||
| 1277 | fYsizeUser: 0, fXsizeReal: 20, fYsizeReal: 10, |
||
| 1278 | fWindowTopX: 0, fWindowTopY: 0, fWindowWidth: 0, fWindowHeight: 0, |
||
| 1279 | fCw: 800, fCh : 500, fCatt: JSROOT.Create("TAttCanvas"), |
||
| 1280 | kMoveOpaque: true, kResizeOpaque: true, fHighLightColor: 5, |
||
| 1281 | fBatch: true, kShowEventStatus: false, kAutoExec: true, kMenuBar: true }); |
||
| 1282 | break; |
||
| 1283 | case 'TGeoVolume': |
||
| 1284 | JSROOT.Create("TNamed", obj); |
||
| 1285 | JSROOT.Create("TAttLine", obj); |
||
| 1286 | JSROOT.Create("TAttFill", obj); |
||
| 1287 | JSROOT.extend(obj, { fGeoAtt:0, fFinder: null, fMedium: null, fNodes: null, fNtotal: 0, fNumber: 0, fRefCount: 0, fShape: null, fVoxels: null }); |
||
| 1288 | break; |
||
| 1289 | case 'TGeoNode': |
||
| 1290 | JSROOT.Create("TNamed", obj); |
||
| 1291 | JSROOT.extend(obj, { fGeoAtt:0, fMother: null, fNovlp: 0, fNumber: 0, fOverlaps: null, fVolume: null }); |
||
| 1292 | break; |
||
| 1293 | case 'TGeoNodeMatrix': |
||
| 1294 | JSROOT.Create("TGeoNode", obj); |
||
| 1295 | JSROOT.extend(obj, { fMatrix: null }); |
||
| 1296 | break; |
||
| 1297 | } |
||
| 1298 | |||
| 1299 | obj._typename = typename; |
||
| 1300 | this.addMethods(obj); |
||
| 1301 | return obj; |
||
| 1302 | } |
||
| 1303 | |||
| 1304 | // obsolete functions, can be removed by next JSROOT release |
||
| 1305 | JSROOT.CreateTList = function() { return JSROOT.Create("TList"); } |
||
| 1306 | JSROOT.CreateTAxis = function() { return JSROOT.Create("TAxis"); } |
||
| 1307 | |||
| 1308 | JSROOT.CreateTH1 = function(nbinsx) { |
||
| 1309 | var histo = JSROOT.extend(JSROOT.Create("TH1I"), |
||
| 1310 | { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" }); |
||
| 1311 | |||
| 1312 | if (nbinsx!==undefined) { |
||
| 1313 | histo.fNcells = nbinsx+2; |
||
| 1314 | for (var i=0;i<histo.fNcells;++i) histo.fArray.push(0); |
||
| 1315 | JSROOT.extend(histo.fXaxis, { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx }); |
||
| 1316 | } |
||
| 1317 | return histo; |
||
| 1318 | } |
||
| 1319 | |||
| 1320 | JSROOT.CreateTH2 = function(nbinsx, nbinsy) { |
||
| 1321 | var histo = JSROOT.extend(JSROOT.Create("TH2I"), |
||
| 1322 | { fName: "dummy_histo_" + this.id_counter++, fTitle: "dummytitle" }); |
||
| 1323 | |||
| 1324 | if ((nbinsx!==undefined) && (nbinsy!==undefined)) { |
||
| 1325 | histo.fNcells = (nbinsx+2) * (nbinsy+2); |
||
| 1326 | for (var i=0;i<histo.fNcells;++i) histo.fArray.push(0); |
||
| 1327 | JSROOT.extend(histo.fXaxis, { fNbins: nbinsx, fXmin: 0, fXmax: nbinsx }); |
||
| 1328 | JSROOT.extend(histo.fYaxis, { fNbins: nbinsy, fXmin: 0, fXmax: nbinsy }); |
||
| 1329 | } |
||
| 1330 | return histo; |
||
| 1331 | } |
||
| 1332 | |||
| 1333 | |||
| 1334 | JSROOT.CreateTPolyLine = function(npoints, use_int32) { |
||
| 1335 | var poly = JSROOT.Create("TPolyLine"); |
||
| 1336 | if (npoints) { |
||
| 1337 | poly.fN = npoints; |
||
| 1338 | if (use_int32) { |
||
| 1339 | poly.fX = new Int32Array(npoints); |
||
| 1340 | poly.fY = new Int32Array(npoints); |
||
| 1341 | } else { |
||
| 1342 | poly.fX = new Float32Array(npoints); |
||
| 1343 | poly.fY = new Float32Array(npoints); |
||
| 1344 | } |
||
| 1345 | } |
||
| 1346 | |||
| 1347 | return poly; |
||
| 1348 | } |
||
| 1349 | |||
| 1350 | JSROOT.CreateTGraph = function(npoints, xpts, ypts) { |
||
| 1351 | var graph = JSROOT.extend(JSROOT.Create("TGraph"), |
||
| 1352 | { fBits: 0x3000408, fName: "dummy_graph_" + this.id_counter++, fTitle: "dummytitle" }); |
||
| 1353 | |||
| 1354 | if (npoints>0) { |
||
| 1355 | graph.fMaxSize = graph.fNpoints = npoints; |
||
| 1356 | |||
| 1357 | var usex = (typeof xpts == 'object') && (xpts.length === npoints); |
||
| 1358 | var usey = (typeof ypts == 'object') && (ypts.length === npoints); |
||
| 1359 | |||
| 1360 | for (var i=0;i<npoints;++i) { |
||
| 1361 | graph.fX.push(usex ? xpts[i] : i/npoints); |
||
| 1362 | graph.fY.push(usey ? ypts[i] : i/npoints); |
||
| 1363 | } |
||
| 1364 | } |
||
| 1365 | |||
| 1366 | return graph; |
||
| 1367 | } |
||
| 1368 | |||
| 1369 | JSROOT.CreateTMultiGraph = function() { |
||
| 1370 | var mgraph = JSROOT.Create("TMultiGraph"); |
||
| 1371 | for(var i=0; i<arguments.length; ++i) |
||
| 1372 | mgraph.fGraphs.Add(arguments[i], ""); |
||
| 1373 | return mgraph; |
||
| 1374 | } |
||
| 1375 | |||
| 1376 | JSROOT.methodsCache = {}; // variable used to keep methods for known classes |
||
| 1377 | |||
| 1378 | JSROOT.getMethods = function(typename, obj) { |
||
| 1379 | var m = JSROOT.methodsCache[typename]; |
||
| 1380 | |||
| 1381 | var has_methods = (m!==undefined); |
||
| 1382 | |||
| 1383 | if (!has_methods) m = {}; |
||
| 1384 | |||
| 1385 | // Due to binary I/O such TObject methods may not be set for derived classes |
||
| 1386 | // Therefore when methods requested for given object, check also that basic methods are there |
||
| 1387 | if ((typename=="TObject") || (typename=="TNamed") || (obj && (obj.fBits!==undefined))) |
||
| 1388 | if (m.TestBit === undefined) { |
||
| 1389 | m.TestBit = function (f) { return (this.fBits & f) != 0; }; |
||
| 1390 | m.InvertBit = function (f) { this.fBits = this.fBits ^ (f & 0xffffff); }; |
||
| 1391 | } |
||
| 1392 | |||
| 1393 | if (has_methods) return m; |
||
| 1394 | |||
| 1395 | if ((typename === 'TList') || (typename === 'THashList')) { |
||
| 1396 | m.Clear = function() { |
||
| 1397 | this.arr = []; |
||
| 1398 | this.opt = []; |
||
| 1399 | } |
||
| 1400 | m.Add = function(obj,opt) { |
||
| 1401 | this.arr.push(obj); |
||
| 1402 | this.opt.push((opt && typeof opt=='string') ? opt : ""); |
||
| 1403 | } |
||
| 1404 | m.AddFirst = function(obj,opt) { |
||
| 1405 | this.arr.unshift(obj); |
||
| 1406 | this.opt.unshift((opt && typeof opt=='string') ? opt : ""); |
||
| 1407 | } |
||
| 1408 | m.RemoveAt = function(indx) { |
||
| 1409 | this.arr.splice(indx, 1); |
||
| 1410 | this.opt.splice(indx, 1); |
||
| 1411 | } |
||
| 1412 | } |
||
| 1413 | |||
| 1414 | if ((typename === "TPaveText") || (typename === "TPaveStats")) { |
||
| 1415 | m.AddText = function(txt) { |
||
| 1416 | this.fLines.Add({ _typename: 'TText', fTitle: txt, fTextColor: 1 }); |
||
| 1417 | } |
||
| 1418 | m.Clear = function() { |
||
| 1419 | this.fLines.Clear(); |
||
| 1420 | } |
||
| 1421 | } |
||
| 1422 | |||
| 1423 | if ((typename.indexOf("TF1") == 0) || (typename === "TF2")) { |
||
| 1424 | m.addFormula = function(obj) { |
||
| 1425 | if (!obj) return; |
||
| 1426 | if (this.formulas === undefined) this.formulas = []; |
||
| 1427 | this.formulas.push(obj); |
||
| 1428 | } |
||
| 1429 | |||
| 1430 | m.evalPar = function(x, y) { |
||
| 1431 | if (! ('_func' in this) || (this._title !== this.fTitle)) { |
||
| 1432 | |||
| 1433 | var _func = this.fTitle; |
||
| 1434 | if (_func === "gaus") _func = "gaus(0)"; |
||
| 1435 | |||
| 1436 | if ('formulas' in this) |
||
| 1437 | for (var i=0;i<this.formulas.length;++i) |
||
| 1438 | while (_func.indexOf(this.formulas[i].fName) >= 0) |
||
| 1439 | _func = _func.replace(this.formulas[i].fName, this.formulas[i].fTitle); |
||
| 1440 | _func = _func.replace(/\b(abs)\b/g, 'TMath::Abs'); |
||
| 1441 | _func = _func.replace('TMath::Exp(', 'Math.exp('); |
||
| 1442 | _func = _func.replace('TMath::Abs(', 'Math.abs('); |
||
| 1443 | if (typeof JSROOT.Math == 'object') { |
||
| 1444 | this._math = JSROOT.Math; |
||
| 1445 | _func = _func.replace('TMath::Prob(', 'this._math.Prob('); |
||
| 1446 | _func = _func.replace('TMath::Gaus(', 'this._math.Gaus('); |
||
| 1447 | _func = _func.replace('gaus(', 'this._math.gaus(this, x, '); |
||
| 1448 | _func = _func.replace('gausn(', 'this._math.gausn(this, x, '); |
||
| 1449 | _func = _func.replace('expo(', 'this._math.expo(this, x, '); |
||
| 1450 | _func = _func.replace('landau(', 'this._math.landau(this, x, '); |
||
| 1451 | _func = _func.replace('landaun(', 'this._math.landaun(this, x, '); |
||
| 1452 | } |
||
| 1453 | _func = _func.replace('pi', 'Math.PI'); |
||
| 1454 | for (var i=0;i<this.fNpar;++i) |
||
| 1455 | while(_func.indexOf('['+i+']') != -1) |
||
| 1456 | _func = _func.replace('['+i+']', '('+this.GetParValue(i)+')'); |
||
| 1457 | _func = _func.replace(/\b(sin)\b/gi, 'Math.sin'); |
||
| 1458 | _func = _func.replace(/\b(cos)\b/gi, 'Math.cos'); |
||
| 1459 | _func = _func.replace(/\b(tan)\b/gi, 'Math.tan'); |
||
| 1460 | _func = _func.replace(/\b(exp)\b/gi, 'Math.exp'); |
||
| 1461 | for (var n=2;n<10;++n) |
||
| 1462 | _func = _func.replace('x^'+n, 'Math.pow(x,'+n+')'); |
||
| 1463 | |||
| 1464 | if (this._typename==="TF2") |
||
| 1465 | this._func = new Function("x", "y", "return " + _func).bind(this); |
||
| 1466 | else |
||
| 1467 | this._func = new Function("x", "return " + _func).bind(this); |
||
| 1468 | |||
| 1469 | this._title = this.fTitle; |
||
| 1470 | } |
||
| 1471 | |||
| 1472 | return this._func(x, y); |
||
| 1473 | } |
||
| 1474 | m.GetParName = function(n) { |
||
| 1475 | if (('fFormula' in this) && ('fParams' in this.fFormula)) return this.fFormula.fParams[n].first; |
||
| 1476 | if ('fNames' in this) return this.fNames[n]; |
||
| 1477 | return "Par"+n; |
||
| 1478 | } |
||
| 1479 | m.GetParValue = function(n) { |
||
| 1480 | if (('fFormula' in this) && ('fClingParameters' in this.fFormula)) return this.fFormula.fClingParameters[n]; |
||
| 1481 | if (('fParams' in this) && (this.fParams!=null)) return this.fParams[n]; |
||
| 1482 | return null; |
||
| 1483 | } |
||
| 1484 | } |
||
| 1485 | |||
| 1486 | if ((typename.indexOf("TGraph") == 0) || (typename == "TCutG")) { |
||
| 1487 | // check if point inside figure specified by the TGrpah |
||
| 1488 | m.IsInside = function(xp,yp) { |
||
| 1489 | var i, j = this.fNpoints - 1, x = this.fX, y = this.fY, oddNodes = false; |
||
| 1490 | |||
| 1491 | for (i=0; i<this.fNpoints; ++i) { |
||
| 1492 | if ((y[i]<yp && y[j]>=yp) || (y[j]<yp && y[i]>=yp)) { |
||
| 1493 | if (x[i]+(yp-y[i])/(y[j]-y[i])*(x[j]-x[i])<xp) { |
||
| 1494 | oddNodes = !oddNodes; |
||
| 1495 | } |
||
| 1496 | } |
||
| 1497 | j=i; |
||
| 1498 | } |
||
| 1499 | |||
| 1500 | return oddNodes; |
||
| 1501 | }; |
||
| 1502 | } |
||
| 1503 | |||
| 1504 | if (typename.indexOf("TH1") == 0 || |
||
| 1505 | typename.indexOf("TH2") == 0 || |
||
| 1506 | typename.indexOf("TH3") == 0) { |
||
| 1507 | m.getBinError = function(bin) { |
||
| 1508 | // -*-*-*-*-*Return value of error associated to bin number bin*-*-*-*-* |
||
| 1509 | // if the sum of squares of weights has been defined (via Sumw2), |
||
| 1510 | // this function returns the sqrt(sum of w2). |
||
| 1511 | // otherwise it returns the sqrt(contents) for this bin. |
||
| 1512 | if (bin >= this.fNcells) bin = this.fNcells - 1; |
||
| 1513 | if (bin < 0) bin = 0; |
||
| 1514 | if (bin < this.fSumw2.length) |
||
| 1515 | return Math.sqrt(this.fSumw2[bin]); |
||
| 1516 | return Math.sqrt(Math.abs(this.fArray[bin])); |
||
| 1517 | }; |
||
| 1518 | m.setBinContent = function(bin, content) { |
||
| 1519 | // Set bin content - only trival case, without expansion |
||
| 1520 | this.fEntries++; |
||
| 1521 | this.fTsumw = 0; |
||
| 1522 | if ((bin>=0) && (bin<this.fArray.length)) |
||
| 1523 | this.fArray[bin] = content; |
||
| 1524 | }; |
||
| 1525 | } |
||
| 1526 | |||
| 1527 | if (typename.indexOf("TH1") == 0) { |
||
| 1528 | m.getBin = function(x) { return x; } |
||
| 1529 | m.getBinContent = function(bin) { return this.fArray[bin]; } |
||
| 1530 | m.Fill = function(x, weight) { |
||
| 1531 | var axis = this.fXaxis, |
||
| 1532 | bin = 1 + Math.round((x - axis.fXmin) / (axis.fXmax - axis.fXmin) * axis.fNbins); |
||
| 1533 | if (bin < 0) bin = 0; else |
||
| 1534 | if (bin > axis.fNbins + 1) bin = axis.fNbins + 1; |
||
| 1535 | this.fArray[bin] += ((weight===undefined) ? 1 : weight); |
||
| 1536 | } |
||
| 1537 | } |
||
| 1538 | |||
| 1539 | if (typename.indexOf("TH2") == 0) { |
||
| 1540 | m.getBin = function(x, y) { return (x + (this.fXaxis.fNbins+2) * y); } |
||
| 1541 | m.getBinContent = function(x, y) { return this.fArray[this.getBin(x, y)]; } |
||
| 1542 | } |
||
| 1543 | |||
| 1544 | if (typename.indexOf("TH3") == 0) { |
||
| 1545 | m.getBin = function(x, y, z) { return (x + (this.fXaxis.fNbins+2) * (y + (this.fYaxis.fNbins+2) * z)); } |
||
| 1546 | m.getBinContent = function(x, y, z) { return this.fArray[this.getBin(x, y, z)]; }; |
||
| 1547 | } |
||
| 1548 | |||
| 1549 | if (typename.indexOf("TProfile") == 0) { |
||
| 1550 | if (typename.indexOf("TProfile2D") == 0) { |
||
| 1551 | m.getBin = function(x, y) { return (x + (this.fXaxis.fNbins+2) * y); } |
||
| 1552 | m.getBinContent = function(x, y) { |
||
| 1553 | var bin = this.getBin(x, y); |
||
| 1554 | if (bin < 0 || bin >= this.fNcells) return 0; |
||
| 1555 | if (this.fBinEntries[bin] < 1e-300) return 0; |
||
| 1556 | if (!this.fArray) return 0; |
||
| 1557 | return this.fArray[bin]/this.fBinEntries[bin]; |
||
| 1558 | } |
||
| 1559 | m.getBinEntries = function(x, y) { |
||
| 1560 | var bin = this.getBin(x, y); |
||
| 1561 | if (bin < 0 || bin >= this.fNcells) return 0; |
||
| 1562 | return this.fBinEntries[bin]; |
||
| 1563 | } |
||
| 1564 | } |
||
| 1565 | else { |
||
| 1566 | m.getBin = function(x) { return x; } |
||
| 1567 | m.getBinContent = function(bin) { |
||
| 1568 | if (bin < 0 || bin >= this.fNcells) return 0; |
||
| 1569 | if (this.fBinEntries[bin] < 1e-300) return 0; |
||
| 1570 | if (!this.fArray) return 0; |
||
| 1571 | return this.fArray[bin]/this.fBinEntries[bin]; |
||
| 1572 | }; |
||
| 1573 | } |
||
| 1574 | m.getBinEffectiveEntries = function(bin) { |
||
| 1575 | if (bin < 0 || bin >= this.fNcells) return 0; |
||
| 1576 | var sumOfWeights = this.fBinEntries[bin]; |
||
| 1577 | if ( this.fBinSumw2 == null || this.fBinSumw2.length != this.fNcells) { |
||
| 1578 | // this can happen when reading an old file |
||
| 1579 | return sumOfWeights; |
||
| 1580 | } |
||
| 1581 | var sumOfWeightsSquare = this.fSumw2[bin]; |
||
| 1582 | return ( sumOfWeightsSquare > 0 ? sumOfWeights * sumOfWeights / sumOfWeightsSquare : 0 ); |
||
| 1583 | }; |
||
| 1584 | m.getBinError = function(bin) { |
||
| 1585 | if (bin < 0 || bin >= this.fNcells) return 0; |
||
| 1586 | var cont = this.fArray[bin], // sum of bin w *y |
||
| 1587 | sum = this.fBinEntries[bin], // sum of bin weights |
||
| 1588 | err2 = this.fSumw2[bin], // sum of bin w * y^2 |
||
| 1589 | neff = this.getBinEffectiveEntries(bin); // (sum of w)^2 / (sum of w^2) |
||
| 1590 | if (sum < 1e-300) return 0; // for empty bins |
||
| 1591 | var EErrorType = { kERRORMEAN : 0, kERRORSPREAD : 1, kERRORSPREADI : 2, kERRORSPREADG : 3 }; |
||
| 1592 | // case the values y are gaussian distributed y +/- sigma and w = 1/sigma^2 |
||
| 1593 | if (this.fErrorMode === EErrorType.kERRORSPREADG) |
||
| 1594 | return 1.0/Math.sqrt(sum); |
||
| 1595 | // compute variance in y (eprim2) and standard deviation in y (eprim) |
||
| 1596 | var contsum = cont/sum; |
||
| 1597 | var eprim2 = Math.abs(err2/sum - contsum*contsum); |
||
| 1598 | var eprim = Math.sqrt(eprim2); |
||
| 1599 | if (this.fErrorMode === EErrorType.kERRORSPREADI) { |
||
| 1600 | if (eprim != 0) return eprim/Math.sqrt(neff); |
||
| 1601 | // in case content y is an integer (so each my has an error +/- 1/sqrt(12) |
||
| 1602 | // when the std(y) is zero |
||
| 1603 | return 1.0/Math.sqrt(12*neff); |
||
| 1604 | } |
||
| 1605 | // if approximate compute the sums (of w, wy and wy2) using all the bins |
||
| 1606 | // when the variance in y is zero |
||
| 1607 | // case option "S" return standard deviation in y |
||
| 1608 | if (this.fErrorMode === EErrorType.kERRORSPREAD) return eprim; |
||
| 1609 | // default case : fErrorMode = kERRORMEAN |
||
| 1610 | // return standard error on the mean of y |
||
| 1611 | return (eprim/Math.sqrt(neff)); |
||
| 1612 | }; |
||
| 1613 | } |
||
| 1614 | |||
| 1615 | if (typename == "TAxis") { |
||
| 1616 | m.GetBinLowEdge = function(bin) { |
||
| 1617 | if (this.fNbins <= 0) return 0; |
||
| 1618 | if ((this.fXbins.length > 0) && (bin > 0) && (bin <= this.fNbins)) return this.fXbins[bin-1]; |
||
| 1619 | return this.fXmin + (bin-1) * (this.fXmax - this.fXmin) / this.fNbins; |
||
| 1620 | } |
||
| 1621 | } |
||
| 1622 | |||
| 1623 | JSROOT.methodsCache[typename] = m; |
||
| 1624 | return m; |
||
| 1625 | }; |
||
| 1626 | |||
| 1627 | JSROOT.addMethods = function(obj) { |
||
| 1628 | this.extend(obj, JSROOT.getMethods(obj._typename, obj)); |
||
| 1629 | }; |
||
| 1630 | |||
| 1631 | JSROOT.lastFFormat = ""; |
||
| 1632 | |||
| 1633 | JSROOT.FFormat = function(value, fmt) { |
||
| 1634 | // method used to convert numeric value to string according specified format |
||
| 1635 | // format can be like 5.4g or 4.2e or 6.4f |
||
| 1636 | // function saves actual format in JSROOT.lastFFormat variable |
||
| 1637 | if (!fmt) fmt = "6.4g"; |
||
| 1638 | |||
| 1639 | JSROOT.lastFFormat = ""; |
||
| 1640 | |||
| 1641 | fmt = fmt.trim(); |
||
| 1642 | var len = fmt.length; |
||
| 1643 | if (len<2) return value.toFixed(4); |
||
| 1644 | var last = fmt.charAt(len-1); |
||
| 1645 | fmt = fmt.slice(0,len-1); |
||
| 1646 | var isexp = null; |
||
| 1647 | var prec = fmt.indexOf("."); |
||
| 1648 | if (prec<0) prec = 4; else prec = Number(fmt.slice(prec+1)); |
||
| 1649 | if (isNaN(prec) || (prec<0) || (prec==null)) prec = 4; |
||
| 1650 | |||
| 1651 | var significance = false; |
||
| 1652 | if ((last=='e') || (last=='E')) { isexp = true; } else |
||
| 1653 | if (last=='Q') { isexp = true; significance = true; } else |
||
| 1654 | if ((last=='f') || (last=='F')) { isexp = false; } else |
||
| 1655 | if (last=='W') { isexp = false; significance = true; } else |
||
| 1656 | if ((last=='g') || (last=='G')) { |
||
| 1657 | var se = JSROOT.FFormat(value, fmt+'Q'); |
||
| 1658 | var _fmt = JSROOT.lastFFormat; |
||
| 1659 | var sg = JSROOT.FFormat(value, fmt+'W'); |
||
| 1660 | |||
| 1661 | if (se.length < sg.length) { |
||
| 1662 | JSROOT.lastFFormat = _fmt; |
||
| 1663 | return se; |
||
| 1664 | } |
||
| 1665 | return sg; |
||
| 1666 | } else { |
||
| 1667 | isexp = false; |
||
| 1668 | prec = 4; |
||
| 1669 | } |
||
| 1670 | |||
| 1671 | if (isexp) { |
||
| 1672 | // for exponential representation only one significant digit befor point |
||
| 1673 | if (significance) prec--; |
||
| 1674 | if (prec<0) prec = 0; |
||
| 1675 | |||
| 1676 | JSROOT.lastFFormat = '5.'+prec+'e'; |
||
| 1677 | |||
| 1678 | return value.toExponential(prec); |
||
| 1679 | } |
||
| 1680 | |||
| 1681 | var sg = value.toFixed(prec); |
||
| 1682 | |||
| 1683 | if (significance) { |
||
| 1684 | |||
| 1685 | // when using fixed representation, one could get 0.0 |
||
| 1686 | if ((value!=0) && (Number(sg)==0.) && (prec>0)) { |
||
| 1687 | prec = 20; sg = value.toFixed(prec); |
||
| 1688 | } |
||
| 1689 | |||
| 1690 | var l = 0; |
||
| 1691 | while ((l<sg.length) && (sg.charAt(l) == '0' || sg.charAt(l) == '-' || sg.charAt(l) == '.')) l++; |
||
| 1692 | |||
| 1693 | var diff = sg.length - l - prec; |
||
| 1694 | if (sg.indexOf(".")>l) diff--; |
||
| 1695 | |||
| 1696 | if (diff != 0) { |
||
| 1697 | prec-=diff; |
||
| 1698 | if (prec<0) prec = 0; else if (prec>20) prec = 20; |
||
| 1699 | sg = value.toFixed(prec); |
||
| 1700 | } |
||
| 1701 | } |
||
| 1702 | |||
| 1703 | JSROOT.lastFFormat = '5.'+prec+'f'; |
||
| 1704 | |||
| 1705 | return sg; |
||
| 1706 | } |
||
| 1707 | |||
| 1708 | JSROOT.log10 = function(n) { |
||
| 1709 | return Math.log(n) / Math.log(10); |
||
| 1710 | } |
||
| 1711 | |||
| 1712 | // dummy function, will be redefined when JSRootPainter is loaded |
||
| 1713 | JSROOT.progress = function(msg) { |
||
| 1714 | if ((msg !== undefined) && (typeof msg=="string")) JSROOT.console(msg); |
||
| 1715 | } |
||
| 1716 | |||
| 1717 | JSROOT.Initialize = function() { |
||
| 1718 | |||
| 1719 | if (JSROOT.source_fullpath.length === 0) return this; |
||
| 1720 | |||
| 1721 | function window_on_load(func) { |
||
| 1722 | if (func!=null) { |
||
| 1723 | if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') |
||
| 1724 | func(); |
||
| 1725 | else |
||
| 1726 | window.onload = func; |
||
| 1727 | } |
||
| 1728 | return JSROOT; |
||
| 1729 | } |
||
| 1730 | |||
| 1731 | var src = JSROOT.source_fullpath; |
||
| 1732 | |||
| 1733 | if (JSROOT.GetUrlOption('gui', src) !== null) |
||
| 1734 | return window_on_load( function() { JSROOT.BuildSimpleGUI(); } ); |
||
| 1735 | |||
| 1736 | if ( typeof define === "function" && define.amd ) |
||
| 1737 | return window_on_load( function() { JSROOT.BuildSimpleGUI('check_existing_elements'); } ); |
||
| 1738 | |||
| 1739 | var prereq = ""; |
||
| 1740 | if (JSROOT.GetUrlOption('io', src)!=null) prereq += "io;"; |
||
| 1741 | if (JSROOT.GetUrlOption('2d', src)!=null) prereq += "2d;"; |
||
| 1742 | if (JSROOT.GetUrlOption('jq2d', src)!=null) prereq += "jq2d;"; |
||
| 1743 | if (JSROOT.GetUrlOption('more2d', src)!=null) prereq += "more2d;"; |
||
| 1744 | if (JSROOT.GetUrlOption('geo', src)!=null) prereq += "geo;"; |
||
| 1745 | if (JSROOT.GetUrlOption('3d', src)!=null) prereq += "3d;"; |
||
| 1746 | if (JSROOT.GetUrlOption('math', src)!=null) prereq += "math;"; |
||
| 1747 | if (JSROOT.GetUrlOption('mathjax', src)!=null) prereq += "mathjax;"; |
||
| 1748 | var user = JSROOT.GetUrlOption('load', src); |
||
| 1749 | if ((user!=null) && (user.length>0)) prereq += "load:" + user; |
||
| 1750 | var onload = JSROOT.GetUrlOption('onload', src); |
||
| 1751 | var bower = JSROOT.GetUrlOption('bower', src); |
||
| 1752 | if (bower!==null) { |
||
| 1753 | if (bower.length>0) JSROOT.bower_dir = bower; else |
||
| 1754 | if (JSROOT.source_dir.indexOf("jsroot/") == JSROOT.source_dir.length - 7) |
||
| 1755 | JSROOT.bower_dir = JSROOT.source_dir.substr(0, JSROOT.source_dir.length - 7); |
||
| 1756 | if (JSROOT.bower_dir.length > 0) console.log("Set JSROOT.bower_dir to " + JSROOT.bower_dir); |
||
| 1757 | } |
||
| 1758 | |||
| 1759 | if ((prereq.length>0) || (onload!=null)) |
||
| 1760 | window_on_load(function() { |
||
| 1761 | if (prereq.length>0) JSROOT.AssertPrerequisites(prereq, onload); else |
||
| 1762 | if (onload!=null) { |
||
| 1763 | onload = JSROOT.findFunction(onload); |
||
| 1764 | if (typeof onload == 'function') onload(); |
||
| 1765 | } |
||
| 1766 | }); |
||
| 1767 | |||
| 1768 | return this; |
||
| 1769 | } |
||
| 1770 | |||
| 1771 | return JSROOT.Initialize(); |
||
| 1772 | |||
| 1773 | })); |
||
| 1774 | |||
| 1775 | /// JSRootCore.js ends |
||
| 1776 |