Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions demo/node/hpainter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// demo how HierarchyPainter can be used without direct display
// in batch display one just able to create images


import { version, HierarchyPainter, draw } from 'jsroot';


console.log(`JSROOT version ${version}`);


const hp = new HierarchyPainter('hpainter');

// configure batch display to properly handle DOM in the node.js
hp.setDisplay('batch');

// catch draw function calls
hp.setDrawFunc((dom, obj, opt) => {
console.log(`trying to draw ${obj._typename}`);
return draw(dom, obj, opt);
});

await hp.openRootFile('https://root.cern/js/files/hsimple.root');

// display of TH2 histogram
await hp.display('hpxpy');

await hp.expandItem('ntuple');

// invoking TTree::Draw
await hp.display('ntuple/pz');


// should be BatchDisplay
const disp = hp.getDisplay();

for (let id = 0; id < disp.numFrames(); ++id) {
const svg = await disp.makeSVG(id);
console.log(`Frame ${id} create svg size ${svg.length}`);

// one can save svg plain file
// writeFileSync(`frame${id}.svg`, svg);
}
35 changes: 26 additions & 9 deletions modules/gui/HierarchyPainter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,8 @@ class HierarchyPainter extends BasePainter {
#one_by_one; // process drop items one by one
#topname; // top item name
#cached_draw_object; // cached object for first draw
#draw_func; // alternative draw function
#redraw_func; // alternative redraw function

/** @summary Create painter
* @param {string} name - symbolic name
Expand Down Expand Up @@ -855,6 +857,23 @@ class HierarchyPainter extends BasePainter {
this.textcolor = settings.DarkMode ? '#eee' : '#111';
}

/** @summary Set alternative draw/redraw functions
* @desc If only only draw function specified - it also will be used for re-drawing
* @protected */
setDrawFunc(_draw, _redraw) {
if (isFunc(_draw)) {
this.#draw_func = _draw;
this.#redraw_func = isFunc(_redraw) ? _redraw : _draw;
}
}

/** @summary Invoke configured draw or redraw function
* @protected */
async callDrawFunc(dom, obj, opt, doredraw) {
const func = doredraw ? (this.#redraw_func || redraw) : (this.#draw_func || draw);
return func(dom, obj, opt);
}

/** @summary Cleanup hierarchy painter
* @desc clear drawing and browser */
cleanup() {
Expand Down Expand Up @@ -2279,10 +2298,8 @@ class HierarchyPainter extends BasePainter {
if (use_dflt_opt && !drawopt && handle?.dflt && (handle.dflt !== kExpand))
drawopt = handle.dflt;

if (dom) {
const func = updating ? redraw : draw;
return func(dom, obj, drawopt).then(p => complete(p)).catch(err => complete(null, err));
}
if (dom)
return this.callDrawFunc(dom, obj, drawopt, updating).then(p => complete(p)).catch(err => complete(null, err));

let did_activate = false;
const arr = [];
Expand Down Expand Up @@ -2326,9 +2343,9 @@ class HierarchyPainter extends BasePainter {
cleanup(frame);
mdi.activateFrame(frame);

return draw(frame, obj, drawopt)
.then(p => complete(p))
.catch(err => complete(null, err));
return this.callDrawFunc(frame, obj, drawopt)
.then(p => complete(p))
.catch(err => complete(null, err));
});
});
}
Expand Down Expand Up @@ -2434,7 +2451,7 @@ class HierarchyPainter extends BasePainter {
if (isFunc(dom?.addPadButtons))
dom.addPadButtons();

return draw(dom, res.obj, opt).then(p => drop_complete(p, mp === p));
return this.callDrawFunc(dom, res.obj, opt).then(p => drop_complete(p, mp === p));
});
}

Expand Down Expand Up @@ -3601,7 +3618,7 @@ class HierarchyPainter extends BasePainter {
}

// check that we can found frame where drawing should be done
if (!document.getElementById(this.disp_frameid))
if (!this.disp_frameid || !document.getElementById(this.disp_frameid))
return null;

if (isBatchMode())
Expand Down
Loading