@@ -97,7 +97,7 @@ function createChart(data, containerId, type) {
97
97
] ;
98
98
} else {
99
99
return [ `${ context . dataset . label } :` ,
100
- `Value: ${ context . parsed . y . toFixed ( 2 ) } ${ data . unit } ` ,
100
+ `Value: ${ context . parsed . y . toFixed ( 2 ) } ${ data . unit } ` ,
101
101
] ;
102
102
}
103
103
}
@@ -111,6 +111,8 @@ function createChart(data, containerId, type) {
111
111
text : data . unit
112
112
} ,
113
113
grace : '20%' ,
114
+ min : isCustomRangesEnabled ( ) ? data . range_min : null ,
115
+ max : isCustomRangesEnabled ( ) ? data . range_max : null
114
116
}
115
117
}
116
118
} ;
@@ -182,7 +184,7 @@ function updateCharts() {
182
184
const filterRunData = ( chart ) => ( {
183
185
...chart ,
184
186
runs : Object . fromEntries (
185
- Object . entries ( chart . runs ) . filter ( ( [ _ , data ] ) =>
187
+ Object . entries ( chart . runs ) . filter ( ( [ _ , data ] ) =>
186
188
activeRuns . has ( data . runName )
187
189
)
188
190
)
@@ -276,25 +278,25 @@ function createChartContainer(data, canvasId, type) {
276
278
// Add tags if present
277
279
if ( metadata && metadata . tags ) {
278
280
container . setAttribute ( 'data-tags' , metadata . tags . join ( ',' ) ) ;
279
-
281
+
280
282
// Add tags display
281
283
const tagsContainer = document . createElement ( 'div' ) ;
282
284
tagsContainer . className = 'benchmark-tags' ;
283
-
285
+
284
286
metadata . tags . forEach ( tag => {
285
287
const tagElement = document . createElement ( 'span' ) ;
286
288
tagElement . className = 'tag' ;
287
289
tagElement . textContent = tag ;
288
290
tagElement . setAttribute ( 'data-tag' , tag ) ;
289
-
291
+
290
292
// Add tooltip with tag description
291
293
if ( benchmarkTags [ tag ] ) {
292
294
tagElement . setAttribute ( 'title' , benchmarkTags [ tag ] . description ) ;
293
295
}
294
-
296
+
295
297
tagsContainer . appendChild ( tagElement ) ;
296
298
} ) ;
297
-
299
+
298
300
container . appendChild ( tagsContainer ) ;
299
301
}
300
302
@@ -493,6 +495,12 @@ function updateURL() {
493
495
url . searchParams . set ( 'unstable' , 'true' ) ;
494
496
}
495
497
498
+ if ( ! isCustomRangesEnabled ( ) ) {
499
+ url . searchParams . delete ( 'customRange' ) ;
500
+ } else {
501
+ url . searchParams . set ( 'customRange' , 'true' ) ;
502
+ }
503
+
496
504
history . replaceState ( null , '' , url ) ;
497
505
}
498
506
@@ -505,12 +513,12 @@ function filterCharts() {
505
513
const label = container . getAttribute ( 'data-label' ) ;
506
514
const suite = container . getAttribute ( 'data-suite' ) ;
507
515
const isUnstable = container . getAttribute ( 'data-unstable' ) === 'true' ;
508
- const tags = container . getAttribute ( 'data-tags' ) ?
509
- container . getAttribute ( 'data-tags' ) . split ( ',' ) : [ ] ;
516
+ const tags = container . getAttribute ( 'data-tags' ) ?
517
+ container . getAttribute ( 'data-tags' ) . split ( ',' ) : [ ] ;
510
518
511
519
// Check if benchmark has all active tags (if any are selected)
512
- const hasAllActiveTags = activeTags . size === 0 ||
513
- Array . from ( activeTags ) . every ( tag => tags . includes ( tag ) ) ;
520
+ const hasAllActiveTags = activeTags . size === 0 ||
521
+ Array . from ( activeTags ) . every ( tag => tags . includes ( tag ) ) ;
514
522
515
523
// Hide unstable benchmarks if showUnstable is false
516
524
const shouldShow = regex . test ( label ) &&
@@ -535,16 +543,19 @@ function processTimeseriesData(benchmarkRuns) {
535
543
536
544
benchmarkRuns . forEach ( run => {
537
545
run . results . forEach ( result => {
546
+ const metadata = metadataForLabel ( result . label , 'benchmark' ) ;
547
+
538
548
if ( ! resultsByLabel [ result . label ] ) {
539
549
resultsByLabel [ result . label ] = {
540
550
label : result . label ,
541
551
suite : result . suite ,
542
552
unit : result . unit ,
543
553
lower_is_better : result . lower_is_better ,
554
+ range_min : metadata ?. range_min ?? null , // can't use || because js treats 0 as null
555
+ range_max : metadata ?. range_max ?? null ,
544
556
runs : { }
545
557
} ;
546
558
}
547
-
548
559
addRunDataPoint ( resultsByLabel [ result . label ] , run , result , run . name ) ;
549
560
} ) ;
550
561
} ) ;
@@ -568,6 +579,8 @@ function processBarChartsData(benchmarkRuns) {
568
579
suite : result . suite ,
569
580
unit : result . unit ,
570
581
lower_is_better : result . lower_is_better ,
582
+ range_min : groupMetadata ?. range_min ?? null , // can't use || because js treats 0 as null
583
+ range_max : groupMetadata ?. range_max ?? null ,
571
584
labels : [ ] ,
572
585
datasets : [ ] ,
573
586
// Add metadata if available
@@ -654,6 +667,8 @@ function processLayerComparisonsData(benchmarkRuns) {
654
667
suite : result . suite ,
655
668
unit : result . unit ,
656
669
lower_is_better : result . lower_is_better ,
670
+ range_min : metadata ?. range_min ?? null , // can't use || because js treats 0 as null
671
+ range_max : metadata ?. range_max ?? null ,
657
672
runs : { } ,
658
673
benchmarkLabels : [ ] ,
659
674
description : metadata ?. description || null ,
@@ -760,26 +775,37 @@ function isUnstableEnabled() {
760
775
return unstableToggle . checked ;
761
776
}
762
777
778
+ function isCustomRangesEnabled ( ) {
779
+ const rangesToggle = document . getElementById ( 'custom-range' ) ;
780
+ return rangesToggle . checked ;
781
+ }
782
+
763
783
function setupToggles ( ) {
764
784
const notesToggle = document . getElementById ( 'show-notes' ) ;
765
785
const unstableToggle = document . getElementById ( 'show-unstable' ) ;
786
+ const customRangeToggle = document . getElementById ( 'custom-range' ) ;
766
787
767
- notesToggle . addEventListener ( 'change' , function ( ) {
788
+ notesToggle . addEventListener ( 'change' , function ( ) {
768
789
// Update all note elements visibility
769
790
document . querySelectorAll ( '.benchmark-note' ) . forEach ( note => {
770
791
note . style . display = isNotesEnabled ( ) ? 'block' : 'none' ;
771
792
} ) ;
772
793
updateURL ( ) ;
773
794
} ) ;
774
795
775
- unstableToggle . addEventListener ( 'change' , function ( ) {
796
+ unstableToggle . addEventListener ( 'change' , function ( ) {
776
797
// Update all unstable warning elements visibility
777
798
document . querySelectorAll ( '.benchmark-unstable' ) . forEach ( warning => {
778
799
warning . style . display = isUnstableEnabled ( ) ? 'block' : 'none' ;
779
800
} ) ;
780
801
filterCharts ( ) ;
781
802
} ) ;
782
803
804
+ customRangeToggle . addEventListener ( 'change' , function ( ) {
805
+ // redraw all charts
806
+ updateCharts ( ) ;
807
+ } ) ;
808
+
783
809
// Initialize from URL params if present
784
810
const notesParam = getQueryParam ( 'notes' ) ;
785
811
const unstableParam = getQueryParam ( 'unstable' ) ;
@@ -793,13 +819,18 @@ function setupToggles() {
793
819
let showUnstable = unstableParam === 'true' ;
794
820
unstableToggle . checked = showUnstable ;
795
821
}
822
+
823
+ const customRangesParam = getQueryParam ( 'customRange' ) ;
824
+ if ( customRangesParam !== null ) {
825
+ customRangeToggle . checked = customRangesParam === 'true' ;
826
+ }
796
827
}
797
828
798
829
function setupTagFilters ( ) {
799
830
tagFiltersContainer = document . getElementById ( 'tag-filters' ) ;
800
831
801
832
const allTags = [ ] ;
802
-
833
+
803
834
if ( benchmarkTags ) {
804
835
for ( const tag in benchmarkTags ) {
805
836
if ( ! allTags . includes ( tag ) ) {
@@ -812,17 +843,17 @@ function setupTagFilters() {
812
843
allTags . forEach ( tag => {
813
844
const tagContainer = document . createElement ( 'div' ) ;
814
845
tagContainer . className = 'tag-filter' ;
815
-
846
+
816
847
const checkbox = document . createElement ( 'input' ) ;
817
848
checkbox . type = 'checkbox' ;
818
849
checkbox . id = `tag-${ tag } ` ;
819
850
checkbox . className = 'tag-checkbox' ;
820
851
checkbox . dataset . tag = tag ;
821
-
852
+
822
853
const label = document . createElement ( 'label' ) ;
823
854
label . htmlFor = `tag-${ tag } ` ;
824
855
label . textContent = tag ;
825
-
856
+
826
857
// Add info icon with tooltip if tag description exists
827
858
if ( benchmarkTags [ tag ] ) {
828
859
const infoIcon = document . createElement ( 'span' ) ;
@@ -831,16 +862,16 @@ function setupTagFilters() {
831
862
infoIcon . title = benchmarkTags [ tag ] . description ;
832
863
label . appendChild ( infoIcon ) ;
833
864
}
834
-
835
- checkbox . addEventListener ( 'change' , function ( ) {
865
+
866
+ checkbox . addEventListener ( 'change' , function ( ) {
836
867
if ( this . checked ) {
837
868
activeTags . add ( tag ) ;
838
869
} else {
839
870
activeTags . delete ( tag ) ;
840
871
}
841
872
filterCharts ( ) ;
842
873
} ) ;
843
-
874
+
844
875
tagContainer . appendChild ( checkbox ) ;
845
876
tagContainer . appendChild ( label ) ;
846
877
tagFiltersContainer . appendChild ( tagContainer ) ;
@@ -849,18 +880,18 @@ function setupTagFilters() {
849
880
850
881
function toggleAllTags ( select ) {
851
882
const checkboxes = document . querySelectorAll ( '.tag-checkbox' ) ;
852
-
883
+
853
884
checkboxes . forEach ( checkbox => {
854
885
checkbox . checked = select ;
855
886
const tag = checkbox . dataset . tag ;
856
-
887
+
857
888
if ( select ) {
858
889
activeTags . add ( tag ) ;
859
890
} else {
860
891
activeTags . delete ( tag ) ;
861
892
}
862
893
} ) ;
863
-
894
+
864
895
filterCharts ( ) ;
865
896
}
866
897
0 commit comments