UNPKG

jsroot

Version:
172 lines (138 loc) 4.87 kB
import { internals, clTMarker } from '../core.mjs'; import { DrawOptions } from '../base/BasePainter.mjs'; import { ObjectPainter } from '../base/ObjectPainter.mjs'; import { TH1Painter } from '../hist2d/TH1Painter.mjs'; import { draw } from '../draw.mjs'; /** * @summary Painter for TGraphTime object * * @private */ class TGraphTimePainter extends ObjectPainter { #step; // step number #selfid; // use to identify primitives which should be clean #wait_animation_frame; // animation flag #running_timeout; // timeout handle constructor(dom, gr, opt) { super(dom, gr, opt); this.decodeOptions(opt); this.#selfid = 'grtime_' + internals.id_counter++; } /** @summary Redraw object */ redraw() { if (this.#step === undefined) this.startDrawing(); } /** @summary Decode drawing options */ decodeOptions(opt) { const d = new DrawOptions(opt || 'REPEAT'); this.setOptions({ once: d.check('ONCE'), repeat: d.check('REPEAT'), first: d.check('FIRST') }); this.storeDrawOpt(opt); } /** @summary Draw primitives */ async drawPrimitives(indx) { const lst = this.getObject()?.fSteps.arr[this.#step]; if (!lst || (indx >= lst.arr.length)) return; const obj = lst.arr[indx], opt = lst.opt[indx] + (obj._typename === clTMarker ? ';no_interactive' : ''); return draw(this.getPadPainter(), obj, opt).then(p => { if (p) { p.$grtimeid = this.#selfid; // indicator that painter created by ourself p.$grstep = this.#step; // remember step } return this.drawPrimitives(indx + 1); }); } /** @summary Continue drawing */ continueDrawing() { const gr = this.getObject(), o = this.getOptions(); if (o.first) { // draw only single frame, cancel all others this.#step = undefined; return; } if (this.#wait_animation_frame) { this.#wait_animation_frame = undefined; // clear pad const pp = this.getPadPainter(); if (!pp) { // most probably, pad is cleared this.#step = undefined; return; } // draw primitives again this.drawPrimitives(0).then(() => { // clear primitives produced by previous drawing to avoid flicking pp.cleanPrimitives(p => { return (p.$grtimeid === this.#selfid) && (p.$grstep !== this.#step); }); this.continueDrawing(); }); } else if (this.#running_timeout) { clearTimeout(this.#running_timeout); this.#running_timeout = undefined; this.#wait_animation_frame = true; // use animation frame to disable update in inactive form requestAnimationFrame(() => this.continueDrawing()); } else { let sleeptime = Math.max(gr.fSleepTime, 10); if (++this.#step > gr.fSteps.arr.length) { if (o.repeat) { this.#step = 0; // start again sleeptime = Math.max(5000, 5 * sleeptime); // increase sleep time } else { this.#step = undefined; // clear indicator that animation running return; } } this.#running_timeout = setTimeout(() => this.continueDrawing(), sleeptime); } } /** @summary Start drawing of TGraphTime */ startDrawing() { this.#step = 0; return this.drawPrimitives(0).then(() => { this.continueDrawing(); return this; }); } /** @summary Draw TGraphTime object */ static async draw(dom, gr, opt) { if (!gr.fFrame) { console.error('Frame histogram not exists'); return null; } const painter = new TGraphTimePainter(dom, gr, opt); if (painter.getMainPainter()) { console.error('Cannot draw graph time on top of other histograms'); return null; } if (!gr.fFrame.fTitle && gr.fTitle) { const arr = gr.fTitle.split(';'); gr.fFrame.fTitle = arr[0]; if (arr[1]) gr.fFrame.fXaxis.fTitle = arr[1]; if (arr[2]) gr.fFrame.fYaxis.fTitle = arr[2]; } return TH1Painter.draw(dom, gr.fFrame, '').then(() => { painter.addToPadPrimitives(); return painter.startDrawing(); }); } } // class TGraphTimePainter /** @summary Draw TRooPlot * @private */ async function drawRooPlot(dom, plot) { return draw(dom, plot._hist, 'hist').then(async hp => { const arr = []; for (let i = 0; i < plot._items.arr.length; ++i) arr.push(draw(dom, plot._items.arr[i], plot._items.opt[i])); return Promise.all(arr).then(() => hp); }); } export { TGraphTimePainter, drawRooPlot };