From 6302eee17ee6cc36881249f17342dbfafe65f99a Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 13 Aug 2015 12:35:48 -0700 Subject: [PATCH] [Code Style] Use prototypes in Scrolling List bundle WTD-1482. --- .../features/scrolling/src/DomainColumn.js | 38 ++- platform/features/scrolling/src/NameColumn.js | 32 +-- .../features/scrolling/src/RangeColumn.js | 46 ++-- .../scrolling/src/ScrollingListController.js | 27 +- .../scrolling/src/ScrollingListPopulator.js | 237 +++++++++--------- 5 files changed, 189 insertions(+), 191 deletions(-) diff --git a/platform/features/scrolling/src/DomainColumn.js b/platform/features/scrolling/src/DomainColumn.js index 96df96f822..a55b4001d5 100644 --- a/platform/features/scrolling/src/DomainColumn.js +++ b/platform/features/scrolling/src/DomainColumn.js @@ -34,6 +34,7 @@ define( * (typically, timestamps.) Used by the ScrollingListController. * * @memberof platform/features/scrolling + * @implements {platform/features/scrolling.ScrollingColumn} * @constructor * @param domainMetadata an object with the machine- and human- * readable names for this domain (in `key` and `name` @@ -42,31 +43,22 @@ define( * formatting service, for making values human-readable. */ function DomainColumn(domainMetadata, telemetryFormatter) { - return { - /** - * Get the title to display in this column's header. - * @returns {string} the title to display - * @memberof platform/features/scrolling.DomainColumn# - */ - getTitle: function () { - return domainMetadata.name; - }, - /** - * Get the text to display inside a row under this - * column. - * @returns {string} the text to display - * @memberof platform/features/scrolling.DomainColumn# - */ - getValue: function (domainObject, datum) { - return { - text: telemetryFormatter.formatDomainValue( - datum[domainMetadata.key] - ) - }; - } - }; + this.domainMetadata = domainMetadata; + this.telemetryFormatter = telemetryFormatter; } + DomainColumn.prototype.getTitle = function () { + return this.domainMetadata.name; + }; + + DomainColumn.prototype.getValue = function (domainObject, datum) { + return { + text: this.telemetryFormatter.formatDomainValue( + datum[this.domainMetadata.key] + ) + }; + }; + return DomainColumn; } ); diff --git a/platform/features/scrolling/src/NameColumn.js b/platform/features/scrolling/src/NameColumn.js index e177f0ceca..8947b279f0 100644 --- a/platform/features/scrolling/src/NameColumn.js +++ b/platform/features/scrolling/src/NameColumn.js @@ -34,32 +34,22 @@ define( * which exposed specific telemetry values. * * @memberof platform/features/scrolling + * @implements {platform/features/scrolling.ScrollingColumn} * @constructor */ function NameColumn() { - return { - /** - * Get the title to display in this column's header. - * @returns {string} the title to display - * @memberof platform/features/scrolling.NameColumn# - */ - getTitle: function () { - return "Name"; - }, - /** - * Get the text to display inside a row under this - * column. This returns the domain object's name. - * @returns {string} the text to display - * @memberof platform/features/scrolling.NameColumn# - */ - getValue: function (domainObject) { - return { - text: domainObject.getModel().name - }; - } - }; } + NameColumn.prototype.getTitle = function () { + return "Name"; + }; + + NameColumn.prototype.getValue = function (domainObject) { + return { + text: domainObject.getModel().name + }; + }; + return NameColumn; } ); diff --git a/platform/features/scrolling/src/RangeColumn.js b/platform/features/scrolling/src/RangeColumn.js index 980ed5da39..637a68517d 100644 --- a/platform/features/scrolling/src/RangeColumn.js +++ b/platform/features/scrolling/src/RangeColumn.js @@ -34,6 +34,7 @@ define( * (typically, measurements.) Used by the ScrollingListController. * * @memberof platform/features/scrolling + * @implements {platform/features/scrolling.ScrollingColumn} * @constructor * @param rangeMetadata an object with the machine- and human- * readable names for this range (in `key` and `name` @@ -42,35 +43,26 @@ define( * formatting service, for making values human-readable. */ function RangeColumn(rangeMetadata, telemetryFormatter) { - return { - /** - * Get the title to display in this column's header. - * @returns {string} the title to display - * @memberof platform/features/scrolling.RangeColumn# - */ - getTitle: function () { - return rangeMetadata.name; - }, - /** - * Get the text to display inside a row under this - * column. - * @returns {string} the text to display - * @memberof platform/features/scrolling.RangeColumn# - */ - getValue: function (domainObject, datum) { - var range = rangeMetadata.key, - limit = domainObject.getCapability('limit'), - value = datum[range], - alarm = limit.evaluate(datum, range); - - return { - cssClass: alarm && alarm.cssClass, - text: telemetryFormatter.formatRangeValue(value) - }; - } - }; + this.rangeMetadata = rangeMetadata; + this.telemetryFormatter = telemetryFormatter; } + RangeColumn.prototype.getTitle = function () { + return this.rangeMetadata.name; + }; + + RangeColumn.prototype.getValue = function (domainObject, datum) { + var range = this.rangeMetadata.key, + limit = domainObject.getCapability('limit'), + value = datum[range], + alarm = limit.evaluate(datum, range); + + return { + cssClass: alarm && alarm.cssClass, + text: this.telemetryFormatter.formatRangeValue(value) + }; + }; + return RangeColumn; } ); diff --git a/platform/features/scrolling/src/ScrollingListController.js b/platform/features/scrolling/src/ScrollingListController.js index 0a179f6102..c6a9f48fd9 100644 --- a/platform/features/scrolling/src/ScrollingListController.js +++ b/platform/features/scrolling/src/ScrollingListController.js @@ -39,8 +39,6 @@ define( * @constructor */ function ScrollingListController($scope, formatter) { - var populator; - // Get a set of populated, ready-to-display rows for the // latest data values. @@ -129,6 +127,31 @@ define( $scope.$watch("telemetry.getMetadata()", setupColumns); } + /** + * A description of how to display a certain column of data in a + * Scrolling List view. + * @interface platform/features/scrolling.ScrollingColumn + * @private + */ + /** + * Get the title to display in this column's header. + * @returns {string} the title to display + * @method platform/features/scrolling.ScrollingColumn#getTitle + */ + /** + * Get the text to display inside a row under this + * column. + * @param {DomainObject} domainObject the domain object associated + * with this row + * @param {TelemetrySeries} series the telemetry data associated + * with this row + * @param {number} index the index of the telemetry datum associated + * with this row + * @returns {string} the text to display + * @method platform/features/scrolling.ScrollingColumn#getValue + */ + + return ScrollingListController; } ); diff --git a/platform/features/scrolling/src/ScrollingListPopulator.js b/platform/features/scrolling/src/ScrollingListPopulator.js index 058829bab0..b5995d65ba 100644 --- a/platform/features/scrolling/src/ScrollingListPopulator.js +++ b/platform/features/scrolling/src/ScrollingListPopulator.js @@ -35,84 +35,114 @@ define( * @param {Column[]} columns the columns to be populated */ function ScrollingListPopulator(columns) { - /** - * Look up the most recent values from a set of data objects. - * Returns an array of objects in the order in which data - * should be displayed; each element is an object with - * two properties: - * - * * objectIndex: The index of the domain object associated - * with the data point to be displayed in that - * row. - * * pointIndex: The index of the data point itself, within - * its data set. - * - * @param {Array} datas an array of the most recent - * data objects; expected to be in the same order - * as the domain objects provided at constructor - * @param {number} count the number of rows to provide - * @memberof platform/features/scrolling.ScrollingListPopulator# - */ - function getLatestDataValues(datas, count) { - var latest = [], - candidate, - candidateTime, - used = datas.map(function () { return 0; }); + this.columns = columns; + } - // This algorithm is O(nk) for n rows and k telemetry elements; - // one O(k) linear search for a max is made for each of n rows. - // This could be done in O(n lg k + k lg k), using a priority - // queue (where priority is max-finding) containing k initial - // values. For n rows, pop the max from the queue and replenish - // the queue with a value from the data at the same - // objectIndex, if available. - // But k is small, so this might not give an observable - // improvement in performance. + /** + * Look up the most recent values from a set of data objects. + * Returns an array of objects in the order in which data + * should be displayed; each element is an object with + * two properties: + * + * * objectIndex: The index of the domain object associated + * with the data point to be displayed in that + * row. + * * pointIndex: The index of the data point itself, within + * its data set. + * + * @param {Array} datas an array of the most recent + * data objects; expected to be in the same order + * as the domain objects provided at constructor + * @param {number} count the number of rows to provide + * @returns {Array} latest data values in display order + * @private + */ + function getLatestDataValues(datas, count) { + var latest = [], + candidate, + candidateTime, + used = datas.map(function () { return 0; }); - // Find the most recent unused data point (this will be used - // in a loop to find and the N most recent data points) - function findCandidate(data, i) { - var nextTime, - pointCount = data.getPointCount(), - pointIndex = pointCount - used[i] - 1; - if (data && pointIndex >= 0) { - nextTime = data.getDomainValue(pointIndex); - if (nextTime > candidateTime) { - candidateTime = nextTime; - candidate = { - objectIndex: i, - pointIndex: pointIndex - }; - } + // This algorithm is O(nk) for n rows and k telemetry elements; + // one O(k) linear search for a max is made for each of n rows. + // This could be done in O(n lg k + k lg k), using a priority + // queue (where priority is max-finding) containing k initial + // values. For n rows, pop the max from the queue and replenish + // the queue with a value from the data at the same + // objectIndex, if available. + // But k is small, so this might not give an observable + // improvement in performance. + + // Find the most recent unused data point (this will be used + // in a loop to find and the N most recent data points) + function findCandidate(data, i) { + var nextTime, + pointCount = data.getPointCount(), + pointIndex = pointCount - used[i] - 1; + if (data && pointIndex >= 0) { + nextTime = data.getDomainValue(pointIndex); + if (nextTime > candidateTime) { + candidateTime = nextTime; + candidate = { + objectIndex: i, + pointIndex: pointIndex + }; } } - - // Assemble a list of the most recent data points - while (latest.length < count) { - // Reset variables pre-search - candidateTime = Number.NEGATIVE_INFINITY; - candidate = undefined; - - // Linear search for most recent - datas.forEach(findCandidate); - - if (candidate) { - // Record this data point - it is the most recent - latest.push(candidate); - - // Track the data points used so we can look farther back - // in the data set on the next iteration - used[candidate.objectIndex] = used[candidate.objectIndex] + 1; - } else { - // Ran out of candidates; not enough data points - // available to fill all rows. - break; - } - } - - return latest; } + // Assemble a list of the most recent data points + while (latest.length < count) { + // Reset variables pre-search + candidateTime = Number.NEGATIVE_INFINITY; + candidate = undefined; + + // Linear search for most recent + datas.forEach(findCandidate); + + if (candidate) { + // Record this data point - it is the most recent + latest.push(candidate); + + // Track the data points used so we can look farther back + // in the data set on the next iteration + used[candidate.objectIndex] = used[candidate.objectIndex] + 1; + } else { + // Ran out of candidates; not enough data points + // available to fill all rows. + break; + } + } + + return latest; + } + + /** + * Get the text which should appear in headers for the + * provided columns. + * @returns {string[]} column headers + */ + ScrollingListPopulator.prototype.getHeaders = function () { + return this.columns.map(function (column) { + return column.getTitle(); + }); + }; + + /** + * Get the contents of rows for the scrolling list view. + * @param {TelemetrySeries[]} datas the data sets + * @param {DomainObject[]} objects the domain objects which + * provided the data sets; these should match + * index-to-index with the `datas` argument + * @param {number} count the number of rows to populate + * @returns {string[][]} an array of rows, each of which + * is an array of values which should appear + * in that row + */ + ScrollingListPopulator.prototype.getRows = function (datas, objects, count) { + var values = getLatestDataValues(datas, count), + self = this; + // From a telemetry series, retrieve a single data point // containing all fields for domains/ranges function makeDatum(domainObject, series, index) { @@ -133,53 +163,24 @@ define( return result; } - return { - /** - * Get the text which should appear in headers for the - * provided columns. - * @returns {string[]} column headers - * @memberof platform/features/scrolling.ScrollingListPopulator# - */ - getHeaders: function () { - return columns.map(function (column) { - return column.getTitle(); - }); - }, - /** - * Get the contents of rows for the scrolling list view. - * @param {TelemetrySeries[]} datas the data sets - * @param {DomainObject[]} objects the domain objects which - * provided the data sets; these should match - * index-to-index with the `datas` argument - * @param {number} count the number of rows to populate - * @returns {string[][]} an array of rows, each of which - * is an array of values which should appear - * in that row - * @memberof platform/features/scrolling.ScrollingListPopulator# - */ - getRows: function (datas, objects, count) { - var values = getLatestDataValues(datas, count); + // Each value will become a row, which will contain + // some value in each column (rendering by the + // column object itself) + return values.map(function (value) { + var datum = makeDatum( + objects[value.objectIndex], + datas[value.objectIndex], + value.pointIndex + ); - // Each value will become a row, which will contain - // some value in each column (rendering by the - // column object itself) - return values.map(function (value) { - var datum = makeDatum( - objects[value.objectIndex], - datas[value.objectIndex], - value.pointIndex - ); - - return columns.map(function (column) { - return column.getValue( - objects[value.objectIndex], - datum - ); - }); - }); - } - }; - } + return self.columns.map(function (column) { + return column.getValue( + objects[value.objectIndex], + datum + ); + }); + }); + }; return ScrollingListPopulator;