@@ -26,21 +26,21 @@ import { keyedTimerDebouncer, pointerId } from '../utils.js';
2626 * - `Loading`: returns a loading placeholder.
2727 * - `Failure`: returns an error box with the error message.
2828 * - `Success`: draws the object using `drawObject`.
29- * @param {QCObject } qcObjectModel - the QCObject model
30- * @param {string } objectName - the name of the QC object to draw
29+ * @param {RemoteData } remoteData - the RemoteData object containing {qcObject, info, timestamps}
3130 * @param {object } options - optional options of presentation
3231 * @param {string[] } drawingOptions - optional drawing options to be used
32+ * @param {(Error) => void } failFn - optional function to execute upon drawing failure
3333 * @returns {vnode } output virtual-dom, a single div with JSROOT attached to it
3434 */
35- export const draw = ( qcObjectModel , objectName , options = { } , drawingOptions = [ ] ) =>
36- qcObjectModel . objects [ objectName ] ?. match ( {
35+ export const draw = ( remoteData , options = { } , drawingOptions = [ ] , failFn = ( ) => { } ) =>
36+ remoteData ?. match ( {
3737 NotAsked : ( ) => null ,
3838 Loading : ( ) => h ( '.flex-column.items-center.justify-center' , [ h ( '.animate-slow-appearance' , 'Loading' ) ] ) ,
3939 Failure : ( error ) => h ( '.error-box.danger.flex-column.justify-center.f6.text-center' , { } , [
4040 h ( 'span.error-icon' , { title : 'Error' } , iconWarning ( ) ) ,
4141 h ( 'span' , error ) ,
4242 ] ) ,
43- Success : ( data ) => drawObject ( data , options , drawingOptions , qcObjectModel ) ,
43+ Success : ( data ) => drawObject ( data , options , drawingOptions , failFn ) ,
4444 } ) ;
4545
4646/**
@@ -50,11 +50,11 @@ export const draw = (qcObjectModel, objectName, options = {}, drawingOptions = [
5050 * @param {JSON } object - {qcObject, info, timestamps}
5151 * @param {object } options - optional options of presentation
5252 * @param {string[] } drawingOptions - optional drawing options to be used
53- * @param {QCObject } qcObjectModel - the QCObject model, used to invalidate ( failure) RemoteData
53+ * @param {(Error) => void } failFn - optional function to execute upon drawing failure
5454 * @returns {vnode } output virtual-dom, a single div with JSROOT attached to it
5555 */
56- export const drawObject = ( object , options = { } , drawingOptions = [ ] , qcObjectModel = undefined ) => {
57- const { qcObject, name , etag } = object ;
56+ export const drawObject = ( object , options = { } , drawingOptions = [ ] , failFn = ( ) => { } ) => {
57+ const { qcObject, etag } = object ;
5858 const { root } = qcObject ;
5959 if ( isObjectOfTypeChecker ( root ) ) {
6060 return checkersPanel ( root ) ;
@@ -79,18 +79,18 @@ export const drawObject = (object, options = {}, drawingOptions = [], qcObjectMo
7979 oncreate : ( vnode ) => {
8080 // Setup resize function
8181 vnode . dom . onresize = ( ) => {
82- redrawOnSizeUpdate ( vnode . dom , root , drawingOptions ) ;
82+ redrawOnSizeUpdate ( vnode . dom , root , drawingOptions , failFn ) ;
8383 } ;
8484
8585 // Resize on window size change
8686 window . addEventListener ( 'resize' , vnode . dom . onresize ) ;
8787
88- drawOnCreate ( vnode . dom , root , drawingOptions , qcObjectModel , name ) ;
88+ drawOnCreate ( vnode . dom , root , drawingOptions , failFn ) ;
8989 } ,
9090 onupdate : ( vnode ) => {
9191 const isRedrawn = redrawOnDataUpdate ( vnode . dom , root , drawingOptions ) ;
9292 if ( ! isRedrawn ) {
93- redrawOnSizeUpdate ( vnode . dom , root , drawingOptions ) ;
93+ redrawOnSizeUpdate ( vnode . dom , root , drawingOptions , failFn ) ;
9494 }
9595 } ,
9696 onremove : ( vnode ) => {
@@ -114,23 +114,27 @@ export const drawObject = (object, options = {}, drawingOptions = [], qcObjectMo
114114 * @param {HTMLElement } dom - the div containing jsroot plot
115115 * @param {object } root - root object in JSON representation
116116 * @param {string[] } drawingOptions - list of options to be used for drawing object
117- * @param {QCObject } qcObjectModel - the QCObject model
118- * @param {string } objectName - the name of the QC object to draw
117+ * @param {(Error) => void } failFn - function to execute upon drawing failure
119118 * @throws {EvalError } If CSP disallows 'unsafe-eval'.
120119 * This is typically called when the drawing is incomplete or malformed.
121120 * @returns {undefined }
122121 */
123- const drawOnCreate = async ( dom , root , drawingOptions , qcObjectModel , objectName ) => {
122+ const drawOnCreate = async ( dom , root , drawingOptions , failFn ) => {
124123 const finalDrawingOptions = generateDrawingOptionString ( root , drawingOptions ) ;
125124 JSROOT . draw ( dom , root , finalDrawingOptions ) . then ( ( painter ) => {
126125 if ( painter === null ) {
127126 // eslint-disable-next-line no-console
128127 console . error ( 'null painter in JSROOT' ) ;
128+ if ( typeof failFn === 'function' ) {
129+ failFn ( new Error ( 'null painter in JSROOT' ) ) ;
130+ }
129131 }
130132 } ) . catch ( ( error ) => {
131133 // eslint-disable-next-line no-console
132134 console . error ( error ) ;
133- qcObjectModel ?. invalidObject ( objectName ) ;
135+ if ( typeof failFn === 'function' ) {
136+ failFn ( error ) ;
137+ }
134138 } ) ;
135139 dom . dataset . fingerprintRedraw = fingerprintResize ( dom . clientWidth , dom . clientHeight ) ;
136140 dom . dataset . fingerprintData = fingerprintData ( root , drawingOptions ) ;
@@ -156,11 +160,12 @@ const drawOnCreate = async (dom, root, drawingOptions, qcObjectModel, objectName
156160 * @param {Model } model - Root model of the application
157161 * @param {HTMLElement } dom - Element containing the JSROOT plot
158162 * @param {TabObject } tabObject - Object describing the graph to redraw inside `dom`
163+ * @param {(Error) => void } failFn - Function to execute upon drawing failure
159164 * @returns {undefined }
160165 */
161166const redrawOnSizeUpdate = keyedTimerDebouncer (
162167 ( _ , dom ) => dom ,
163- ( dom , root , drawingOptions ) => {
168+ ( dom , root , drawingOptions , failFn ) => {
164169 let previousFingerprint = dom . dataset . fingerprintResize ;
165170
166171 const intervalId = setInterval ( ( ) => {
@@ -175,7 +180,7 @@ const redrawOnSizeUpdate = keyedTimerDebouncer(
175180
176181 // Size stable across intervals (safe to redraw)
177182 if ( dom . dataset . fingerprintResize !== currentFingerprint ) {
178- redraw ( dom , root , drawingOptions ) ;
183+ redraw ( dom , root , drawingOptions , failFn ) ;
179184 }
180185
181186 clearInterval ( intervalId ) ;
@@ -187,10 +192,10 @@ const redrawOnSizeUpdate = keyedTimerDebouncer(
187192 } , 50 ) ;
188193 } ,
189194 200 ,
190- ( dom , root , drawingOptions ) => {
195+ ( dom , root , drawingOptions , failFn ) => {
191196 const resizeFingerprint = fingerprintResize ( dom . clientWidth , dom . clientHeight ) ;
192197 if ( dom . dataset . fingerprintResize !== resizeFingerprint ) {
193- redraw ( dom , root , drawingOptions ) ;
198+ redraw ( dom , root , drawingOptions , failFn ) ;
194199 }
195200 } ,
196201) ;
@@ -202,12 +207,13 @@ const redrawOnSizeUpdate = keyedTimerDebouncer(
202207 * @param {HTMLElement } dom - Target element containing the JSROOT graph.
203208 * @param {object } root - JSROOT-compatible data object to be rendered.
204209 * @param {string[] } drawingOptions - Initial or user-provided drawing options.
210+ * @param {(Error) => void } failFn - Function to execute upon drawing failure
205211 * @returns {boolean } whether the JSROOT plot was redrawn
206212 */
207- const redrawOnDataUpdate = ( dom , root , drawingOptions ) => {
213+ const redrawOnDataUpdate = ( dom , root , drawingOptions , failFn ) => {
208214 const dataFingerprint = fingerprintData ( root , drawingOptions ) ;
209215 if ( dom . dataset . fingerprintData !== dataFingerprint ) {
210- redraw ( dom , root , drawingOptions ) ;
216+ redraw ( dom , root , drawingOptions , failFn ) ;
211217 return true ;
212218 }
213219 return false ;
@@ -218,14 +224,23 @@ const redrawOnDataUpdate = (dom, root, drawingOptions) => {
218224 * @param {HTMLElement } dom - Target element containing the JSROOT graph.
219225 * @param {object } root - JSROOT-compatible data object to be rendered.
220226 * @param {string[] } drawingOptions - Initial or user-provided drawing options.
227+ * @param {(Error) => void } failFn - Function to execute upon drawing failure
221228 * @returns {undefined }
222229 */
223- const redraw = ( dom , root , drawingOptions ) => {
230+ const redraw = ( dom , root , drawingOptions , failFn ) => {
224231 // A bug exists in JSROOT where the cursor gets stuck on `wait` when redrawing multiple objects simultaneously.
225232 // We save the current cursor state here and revert back to it after redrawing is complete.
226233 const currentCursor = document . body . style . cursor ;
227234 const finalDrawingOptions = generateDrawingOptionString ( root , drawingOptions ) ;
228- JSROOT . redraw ( dom , root , finalDrawingOptions ) ;
235+ try {
236+ JSROOT . redraw ( dom , root , finalDrawingOptions ) ;
237+ } catch ( error ) {
238+ // eslint-disable-next-line no-console
239+ console . error ( error ) ;
240+ if ( typeof failFn === 'function' ) {
241+ failFn ( error ) ;
242+ }
243+ }
229244 document . body . style . cursor = currentCursor ;
230245} ;
231246
0 commit comments