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

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

Issue 449843002: rebaseline-server: sorting of columns (asc/desc) in frontend. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebased code Created 6 years, 4 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/live-view.html ('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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 123
124 Loader.controller( 124 Loader.controller(
125 'Loader.Controller', 125 'Loader.Controller',
126 function($scope, $http, $filter, $location, $log, $timeout, constants) { 126 function($scope, $http, $filter, $location, $log, $timeout, constants) {
127 $scope.readyToDisplay = false; 127 $scope.readyToDisplay = false;
128 $scope.constants = constants; 128 $scope.constants = constants;
129 $scope.windowTitle = "Loading GM Results..."; 129 $scope.windowTitle = "Loading GM Results...";
130 $scope.resultsToLoad = $location.search().resultsToLoad; 130 $scope.resultsToLoad = $location.search().resultsToLoad;
131 $scope.loadingMessage = "please wait..."; 131 $scope.loadingMessage = "please wait...";
132 132
133 var currSortAsc = true;
134
135
133 /** 136 /**
134 * On initial page load, load a full dictionary of results. 137 * On initial page load, load a full dictionary of results.
135 * Once the dictionary is loaded, unhide the page elements so they can 138 * Once the dictionary is loaded, unhide the page elements so they can
136 * render the data. 139 * render the data.
137 */ 140 */
138 $http.get($scope.resultsToLoad).success( 141 $http.get($scope.resultsToLoad).success(
139 function(data, status, header, config) { 142 function(data, status, header, config) {
140 var dataHeader = data[constants.KEY__ROOT__HEADER]; 143 var dataHeader = data[constants.KEY__ROOT__HEADER];
141 if (dataHeader[constants.KEY__HEADER__SCHEMA_VERSION] != 144 if (dataHeader[constants.KEY__HEADER__SCHEMA_VERSION] !=
142 constants.VALUE__HEADER__SCHEMA_VERSION) { 145 constants.VALUE__HEADER__SCHEMA_VERSION) {
(...skipping 17 matching lines...) Expand all
160 function(){location.reload();}, 163 function(){location.reload();},
161 timeToReload - timeNow); 164 timeToReload - timeNow);
162 } else { 165 } else {
163 $scope.loadingMessage = "processing data, please wait..."; 166 $scope.loadingMessage = "processing data, please wait...";
164 167
165 $scope.header = dataHeader; 168 $scope.header = dataHeader;
166 $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADE RS]; 169 $scope.extraColumnHeaders = data[constants.KEY__ROOT__EXTRACOLUMNHEADE RS];
167 $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER ]; 170 $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER ];
168 $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS]; 171 $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS];
169 $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS]; 172 $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS];
173
174 // set the default sort column and make it ascending.
170 $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES; 175 $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES;
171 $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF; 176 $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF;
177 currSortAsc = true;
172 178
173 $scope.showSubmitAdvancedSettings = false; 179 $scope.showSubmitAdvancedSettings = false;
174 $scope.submitAdvancedSettings = {}; 180 $scope.submitAdvancedSettings = {};
175 $scope.submitAdvancedSettings[ 181 $scope.submitAdvancedSettings[
176 constants.KEY__EXPECTATIONS__REVIEWED] = true; 182 constants.KEY__EXPECTATIONS__REVIEWED] = true;
177 $scope.submitAdvancedSettings[ 183 $scope.submitAdvancedSettings[
178 constants.KEY__EXPECTATIONS__IGNOREFAILURE] = false; 184 constants.KEY__EXPECTATIONS__IGNOREFAILURE] = false;
179 $scope.submitAdvancedSettings['bug'] = ''; 185 $scope.submitAdvancedSettings['bug'] = '';
180 186
181 // Create the list of tabs (lists into which the user can file each 187 // Create the list of tabs (lists into which the user can file each
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 * Select all currently showing tests. 319 * Select all currently showing tests.
314 */ 320 */
315 $scope.selectAllImagePairs = function() { 321 $scope.selectAllImagePairs = function() {
316 var numImagePairsShowing = $scope.limitedImagePairs.length; 322 var numImagePairsShowing = $scope.limitedImagePairs.length;
317 for (var i = 0; i < numImagePairsShowing; i++) { 323 for (var i = 0; i < numImagePairsShowing; i++) {
318 var index = $scope.limitedImagePairs[i].index; 324 var index = $scope.limitedImagePairs[i].index;
319 if (!$scope.isValueInArray(index, $scope.selectedImagePairs)) { 325 if (!$scope.isValueInArray(index, $scope.selectedImagePairs)) {
320 $scope.toggleValueInArray(index, $scope.selectedImagePairs); 326 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
321 } 327 }
322 } 328 }
323 } 329 };
324 330
325 /** 331 /**
326 * Deselect all currently showing tests. 332 * Deselect all currently showing tests.
327 */ 333 */
328 $scope.clearAllImagePairs = function() { 334 $scope.clearAllImagePairs = function() {
329 var numImagePairsShowing = $scope.limitedImagePairs.length; 335 var numImagePairsShowing = $scope.limitedImagePairs.length;
330 for (var i = 0; i < numImagePairsShowing; i++) { 336 for (var i = 0; i < numImagePairsShowing; i++) {
331 var index = $scope.limitedImagePairs[i].index; 337 var index = $scope.limitedImagePairs[i].index;
332 if ($scope.isValueInArray(index, $scope.selectedImagePairs)) { 338 if ($scope.isValueInArray(index, $scope.selectedImagePairs)) {
333 $scope.toggleValueInArray(index, $scope.selectedImagePairs); 339 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
334 } 340 }
335 } 341 }
336 } 342 };
337 343
338 /** 344 /**
339 * Toggle selection of all currently showing tests. 345 * Toggle selection of all currently showing tests.
340 */ 346 */
341 $scope.toggleAllImagePairs = function() { 347 $scope.toggleAllImagePairs = function() {
342 var numImagePairsShowing = $scope.limitedImagePairs.length; 348 var numImagePairsShowing = $scope.limitedImagePairs.length;
343 for (var i = 0; i < numImagePairsShowing; i++) { 349 for (var i = 0; i < numImagePairsShowing; i++) {
344 var index = $scope.limitedImagePairs[i].index; 350 var index = $scope.limitedImagePairs[i].index;
345 $scope.toggleValueInArray(index, $scope.selectedImagePairs); 351 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
346 } 352 }
347 } 353 };
348 354
349 /** 355 /**
350 * Toggle selection state of a subset of the currently showing tests. 356 * Toggle selection state of a subset of the currently showing tests.
351 * 357 *
352 * @param startIndex index within $scope.limitedImagePairs of the first 358 * @param startIndex index within $scope.limitedImagePairs of the first
353 * test to toggle selection state of 359 * test to toggle selection state of
354 * @param num number of tests (in a contiguous block) to toggle 360 * @param num number of tests (in a contiguous block) to toggle
355 */ 361 */
356 $scope.toggleSomeImagePairs = function(startIndex, num) { 362 $scope.toggleSomeImagePairs = function(startIndex, num) {
357 var numImagePairsShowing = $scope.limitedImagePairs.length; 363 var numImagePairsShowing = $scope.limitedImagePairs.length;
358 for (var i = startIndex; i < startIndex + num; i++) { 364 for (var i = startIndex; i < startIndex + num; i++) {
359 var index = $scope.limitedImagePairs[i].index; 365 var index = $scope.limitedImagePairs[i].index;
360 $scope.toggleValueInArray(index, $scope.selectedImagePairs); 366 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
361 } 367 }
362 } 368 };
363 369
364 370
365 // 371 //
366 // Tab operations. 372 // Tab operations.
367 // 373 //
368 374
369 /** 375 /**
370 * Change the selected tab. 376 * Change the selected tab.
371 * 377 *
372 * @param tab (string): name of the tab to select 378 * @param tab (string): name of the tab to select
373 */ 379 */
374 $scope.setViewingTab = function(tab) { 380 $scope.setViewingTab = function(tab) {
375 $scope.viewingTab = tab; 381 $scope.viewingTab = tab;
376 $scope.updateResults(); 382 $scope.updateResults();
377 } 383 };
378 384
379 /** 385 /**
380 * Move the imagePairs in $scope.selectedImagePairs to a different tab, 386 * Move the imagePairs in $scope.selectedImagePairs to a different tab,
381 * and then clear $scope.selectedImagePairs. 387 * and then clear $scope.selectedImagePairs.
382 * 388 *
383 * @param newTab (string): name of the tab to move the tests to 389 * @param newTab (string): name of the tab to move the tests to
384 */ 390 */
385 $scope.moveSelectedImagePairsToTab = function(newTab) { 391 $scope.moveSelectedImagePairsToTab = function(newTab) {
386 $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab); 392 $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab);
387 $scope.selectedImagePairs = []; 393 $scope.selectedImagePairs = [];
388 $scope.updateResults(); 394 $scope.updateResults();
389 } 395 };
390 396
391 /** 397 /**
392 * Move a subset of $scope.imagePairs to a different tab. 398 * Move a subset of $scope.imagePairs to a different tab.
393 * 399 *
394 * @param imagePairIndices (array of ints): indices into $scope.imagePairs 400 * @param imagePairIndices (array of ints): indices into $scope.imagePairs
395 * indicating which test results to move 401 * indicating which test results to move
396 * @param newTab (string): name of the tab to move the tests to 402 * @param newTab (string): name of the tab to move the tests to
397 */ 403 */
398 $scope.moveImagePairsToTab = function(imagePairIndices, newTab) { 404 $scope.moveImagePairsToTab = function(imagePairIndices, newTab) {
399 var imagePairIndex; 405 var imagePairIndex;
400 var numImagePairs = imagePairIndices.length; 406 var numImagePairs = imagePairIndices.length;
401 for (var i = 0; i < numImagePairs; i++) { 407 for (var i = 0; i < numImagePairs; i++) {
402 imagePairIndex = imagePairIndices[i]; 408 imagePairIndex = imagePairIndices[i];
403 $scope.numResultsPerTab[$scope.imagePairs[imagePairIndex].tab]--; 409 $scope.numResultsPerTab[$scope.imagePairs[imagePairIndex].tab]--;
404 $scope.imagePairs[imagePairIndex].tab = newTab; 410 $scope.imagePairs[imagePairIndex].tab = newTab;
405 } 411 }
406 $scope.numResultsPerTab[newTab] += numImagePairs; 412 $scope.numResultsPerTab[newTab] += numImagePairs;
407 } 413 };
408 414
409 415
410 // 416 //
411 // $scope.queryParameters: 417 // $scope.queryParameters:
412 // Transfer parameter values between $scope and the URL query string. 418 // Transfer parameter values between $scope and the URL query string.
413 // 419 //
414 $scope.queryParameters = {}; 420 $scope.queryParameters = {};
415 421
416 // load and save functions for parameters of each type 422 // load and save functions for parameters of each type
417 // (load a parameter value into $scope from nameValuePairs, 423 // (load a parameter value into $scope from nameValuePairs,
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 ); 596 );
591 $scope.showingColumnValues[columnName] = showingColumnValues; 597 $scope.showingColumnValues[columnName] = showingColumnValues;
592 } 598 }
593 } 599 }
594 ); 600 );
595 601
596 // TODO(epoger): Every time we apply a filter, AngularJS creates 602 // TODO(epoger): Every time we apply a filter, AngularJS creates
597 // another copy of the array. Is there a way we can filter out 603 // another copy of the array. Is there a way we can filter out
598 // the imagePairs as they are displayed, rather than storing multiple 604 // the imagePairs as they are displayed, rather than storing multiple
599 // array copies? (For better performance.) 605 // array copies? (For better performance.)
600
601 if ($scope.viewingTab == $scope.defaultTab) { 606 if ($scope.viewingTab == $scope.defaultTab) {
602 607 var doReverse = !currSortAsc;
603 // TODO(epoger): Until we allow the user to reverse sort order,
604 // there are certain columns we want to sort in a different order.
605 var doReverse = (
606 ($scope.sortColumnKey ==
607 constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) ||
608 ($scope.sortColumnKey ==
609 constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF));
610 608
611 $scope.filteredImagePairs = 609 $scope.filteredImagePairs =
612 $filter("orderBy")( 610 $filter("orderBy")(
613 $filter("removeHiddenImagePairs")( 611 $filter("removeHiddenImagePairs")(
614 $scope.imagePairs, 612 $scope.imagePairs,
615 $scope.filterableColumnNames, 613 $scope.filterableColumnNames,
616 $scope.showingColumnValues, 614 $scope.showingColumnValues,
617 $scope.viewingTab 615 $scope.viewingTab
618 ), 616 ),
619 [$scope.getSortColumnValue, $scope.getSecondOrderSortValue], 617 // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue],
618 $scope.getSortColumnValue,
620 doReverse); 619 doReverse);
621 $scope.limitedImagePairs = $filter("mergeAndLimit")( 620 $scope.limitedImagePairs = $filter("mergeAndLimit")(
622 $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdentica lRows); 621 $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdentica lRows);
623 } else { 622 } else {
624 $scope.filteredImagePairs = 623 $scope.filteredImagePairs =
625 $filter("orderBy")( 624 $filter("orderBy")(
626 $filter("filter")( 625 $filter("filter")(
627 $scope.imagePairs, 626 $scope.imagePairs,
628 {tab: $scope.viewingTab}, 627 {tab: $scope.viewingTab},
629 true 628 true
630 ), 629 ),
631 [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]); 630 // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]);
631 $scope.getSortColumnValue);
632 $scope.limitedImagePairs = $filter("mergeAndLimit")( 632 $scope.limitedImagePairs = $filter("mergeAndLimit")(
633 $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows); 633 $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows);
634 } 634 }
635 $scope.showThumbnails = $scope.showThumbnailsPending; 635 $scope.showThumbnails = $scope.showThumbnailsPending;
636 $scope.imageSize = $scope.imageSizePending; 636 $scope.imageSize = $scope.imageSizePending;
637 $scope.setUpdatesPending(false); 637 $scope.setUpdatesPending(false);
638 $scope.queryParameters.save(); 638 $scope.queryParameters.save();
639 } 639 }
640 640
641 /** 641 /**
642 * This function is called when the results have been completely rendered 642 * This function is called when the results have been completely rendered
643 * after updateResults(). 643 * after updateResults().
644 */ 644 */
645 $scope.resultsUpdatedCallback = function() { 645 $scope.resultsUpdatedCallback = function() {
646 $scope.renderEndTime = window.performance.now(); 646 $scope.renderEndTime = window.performance.now();
647 $log.debug("renderEndTime: " + $scope.renderEndTime); 647 $log.debug("renderEndTime: " + $scope.renderEndTime);
648 } 648 };
649 649
650 /** 650 /**
651 * Re-sort the displayed results. 651 * Re-sort the displayed results.
652 * 652 *
653 * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary 653 * @param subdict (string): which KEY__IMAGEPAIRS__* subdictionary
654 * the sort column key is within, or 'none' if the sort column 654 * the sort column key is within, or 'none' if the sort column
655 * key is one of KEY__IMAGEPAIRS__* 655 * key is one of KEY__IMAGEPAIRS__*
656 * @param key (string): sort by value associated with this key in subdict 656 * @param key (string): sort by value associated with this key in subdict
657 */ 657 */
658 $scope.sortResultsBy = function(subdict, key) { 658 $scope.sortResultsBy = function(subdict, key) {
659 $scope.sortColumnSubdict = subdict; 659 // if we are already sorting by this column then toggle between asc/desc
660 $scope.sortColumnKey = key; 660 if ((subdict === $scope.sortColumnSubdict) && ($scope.sortColumnKey === ke y)) {
661 currSortAsc = !currSortAsc;
662 } else {
663 $scope.sortColumnSubdict = subdict;
664 $scope.sortColumnKey = key;
665 currSortAsc = true;
666 }
661 $scope.updateResults(); 667 $scope.updateResults();
662 } 668 };
669
670 /**
671 * Returns ASC or DESC (from constants) if currently the data
672 * is sorted by the provided column.
673 *
674 * @param colName: name of the column for which we need to get the class.
675 */
676
677 $scope.sortedByColumnsCls = function (colName) {
678 if ($scope.sortColumnKey !== colName) {
679 return '';
680 }
681
682 var result = (currSortAsc) ? constants.ASC : constants.DESC;
683 console.log("sort class:", result);
684 return result;
685 };
663 686
664 /** 687 /**
665 * For a particular ImagePair, return the value of the column we are 688 * For a particular ImagePair, return the value of the column we are
666 * sorting on (according to $scope.sortColumnSubdict and 689 * sorting on (according to $scope.sortColumnSubdict and
667 * $scope.sortColumnKey). 690 * $scope.sortColumnKey).
668 * 691 *
669 * @param imagePair: imagePair to get a column value out of. 692 * @param imagePair: imagePair to get a column value out of.
670 */ 693 */
671 $scope.getSortColumnValue = function(imagePair) { 694 $scope.getSortColumnValue = function(imagePair) {
672 if ($scope.sortColumnSubdict in imagePair) { 695 if ($scope.sortColumnSubdict in imagePair) {
673 return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey]; 696 return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey];
674 } else if ($scope.sortColumnKey in imagePair) { 697 } else if ($scope.sortColumnKey in imagePair) {
675 return imagePair[$scope.sortColumnKey]; 698 return imagePair[$scope.sortColumnKey];
676 } else { 699 } else {
677 return undefined; 700 return undefined;
678 } 701 }
679 } 702 };
680 703
681 /** 704 /**
682 * For a particular ImagePair, return the value we use for the 705 * For a particular ImagePair, return the value we use for the
683 * second-order sort (tiebreaker when multiple rows have 706 * second-order sort (tiebreaker when multiple rows have
684 * the same getSortColumnValue()). 707 * the same getSortColumnValue()).
685 * 708 *
686 * We join the imageA and imageB urls for this value, so that we merge 709 * We join the imageA and imageB urls for this value, so that we merge
687 * adjacent rows as much as possible. 710 * adjacent rows as much as possible.
688 * 711 *
689 * @param imagePair: imagePair to get a column value out of. 712 * @param imagePair: imagePair to get a column value out of.
690 */ 713 */
691 $scope.getSecondOrderSortValue = function(imagePair) { 714 $scope.getSecondOrderSortValue = function(imagePair) {
692 return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" + 715 return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
693 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]; 716 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
694 } 717 };
695 718
696 /** 719 /**
697 * Set $scope.columnStringMatch[name] = value, and update results. 720 * Set $scope.columnStringMatch[name] = value, and update results.
698 * 721 *
699 * @param name 722 * @param name
700 * @param value 723 * @param value
701 */ 724 */
702 $scope.setColumnStringMatch = function(name, value) { 725 $scope.setColumnStringMatch = function(name, value) {
703 $scope.columnStringMatch[name] = value; 726 $scope.columnStringMatch[name] = value;
704 $scope.updateResults(); 727 $scope.updateResults();
705 } 728 };
706 729
707 /** 730 /**
708 * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatc h[columnName] 731 * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatc h[columnName]
709 * so that ONLY entries with this columnValue are showing, and update the vi sible results. 732 * so that ONLY entries with this columnValue are showing, and update the vi sible results.
710 * (We update both of those, so we cover both freeform and checkbox filtered columns.) 733 * (We update both of those, so we cover both freeform and checkbox filtered columns.)
711 * 734 *
712 * @param columnName 735 * @param columnName
713 * @param columnValue 736 * @param columnValue
714 */ 737 */
715 $scope.showOnlyColumnValue = function(columnName, columnValue) { 738 $scope.showOnlyColumnValue = function(columnName, columnValue) {
716 $scope.columnStringMatch[columnName] = columnValue; 739 $scope.columnStringMatch[columnName] = columnValue;
717 $scope.showingColumnValues[columnName] = {}; 740 $scope.showingColumnValues[columnName] = {};
718 $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName ]); 741 $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName ]);
719 $scope.updateResults(); 742 $scope.updateResults();
720 } 743 };
721 744
722 /** 745 /**
723 * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatc h[columnName] 746 * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatc h[columnName]
724 * so that ALL entries are showing, and update the visible results. 747 * so that ALL entries are showing, and update the visible results.
725 * (We update both of those, so we cover both freeform and checkbox filtered columns.) 748 * (We update both of those, so we cover both freeform and checkbox filtered columns.)
726 * 749 *
727 * @param columnName 750 * @param columnName
728 */ 751 */
729 $scope.showAllColumnValues = function(columnName) { 752 $scope.showAllColumnValues = function(columnName) {
730 $scope.columnStringMatch[columnName] = ""; 753 $scope.columnStringMatch[columnName] = "";
731 $scope.showingColumnValues[columnName] = {}; 754 $scope.showingColumnValues[columnName] = {};
732 $scope.toggleValuesInSet($scope.allColumnValues[columnName], 755 $scope.toggleValuesInSet($scope.allColumnValues[columnName],
733 $scope.showingColumnValues[columnName]); 756 $scope.showingColumnValues[columnName]);
734 $scope.updateResults(); 757 $scope.updateResults();
735 } 758 };
736 759
737 760
738 // 761 //
739 // Operations for sending info back to the server. 762 // Operations for sending info back to the server.
740 // 763 //
741 764
742 /** 765 /**
743 * Tell the server that the actual results of these particular tests 766 * Tell the server that the actual results of these particular tests
744 * are acceptable. 767 * are acceptable.
745 * 768 *
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 "finished loading the update results into memory!) and you can " + 858 "finished loading the update results into memory!) and you can " +
836 "submit more baselines if you want."); 859 "submit more baselines if you want.");
837 // I don't know why, but if I just call reload() here it doesn't work. 860 // I don't know why, but if I just call reload() here it doesn't work.
838 // Making a timer call it fixes the problem. 861 // Making a timer call it fixes the problem.
839 $timeout(function(){location.reload();}, 1); 862 $timeout(function(){location.reload();}, 1);
840 }).error(function(data, status, headers, config) { 863 }).error(function(data, status, headers, config) {
841 alert("There was an error submitting your baselines.\n\n" + 864 alert("There was an error submitting your baselines.\n\n" +
842 "Please see server-side log for details."); 865 "Please see server-side log for details.");
843 $scope.submitPending = false; 866 $scope.submitPending = false;
844 }); 867 });
845 } 868 };
846 869
847 870
848 // 871 //
849 // Operations we use to mimic Set semantics, in such a way that 872 // Operations we use to mimic Set semantics, in such a way that
850 // checking for presence within the Set is as fast as possible. 873 // checking for presence within the Set is as fast as possible.
851 // But getting a list of all values within the Set is not necessarily 874 // But getting a list of all values within the Set is not necessarily
852 // possible. 875 // possible.
853 // TODO(epoger): move into a separate .js file? 876 // TODO(epoger): move into a separate .js file?
854 // 877 //
855 878
856 /** 879 /**
857 * Returns the number of values present within set "set". 880 * Returns the number of values present within set "set".
858 * 881 *
859 * @param set an Object which we use to mimic set semantics 882 * @param set an Object which we use to mimic set semantics
860 */ 883 */
861 $scope.setSize = function(set) { 884 $scope.setSize = function(set) {
862 return Object.keys(set).length; 885 return Object.keys(set).length;
863 } 886 };
864 887
865 /** 888 /**
866 * Returns true if value "value" is present within set "set". 889 * Returns true if value "value" is present within set "set".
867 * 890 *
868 * @param value a value of any type 891 * @param value a value of any type
869 * @param set an Object which we use to mimic set semantics 892 * @param set an Object which we use to mimic set semantics
870 * (this should make isValueInSet faster than if we used an Array) 893 * (this should make isValueInSet faster than if we used an Array)
871 */ 894 */
872 $scope.isValueInSet = function(value, set) { 895 $scope.isValueInSet = function(value, set) {
873 return (true == set[value]); 896 return (true == set[value]);
874 } 897 };
875 898
876 /** 899 /**
877 * If value "value" is already in set "set", remove it; otherwise, add it. 900 * If value "value" is already in set "set", remove it; otherwise, add it.
878 * 901 *
879 * @param value a value of any type 902 * @param value a value of any type
880 * @param set an Object which we use to mimic set semantics 903 * @param set an Object which we use to mimic set semantics
881 */ 904 */
882 $scope.toggleValueInSet = function(value, set) { 905 $scope.toggleValueInSet = function(value, set) {
883 if (true == set[value]) { 906 if (true == set[value]) {
884 delete set[value]; 907 delete set[value];
885 } else { 908 } else {
886 set[value] = true; 909 set[value] = true;
887 } 910 }
888 } 911 };
889 912
890 /** 913 /**
891 * For each value in valueArray, call toggleValueInSet(value, set). 914 * For each value in valueArray, call toggleValueInSet(value, set).
892 * 915 *
893 * @param valueArray 916 * @param valueArray
894 * @param set 917 * @param set
895 */ 918 */
896 $scope.toggleValuesInSet = function(valueArray, set) { 919 $scope.toggleValuesInSet = function(valueArray, set) {
897 var arrayLength = valueArray.length; 920 var arrayLength = valueArray.length;
898 for (var i = 0; i < arrayLength; i++) { 921 for (var i = 0; i < arrayLength; i++) {
899 $scope.toggleValueInSet(valueArray[i], set); 922 $scope.toggleValueInSet(valueArray[i], set);
900 } 923 }
901 } 924 };
902 925
903 926
904 // 927 //
905 // Array operations; similar to our Set operations, but operate on a 928 // Array operations; similar to our Set operations, but operate on a
906 // Javascript Array so we *can* easily get a list of all values in the Set. 929 // Javascript Array so we *can* easily get a list of all values in the Set.
907 // TODO(epoger): move into a separate .js file? 930 // TODO(epoger): move into a separate .js file?
908 // 931 //
909 932
910 /** 933 /**
911 * Returns true if value "value" is present within array "array". 934 * Returns true if value "value" is present within array "array".
912 * 935 *
913 * @param value a value of any type 936 * @param value a value of any type
914 * @param array a Javascript Array 937 * @param array a Javascript Array
915 */ 938 */
916 $scope.isValueInArray = function(value, array) { 939 $scope.isValueInArray = function(value, array) {
917 return (-1 != array.indexOf(value)); 940 return (-1 != array.indexOf(value));
918 } 941 };
919 942
920 /** 943 /**
921 * If value "value" is already in array "array", remove it; otherwise, 944 * If value "value" is already in array "array", remove it; otherwise,
922 * add it. 945 * add it.
923 * 946 *
924 * @param value a value of any type 947 * @param value a value of any type
925 * @param array a Javascript Array 948 * @param array a Javascript Array
926 */ 949 */
927 $scope.toggleValueInArray = function(value, array) { 950 $scope.toggleValueInArray = function(value, array) {
928 var i = array.indexOf(value); 951 var i = array.indexOf(value);
929 if (-1 == i) { 952 if (-1 == i) {
930 array.push(value); 953 array.push(value);
931 } else { 954 } else {
932 array.splice(i, 1); 955 array.splice(i, 1);
933 } 956 }
934 } 957 };
935 958
936 959
937 // 960 //
938 // Miscellaneous utility functions. 961 // Miscellaneous utility functions.
939 // TODO(epoger): move into a separate .js file? 962 // TODO(epoger): move into a separate .js file?
940 // 963 //
941 964
942 /** 965 /**
943 * Returns a single "column slice" of a 2D array. 966 * Returns a single "column slice" of a 2D array.
944 * 967 *
945 * For example, if array is: 968 * For example, if array is:
946 * [[A0, A1], 969 * [[A0, A1],
947 * [B0, B1], 970 * [B0, B1],
948 * [C0, C1]] 971 * [C0, C1]]
949 * and index is 0, this this will return: 972 * and index is 0, this this will return:
950 * [A0, B0, C0] 973 * [A0, B0, C0]
951 * 974 *
952 * @param array a Javascript Array 975 * @param array a Javascript Array
953 * @param column (numeric): index within each row array 976 * @param column (numeric): index within each row array
954 */ 977 */
955 $scope.columnSliceOf2DArray = function(array, column) { 978 $scope.columnSliceOf2DArray = function(array, column) {
956 var slice = []; 979 var slice = [];
957 var numRows = array.length; 980 var numRows = array.length;
958 for (var row = 0; row < numRows; row++) { 981 for (var row = 0; row < numRows; row++) {
959 slice.push(array[row][column]); 982 slice.push(array[row][column]);
960 } 983 }
961 return slice; 984 return slice;
962 } 985 };
963 986
964 /** 987 /**
965 * Returns a human-readable (in local time zone) time string for a 988 * Returns a human-readable (in local time zone) time string for a
966 * particular moment in time. 989 * particular moment in time.
967 * 990 *
968 * @param secondsPastEpoch (numeric): seconds past epoch in UTC 991 * @param secondsPastEpoch (numeric): seconds past epoch in UTC
969 */ 992 */
970 $scope.localTimeString = function(secondsPastEpoch) { 993 $scope.localTimeString = function(secondsPastEpoch) {
971 var d = new Date(secondsPastEpoch * 1000); 994 var d = new Date(secondsPastEpoch * 1000);
972 return d.toString(); 995 return d.toString();
973 } 996 };
974 997
975 /** 998 /**
976 * Returns a hex color string (such as "#aabbcc") for the given RGB values. 999 * Returns a hex color string (such as "#aabbcc") for the given RGB values.
977 * 1000 *
978 * @param r (numeric): red channel value, 0-255 1001 * @param r (numeric): red channel value, 0-255
979 * @param g (numeric): green channel value, 0-255 1002 * @param g (numeric): green channel value, 0-255
980 * @param b (numeric): blue channel value, 0-255 1003 * @param b (numeric): blue channel value, 0-255
981 */ 1004 */
982 $scope.hexColorString = function(r, g, b) { 1005 $scope.hexColorString = function(r, g, b) {
983 var rString = r.toString(16); 1006 var rString = r.toString(16);
984 if (r < 16) { 1007 if (r < 16) {
985 rString = "0" + rString; 1008 rString = "0" + rString;
986 } 1009 }
987 var gString = g.toString(16); 1010 var gString = g.toString(16);
988 if (g < 16) { 1011 if (g < 16) {
989 gString = "0" + gString; 1012 gString = "0" + gString;
990 } 1013 }
991 var bString = b.toString(16); 1014 var bString = b.toString(16);
992 if (b < 16) { 1015 if (b < 16) {
993 bString = "0" + bString; 1016 bString = "0" + bString;
994 } 1017 }
995 return '#' + rString + gString + bString; 1018 return '#' + rString + gString + bString;
996 } 1019 };
997 1020
998 /** 1021 /**
999 * Returns a hex color string (such as "#aabbcc") for the given brightness. 1022 * Returns a hex color string (such as "#aabbcc") for the given brightness.
1000 * 1023 *
1001 * @param brightnessString (string): 0-255, 0 is completely black 1024 * @param brightnessString (string): 0-255, 0 is completely black
1002 * 1025 *
1003 * TODO(epoger): It might be nice to tint the color when it's not completely 1026 * TODO(epoger): It might be nice to tint the color when it's not completely
1004 * black or completely white. 1027 * black or completely white.
1005 */ 1028 */
1006 $scope.brightnessStringToHexColor = function(brightnessString) { 1029 $scope.brightnessStringToHexColor = function(brightnessString) {
1007 var v = parseInt(brightnessString); 1030 var v = parseInt(brightnessString);
1008 return $scope.hexColorString(v, v, v); 1031 return $scope.hexColorString(v, v, v);
1009 } 1032 };
1010 1033
1011 /** 1034 /**
1012 * Returns the last path component of image diff URL for a given ImagePair. 1035 * Returns the last path component of image diff URL for a given ImagePair.
1013 * 1036 *
1014 * Depending on which diff this is (whitediffs, pixeldiffs, etc.) this 1037 * Depending on which diff this is (whitediffs, pixeldiffs, etc.) this
1015 * will be relative to different base URLs. 1038 * will be relative to different base URLs.
1016 * 1039 *
1017 * We must keep this function in sync with _get_difference_locator() in 1040 * We must keep this function in sync with _get_difference_locator() in
1018 * ../imagediffdb.py 1041 * ../imagediffdb.py
1019 * 1042 *
1020 * @param imagePair: ImagePair to generate image diff URL for 1043 * @param imagePair: ImagePair to generate image diff URL for
1021 */ 1044 */
1022 $scope.getImageDiffRelativeUrl = function(imagePair) { 1045 $scope.getImageDiffRelativeUrl = function(imagePair) {
1023 var before = 1046 var before =
1024 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" + 1047 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" +
1025 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]; 1048 imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL];
1026 return before.replace(/[^\w\-]/g, "_") + ".png"; 1049 return before.replace(/[^\w\-]/g, "_") + ".png";
1027 } 1050 };
1028 1051
1029 } 1052 }
1030 ); 1053 );
OLDNEW
« no previous file with comments | « gm/rebaseline_server/static/live-view.html ('k') | gm/rebaseline_server/static/view.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698