Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(972)

Side by Side Diff: gm/rebaseline_server/static/loader.js

Issue 326013002: rebaseline_server: merge identical results (across multiple builders/configs) into a single row (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up for codereview Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gm/rebaseline_server/static/constants.js ('k') | gm/rebaseline_server/static/view.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Loader: 2 * Loader:
3 * Reads GM result reports written out by results.py, and imports 3 * Reads GM result reports written out by results.py, and imports
4 * them into $scope.extraColumnHeaders and $scope.imagePairs . 4 * them into $scope.extraColumnHeaders and $scope.imagePairs .
5 */ 5 */
6 var Loader = angular.module( 6 var Loader = angular.module(
7 'Loader', 7 'Loader',
8 ['ConstantsModule'] 8 ['ConstantsModule']
9 ); 9 );
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 .indexOf(testSubstring)) && 49 .indexOf(testSubstring)) &&
50 (viewingTab == imagePair.tab)) { 50 (viewingTab == imagePair.tab)) {
51 filteredImagePairs.push(imagePair); 51 filteredImagePairs.push(imagePair);
52 } 52 }
53 } 53 }
54 return filteredImagePairs; 54 return filteredImagePairs;
55 }; 55 };
56 } 56 }
57 ); 57 );
58 58
59 /**
60 * Limit the input imagePairs to some max number, and merge identical rows
61 * (adjacent rows which have the same (imageA, imageB) pair).
62 *
63 * @param unfilteredImagePairs imagePairs to filter
64 * @param maxPairs maximum number of pairs to output, or <0 for no limit
65 * @param mergeIdenticalRows if true, merge identical rows by setting
66 * ROWSPAN>1 on the first merged row, and ROWSPAN=0 for the rest
67 */
68 Loader.filter(
69 'mergeAndLimit',
70 function(constants) {
71 return function(unfilteredImagePairs, maxPairs, mergeIdenticalRows) {
72 var numPairs = unfilteredImagePairs.length;
73 if ((maxPairs > 0) && (maxPairs < numPairs)) {
74 numPairs = maxPairs;
75 }
76 var filteredImagePairs = [];
77 if (!mergeIdenticalRows || (numPairs == 1)) {
78 // Take a shortcut if we're not merging identical rows.
79 // We still need to set ROWSPAN to 1 for each row, for the HTML viewer.
80 for (var i = numPairs-1; i >= 0; i--) {
81 var imagePair = unfilteredImagePairs[i];
82 imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
83 filteredImagePairs[i] = imagePair;
84 }
85 } else if (numPairs > 1) {
86 // General case--there are at least 2 rows, so we may need to merge some .
87 // Work from the bottom up, so we can keep a running total of how many
88 // rows should be merged, and set ROWSPAN of the top row accordingly.
89 var imagePair = unfilteredImagePairs[numPairs-1];
90 var nextRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] ;
91 var nextRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL] ;
92 imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
93 filteredImagePairs[numPairs-1] = imagePair;
94 for (var i = numPairs-2; i >= 0; i--) {
95 imagePair = unfilteredImagePairs[i];
96 var thisRowImageAUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_UR L];
97 var thisRowImageBUrl = imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_UR L];
98 if ((thisRowImageAUrl == nextRowImageAUrl) &&
99 (thisRowImageBUrl == nextRowImageBUrl)) {
100 imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] =
101 filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] + 1;
102 filteredImagePairs[i+1][constants.KEY__IMAGEPAIRS__ROWSPAN] = 0;
103 } else {
104 imagePair[constants.KEY__IMAGEPAIRS__ROWSPAN] = 1;
105 nextRowImageAUrl = thisRowImageAUrl;
106 nextRowImageBUrl = thisRowImageBUrl;
107 }
108 filteredImagePairs[i] = imagePair;
109 }
110 } else {
111 // No results.
112 }
113 return filteredImagePairs;
114 };
115 }
116 );
117
59 118
60 Loader.controller( 119 Loader.controller(
61 'Loader.Controller', 120 'Loader.Controller',
62 function($scope, $http, $filter, $location, $log, $timeout, constants) { 121 function($scope, $http, $filter, $location, $log, $timeout, constants) {
63 $scope.constants = constants; 122 $scope.constants = constants;
64 $scope.windowTitle = "Loading GM Results..."; 123 $scope.windowTitle = "Loading GM Results...";
65 $scope.resultsToLoad = $location.search().resultsToLoad; 124 $scope.resultsToLoad = $location.search().resultsToLoad;
66 $scope.loadingMessage = "please wait..."; 125 $scope.loadingMessage = "please wait...";
67 126
68 /** 127 /**
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 * Toggle selection of all currently showing tests. 286 * Toggle selection of all currently showing tests.
228 */ 287 */
229 $scope.toggleAllImagePairs = function() { 288 $scope.toggleAllImagePairs = function() {
230 var numImagePairsShowing = $scope.limitedImagePairs.length; 289 var numImagePairsShowing = $scope.limitedImagePairs.length;
231 for (var i = 0; i < numImagePairsShowing; i++) { 290 for (var i = 0; i < numImagePairsShowing; i++) {
232 var index = $scope.limitedImagePairs[i].index; 291 var index = $scope.limitedImagePairs[i].index;
233 $scope.toggleValueInArray(index, $scope.selectedImagePairs); 292 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
234 } 293 }
235 } 294 }
236 295
296 /**
297 * Toggle selection state of a subset of the currently showing tests.
298 *
299 * @param startIndex index within $scope.limitedImagePairs of the first
300 * test to toggle selection state of
301 * @param num number of tests (in a contiguous block) to toggle
302 */
303 $scope.toggleSomeImagePairs = function(startIndex, num) {
304 var numImagePairsShowing = $scope.limitedImagePairs.length;
305 for (var i = startIndex; i < startIndex + num; i++) {
306 var index = $scope.limitedImagePairs[i].index;
307 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
308 }
309 }
310
237 311
238 // 312 //
239 // Tab operations. 313 // Tab operations.
240 // 314 //
241 315
242 /** 316 /**
243 * Change the selected tab. 317 * Change the selected tab.
244 * 318 *
245 * @param tab (string): name of the tab to select 319 * @param tab (string): name of the tab to select
246 */ 320 */
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 402 }
329 }, 403 },
330 404
331 }; 405 };
332 406
333 // parameter name -> copier objects to load/save parameter value 407 // parameter name -> copier objects to load/save parameter value
334 $scope.queryParameters.map = { 408 $scope.queryParameters.map = {
335 'resultsToLoad': $scope.queryParameters.copiers.simple, 409 'resultsToLoad': $scope.queryParameters.copiers.simple,
336 'displayLimitPending': $scope.queryParameters.copiers.simple, 410 'displayLimitPending': $scope.queryParameters.copiers.simple,
337 'showThumbnailsPending': $scope.queryParameters.copiers.simple, 411 'showThumbnailsPending': $scope.queryParameters.copiers.simple,
412 'mergeIdenticalRowsPending': $scope.queryParameters.copiers.simple,
338 'imageSizePending': $scope.queryParameters.copiers.simple, 413 'imageSizePending': $scope.queryParameters.copiers.simple,
339 'sortColumnSubdict': $scope.queryParameters.copiers.simple, 414 'sortColumnSubdict': $scope.queryParameters.copiers.simple,
340 'sortColumnKey': $scope.queryParameters.copiers.simple, 415 'sortColumnKey': $scope.queryParameters.copiers.simple,
341 416
342 'hiddenResultTypes': $scope.queryParameters.copiers.set, 417 'hiddenResultTypes': $scope.queryParameters.copiers.set,
343 'hiddenConfigs': $scope.queryParameters.copiers.set, 418 'hiddenConfigs': $scope.queryParameters.copiers.set,
344 }; 419 };
345 $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__BUILDER] = 420 $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__BUILDER] =
346 $scope.queryParameters.copiers.categoryValueMatch; 421 $scope.queryParameters.copiers.categoryValueMatch;
347 $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__TEST] = 422 $scope.queryParameters.map[constants.KEY__EXTRACOLUMNS__TEST] =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 468
394 /** 469 /**
395 * Update the displayed results, based on filters/settings, 470 * Update the displayed results, based on filters/settings,
396 * and call $scope.queryParameters.save() so that the new filter results 471 * and call $scope.queryParameters.save() so that the new filter results
397 * can be bookmarked. 472 * can be bookmarked.
398 */ 473 */
399 $scope.updateResults = function() { 474 $scope.updateResults = function() {
400 $scope.renderStartTime = window.performance.now(); 475 $scope.renderStartTime = window.performance.now();
401 $log.debug("renderStartTime: " + $scope.renderStartTime); 476 $log.debug("renderStartTime: " + $scope.renderStartTime);
402 $scope.displayLimit = $scope.displayLimitPending; 477 $scope.displayLimit = $scope.displayLimitPending;
478 $scope.mergeIdenticalRows = $scope.mergeIdenticalRowsPending;
403 // TODO(epoger): Every time we apply a filter, AngularJS creates 479 // TODO(epoger): Every time we apply a filter, AngularJS creates
404 // another copy of the array. Is there a way we can filter out 480 // another copy of the array. Is there a way we can filter out
405 // the imagePairs as they are displayed, rather than storing multiple 481 // the imagePairs as they are displayed, rather than storing multiple
406 // array copies? (For better performance.) 482 // array copies? (For better performance.)
407 483
408 if ($scope.viewingTab == $scope.defaultTab) { 484 if ($scope.viewingTab == $scope.defaultTab) {
409 485
410 // TODO(epoger): Until we allow the user to reverse sort order, 486 // TODO(epoger): Until we allow the user to reverse sort order,
411 // there are certain columns we want to sort in a different order. 487 // there are certain columns we want to sort in a different order.
412 var doReverse = ( 488 var doReverse = (
413 ($scope.sortColumnKey == 489 ($scope.sortColumnKey ==
414 constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) || 490 constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) ||
415 ($scope.sortColumnKey == 491 ($scope.sortColumnKey ==
416 constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)); 492 constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF));
417 493
418 $scope.filteredImagePairs = 494 $scope.filteredImagePairs =
419 $filter("orderBy")( 495 $filter("orderBy")(
420 $filter("removeHiddenImagePairs")( 496 $filter("removeHiddenImagePairs")(
421 $scope.imagePairs, 497 $scope.imagePairs,
422 $scope.hiddenResultTypes, 498 $scope.hiddenResultTypes,
423 $scope.hiddenConfigs, 499 $scope.hiddenConfigs,
424 $scope.categoryValueMatch.builder, 500 $scope.categoryValueMatch.builder,
425 $scope.categoryValueMatch.test, 501 $scope.categoryValueMatch.test,
426 $scope.viewingTab 502 $scope.viewingTab
427 ), 503 ),
428 $scope.getSortColumnValue, doReverse); 504 [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
429 $scope.limitedImagePairs = $filter("limitTo")( 505 doReverse);
430 $scope.filteredImagePairs, $scope.displayLimit); 506 $scope.limitedImagePairs = $filter("mergeAndLimit")(
507 $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdentica lRows);
431 } else { 508 } else {
432 $scope.filteredImagePairs = 509 $scope.filteredImagePairs =
433 $filter("orderBy")( 510 $filter("orderBy")(
434 $filter("filter")( 511 $filter("filter")(
435 $scope.imagePairs, 512 $scope.imagePairs,
436 {tab: $scope.viewingTab}, 513 {tab: $scope.viewingTab},
437 true 514 true
438 ), 515 ),
439 $scope.getSortColumnValue); 516 [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
440 $scope.limitedImagePairs = $scope.filteredImagePairs; 517 $scope.limitedImagePairs = $filter("mergeAndLimit")(
518 $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows);
441 } 519 }
442 $scope.showThumbnails = $scope.showThumbnailsPending; 520 $scope.showThumbnails = $scope.showThumbnailsPending;
443 $scope.imageSize = $scope.imageSizePending; 521 $scope.imageSize = $scope.imageSizePending;
444 $scope.setUpdatesPending(false); 522 $scope.setUpdatesPending(false);
445 $scope.queryParameters.save(); 523 $scope.queryParameters.save();
446 } 524 }
447 525
448 /** 526 /**
449 * This function is called when the results have been completely rendered 527 * This function is called when the results have been completely rendered
450 * after updateResults(). 528 * after updateResults().
451 */ 529 */
452 $scope.resultsUpdatedCallback = function() { 530 $scope.resultsUpdatedCallback = function() {
453 $scope.renderEndTime = window.performance.now(); 531 $scope.renderEndTime = window.performance.now();
454 $log.debug("renderEndTime: " + $scope.renderEndTime); 532 $log.debug("renderEndTime: " + $scope.renderEndTime);
455 } 533 }
456 534
457 /** 535 /**
458 * Re-sort the displayed results. 536 * Re-sort the displayed results.
459 * 537 *
460 * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary 538 * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary
461 * the sort column key is within 539 * the sort column key is within, or 'none' if the sort column
540 * key is one of KEY__IMAGEPAIRS__*
462 * @param key (string): sort by value associated with this key in subdict 541 * @param key (string): sort by value associated with this key in subdict
463 */ 542 */
464 $scope.sortResultsBy = function(subdict, key) { 543 $scope.sortResultsBy = function(subdict, key) {
465 $scope.sortColumnSubdict = subdict; 544 $scope.sortColumnSubdict = subdict;
466 $scope.sortColumnKey = key; 545 $scope.sortColumnKey = key;
467 $scope.updateResults(); 546 $scope.updateResults();
468 } 547 }
469 548
470 /** 549 /**
471 * For a particular ImagePair, return the value of the column we are 550 * For a particular ImagePair, return the value of the column we are
472 * sorting on (according to $scope.sortColumnSubdict and 551 * sorting on (according to $scope.sortColumnSubdict and
473 * $scope.sortColumnKey). 552 * $scope.sortColumnKey).
474 * 553 *
475 * @param imagePair: imagePair to get a column value out of. 554 * @param imagePair: imagePair to get a column value out of.
476 */ 555 */
477 $scope.getSortColumnValue = function(imagePair) { 556 $scope.getSortColumnValue = function(imagePair) {
478 if ($scope.sortColumnSubdict in imagePair) { 557 if ($scope.sortColumnSubdict in imagePair) {
479 return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey]; 558 return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey];
559 } else if ($scope.sortColumnKey in imagePair) {
560 return imagePair[$scope.sortColumnKey];
480 } else { 561 } else {
481 return undefined; 562 return undefined;
482 } 563 }
483 } 564 }
484 565
485 /** 566 /**
567 * For a particular ImagePair, return the value we use for the
568 * second-order sort (tiebreaker when multiple rows have
569 * the same getSortColumnValue()).
570 *
571 * We join the imageA and imageB urls for this value, so that we merge
572 * adjacent rows as much as possible.
573 *
574 * @param imagePair: imagePair to get a column value out of.
575 */
576 $scope.getSecondOrderSortValue = function(imagePair) {
577 return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
578 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
579 }
580
581 /**
486 * Set $scope.categoryValueMatch[name] = value, and update results. 582 * Set $scope.categoryValueMatch[name] = value, and update results.
487 * 583 *
488 * @param name 584 * @param name
489 * @param value 585 * @param value
490 */ 586 */
491 $scope.setCategoryValueMatch = function(name, value) { 587 $scope.setCategoryValueMatch = function(name, value) {
492 $scope.categoryValueMatch[name] = value; 588 $scope.categoryValueMatch[name] = value;
493 $scope.updateResults(); 589 $scope.updateResults();
494 } 590 }
495 591
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 */ 923 */
828 $scope.getImageDiffRelativeUrl = function(imagePair) { 924 $scope.getImageDiffRelativeUrl = function(imagePair) {
829 var before = 925 var before =
830 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" + 926 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
831 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]; 927 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
832 return before.replace(/[^\w\-]/g, "_") + ".png"; 928 return before.replace(/[^\w\-]/g, "_") + ".png";
833 } 929 }
834 930
835 } 931 }
836 ); 932 );
OLDNEW
« no previous file with comments | « gm/rebaseline_server/static/constants.js ('k') | gm/rebaseline_server/static/view.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698