` element:
```html
```
One could use the `draw` function:
```javascript
import { draw } from 'https://root.cern/js/latest/modules/main.mjs';
draw("drawing", obj, "colz");
```
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.
Here is complete [running example](https://root.cern/js/latest/api.htm#custom_html_read_json) ans [source code](https://github.com/root-project/jsroot/blob/master/demo/read_json.htm):
```javascript
import { httpRequest, draw, redraw, resize, cleanup } from 'https://root.cern/js/latest/modules/main.mjs';
let filename = "https://root.cern/js/files/th2ul.json.gz";
let obj = await httpRequest(filename, 'object');
draw("drawing", obj, "lego");
```
In very seldom cases one need to access painter object, created in `draw()` function. This can be done via
handling Promise results like:
```javascript
let painter = await draw("drawing", obj, "colz");
console.log('Object type in painter', painter.getClassName());
```
One is also able to update the drawing with a new version of the object:
```javascript
// after some interval request object again
redraw("drawing", obj2, "colz");
```
The `redraw` function will call `draw` if the drawing was not performed before.
In the case when changing of HTML layout leads to resize of element with JSROOT drawing,
one should call `resize()` to let JSROOT adjust drawing size. One should do:
```javascript
resize("drawing");
```
As second argument one could specify exact size for draw elements like:
```javascript
resize("drawing", { width: 500, height: 200 });
```
To correctly cleanup JSROOT drawings from HTML element, one should call:
```javascript
cleanup("drawing");
```
### File API
JSROOT defines the TFile class, which can be used to access binary ROOT files.
One should always remember that all I/O operations are asynchronous in JSROOT.
Therefore promises are used to retrieve results when the I/O operation is completed.
For example, reading an object from a file and displaying it will look like:
```javascript
import { openFile, draw } from 'https://root.cern/js/latest/modules/main.mjs';
let filename = "https://root.cern/js/files/hsimple.root";
let file = await openFile(filename);
let obj = await file.readObject("hpxpy;1");
await draw("drawing", obj, "colz");
console.log('drawing completed');
```
Here is [running example](https://root.cern/js/latest/api.htm#custom_html_read_root_file) and [source code](https://github.com/root-project/jsroot/blob/master/demo/read_file.htm)
### TTree API
Simple TTree::Draw operation can be performed with following code:
```javascript
import { openFile } from 'https://root.cern/js/latest/modules/io.mjs';
import { draw } from 'https://root.cern/js/latest/modules/draw.mjs';
let file = await openFile("https://root.cern/js/files/hsimple.root");
let tree = await file.readObject("ntuple;1");
draw("drawing", tree, "px:py::pz>5");
```
To get access to selected branches, one should use `TSelector` class:
```javascript
import { openFile } from 'https://root.cern/js/latest/modules/io.mjs';
import { draw } from 'https://root.cern/js/latest/modules/draw.mjs';
import { TSelector, treeProcess } from 'https://root.cern/js/latest/modules/tree.mjs';
let file = await openFile("https://root.cern/js/files/hsimple.root");
let tree = await file.readObject("ntuple;1");
let selector = new TSelector();
selector.AddBranch("px");
selector.AddBranch("py");
let cnt = 0, sumpx = 0, sumpy = 0;
selector.Begin = function() {
// function called before reading of TTree starts
}
selector.Process = function() {
// function called for every entry
sumpx += this.tgtobj.px;
sumpy += this.tgtobj.py;
cnt++;
}
selector.Terminate = function(res) {
if (!res || (cnt === 0))
return;
let meanpx = sumpx/cnt, meanpy = sumpy/cnt;
console.log(`Results meanpx = ${meanpx} meanpy = ${meanpy}`);
}
await treeProcess(tree, selector);
```
Here is [running example](https://root.cern/js/latest/api.htm#ttree_tselector) and [source code](https://github.com/root-project/jsroot/blob/master/demo/read_tree.htm)
This examples shows how read TTree from binary file and create `TSelector` object.
Logically it is similar to original TSelector class - for every read entry `TSelector::Process()` method is called.
Selected branches can be accessed from **tgtobj** data member. At the end of tree reading `TSelector::Terminate()` method
will be called.
As third parameter of treeProcess() function one could provide object with arguments
```javascript
let args = { numentries: 1000, firstentry: 500 };
treeProcess(tree, selector, args);
```
In some applications access to TTree can be optimized using 'staged' approach.
It means that on the first stage interesting entries identified in the TTree and
on the second stage data only for these entries are read. This can boost performance a lot.
To get list of entries which match to some condition, one can use `>>elist` redirection in draw expression.
```javascript
const entries = await treeDraw(tree, '::pz>5>>elist');
```
Here only cut condition `pz>5` is specified - no any normal draw expression is configured.
On the second stage one simply use entries for drawing. Like:
```javascript
const hist = await treeDraw(tree, `px:py;elist:[${entries}]`);
```
Such 'staged' approach directly implemented in the tree drawing:
```javascript
const hist2 = await treeDraw(tree, 'px:py::pz>5;staged');
```
In the [tree_staged.js](https://github.com/root-project/jsroot/blob/master/demo/node/tree_staged.js) macro
one can see different possibilities to use staged approach for TTree processing
### TGeo API
Any supported TGeo object can be drawn directly with normal `draw()` function.
If necessary, one can create three.js model for supported object directly and use such model
separately. This can be done with the function:
```javascript
import { build } from './path_to_jsroot/modules/geom/TGeoPainter.mjs';
let opt = { numfaces: 100000 };
let obj3d = build(obj, opt);
scene.add( obj3d );
```
Following options can be specified:
- numfaces - approximate maximal number of faces in three.js model (default 100000)
- numnodes - approximate maximal number of meshes in three.js model (default 1000)
- doubleside - use double-side material (default only front side is set)
- wireframe - show wireframe for created object (default - off)
- dflt_colors - assign default ROOT colors for the volumes
When transparent volumes appeared in the model, one could use `produceRenderOrder()` function
to correctly set rendering order. It should be used as:
```javascript
import { produceRenderOrder } from './path_to_jsroot/modules/geom/TGeoPainter.mjs';
produceRenderOrder(scene, camera.position, 'box');
```
Following methods can be applied: "box", "pnt", "size", "ray" and "dflt". See more info in draw options description for TGeo classes.
Here is [running example](https://root.cern/js/latest/api.htm#custom_html_geometry) and [source code](https://github.com/root-project/jsroot/blob/master/demo/tgeo_build.htm).
### Custom user class
There is [code example](https://github.com/root-project/jsroot/tree/master/demo/custom) how custom user class can be implemented.
It shows usage of different draw options for the class and ability to access sub-elements of the object using specialized `expand` function.
### Use with Node.js
To install latest JSROOT release, just do:
```bash
[shell] npm install jsroot
```
To use in the Node.js scripts, one should add following line:
```javascript
import { httpRequest, makeSVG } from 'jsroot';
```
Using JSROOT functionality, one can open binary ROOT files (local and remote), parse ROOT JSON,
create SVG output. For example, to create SVG image with lego plot, one should do:
```javascript
import { openFile, makeSVG } from 'jsroot';
import { writeFileSync } from 'fs';
let file = await openFile("https://root.cern/js/files/hsimple.root");
let obj = await file.readObject("hpx;1");
let svg = await makeSVG({ object: obj, option: "lego2", width: 1200, height: 800 });
writeFileSync("lego2.svg", svg);
```
It is also possible to convert any JavaScript object into ROOT JSON string, using `toJSON()` function. Like:
```javascript
import { toJSON, openFile, makeSVG } from 'jsroot';
import { writeFileSync } from 'fs';
let file = await openFile("https://root.cern/js/files/hsimple.root");
let obj = await file.readObject("hpx;1");
let json = await toJSON(obj);
writrFileSync("hpxpy.json", json);
```
Such JSON string could be parsed by any other JSROOT-based application.
When WebGL rendering is used (lego plots or TGeo drawing), on the Linux one need to have `DISPLAY` correctly set
to make it working. To run JSROOT on headless machine, one have to use `xvfb-run` utility,
see also [here](https://github.com/stackgl/headless-gl#how-can-headless-gl-be-used-on-a-headless-linux-machine):
```bash
[shell] xvfb-run -s "-ac -screen 0 1280x1024x24" node geomsvg.js
```
### Use with OpenUI5
[OpenUI5](http://openui5.org/) is a web toolkit for developers to ease and speed up the development of full-blown HTML5 web applications.
JSROOT provides `loadOpenui5` function to load supported OpenUI5:
```javascript
```
JSROOT uses
when no other source is specified.
There are small details when using OpenUI5 with THttpServer. First of all, location of JSROOT modules should be specified
as `/jsrootsys/modules/main.mjs`. And then trying to access files from local disk, one should specify `/currentdir/` folder:
```javascript
jQuery.sap.registerModulePath("NavExample", "/currentdir/");
```
JSROOT provides [example](https://root.cern/js/latest/demo/openui5/) showing usage of JSROOT drawing in the OpenUI5,
[source code](https://github.com/root-project/jsroot/tree/master/demo/openui5) can be found in repository.
### Migration v6 -> v7
* Core functionality should be imported from `main.mjs` module like:
```javascript
import { create, parse, createHistogram, redraw } from 'https://root.cern/js/7.9.0/modules/main.mjs';
```
* It is still possible to use `JSRoot.core.js` script, which provides very similar (but not identical!) functionality as with `v6` via global `JSROOT` object
* `JSROOT.define()` and `JSROOT.require()` functions only available after `JSRoot.core.js` loading
* Support of `require.js` and `openui5` loaders was removed
* Global hierarchy painter `JSROOT.hpainter` no longer existing, one can use `getHPainter` function:
```javascript
import { getHPainter } from 'https://root.cern/js/7.9.0/modules/main.mjs';
let hpainter = getHPainter();
```
* All math functions previously available via `JSROOT.Math` should be imported from `base/math.mjs` module:
```javascript
import * as math from 'https://root.cern/js/7.9.0/modules/base/math.mjs';
```
* Indication of batch mode `JSROOT.batch_mode` should be accessed via functions:
```javascript
import { isBatchMode, setBatchMode } from 'https://root.cern/js/7.9.0/modules/main.mjs';
let was_batch = isBatchMode();
if (!was_batch) setBatchMode(true);
```
* `JSROOT.extend()` function was removed, use `Object.assign()` instead
### Migration v5 -> v6
* Main script was renamed to `JSRoot.core.js`. Old `JSRootCore.js` was deprecated and removed in v6.2. All URL parameters for main script ignored now, to load JSROOT functionality one should use `JSROOT.require` function. To create standard GUI, `JSROOT.buildGUI` function has to be used.
* Instead of `JSROOT.JSONR_unref()` one can use `JSROOT.parse()`. If object is provided to `JSROOT.parse()` it just replaces all references which were introduced by `TBufferJSON::ToJSON()` method.
* Instead of `JSROOT.console()` one should use `console.log()`. Instead of `JSROOT.alert()` one should use `console.error()`.
* Many settings were moved from `JSROOT.gStyle` to `JSROOT.settings` object. It was done to keep only TStyle-related members in `JSROOT.gStyle`.
* Basic painter classes were renamed and made public:
- `JSROOT.TBasePainter` -> `JSROOT.BasePainter`
- `JSROOT.TObjectPainter` -> `JSROOT.ObjectPainter`
* Internal `ObjectPainter.DrawingReady` api was deprecated. Draw function has to return `Promise` if object drawing postponed. As argument of returned promise object painter has to be used.
* Many function names where adjusted to naming conventions. Like:
- `JSROOT.CreateHistogram` -> `JSROOT.createHistogram`
- `JSROOT.CreateTGraph` -> `JSROOT.createTGraph`
- `JSROOT.Create` -> `JSROOT.create`