@@ -51,6 +51,7 @@ import {
5151 clamp ,
5252 deepGet ,
5353 filterMap ,
54+ formatByteRate ,
5455 formatBytesCompact ,
5556 formatDurationWithMs ,
5657 formatDurationWithMsIfNeeded ,
@@ -97,6 +98,23 @@ const formatFileOfTotal = (files: number, totalFiles: number) =>
9798const formatFileOfTotalForBrace = ( files : number , totalFiles : number ) =>
9899 `(${ formatInteger ( files ) } /GB ${ formatInteger ( totalFiles ) } )` ;
99100
101+ function formatLoadTooltip (
102+ loadFiles : number ,
103+ loadBytes ?: number ,
104+ loadTime ?: number ,
105+ loadWait ?: number ,
106+ ) : string {
107+ return assemble (
108+ `Loaded files: ${ formatInteger ( loadFiles ) } ` ,
109+ loadBytes != null && `Loaded bytes: ${ formatBytesCompact ( loadBytes ) } ` ,
110+ loadTime != null && loadTime > 0 && `Load time: ${ formatDurationWithMs ( loadTime ) } ` ,
111+ loadTime && loadBytes
112+ ? `Load rate: ${ formatByteRate ( loadBytes / ( loadTime / 1000 ) ) } `
113+ : undefined ,
114+ loadWait != null && loadWait > 0 && `Load wait: ${ formatDurationWithMs ( loadWait ) } ` ,
115+ ) . join ( '\n' ) ;
116+ }
117+
100118function inputLabelContent ( stage : StageDefinition , inputIndex : number ) {
101119 const { input, broadcast } = stage . definition ;
102120 const stageInput = input [ inputIndex ] ;
@@ -337,6 +355,22 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
337355 />
338356 </ >
339357 ) }
358+ { Boolean ( c . loadFiles ) && (
359+ < >
360+ { ' ' }
361+ { ' ' }
362+ < Icon
363+ className = "load-indicator"
364+ icon = { IconNames . IMPORT }
365+ data-tooltip = { formatLoadTooltip (
366+ c . loadFiles ,
367+ c . loadBytes ,
368+ c . loadTime ,
369+ c . loadWait ,
370+ ) }
371+ />
372+ </ >
373+ ) }
340374 </ >
341375 ) ;
342376 } ,
@@ -505,6 +539,10 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
505539 const hasCounter = stages . hasCounterForStage ( stage , inputCounter ) ;
506540 const bytes = stages . getTotalCounterForStage ( stage , inputCounter , 'bytes' ) ;
507541 const inputFileCount = stages . getTotalCounterForStage ( stage , inputCounter , 'totalFiles' ) ;
542+ const loadFiles = stages . getTotalCounterForStage ( stage , inputCounter , 'loadFiles' ) ;
543+ const loadBytes = stages . getTotalCounterForStage ( stage , inputCounter , 'loadBytes' ) ;
544+ const loadTime = stages . getTotalCounterForStage ( stage , inputCounter , 'loadTime' ) ;
545+ const loadWait = stages . getTotalCounterForStage ( stage , inputCounter , 'loadWait' ) ;
508546 const inputLabel = `${ formatInputLabel ( stage , inputNumber ) } (input${ inputNumber } )` ;
509547 return (
510548 < div
@@ -524,7 +562,7 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
524562 }
525563 braces = { rowsValues }
526564 />
527- { inputFileCount ? (
565+ { Boolean ( inputFileCount ) && (
528566 < >
529567 { ' ' }
530568 { ' ' }
@@ -536,7 +574,18 @@ export const ExecutionStagesPane = React.memo(function ExecutionStagesPane(
536574 braces = { filesValues }
537575 />
538576 </ >
539- ) : undefined }
577+ ) }
578+ { Boolean ( loadFiles ) && (
579+ < >
580+ { ' ' }
581+ { ' ' }
582+ < Icon
583+ className = "load-indicator"
584+ icon = { IconNames . IMPORT }
585+ data-tooltip = { formatLoadTooltip ( loadFiles , loadBytes , loadTime , loadWait ) }
586+ />
587+ </ >
588+ ) }
540589 </ div >
541590 ) ;
542591 }
0 commit comments