@@ -268,6 +268,14 @@ <h3>Result Table ({{ field.display_name }})</h3>
268
268
return ret ;
269
269
}
270
270
271
+ const MACHINES = {
272
+ { % for machine in report . reporting_machines % }
273
+ { { machine. id } } : {
274
+ name : "{{ machine.name }}" ,
275
+ } ,
276
+ { % endfor % }
277
+ } ;
278
+
271
279
const FIELDS = [
272
280
{ % for field in report . fields | reverse % }
273
281
{
@@ -277,6 +285,76 @@ <h3>Result Table ({{ field.display_name }})</h3>
277
285
{ % endfor % }
278
286
] ;
279
287
288
+ // this is filled in asynchronously and used to regenerate the result table.
289
+ // we cannot just append to the DOM directly since we want the result table
290
+ // to be sorted by some priority metric (largest abs percentage delta).
291
+ var KEY_RUNS = { } ; // { machine.id -> run.id }
292
+ var RESULTS = { } ; // { field.display_name -> { test.id -> { name, results: { machine.id -> day results }}}}
293
+
294
+ function test_priority_compare ( a , b ) {
295
+ const a_res = a [ 1 ] . results ;
296
+ const b_res = b [ 1 ] . results ;
297
+ var a_max_delta = 0 ;
298
+ var b_max_delta = 0 ;
299
+ for ( const [ machine_id , rt_day_results ] of Object . entries ( a [ 1 ] . results ) ) {
300
+ a_max_delta = Math . max ( a_max_delta , Math . abs ( rt_day_results [ 0 ] . pct_delta ) ) ;
301
+ }
302
+ for ( const [ machine_id , rt_day_results ] of Object . entries ( b [ 1 ] . results ) ) {
303
+ b_max_delta = Math . max ( b_max_delta , Math . abs ( rt_day_results [ 0 ] . pct_delta ) ) ;
304
+ }
305
+ // descending order, higher deltas first.
306
+ return b_max_delta - a_max_delta ;
307
+ }
308
+
309
+ function regenerate_results_tables_for_field ( field , results ) {
310
+ var rt_table_id = "rt-" + field . display_name ;
311
+ var rt_table = document . getElementById ( rt_table_id ) ;
312
+ rt_table . innerHTML = '' ;
313
+ for ( const [ rt_test_id , rt_value ] of Object . entries ( results ) . sort ( test_priority_compare ) ) {
314
+ var rt_test_name = rt_value . name ;
315
+ // make the test header (used for multiple machines)
316
+ var rt_header_str = '' ;
317
+ rt_header_str += '<tr>' ;
318
+ rt_header_str += ' <td style="{{ styles.td }}" colspan=2><b>' + rt_test_name + '</b></td>' ;
319
+ rt_header_str += ' <td style="{{ styles.td }}" colspan="{{report.num_prior_days_to_include + 1}}"> </td>' ;
320
+ rt_header_str += '</tr>'
321
+ rt_table . insertAdjacentHTML ( 'beforeend' , rt_header_str ) ;
322
+ // actually write each result
323
+ for ( const [ machine_id , rt_day_results ] of Object . entries ( rt_value . results ) ) {
324
+ const machine_name = MACHINES [ machine_id ] . name ;
325
+ const today_key_run = KEY_RUNS [ machine_id ] ;
326
+ var rt_detail_str = '' ;
327
+ rt_detail_str += '<tr class="searchable">' ;
328
+ rt_detail_str += ' <td style="{{ styles.td }}"> </td>' ;
329
+ rt_detail_str += ' <td class="machine-name" style="{{ styles.td }}">' ;
330
+ // e.g. http://base_url/db_default/v4/db_name/graph?plot=29.348.0&highlight_run=8122
331
+ rt_detail_str += ' <a href="{{ ts_url }}/graph?plot=' + machine_id + '.' + rt_test_id + '.' + field . index + '&highlight_run=' + today_key_run + '">' + machine_name + '</a>' ;
332
+ rt_detail_str += ' </td>' ;
333
+ var first = true ;
334
+ for ( var i = { { report . num_prior_days_to_include } } - 1 ; i >= 0 ; i -- ) {
335
+ const rt_day_val = rt_day_results [ i ] ;
336
+ if ( ! rt_day_val ) {
337
+ rt_detail_str += ' <td style="{{ styles.td }}">-</td>' ;
338
+ } else if ( first ) {
339
+ rt_detail_str += get_initial_cell_value ( rt_day_val ) ;
340
+ first = false ;
341
+ } else {
342
+ rt_detail_str += get_cell_value ( rt_day_val ) ;
343
+ }
344
+ }
345
+ rt_detail_str += ' <td>' + spark_plot ( rt_day_results ) + '</td>' ;
346
+ rt_detail_str += '</tr>' ;
347
+ rt_table . insertAdjacentHTML ( 'beforeend' , rt_detail_str ) ;
348
+ }
349
+ }
350
+ }
351
+
352
+ function regenerate_results_tables ( ) {
353
+ for ( const field of FIELDS ) {
354
+ regenerate_results_tables_for_field ( field , RESULTS [ field . display_name ] ) ;
355
+ }
356
+ }
357
+
280
358
function handle_async_populate_result ( res ) {
281
359
for ( const machine of Object . values ( res . data . reporting_machines ) ) {
282
360
for ( var i = 0 ; i < { { report . num_prior_days_to_include } } ; i ++ ) {
@@ -297,50 +375,23 @@ <h3>Result Table ({{ field.display_name }})</h3>
297
375
}
298
376
var today_key_run = res . data . machine_runs [ '' + machine . id ] [ "0" ] ;
299
377
if ( today_key_run ) {
378
+ KEY_RUNS [ machine . id ] = today_key_run . id ;
379
+ // RESULTS: { field.display_name -> { test.id -> { name, results: { machine.id -> day results }}}}
300
380
for ( const field of FIELDS ) {
301
- var rt_table_id = "rt-" + field . display_name ;
302
- var rt_table = document . getElementById ( rt_table_id ) ;
381
+ RESULTS [ field . display_name ] = RESULTS [ field . display_name ] || { } ;
382
+ var field_results = RESULTS [ field . display_name ] ;
383
+ // merge new data into (possibly pre-existing from other results) field_results object.
303
384
var rt_data = res . data [ 'result_table' ] [ field . display_name ]
304
385
for ( const [ rt_test_id , rt_value ] of Object . entries ( rt_data ) ) {
305
- var rt_header_id = rt_table_id + '-' + rt_test_id ;
306
386
var rt_test_name = res . data . reporting_tests [ '' + rt_test_id ] . name ;
307
- // merge the same test id under a common header if it already exists.
308
- var rt_header = document . getElementById ( rt_header_id ) ;
309
- if ( ! rt_header ) {
310
- var rt_header_str = '' ;
311
- rt_header_str += '<tr id="' + rt_header_id + '">' ;
312
- rt_header_str += ' <td style="{{ styles.td }}" colspan=2><b>' + rt_test_name + '</b></td>' ;
313
- rt_header_str += ' <td style="{{ styles.td }}" colspan="{{report.num_prior_days_to_include + 1}}"> </td>' ;
314
- rt_header_str += '</tr>'
315
- rt_table . insertAdjacentHTML ( 'beforeend' , rt_header_str ) ;
316
- rt_header = document . getElementById ( rt_header_id ) ;
317
- }
318
- var rt_detail_str = '' ;
319
- rt_detail_str += '<tr class="searchable">' ;
320
- rt_detail_str += ' <td style="{{ styles.td }}"> </td>' ;
321
- rt_detail_str += ' <td class="machine-name" style="{{ styles.td }}">' ;
322
- // e.g. http://base_url/db_default/v4/db_name/graph?plot=29.348.0&highlight_run=8122
323
- rt_detail_str += ' <a href="{{ ts_url }}/graph?plot=' + machine . id + '.' + rt_test_id + '.' + field . index + '&highlight_run=' + today_key_run . id + '">' + machine . name + '</a>' ;
324
- rt_detail_str += ' </td>' ;
325
- var first = true ;
326
- for ( var i = { { report . num_prior_days_to_include } } - 1 ; i >= 0 ; i -- ) {
327
- const rt_day_val = rt_value [ '' + machine . id ] [ i ] ;
328
- if ( ! rt_day_val ) {
329
- rt_detail_str += ' <td style="{{ styles.td }}">-</td>' ;
330
- } else if ( first ) {
331
- rt_detail_str += get_initial_cell_value ( rt_day_val ) ;
332
- first = false ;
333
- } else {
334
- rt_detail_str += get_cell_value ( rt_day_val ) ;
335
- }
336
- }
337
- rt_detail_str += ' <td>' + spark_plot ( rt_value [ '' + machine . id ] ) + '</td>' ;
338
- rt_detail_str += '</tr>' ;
339
- rt_header . insertAdjacentHTML ( 'afterend' , rt_detail_str ) ;
387
+ field_results [ rt_test_id ] = field_results [ rt_test_id ] || { name : rt_test_name , results : { } } ;
388
+ field_results [ rt_test_id ] . results [ machine . id ] = rt_value [ '' + machine . id ] ;
340
389
}
341
390
}
342
391
}
343
392
}
393
+ // now that we've updated the RESULTS object, regenerate any results tables.
394
+ regenerate_results_tables ( ) ;
344
395
}
345
396
346
397
async function populate_table ( res ) {
0 commit comments