otsdaq_utilities  v2_04_01
src/WebGUI/js/visualizers_lib/ViewerRoot_lib/JsRoot/docs/JSROOT.md
1 # JavaScript ROOT
2 
3 The JSROOT project intends to implement ROOT graphics for web browsers.
4 Reading of binary ROOT files is supported.
5 It is the successor of the JSRootIO project.
6 
7 
8 ## Installing JSROOT
9 
10 In most practical cases it is not necessary to install JSROOT on the local computer - it can be used directly from project web sites <https://root.cern.ch/js/> and <http://jsroot.gsi.de/>. Developers repository for JSROOT code situated on <https://github.com/linev/jsroot/>.
11 
12 In rare cases one need to install JSROOT on separate web server - for such case one could use provided packages from <https://github.com/linev/jsroot/releases>.
13 
14 One could use JSROOT directly from local file system. If source code was unpacked in `/home/user/jsroot/` subfolder, one could just open it in browser with <file:
15 
16 
17 
18 ## Reading ROOT files in JSROOT
19 
20 [The main page](https://root.cern.ch/js/latest/) of the JSROOT project provides the possibility to interactively open ROOT files and draw objects like histogram or canvas.
21 
22 The following parameters can be specified in the URL string:
23 
24 - file, files - name of the file(s), which will be automatically open with page loading
25 - json - name of JSON file with stored ROOT object like histogram or canvas
26 - item, items - name of the item(s) to be displayed
27 - opt, opts - drawing option(s) for the item(s)
28 - layout - can be 'simple', 'flex', 'collapsible', 'tabs' or 'gridNxM' where N and M integer values
29 - nobrowser - do not display file browser
30 - load - name of extra JavaScript to load
31 - optimize - drawing optimization 0:off, 1:only large histograms (default), 2:always
32 - paltte - id of default color palette, 51..121 - new ROOT6 palette (default 57)
33 - interactive - enable/disable interactive functions 0-disable all, 1-enable all
34 - noselect - hide file-selection part in the browser (only when file name is specified)
35 - mathjax - use MathJax for latex output
36 
37 When specifying `file`, `item` or `opt` parameters, one could provide array like `file=['file1.root','file2.root']`. One could skip quotes when specifying elements names `item=[file1.root/hpx,file2.root/hpy]` or `opt=['',colz]`.
38 
39 Examples:
40 
41 - <https://root.cern.ch/js/latest/?file=../files/hsimple.root&item=hpx;1>
42 - <https://root.cern.ch/js/latest/?file=../files/hsimple.root&nobrowser&item=hpxpy;1&opt=colz>
43 - <https://root.cern.ch/js/latest/?file=../files/hsimple.root&noselect&layout=grid2x2&item=hprof;1>
44 
45 Many examples of URL string usage can be found on [JSROOT examples](https://root.cern.ch/js/latest/api.htm) page.
46 
47 
48 One can very easy integrate JSROOT graphic into other HTML pages using a __iframe__ tag:
49 
50 <iframe width="600" height="500" src="https://root.cern.ch/js/latest/index.htm?nobrowser&file=../files/hsimple.root&item=hpxpy;1&opt=colz">
51 </iframe>
52 
53 
54 ## Reading ROOT files from other servers
55 
56 In principle, one could open any ROOT file placed in the web, providing the full URL to it like:
57 
58 <https://jsroot.gsi.de/latest/?file=https://root.cern.ch/js/files/hsimple.root&item=hpx>
59 
60 But one should be aware of [Same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy), when the browser blocks requests to files from domains other than current web page.
61 To enable CORS on Apache web server, hosting ROOT files, one should add following lines to `.htaccess` file:
62 
63  <IfModule mod_headers.c>
64  <FilesMatch "\.root">
65  Header set Access-Control-Allow-Origin "*"
66  Header set Access-Control-Allow-Headers "range"
67  Header set Access-Control-Expose-Headers "content-range,content-length,accept-ranges"
68  Header set Access-Control-Allow-Methods "HEAD,GET"
69  </FilesMatch>
70  </IfModule>
71 
72 More details about configuring of CORS headers can be found [here](https://developer.mozilla.org/en/http_access_control).
73 
74 Other solution - copy all JSROOT files to the same location than where the data files are located.
75 In such case one could use the server with its default settings.
76 
77 A simple case is to copy only the top index.htm file on the server and specify the full path to JSRootCore.js script like:
78 
79  ...
80  <script type="text/javascript" src="https://root.cern.ch/js/latest/scripts/JSRootCore.js?gui"></script>
81  ...
82 
83 In such case one can also specify a custom files list:
84 
85  ...
86  <div id="simpleGUI" path="files/subdir" files="userfile1.root;subdir/usefile2.root">
87  loading scripts ...
88  </div>
89  ...
90 
91 
92 ## JSROOT with THttpServer
93 
94 THttpServer provides http access to objects from running ROOT application.
95 JSROOT is used to implement the user interface in the web browsers.
96 
97 The layout of the main page coming from THttpServer is similar to the file I/O one.
98 One could browse existing items and display them. A snapshot of running
99 server can be seen on the [demo page](https://root.cern.ch/js/latest/httpserver.C/).
100 
101 One could also specify similar URL parameters to configure the displayed items and drawing options.
102 
103 It is also possible to display one single item from the THttpServer server like:
104 
105 <https://root.cern.ch/js/latest/httpserver.C/Files/job1.root/hpxpy/draw.htm?opt=colz>
106 
107 
108 ## Data monitoring with JSROOT
109 
110 ### Monitoring with http server
111 
112 The best possibility to organize the monitoring of data from a running application
113 is to use THttpServer. In such case the client can always access the latest
114 changes and request only the items currently displayed in the browser.
115 To enable monitoring, one should activate the appropriate checkbox or
116 provide __monitoring__ parameter in the URL string like:
117 
118 <https://root.cern.ch/js/latest/httpserver.C/Files/job1.root/hprof/draw.htm?monitoring=1000>
119 
120 The parameter value is the update interval in milliseconds.
121 
122 
123 ### JSON file-based monitoring
124 
125 Solid file-based monitoring (without integration of THttpServer into application) can be
126 implemented in JSON format. There is the TBufferJSON class, which is capable to potentially
127 convert any ROOT object (beside TTree) into JSON. Any ROOT application can use such class to
128 create JSON files for selected objects and write such files in a directory,
129 which can be accessed via web server. Then one can use JSROOT to read such files and display objects in a web browser.
130 There is a demonstration page showing such functionality:
131 
132 <https://root.cern.ch/js/latest/demo/demo.htm>
133 
134 <iframe width="500" height="300" src="https://root.cern.ch/js/latest/demo/demo.htm">
135 </iframe>
136 
137 This demo page reads in cycle 20 json files and displays them.
138 
139 If one has a web server which already provides such JSON file, one could specify the URL to this file like:
140 
141 <https://root.cern.ch/js/latest/demo/demo.htm?addr=../httpserver.C/Canvases/c1/root.json.gz>
142 
143 Here the same problem with [Cross-Origin Request](https://developer.mozilla.org/en/http_access_control) can appear.
144 If the web server configuration cannot be changed, just copy JSROOT to the web server itself.
145 
146 
147 ### Binary file-based monitoring (not recommended)
148 
149 Theoretically, one could use binary ROOT files to implement monitoring.
150 With such approach, a ROOT-based application creates and regularly updates content of a ROOT file, which can be accessed via normal web server. From the browser side, JSROOT could regularly read the specified objects and update their drawings. But such solution has three major caveats.
151 
152 First of all, one need to store the data of all objects, which only potentially could be displayed in the browser. In case of 10 objects it does not matter, but for 1000 or 100000 objects this will be a major performance penalty. With such big amount of data one will never achieve higher update rate.
153 
154 The second problem is I/O. To read the first object from the ROOT file, one need to perform several (about 5) file-reading operations via http protocol.
155 There is no http file locking mechanism (at least not for standard web servers),
156 therefore there is no guarantee that the file content is not changed/replaced between consequent read operations. Therefore, one should expect frequent I/O failures while trying to monitor data from ROOT binary files. There is a workaround for the problem - one could load the file completely and exclude many partial I/O operations by this. To achieve this with JSROOT, one should add "+" sign at the end of the file name. Of course, it only could work for small files.
157 
158 The third problem is the limitations of ROOT I/O in JavaScript. Although it tries to fully repeat logic of binary I/O with the streamer infos evaluation, the JavaScript ROOT I/O will never have 100% functionality of native ROOT. Especially, the custom streamers are a problem for JavaScript - one need to implement them once again and keep them synchronous with ROOT itself. And ROOT is full of custom streamers! Therefore it is just great feature that one can read binary files from a web browser, but one should never rely on the fact that such I/O works for all cases.
159 Let say that major classes like TH1 or TGraph or TCanvas will be supported, but one will never see full support of TTree or RooWorkspace in JavaScript.
160 
161 If somebody still wants to use monitoring of data from ROOT files, could try link like:
162 
163 <https://root.cern.ch/js/latest/index.htm?nobrowser&file=../files/hsimple.root+&item=hpx;1&monitoring=2000>
164 
165 In this particular case, the histogram is not changing.
166 
167 
168 ## Stand-alone usage of JSROOT
169 
170 Even without any server-side application, JSROOT provides nice ROOT-like graphics,
171 which could be used in arbitrary HTML pages.
172 There is [example page](https://root.cern.ch/js/latest/demo/example.htm),
173 where a 2-D histogram is artificially generated and displayed.
174 Details about the JSROOT API can be found in the next chapters.
175 
176 
177 ## JSROOT API
178 
179 JSROOT consists of several libraries (.js files). They are all provided in the ROOT
180 repository and are available in the 'etc/http/scripts/' subfolder.
181 Only the central classes and functions will be documented here.
182 
183 ### Scripts loading
184 
185 Before JSROOT can be used, all appropriate scripts should be loaded.
186 Any HTML pages where JSROOT is used should include the JSRootCore.js script.
187 The `<head>` section of the HTML page should have the following line:
188 
189  <script type="text/javascript" src="https://root.cern.ch/js/latest/scripts/JSRootCore.js?2d"></script>
190 
191 Here, the default location of JSROOT is specified. One could have a local copy on the file system or on a private web server. When JSROOT is used with THttpServer, the address looks like:
192 
193  <script type="text/javascript" src="http://your_root_server:8080/jsrootsys/scripts/JSRootCore.js?2d"></script>
194 
195 In URL string with JSRootCore.js script one should specify which JSROOT functionality will be loaded:
196 
197  + '2d' normal drawing for objects like TH1/TCanvas/TGraph
198  + 'more2d' more classes for 2D drawing like TH2/TF1/TEllipse
199  + '3d' 3D drawing for 2D/3D histograms
200  + 'geo' 3D drawing of TGeo classes
201  + 'io' binary file I/O
202  + 'math' advanced mathemathical functions
203  + 'mathjax' loads MathJax.js and use it for latex output
204  + 'gui' default gui for offline/online applications
205  + 'load' name of user script(s) to load
206  + 'onload' name of function to call when scripts loading completed
207 
208 For instance, to load functionality with normal 2D graphics and binary ROOT files support, one should specify:
209 
210  <script type="text/javascript" src="https://root.cern.ch/js/latest/scripts/JSRootCore.min.js?2d&io"></script>
211 
212 One could use minified version of all scripts (as shown in example) - this reduce page loading time significantly.
213 
214 
215 ### Use of JSON
216 
217 It is strongly recommended to use JSON when communicating with ROOT application.
218 THttpServer provides a JSON representation for every registered object with an url address like:
219 
220  http://your_root_server:8080/Canvases/c1/root.json
221 
222 Such JSON representation generated using the [TBufferJSON](http://root.cern.ch/root/html/TBufferJSON.html) class.
223 
224 To access data from a remote web server, it is recommended to use the [XMLHttpRequest](http://en.wikipedia.org/wiki/XMLHttpRequest) class.
225 JSROOT provides a special method to create such class and properly handle it in different browsers.
226 For receiving JSON from a server one could use following code:
227 
228  var req = JSROOT.NewHttpRequest("http://your_root_server:8080/Canvases/c1/root.json", 'object', userCallback);
229  req.send(null);
230 
231 In the callback function, one gets JavaScript object (or null in case of failure)
232 
233 
234 ### Objects drawing
235 
236 After an object has been created, one can directly draw it. If somewhere in a HTML page there is a `<div>` element:
237 
238  ...
239  <div id="drawing"></div>
240  ...
241 
242 One could use the JSROOT.draw function:
243 
244  JSROOT.draw("drawing", obj, "colz");
245 
246 The first argument is the id of the HTML div element, where drawing will be performed. The second argument is the object to draw and the third one is the drawing option.
247 One is also able to update the drawing with a new version of the object:
248 
249  // after some interval request object again
250  JSROOT.redraw("drawing", obj2, "colz");
251 
252 The JSROOT.redraw() function will call JSROOT.draw if the drawing was not performed before.
253 
254 In the case when changing of HTML layout leads to resize of element with JSROOT drawing,
255 one should call JSROOT.resize() to let JSROOT adjust drawing size. One should do:
256 
257  JSROOT.resize("drawing");
258 
259  As second argument one could specify exact size for draw elements like:
260 
261  JSROOT.resize("drawing", { width: 500, height: 200 } );
262 
263 To correctly cleanup JSROOT drawings from HTML element, one should call:
264 
265  JSROOT.cleanup("drawing");
266 
267 Many examples of supported ROOT classes and draw options can be found on [JSROOT examples](https://root.cern.ch/js/latest/examples.htm) page.
268 
269 
270 ### File API
271 
272 JSROOT defines the JSROOT.TFile class, which can be used to access binary ROOT files.
273 One should always remember that all I/O operations are asynchronous in JSROOT.
274 Therefore, callback functions are used to react when the I/O operation completed.
275 For example, reading an object from a file and displaying it will look like:
276 
277  var filename = "https://root.cern.ch/js/files/hsimple.root";
278  JSROOT.OpenFile(filename, function(file) {
279  file.ReadObject("hpxpy;1", function(obj) {
280  JSROOT.draw("drawing", obj, "colz");
281  });
282  });
283 
284 
285 ## More API examples
286 
287 Many different examples of JSROOT API usage can be found on [JSROOT API](https://root.cern.ch/js/latest/api.htm) page