@@ -88,7 +88,7 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
8888 ctx . fillStyle = colors . textColor ;
8989 ctx . textAlign = 'left' ;
9090 ctx . font = 'bold 12px sans-serif' ;
91- ctx . fillText ( `Resolved Instances Matrix (hover for details, drag to zoom, double-click to reset ) - ${ percentageResolvedByAtLeastOne } % of instances resolved by at least one model` , 10 , 15 ) ;
91+ ctx . fillText ( `Resolved Instances Matrix (hover for details, drag to zoom) - ${ percentageResolvedByAtLeastOne } % of instances resolved by at least one model` , 10 , 15 ) ;
9292
9393 // Draw model names (y-axis labels) with line breaks
9494 ctx . fillStyle = colors . textColor ;
@@ -188,6 +188,52 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
188188 document . body . appendChild ( tooltip ) ;
189189 }
190190
191+ // Create zoom out button if it doesn't exist
192+ let zoomOutBtn = document . getElementById ( 'matrix-zoom-out-btn' ) ;
193+ if ( ! zoomOutBtn ) {
194+ zoomOutBtn = document . createElement ( 'button' ) ;
195+ zoomOutBtn . id = 'matrix-zoom-out-btn' ;
196+ zoomOutBtn . textContent = 'Zoom Out' ;
197+ zoomOutBtn . style . position = 'absolute' ;
198+ zoomOutBtn . style . backgroundColor = 'rgba(59, 130, 246, 0.9)' ;
199+ zoomOutBtn . style . color = 'white' ;
200+ zoomOutBtn . style . border = 'none' ;
201+ zoomOutBtn . style . padding = '6px 12px' ;
202+ zoomOutBtn . style . borderRadius = '4px' ;
203+ zoomOutBtn . style . fontSize = '12px' ;
204+ zoomOutBtn . style . fontFamily = 'sans-serif' ;
205+ zoomOutBtn . style . cursor = 'pointer' ;
206+ zoomOutBtn . style . zIndex = '10001' ;
207+ zoomOutBtn . style . display = 'none' ;
208+ zoomOutBtn . style . boxShadow = '0 2px 4px rgba(0,0,0,0.2)' ;
209+ document . body . appendChild ( zoomOutBtn ) ;
210+
211+ // Hover effect
212+ zoomOutBtn . addEventListener ( 'mouseenter' , ( ) => {
213+ zoomOutBtn . style . backgroundColor = 'rgba(59, 130, 246, 1)' ;
214+ } ) ;
215+ zoomOutBtn . addEventListener ( 'mouseleave' , ( ) => {
216+ zoomOutBtn . style . backgroundColor = 'rgba(59, 130, 246, 0.9)' ;
217+ } ) ;
218+ }
219+
220+ // Function to update zoom button position and visibility
221+ function updateZoomButton ( ) {
222+ const rect = canvas . getBoundingClientRect ( ) ;
223+ const isZoomed = currentSize !== null && ( currentStart !== 0 || currentSize !== allSortedInstanceIds . length ) ;
224+
225+ if ( isZoomed ) {
226+ zoomOutBtn . style . display = 'block' ;
227+ zoomOutBtn . style . left = ( rect . right - 100 ) + 'px' ;
228+ zoomOutBtn . style . top = ( rect . top + 5 ) + 'px' ;
229+ } else {
230+ zoomOutBtn . style . display = 'none' ;
231+ }
232+ }
233+
234+ // Initial button state
235+ updateZoomButton ( ) ;
236+
191237 // State for drag-to-zoom
192238 let isDragging = false ;
193239 let dragStartX = null ;
@@ -296,6 +342,9 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
296342 // Update the metadata
297343 chartInstance . _matrixMetadata . chunkStart = currentStart ;
298344 chartInstance . _matrixMetadata . chunkSize = currentSize ;
345+
346+ // Update zoom button visibility
347+ updateZoomButton ( ) ;
299348 }
300349 }
301350
@@ -317,7 +366,7 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
317366 }
318367 } ;
319368
320- const doubleClickHandler = ( e ) => {
369+ const zoomOutHandler = ( e ) => {
321370 // Reset to show all instances
322371 currentStart = 0 ;
323372 currentSize = null ;
@@ -326,14 +375,17 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
326375 // Update the metadata
327376 chartInstance . _matrixMetadata . chunkStart = currentStart ;
328377 chartInstance . _matrixMetadata . chunkSize = allSortedInstanceIds . length ;
378+
379+ // Update zoom button visibility
380+ updateZoomButton ( ) ;
329381 } ;
330382
331383 // Add event listeners
332384 canvas . addEventListener ( 'mousemove' , mouseMoveHandler ) ;
333385 canvas . addEventListener ( 'mousedown' , mouseDownHandler ) ;
334386 canvas . addEventListener ( 'mouseup' , mouseUpHandler ) ;
335387 canvas . addEventListener ( 'mouseleave' , mouseLeaveHandler ) ;
336- canvas . addEventListener ( 'dblclick ' , doubleClickHandler ) ;
388+ zoomOutBtn . addEventListener ( 'click ' , zoomOutHandler ) ;
337389
338390 // Return a Chart-like object for compatibility
339391 const chartInstance = {
@@ -343,16 +395,23 @@ function renderResolvedInstancesMatrix(ctx, selected, colors, backgroundPlugin,
343395 canvas . removeEventListener ( 'mousedown' , mouseDownHandler ) ;
344396 canvas . removeEventListener ( 'mouseup' , mouseUpHandler ) ;
345397 canvas . removeEventListener ( 'mouseleave' , mouseLeaveHandler ) ;
346- canvas . removeEventListener ( 'dblclick ' , doubleClickHandler ) ;
398+ zoomOutBtn . removeEventListener ( 'click ' , zoomOutHandler ) ;
347399
348400 // Hide tooltip when chart is destroyed
349401 const tooltip = document . getElementById ( 'matrix-tooltip' ) ;
350402 if ( tooltip ) {
351403 tooltip . style . display = 'none' ;
352404 }
405+
406+ // Hide zoom button when chart is destroyed
407+ const zoomBtn = document . getElementById ( 'matrix-zoom-out-btn' ) ;
408+ if ( zoomBtn ) {
409+ zoomBtn . style . display = 'none' ;
410+ }
353411 } ,
354412 resize : ( ) => {
355413 dims = drawMatrix ( currentStart , currentSize ) ;
414+ updateZoomButton ( ) ;
356415 } ,
357416 update : ( ) => { } ,
358417 data : { datasets : [ ] } ,
0 commit comments