7
7
let activeRuns = new Set ( defaultCompareNames ) ;
8
8
let chartInstances = new Map ( ) ;
9
9
let suiteNames = new Set ( ) ;
10
- let timeseriesData , barChartsData , allRunNames ;
11
10
let activeTags = new Set ( ) ;
11
+ let timeseriesData , barChartsData , allRunNames ;
12
12
let layerComparisonsData ;
13
13
let latestRunsLookup = new Map ( ) ;
14
14
let pendingCharts = new Map ( ) ; // Store chart data for lazy loading
15
15
let chartObserver ; // Intersection observer for lazy loading charts
16
16
let annotationsOptions = new Map ( ) ; // Global options map for annotations
17
+ let archivedDataLoaded = false ;
17
18
18
19
// DOM Elements
19
20
let runSelect , selectedRunsDiv , suiteFiltersContainer , tagFiltersContainer ;
@@ -577,6 +578,12 @@ function updateURL() {
577
578
} else {
578
579
url . searchParams . set ( 'customRange' , 'true' ) ;
579
580
}
581
+
582
+ if ( ! isArchivedDataEnabled ( ) ) {
583
+ url . searchParams . delete ( 'archived' ) ;
584
+ } else {
585
+ url . searchParams . set ( 'archived' , 'true' ) ;
586
+ }
580
587
581
588
history . replaceState ( null , '' , url ) ;
582
589
}
@@ -835,6 +842,9 @@ function setupRunSelector() {
835
842
runSelect = document . getElementById ( 'run-select' ) ;
836
843
selectedRunsDiv = document . getElementById ( 'selected-runs' ) ;
837
844
845
+ // Clear existing options first to prevent duplicates when reloading with archived data
846
+ runSelect . innerHTML = '' ;
847
+
838
848
allRunNames . forEach ( name => {
839
849
const option = document . createElement ( 'option' ) ;
840
850
option . value = name ;
@@ -848,6 +858,9 @@ function setupRunSelector() {
848
858
function setupSuiteFilters ( ) {
849
859
suiteFiltersContainer = document . getElementById ( 'suite-filters' ) ;
850
860
861
+ // Clear existing suite filters before adding new ones
862
+ suiteFiltersContainer . innerHTML = '' ;
863
+
851
864
benchmarkRuns . forEach ( run => {
852
865
run . results . forEach ( result => {
853
866
suiteNames . add ( result . suite ) ;
@@ -883,10 +896,16 @@ function isCustomRangesEnabled() {
883
896
return rangesToggle . checked ;
884
897
}
885
898
899
+ function isArchivedDataEnabled ( ) {
900
+ const archivedDataToggle = document . getElementById ( 'show-archived-data' ) ;
901
+ return archivedDataToggle . checked ;
902
+ }
903
+
886
904
function setupToggles ( ) {
887
905
const notesToggle = document . getElementById ( 'show-notes' ) ;
888
906
const unstableToggle = document . getElementById ( 'show-unstable' ) ;
889
907
const customRangeToggle = document . getElementById ( 'custom-range' ) ;
908
+ const archivedDataToggle = document . getElementById ( 'show-archived-data' ) ;
890
909
891
910
notesToggle . addEventListener ( 'change' , function ( ) {
892
911
// Update all note elements visibility
@@ -908,10 +927,26 @@ function setupToggles() {
908
927
// redraw all charts
909
928
updateCharts ( ) ;
910
929
} ) ;
930
+
931
+ // Add event listener for archived data toggle
932
+ if ( archivedDataToggle ) {
933
+ archivedDataToggle . addEventListener ( 'change' , function ( ) {
934
+ if ( archivedDataToggle . checked ) {
935
+ loadArchivedData ( ) ;
936
+ } else {
937
+ if ( archivedDataLoaded ) {
938
+ // Reload the page to reset
939
+ location . reload ( ) ;
940
+ }
941
+ }
942
+ updateURL ( ) ;
943
+ } ) ;
944
+ }
911
945
912
946
// Initialize from URL params if present
913
947
const notesParam = getQueryParam ( 'notes' ) ;
914
948
const unstableParam = getQueryParam ( 'unstable' ) ;
949
+ const archivedParam = getQueryParam ( 'archived' ) ;
915
950
916
951
if ( notesParam !== null ) {
917
952
let showNotes = notesParam === 'true' ;
@@ -927,11 +962,22 @@ function setupToggles() {
927
962
if ( customRangesParam !== null ) {
928
963
customRangeToggle . checked = customRangesParam === 'true' ;
929
964
}
965
+
966
+ if ( archivedDataToggle && archivedParam !== null ) {
967
+ archivedDataToggle . checked = archivedParam === 'true' ;
968
+
969
+ if ( archivedDataToggle . checked ) {
970
+ loadArchivedData ( ) ;
971
+ }
972
+ }
930
973
}
931
974
932
975
function setupTagFilters ( ) {
933
976
tagFiltersContainer = document . getElementById ( 'tag-filters' ) ;
934
977
978
+ // Clear existing tag filters before adding new ones
979
+ tagFiltersContainer . innerHTML = '' ;
980
+
935
981
const allTags = [ ] ;
936
982
937
983
if ( benchmarkTags ) {
@@ -1087,38 +1133,124 @@ window.addSelectedRun = addSelectedRun;
1087
1133
window . removeRun = removeRun ;
1088
1134
window . toggleAllTags = toggleAllTags ;
1089
1135
1136
+ // Helper function to fetch and process benchmark data
1137
+ function fetchAndProcessData ( url , isArchived = false ) {
1138
+ const loadingIndicator = document . getElementById ( 'loading-indicator' ) ;
1139
+
1140
+ return fetch ( url )
1141
+ . then ( response => {
1142
+ if ( ! response . ok ) { throw new Error ( `Got response status ${ response . status } .` ) }
1143
+ return response . json ( ) ;
1144
+ } )
1145
+ . then ( data => {
1146
+ const newRuns = data . runs || data ;
1147
+
1148
+ if ( isArchived ) {
1149
+ // Merge with existing data for archived data
1150
+ benchmarkRuns = benchmarkRuns . concat ( newRuns ) ;
1151
+
1152
+ // Merge metadata and tags if available
1153
+ if ( data . metadata ) {
1154
+ benchmarkMetadata = { ...benchmarkMetadata , ...data . metadata } ;
1155
+ }
1156
+
1157
+ if ( data . tags ) {
1158
+ benchmarkTags = { ...benchmarkTags , ...data . tags } ;
1159
+ }
1160
+
1161
+ archivedDataLoaded = true ;
1162
+ } else {
1163
+ // Replace existing data for primary data
1164
+ benchmarkRuns = newRuns ;
1165
+ benchmarkMetadata = data . metadata || benchmarkMetadata || { } ;
1166
+ benchmarkTags = data . tags || benchmarkTags || { } ;
1167
+ }
1168
+
1169
+ initializeCharts ( ) ;
1170
+ } )
1171
+ . catch ( error => {
1172
+ console . error ( `Error fetching ${ isArchived ? 'archived' : 'remote' } data:` , error ) ;
1173
+ loadingIndicator . textContent = 'Fetching remote data failed.' ;
1174
+ } )
1175
+ . finally ( ( ) => {
1176
+ loadingIndicator . style . display = 'none' ;
1177
+ } ) ;
1178
+ }
1179
+
1090
1180
// Load data based on configuration
1091
1181
function loadData ( ) {
1092
1182
const loadingIndicator = document . getElementById ( 'loading-indicator' ) ;
1093
1183
loadingIndicator . style . display = 'block' ; // Show loading indicator
1094
1184
1095
1185
if ( typeof remoteDataUrl !== 'undefined' && remoteDataUrl !== '' ) {
1096
1186
// Fetch data from remote URL
1097
- fetch ( remoteDataUrl )
1098
- . then ( response => {
1099
- if ( ! response . ok ) { throw new Error ( `Got response status ${ response . status } .` ) }
1100
- return response . json ( ) ;
1101
- } )
1102
- . then ( data => {
1103
- benchmarkRuns = data . runs || data ;
1104
- benchmarkMetadata = data . metadata || benchmarkMetadata || { } ;
1105
- benchmarkTags = data . tags || benchmarkTags || { } ;
1106
- initializeCharts ( ) ;
1107
- } )
1108
- . catch ( error => {
1109
- console . error ( 'Error fetching remote data:' , error ) ;
1110
- loadingIndicator . textContent = 'Fetching remote data failed.' ;
1111
- } )
1112
- . finally ( ( ) => {
1113
- loadingIndicator . style . display = 'none' ; // Hide loading indicator
1114
- } ) ;
1187
+ fetchAndProcessData ( remoteDataUrl ) ;
1115
1188
} else {
1116
1189
// Use local data (benchmarkRuns and benchmarkMetadata should be defined in data.js)
1117
1190
initializeCharts ( ) ;
1118
1191
loadingIndicator . style . display = 'none' ; // Hide loading indicator
1119
1192
}
1120
1193
}
1121
1194
1195
+ // Function to load archived data and merge with current data
1196
+ // Archived data consists of older benchmark results that have been separated from
1197
+ // the primary dataset but are still available for historical analysis.
1198
+ function loadArchivedData ( ) {
1199
+ const loadingIndicator = document . getElementById ( 'loading-indicator' ) ;
1200
+ loadingIndicator . style . display = 'block' ;
1201
+
1202
+ if ( archivedDataLoaded ) {
1203
+ updateCharts ( ) ;
1204
+ loadingIndicator . style . display = 'none' ;
1205
+ return ;
1206
+ }
1207
+
1208
+ if ( typeof remoteDataUrl !== 'undefined' && remoteDataUrl !== '' ) {
1209
+ // For remote data, construct the archive URL by adding _archive before the extension
1210
+ const archiveUrl = remoteDataUrl . replace ( / ( \. [ ^ . ] + ) $ / , '_archive$1' ) ;
1211
+
1212
+ // Check if we're using local JSON files
1213
+ if ( remoteDataUrl . startsWith ( './' ) && remoteDataUrl . endsWith ( '.json' ) ) {
1214
+ fetchAndProcessData ( archiveUrl , true ) ;
1215
+ } else {
1216
+ fetchAndProcessData ( archiveUrl , true ) ;
1217
+ }
1218
+ } else {
1219
+ // For local data using a static js file
1220
+ const script = document . createElement ( 'script' ) ;
1221
+ script . src = 'data_archive.js' ;
1222
+ script . onload = ( ) => {
1223
+ if ( typeof archivedBenchmarkRuns !== 'undefined' ) {
1224
+ // Merge the archived runs with current runs
1225
+ benchmarkRuns = benchmarkRuns . concat ( archivedBenchmarkRuns ) ;
1226
+
1227
+ // Merge metadata and tags if available
1228
+ if ( typeof archivedBenchmarkMetadata !== 'undefined' ) {
1229
+ benchmarkMetadata = { ...benchmarkMetadata , ...archivedBenchmarkMetadata } ;
1230
+ }
1231
+
1232
+ if ( typeof archivedBenchmarkTags !== 'undefined' ) {
1233
+ benchmarkTags = { ...benchmarkTags , ...archivedBenchmarkTags } ;
1234
+ }
1235
+
1236
+ archivedDataLoaded = true ;
1237
+
1238
+ initializeCharts ( ) ;
1239
+ } else {
1240
+ console . error ( 'Archived runs data not found in data_archive.js' ) ;
1241
+ }
1242
+ loadingIndicator . style . display = 'none' ;
1243
+ } ;
1244
+
1245
+ script . onerror = ( ) => {
1246
+ console . error ( 'Failed to load data_archive.js' ) ;
1247
+ loadingIndicator . style . display = 'none' ;
1248
+ } ;
1249
+
1250
+ document . head . appendChild ( script ) ;
1251
+ }
1252
+ }
1253
+
1122
1254
// Initialize when DOM is ready
1123
1255
document . addEventListener ( 'DOMContentLoaded' , ( ) => {
1124
1256
loadData ( ) ;
0 commit comments