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

Unified Diff: gm/rebaseline_server/static/new/js/app.js

Issue 856103002: Revert "Revert "delete old things!"" (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/rebaseline_server/static/new/css/app.css ('k') | gm/rebaseline_server/static/new/new-index.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gm/rebaseline_server/static/new/js/app.js
diff --git a/gm/rebaseline_server/static/new/js/app.js b/gm/rebaseline_server/static/new/js/app.js
deleted file mode 100644
index 0a1fac0a450f848083742c51e9ab3a159cab6ed9..0000000000000000000000000000000000000000
--- a/gm/rebaseline_server/static/new/js/app.js
+++ /dev/null
@@ -1,1130 +0,0 @@
-'use strict';
-
-/**
- * TODO (stephana@): This is still work in progress.
- * It does not offer the same functionality as the current version, but
- * will serve as the starting point for a new backend.
- * It works with the current backend, but does not support rebaselining.
- */
-
-/*
- * Wrap everything into an IIFE to not polute the global namespace.
- */
-(function () {
-
- // Declare app level module which contains everything of the current app.
- // ui.bootstrap refers to directives defined in the AngularJS Bootstrap
- // UI package (http://angular-ui.github.io/bootstrap/).
- var app = angular.module('rbtApp', ['ngRoute', 'ui.bootstrap']);
-
- // Configure the different within app views.
- app.config(['$routeProvider', function($routeProvider) {
- $routeProvider.when('/', {templateUrl: 'partials/index-view.html',
- controller: 'IndexCtrl'});
- $routeProvider.when('/view', {templateUrl: 'partials/rebaseline-view.html',
- controller: 'RebaselineCrtrl'});
- $routeProvider.otherwise({redirectTo: '/'});
- }]);
-
-
- // TODO (stephana): Some of these constants are 'gm' specific. In the
- // next iteration we need to remove those as we move the more generic
- // 'dm' testing tool.
- //
- // Shared constants used here and in the markup. These are exported when
- // when used by a controller.
- var c = {
- // Define different view states as we load the data.
- ST_LOADING: 1,
- ST_STILL_LOADING: 2,
- ST_READY: 3,
-
- // These column types are used by the Column class.
- COL_T_FILTER: 'filter',
- COL_T_IMAGE: 'image',
- COL_T_REGULAR: 'regular',
-
- // Request parameters used to select between subsets of results.
- RESULTS_ALL: 'all',
- RESULTS_FAILURES: 'failures',
-
- // Filter types are used by the Column class.
- FILTER_FREE_FORM: 'free_form',
- FILTER_CHECK_BOX: 'checkbox',
-
- // Columns either provided by the backend response or added in code.
- // TODO (stephana): This should go away once we switch to 'dm'.
- COL_BUGS: 'bugs',
- COL_IGNORE_FAILURE: 'ignore-failure',
- COL_REVIEWED_BY_HUMANS: 'reviewed-by-human',
-
- // Defines the order in which image columns appear.
- // TODO (stephana@): needs to be driven by backend data.
- IMG_COL_ORDER: [
- {
- key: 'imageA',
- urlField: ['imageAUrl']
- },
- {
- key: 'imageB',
- urlField: ['imageBUrl']
- },
- {
- key: 'whiteDiffs',
- urlField: ['differenceData', 'whiteDiffUrl'],
- percentField: ['differenceData', 'percentDifferingPixels'],
- valueField: ['differenceData', 'numDifferingPixels']
- },
- {
- key: 'diffs',
- urlField: ['differenceData', 'diffUrl'],
- percentField: ['differenceData', 'perceptualDifference'],
- valueField: ['differenceData', 'maxDiffPerChannel']
- }
- ],
-
- // Choice of availabe image size selection.
- IMAGE_SIZES: [
- 100,
- 200,
- 400
- ],
-
- // Choice of available number of records selection.
- MAX_RECORDS: [
- '100',
- '200',
- '300'
- ]
- }; // end constants
-
- /*
- * Index Controller
- */
- // TODO (stephana): Remove $timeout since it only simulates loading delay.
- app.controller('IndexCtrl', ['$scope', '$timeout', 'dataService',
- function($scope, $timeout, dataService) {
- // init the scope
- $scope.c = c;
- $scope.state = c.ST_LOADING;
- $scope.qStr = dataService.getQueryString;
-
- // TODO (stephana): Remove and replace with index data generated by the
- // backend to reflect the current "known" image sets to compare.
- $scope.allSKPs = [
- {
- params: {
- setBSection: 'actual-results',
- setASection: 'expected-results',
- setBDir: 'gs://chromium-skia-skp-summaries/' +
- 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug',
- setADir: 'repo:expectations/skp/' +
- 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
- },
- title: 'expected vs actuals on ' +
- 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
- },
- {
- params: {
- setBSection: 'actual-results',
- setASection: 'expected-results',
- setBDir: 'gs://chromium-skia-skp-summaries/' +
- 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
- setADir: 'repo:expectations/skp/'+
- 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
- },
- title: 'expected vs actuals on Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
- },
- {
- params: {
- setBSection: 'actual-results',
- setASection: 'actual-results',
- setBDir: 'gs://chromium-skia-skp-summaries/' +
- 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release',
- setADir: 'gs://chromium-skia-skp-summaries/' +
- 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug'
- },
- title: 'Actuals on Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug ' +
- 'vs Test-Ubuntu12-ShuttleA-GTX660-x86-Release'
- }
- ];
-
- // TODO (stephana): Remove this once we load index data from the server.
- $timeout(function () {
- $scope.state = c.ST_READY;
- });
- }]);
-
- /*
- * RebaselineCtrl
- * Controls the main comparison view.
- *
- * @param {service} dataService Service that encapsulates functions to
- * retrieve data from the backend.
- *
- */
- app.controller('RebaselineCrtrl', ['$scope', '$timeout', 'dataService',
- function($scope, $timeout, dataService) {
- // determine which to request
- // TODO (stephana): This should be extracted from the query parameters.
- var target = c.TARGET_GM;
-
- // process the rquest arguments
- // TODO (stephana): This should be determined from the query parameters.
- var loadFn = dataService.loadAll;
-
- // controller state variables
- var allData = null;
- var filterFuncs = null;
- var currentData = null;
- var selectedData = null;
-
- // Index of the column that should provide the sort key
- var sortByIdx = 0;
-
- // Sort in asending (true) or descending (false) order
- var sortOrderAsc = true;
-
- // Array of functions for each column used for comparison during sort.
- var compareFunctions = null;
-
- // Variables to track load and render times
- var startTime;
- var loadStartTime;
-
-
- /** Load the data from the backend **/
- loadStartTime = Date.now();
- function loadData() {
- loadFn().then(
- function (serverData) {
- $scope.header = serverData.header;
- $scope.loadTime = (Date.now() - loadStartTime)/1000;
-
- // keep polling if the data are not ready yet
- if ($scope.header.resultsStillLoading) {
- $scope.state = c.ST_STILL_LOADING;
- $timeout(loadData, 5000);
- return;
- }
-
- // get the filter colunms and an array to hold filter data by user
- var fcol = getFilterColumns(serverData);
- $scope.filterCols = fcol[0];
- $scope.filterVals = fcol[1];
-
- // Add extra columns and retrieve the image columns
- var otherCols = [ Column.regular(c.COL_BUGS) ];
- var imageCols = getImageColumns(serverData);
-
- // Concat to get all columns
- // NOTE: The order is important since filters are rendered first,
- // followed by regular columns and images
- $scope.allCols = $scope.filterCols.concat(otherCols, imageCols);
-
- // Pre-process the data and get the filter functions.
- var dataFilters = getDataAndFilters(serverData, $scope.filterCols,
- otherCols, imageCols);
- allData = dataFilters[0];
- filterFuncs = dataFilters[1];
-
- // Get regular columns (== not image columns)
- var regularCols = $scope.filterCols.concat(otherCols);
-
- // Get the compare functions for regular and image columns. These
- // are then used to sort by the respective columns.
- compareFunctions = DataRow.getCompareFunctions(regularCols,
- imageCols);
-
- // Filter and sort the results to get them ready for rendering
- updateResults();
-
- // Data are ready for display
- $scope.state = c.ST_READY;
- },
- function (httpErrResponse) {
- console.log(httpErrResponse);
- });
- };
-
- /*
- * updateResults
- * Central render function. Everytime settings/filters/etc. changed
- * this function is called to filter, sort and splice the data.
- *
- * NOTE (stephana): There is room for improvement here: before filtering
- * and sorting we could check if this is necessary. But this has not been
- * a bottleneck so far.
- */
- function updateResults () {
- // run digest before we update the results. This allows
- // updateResults to be called from functions trigger by ngChange
- $scope.updating = true;
- startTime = Date.now();
-
- // delay by one render cycle so it can be called via ng-change
- $timeout(function() {
- // filter data
- selectedData = filterData(allData, filterFuncs, $scope.filterVals);
-
- // sort the selected data.
- sortData(selectedData, compareFunctions, sortByIdx, sortOrderAsc);
-
- // only conside the elements that we really need
- var nRecords = $scope.settings.nRecords;
- currentData = selectedData.slice(0, parseInt(nRecords));
-
- DataRow.setRowspanValues(currentData, $scope.mergeIdenticalRows);
-
- // update the scope with relevant data for rendering.
- $scope.data = currentData;
- $scope.totalRecords = allData.length;
- $scope.showingRecords = currentData.length;
- $scope.selectedRecords = selectedData.length;
- $scope.updating = false;
-
- // measure the filter time and total render time (via timeout).
- $scope.filterTime = Date.now() - startTime;
- $timeout(function() {
- $scope.renderTime = Date.now() - startTime;
- });
- });
- };
-
- /**
- * Generate the style value to set the width of images.
- *
- * @param {Column} col Column that we are trying to render.
- * @param {int} paddingPx Number of padding pixels.
- * @param {string} defaultVal Default value if not an image column.
- *
- * @return {string} Value to be used in ng-style element to set the width
- * of a image column.
- **/
- $scope.getImageWidthStyle = function (col, paddingPx, defaultVal) {
- var result = (col.ctype === c.COL_T_IMAGE) ?
- ($scope.imageSize + paddingPx + 'px') : defaultVal;
- return result;
- };
-
- /**
- * Sets the column by which to sort the data. If called for the
- * currently sorted column it will cause the sort to toggle between
- * ascending and descending.
- *
- * @param {int} colIdx Index of the column to use for sorting.
- **/
- $scope.sortBy = function (colIdx) {
- if (sortByIdx === colIdx) {
- sortOrderAsc = !sortOrderAsc;
- } else {
- sortByIdx = colIdx;
- sortOrderAsc = true;
- }
- updateResults();
- };
-
- /**
- * Helper function to generate a CSS class indicating whether this column
- * is the sort key. If it is a class name with the sort direction (Asc/Desc) is
- * return otherwise the default value is returned. In markup we use this
- * to display (or not display) an arrow next to the column name.
- *
- * @param {string} prefix Prefix of the classname to be generated.
- * @param {int} idx Index of the target column.
- * @param {string} defaultVal Value to return if current column is not used
- * for sorting.
- *
- * @return {string} CSS class name that a combination of the prefix and
- * direction indicator ('Asc' or 'Desc') if the column is
- * used for sorting. Otherwise the defaultVal is returned.
- **/
- $scope.getSortedClass = function (prefix, idx, defaultVal) {
- if (idx === sortByIdx) {
- return prefix + ((sortOrderAsc) ? 'Asc' : 'Desc');
- }
-
- return defaultVal;
- };
-
- /**
- * Checkbox to merge identical records has change. Force an update.
- **/
- $scope.mergeRowsChanged = function () {
- updateResults();
- }
-
- /**
- * Max number of records to display has changed. Force an update.
- **/
- $scope.maxRecordsChanged = function () {
- updateResults();
- };
-
- /**
- * Filter settings changed. Force an update.
- **/
- $scope.filtersChanged = function () {
- updateResults();
- };
-
- /**
- * Sets all possible values of the specified values to the given value.
- * That means all checkboxes are eiter selected or unselected.
- * Then force an update.
- *
- * @param {int} idx Index of the target filter column.
- * @param {boolean} val Value to set the filter values to.
- *
- **/
- $scope.setFilterAll = function (idx, val) {
- for(var i=0, len=$scope.filterVals[idx].length; i<len; i++) {
- $scope.filterVals[idx][i] = val;
- }
- updateResults();
- };
-
- /**
- * Toggle the values of a filter. This toggles all values in a
- * filter.
- *
- * @param {int} idx Index of the target filter column.
- **/
- $scope.setFilterToggle = function (idx) {
- for(var i=0, len=$scope.filterVals[idx].length; i<len; i++) {
- $scope.filterVals[idx][i] = !$scope.filterVals[idx][i];
- }
- updateResults();
- };
-
- // ****************************************
- // Initialize the scope.
- // ****************************************
-
- // Inject the constants into the scope and set the initial state.
- $scope.c = c;
- $scope.state = c.ST_LOADING;
-
- // Initial settings
- $scope.settings = {
- showThumbnails: true,
- imageSize: c.IMAGE_SIZES[0],
- nRecords: c.MAX_RECORDS[0],
- mergeIdenticalRows: true
- };
-
- // Initial values for filters set in loadData()
- $scope.filterVals = [];
-
- // Information about records - set in loadData()
- $scope.totalRecords = 0;
- $scope.showingRecords = 0;
- $scope.updating = false;
-
- // Trigger the data loading.
- loadData();
-
- }]);
-
- // data structs to interface with markup and backend
- /**
- * Models a column. It aggregates attributes of all
- * columns types. Some might be empty. See convenience
- * factory methods below for different column types.
- *
- * @param {string} key Uniquely identifies this columns
- * @param {string} ctype Type of columns. Use COL_* constants.
- * @param {string} ctitle Human readable title of the column.
- * @param {string} ftype Filter type. Use FILTER_* constants.
- * @param {FilterOpt[]} foptions Filter options. For 'checkbox' filters this
- is used to render all the checkboxes.
- For freeform filters this is a list of all
- available values.
- * @param {string} baseUrl Baseurl for image columns. All URLs are relative
- to this.
- *
- * @return {Column} Instance of the Column class.
- **/
- function Column(key, ctype, ctitle, ftype, foptions, baseUrl) {
- this.key = key;
- this.ctype = ctype;
- this.ctitle = ctitle;
- this.ftype = ftype;
- this.foptions = foptions;
- this.baseUrl = baseUrl;
- this.foptionsArr = [];
-
- // get the array of filter options for lookup in indexOfOptVal
- if (this.foptions) {
- for(var i=0, len=foptions.length; i<len; i++) {
- this.foptionsArr.push(this.foptions[i].value);
- }
- }
- }
-
- /**
- * Find the index of an value in a column with a fixed set
- * of options.
- *
- * @param {string} optVal Value of the column.
- *
- * @return {int} Index of optVal in this column.
- **/
- Column.prototype.indexOfOptVal = function (optVal) {
- return this.foptionsArr.indexOf(optVal);
- };
-
- /**
- * Set filter options for this column.
- *
- * @param {FilterOpt[]} foptions Possible values for this column.
- **/
- Column.prototype.setFilterOptions = function (foptions) {
- this.foptions = foptions;
- };
-
- /**
- * Factory function to create a filter column. Same args as Column()
- **/
- Column.filter = function(key, ctitle, ftype, foptions) {
- return new Column(key, c.COL_T_FILTER, ctitle || key, ftype, foptions);
- }
-
- /**
- * Factory function to create an image column. Same args as Column()
- **/
- Column.image = function (key, ctitle, baseUrl) {
- return new Column(key, c.COL_T_IMAGE, ctitle || key, null, null, baseUrl);
- };
-
- /**
- * Factory function to create a regular column. Same args as Column()
- **/
- Column.regular = function (key, ctitle) {
- return new Column(key, c.COL_T_REGULAR, ctitle || key);
- };
-
- /**
- * Helper class to wrap a single option in a filter.
- *
- * @param {string} value Option value.
- * @param {int} count Number of instances of this option in the dataset.
- *
- * @return {} Instance of FiltertOpt
- **/
- function FilterOpt(value, count) {
- this.value = value;
- this.count = count;
- }
-
- /**
- * Container for a single row in the dataset.
- *
- * @param {int} rowspan Number of rows (including this and following rows)
- that have identical values.
- * @param {string[]} dataCols Values of the respective columns (combination
- of filter and regular columns)
- * @param {ImgVal[]} imageCols Image meta data for the image columns.
- *
- * @return {DataRow} Instance of DataRow.
- **/
- function DataRow(rowspan, dataCols, imageCols) {
- this.rowspan = rowspan;
- this.dataCols = dataCols;
- this.imageCols = imageCols;
- }
-
- /**
- * Gets the comparator functions for the columns in this dataset.
- * The comparators are then used to sort the dataset by the respective
- * column.
- *
- * @param {Column[]} dataCols Data columns (= non-image columns)
- * @param {Column[]} imgCols Image columns.
- *
- * @return {Function[]} Array of functions that can be used to sort by the
- * respective column.
- **/
- DataRow.getCompareFunctions = function (dataCols, imgCols) {
- var result = [];
- for(var i=0, len=dataCols.length; i<len; i++) {
- result.push(( function (col, idx) {
- return function (a, b) {
- return (a.dataCols[idx] < b.dataCols[idx]) ? -1 :
- ((a.dataCols[idx] === b.dataCols[idx]) ? 0 : 1);
- };
- }(dataCols[i], i) ));
- }
-
- for(var i=0, len=imgCols.length; i<len; i++) {
- result.push((function (col, idx) {
- return function (a,b) {
- var aVal = a.imageCols[idx].percent;
- var bVal = b.imageCols[idx].percent;
-
- return (aVal < bVal) ? -1 : ((aVal === bVal) ? 0 : 1);
- };
- }(imgCols[i], i) ));
- }
-
- return result;
- };
-
- /**
- * Set the rowspan values of a given array of DataRow instances.
- *
- * @param {DataRow[]} data Dataset in desired order (after sorting).
- * @param {mergeRows} mergeRows Indicate whether to sort
- **/
- DataRow.setRowspanValues = function (data, mergeRows) {
- var curIdx, rowspan, cur;
- if (mergeRows) {
- for(var i=0, len=data.length; i<len;) {
- curIdx = i;
- cur = data[i];
- rowspan = 1;
- for(i++; ((i<len) && (data[i].dataCols === cur.dataCols)); i++) {
- rowspan++;
- data[i].rowspan=0;
- }
- data[curIdx].rowspan = rowspan;
- }
- } else {
- for(var i=0, len=data.length; i<len; i++) {
- data[i].rowspan = 1;
- }
- }
- };
-
- /**
- * Wrapper class for image related data.
- *
- * @param {string} url Relative Url of the image or null if not available.
- * @param {float} percent Percent of pixels that are differing.
- * @param {int} value Absolute number of pixes differing.
- *
- * @return {ImgVal} Instance of ImgVal.
- **/
- function ImgVal(url, percent, value) {
- this.url = url;
- this.percent = percent;
- this.value = value;
- }
-
- /**
- * Extracts the filter columns from the JSON response of the server.
- *
- * @param {object} data Server response.
- *
- * @return {Column[]} List of filter columns as described in 'header' field.
- **/
- function getFilterColumns(data) {
- var result = [];
- var vals = [];
- var colOrder = data.extraColumnOrder;
- var colHeaders = data.extraColumnHeaders;
- var fopts, optVals, val;
-
- for(var i=0, len=colOrder.length; i<len; i++) {
- if (colHeaders[colOrder[i]].isFilterable) {
- if (colHeaders[colOrder[i]].useFreeformFilter) {
- result.push(Column.filter(colOrder[i],
- colHeaders[colOrder[i]].headerText,
- c.FILTER_FREE_FORM));
- vals.push('');
- }
- else {
- fopts = [];
- optVals = [];
-
- // extract the different options for this column
- for(var j=0, jlen=colHeaders[colOrder[i]].valuesAndCounts.length;
- j<jlen; j++) {
- val = colHeaders[colOrder[i]].valuesAndCounts[j];
- fopts.push(new FilterOpt(val[0], val[1]));
- optVals.push(false);
- }
-
- // ad the column and values
- result.push(Column.filter(colOrder[i],
- colHeaders[colOrder[i]].headerText,
- c.FILTER_CHECK_BOX,
- fopts));
- vals.push(optVals);
- }
- }
- }
-
- return [result, vals];
- }
-
- /**
- * Extracts the image columns from the JSON response of the server.
- *
- * @param {object} data Server response.
- *
- * @return {Column[]} List of images columns as described in 'header' field.
- **/
- function getImageColumns(data) {
- var CO = c.IMG_COL_ORDER;
- var imgSet;
- var result = [];
- for(var i=0, len=CO.length; i<len; i++) {
- imgSet = data.imageSets[CO[i].key];
- result.push(Column.image(CO[i].key,
- imgSet.description,
- ensureTrailingSlash(imgSet.baseUrl)));
- }
- return result;
- }
-
- /**
- * Make sure Url has a trailing '/'.
- *
- * @param {string} url Base url.
- * @return {string} Same url with a trailing '/' or same as input if it
- already contained '/'.
- **/
- function ensureTrailingSlash(url) {
- var result = url.trim();
-
- // TODO: remove !!!
- result = fixUrl(url);
- if (result[result.length-1] !== '/') {
- result += '/';
- }
- return result;
- }
-
- // TODO: remove. The backend should provide absoute URLs
- function fixUrl(url) {
- url = url.trim();
- if ('http' === url.substr(0, 4)) {
- return url;
- }
-
- var idx = url.indexOf('static');
- if (idx != -1) {
- return '/' + url.substr(idx);
- }
-
- return url;
- };
-
- /**
- * Processes that data and returns filter functions.
- *
- * @param {object} Server response.
- * @param {Column[]} filterCols Filter columns.
- * @param {Column[]} otherCols Columns that are neither filters nor images.
- * @param {Column[]} imageCols Image columns.
- *
- * @return {[]} Returns a pair [dataRows, filterFunctions] where:
- * - dataRows is an array of DataRow instances.
- * - filterFunctions is an array of functions that can be used to
- * filter the column at the corresponding index.
- *
- **/
- function getDataAndFilters(data, filterCols, otherCols, imageCols) {
- var el;
- var result = [];
- var lookupIndices = [];
- var indexerFuncs = [];
- var temp;
-
- // initialize the lookupIndices
- var filterFuncs = initIndices(filterCols, lookupIndices, indexerFuncs);
-
- // iterate over the data and get the rows
- for(var i=0, len=data.imagePairs.length; i<len; i++) {
- el = data.imagePairs[i];
- temp = new DataRow(1, getColValues(el, filterCols, otherCols),
- getImageValues(el, imageCols));
- result.push(temp);
-
- // index the row
- for(var j=0, jlen=filterCols.length; j < jlen; j++) {
- indexerFuncs[j](lookupIndices[j], filterCols[j], temp.dataCols[j], i);
- }
- }
-
- setFreeFormFilterOptions(filterCols, lookupIndices);
- return [result, filterFuncs];
- }
-
- /**
- * Initiazile the lookup indices and indexer functions for the filter
- * columns.
- *
- * @param {Column} filterCols Filter columns
- * @param {[]} lookupIndices Will be filled with datastructures for
- fast lookup (output parameter)
- * @param {[]} lookupIndices Will be filled with functions to index data
- of the column with the corresponding column.
- *
- * @return {[]} Returns an array of filter functions that can be used to
- filter the respective column.
- **/
- function initIndices(filterCols, lookupIndices, indexerFuncs) {
- var filterFuncs = [];
- var temp;
-
- for(var i=0, len=filterCols.length; i<len; i++) {
- if (filterCols[i].ftype === c.FILTER_FREE_FORM) {
- lookupIndices.push({});
- indexerFuncs.push(indexFreeFormValue);
- filterFuncs.push(
- getFreeFormFilterFunc(lookupIndices[lookupIndices.length-1]));
- }
- else if (filterCols[i].ftype === c.FILTER_CHECK_BOX) {
- temp = [];
- for(var j=0, jlen=filterCols[i].foptions.length; j<jlen; j++) {
- temp.push([]);
- }
- lookupIndices.push(temp);
- indexerFuncs.push(indexDiscreteValue);
- filterFuncs.push(
- getDiscreteFilterFunc(lookupIndices[lookupIndices.length-1]));
- }
- }
-
- return filterFuncs;
- }
-
- /**
- * Helper function that extracts the values of free form columns from
- * the lookupIndex and injects them into the Column object as FilterOpt
- * objects.
- **/
- function setFreeFormFilterOptions(filterCols, lookupIndices) {
- var temp, k;
- for(var i=0, len=filterCols.length; i<len; i++) {
- if (filterCols[i].ftype === c.FILTER_FREE_FORM) {
- temp = []
- for(k in lookupIndices[i]) {
- if (lookupIndices[i].hasOwnProperty(k)) {
- temp.push(new FilterOpt(k, lookupIndices[i][k].length));
- }
- }
- filterCols[i].setFilterOptions(temp);
- }
- }
- }
-
- /**
- * Index a discrete column (column with fixed number of values).
- *
- **/
- function indexDiscreteValue(lookupIndex, col, dataVal, dataRowIndex) {
- var i = col.indexOfOptVal(dataVal);
- lookupIndex[i].push(dataRowIndex);
- }
-
- /**
- * Index a column with free form text (= not fixed upfront)
- *
- **/
- function indexFreeFormValue(lookupIndex, col, dataVal, dataRowIndex) {
- if (!lookupIndex[dataVal]) {
- lookupIndex[dataVal] = [];
- }
- lookupIndex[dataVal].push(dataRowIndex);
- }
-
-
- /**
- * Get the function to filter a column with the given lookup index
- * for discrete (fixed upfront) values.
- *
- **/
- function getDiscreteFilterFunc(lookupIndex) {
- return function(filterVal) {
- var result = [];
- for(var i=0, len=lookupIndex.length; i < len; i++) {
- if (filterVal[i]) {
- // append the indices to the current array
- result.push.apply(result, lookupIndex[i]);
- }
- }
- return { nofilter: false, records: result };
- };
- }
-
- /**
- * Get the function to filter a column with the given lookup index
- * for free form values.
- *
- **/
- function getFreeFormFilterFunc(lookupIndex) {
- return function(filterVal) {
- filterVal = filterVal.trim();
- if (filterVal === '') {
- return { nofilter: true };
- }
- return {
- nofilter: false,
- records: lookupIndex[filterVal] || []
- };
- };
- }
-
- /**
- * Filters the data based on the given filterColumns and
- * corresponding filter values.
- *
- * @return {[]} Subset of the input dataset based on the
- * filter values.
- **/
- function filterData(data, filterFuncs, filterVals) {
- var recordSets = [];
- var filterResult;
-
- // run through all the filters
- for(var i=0, len=filterFuncs.length; i<len; i++) {
- filterResult = filterFuncs[i](filterVals[i]);
- if (!filterResult.nofilter) {
- recordSets.push(filterResult.records);
- }
- }
-
- // If there are no restrictions then return the whole dataset.
- if (recordSets.length === 0) {
- return data;
- }
-
- // intersect the records returned by filters.
- var targets = intersectArrs(recordSets);
- var result = [];
- for(var i=0, len=targets.length; i<len; i++) {
- result.push(data[targets[i]]);
- }
-
- return result;
- }
-
- /**
- * Creates an object where the keys are the elements of the input array
- * and the values are true. To be used for set operations with integer.
- **/
- function arrToObj(arr) {
- var o = {};
- var i,len;
- for(i=0, len=arr.length; i<len; i++) {
- o[arr[i]] = true;
- }
- return o;
- }
-
- /**
- * Converts the keys of an object to an array after converting
- * each key to integer. To be used for set operations with integers.
- **/
- function objToArr(obj) {
- var result = [];
- for(var k in obj) {
- if (obj.hasOwnProperty(k)) {
- result.push(parseInt(k));
- }
- }
- return result;
- }
-
- /**
- * Find the intersection of a set of arrays.
- **/
- function intersectArrs(sets) {
- var temp, obj;
-
- if (sets.length === 1) {
- return sets[0];
- }
-
- // sort by size and load the smallest into the object
- sets.sort(function(a,b) { return a.length - b.length; });
- obj = arrToObj(sets[0]);
-
- // shrink the hash as we fail to find elements in the other sets
- for(var i=1, len=sets.length; i<len; i++) {
- temp = arrToObj(sets[i]);
- for(var k in obj) {
- if (obj.hasOwnProperty(k) && !temp[k]) {
- delete obj[k];
- }
- }
- }
-
- return objToArr(obj);
- }
-
- /**
- * Extract the column values from an ImagePair (contained in the server
- * response) into filter and data columns.
- *
- * @return {[]} Array of data contained in one data row.
- **/
- function getColValues(imagePair, filterCols, otherCols) {
- var result = [];
- for(var i=0, len=filterCols.length; i<len; i++) {
- result.push(imagePair.extraColumns[filterCols[i].key]);
- }
-
- for(var i=0, len=otherCols.length; i<len; i++) {
- result.push(get_robust(imagePair, ['expectations', otherCols[i].key]));
- }
-
- return result;
- }
-
- /**
- * Extract the image meta data from an Image pair returned by the server.
- **/
- function getImageValues(imagePair, imageCols) {
- var result=[];
- var url, value, percent, diff;
- var CO = c.IMG_COL_ORDER;
-
- for(var i=0, len=imageCols.length; i<len; i++) {
- percent = get_robust(imagePair, CO[i].percentField);
- value = get_robust(imagePair, CO[i].valueField);
- url = get_robust(imagePair, CO[i].urlField);
- if (url) {
- url = imageCols[i].baseUrl + url;
- }
- result.push(new ImgVal(url, percent, value));
- }
-
- return result;
- }
-
- /**
- * Given an object find sub objects for the given index without
- * throwing an error if any of the sub objects do not exist.
- **/
- function get_robust(obj, idx) {
- if (!idx) {
- return;
- }
-
- for(var i=0, len=idx.length; i<len; i++) {
- if ((typeof obj === 'undefined') || (!idx[i])) {
- return; // returns 'undefined'
- }
-
- obj = obj[idx[i]];
- }
-
- return obj;
- }
-
- /**
- * Set all elements in the array to the given value.
- **/
- function setArrVals(arr, newVal) {
- for(var i=0, len=arr.length; i<len; i++) {
- arr[i] = newVal;
- }
- }
-
- /**
- * Toggle the elements of a boolean array.
- *
- **/
- function toggleArrVals(arr) {
- for(var i=0, len=arr.length; i<len; i++) {
- arr[i] = !arr[i];
- }
- }
-
- /**
- * Sort the array of DataRow instances with the given compare functions
- * and the column at the given index either in ascending or descending order.
- **/
- function sortData (allData, compareFunctions, sortByIdx, sortOrderAsc) {
- var cmpFn = compareFunctions[sortByIdx];
- var useCmp = cmpFn;
- if (!sortOrderAsc) {
- useCmp = function ( _ ) {
- return -cmpFn.apply(this, arguments);
- };
- }
- allData.sort(useCmp);
- }
-
-
- // ***************************** Services *********************************
-
- /**
- * Encapsulates all interactions with the backend by handling
- * Urls and HTTP requests. Also exposes some utility functions
- * related to processing Urls.
- */
- app.factory('dataService', [ '$http', function ($http) {
- /** Backend related constants **/
- var c = {
- /** Url to retrieve failures */
- FAILURES: '/results/failures',
-
- /** Url to retrieve all GM results */
- ALL: '/results/all'
- };
-
- /**
- * Convenience function to retrieve all results.
- *
- * @return {Promise} Will resolve to either the data (success) or to
- * the HTTP response (error).
- **/
- function loadAll() {
- return httpGetData(c.ALL);
- }
-
- /**
- * Make a HTTP get request with the given query parameters.
- *
- * @param {}
- * @param {}
- *
- * @return {}
- **/
- function httpGetData(url, queryParams) {
- var reqConfig = {
- method: 'GET',
- url: url,
- params: queryParams
- };
-
- return $http(reqConfig).then(
- function(successResp) {
- return successResp.data;
- });
- }
-
- /**
- * Takes an arbitrary number of objects and generates a Url encoded
- * query string.
- *
- **/
- function getQueryString( _params_ ) {
- var result = [];
- for(var i=0, len=arguments.length; i < len; i++) {
- if (arguments[i]) {
- for(var k in arguments[i]) {
- if (arguments[i].hasOwnProperty(k)) {
- result.push(encodeURIComponent(k) + '=' +
- encodeURIComponent(arguments[i][k]));
- }
- }
- }
- }
- return result.join("&");
- }
-
- // Interface of the service:
- return {
- getQueryString: getQueryString,
- loadAll: loadAll
- };
-
- }]);
-
-})();
« no previous file with comments | « gm/rebaseline_server/static/new/css/app.css ('k') | gm/rebaseline_server/static/new/new-index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698