[Table] #670 Added new view type 'table'

This commit is contained in:
Henry
2016-02-26 11:09:51 -08:00
parent 77a2e0a70b
commit ffa497f22f
20 changed files with 2171 additions and 0 deletions

View File

@ -0,0 +1,64 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,moment*/
/**
* Module defining DomainColumn.
*/
define(
[],
function () {
"use strict";
/**
* A column which will report telemetry domain values
* (typically, timestamps.) Used by the ScrollingListController.
*
* @memberof platform/features/table
* @constructor
* @param domainMetadata an object with the machine- and human-
* readable names for this domain (in `key` and `name`
* fields, respectively.)
* @param {TelemetryFormatter} telemetryFormatter the telemetry
* formatting service, for making values human-readable.
*/
function DomainColumn(domainMetadata, telemetryFormatter) {
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],
this.domainMetadata.format
)
};
};
return DomainColumn;
}
);

View File

@ -0,0 +1,54 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining NameColumn. Created by vwoeltje on 11/18/14.
*/
define(
[],
function () {
"use strict";
/**
* A column which will report the name of the domain object
* which exposed specific telemetry values.
*
* @memberof platform/features/table
* @constructor
*/
function NameColumn() {
}
NameColumn.prototype.getTitle = function () {
return "Name";
};
NameColumn.prototype.getValue = function (domainObject) {
return {
text: domainObject.getModel().name
};
};
return NameColumn;
}
);

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
*/
define(
[],
function () {
"use strict";
/**
* A column which will report telemetry range values
* (typically, measurements.) Used by the ScrollingListController.
*
* @memberof platform/features/table
* @constructor
* @param rangeMetadata an object with the machine- and human-
* readable names for this range (in `key` and `name`
* fields, respectively.)
* @param {TelemetryFormatter} telemetryFormatter the telemetry
* formatting service, for making values human-readable.
*/
function RangeColumn(rangeMetadata, telemetryFormatter) {
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 = isNaN(datum[range]) ? datum[range] : parseFloat(datum[range]),
alarm = limit && limit.evaluate(datum, range);
return {
cssClass: alarm && alarm.cssClass,
text: typeof(value) === 'undefined' ? undefined : this.telemetryFormatter.formatRangeValue(value)
};
};
return RangeColumn;
}
);

View File

@ -0,0 +1,163 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,moment*/
define(
[
'./DomainColumn',
'./RangeColumn',
'./NameColumn'
],
function (DomainColumn, RangeColumn, NameColumn) {
"use strict";
/**
* Class that manages table metadata, state, and contents.
* @memberof platform/features/table
* @param domainObject
* @constructor
*/
function Table(domainObject, telemetryFormatter) {
this.domainObject = domainObject;
this.columns = [];
this.telemetryFormatter = telemetryFormatter;
}
/**
* Build column definitions based on supplied telemetry metadata
* @param metadata Metadata describing the domains and ranges available
* @returns {Table} This object
*/
Table.prototype.buildColumns = function(metadata) {
var self = this;
this.columns = [];
if (metadata) {
metadata.forEach(function (metadatum) {
//Push domains first
metadatum.domains.forEach(function (domainMetadata) {
self.addColumn(new DomainColumn(domainMetadata, self.telemetryFormatter));
});
metadatum.ranges.forEach(function (rangeMetadata) {
self.addColumn(new RangeColumn(rangeMetadata, self.telemetryFormatter));
});
});
}
return this;
};
/**
* Add a column definition to this Table
* @param {RangeColumn | DomainColumn | NameColumn} column
* @param {Number} [index] Where the column should appear (will be
* affected by column filtering)
*/
Table.prototype.addColumn = function (column, index) {
if (typeof index === 'undefined') {
this.columns.push(column);
} else {
this.columns.splice(index, 0, column);
}
};
/**
* @private
* @param column
* @returns {*|string}
*/
Table.prototype.getColumnTitle = function (column) {
return column.getTitle();
};
/**
* Get a simple list of column titles
* @returns {Array} The titles of the columns
*/
Table.prototype.getHeaders = function() {
var self = this;
return this.columns.map(function (column){
return self.getColumnTitle(column);
});
};
/**
* Retrieve and format values for a given telemetry datum.
* @param telemetryObject The object that the telemetry data is
* associated with
* @param datum The telemetry datum to retrieve values from
* @returns {Object} Key value pairs where the key is the column
* title, and the value is the formatted value from the provided datum.
*/
Table.prototype.getRowValues = function(telemetryObject, datum) {
var self = this;
return this.columns.reduce(function(rowObject, column){
var columnTitle = self.getColumnTitle(column),
columnValue = column.getValue(telemetryObject, datum);
if (columnValue !== undefined && columnValue.text === undefined){
columnValue.text = '';
}
// Don't replace something with nothing.
// This occurs when there are multiple columns with the
// column title
if (rowObject[columnTitle] === undefined || rowObject[columnTitle].text === undefined || rowObject[columnTitle].text.length === 0) {
rowObject[columnTitle] = columnValue;
}
return rowObject;
}, {});
};
/**
* @private
*/
Table.prototype.defaultColumnConfiguration = function () {
return ((this.domainObject.getModel().configuration || {}).table || {}).columns || {};
};
/**
* As part of the process of building the table definition, extract
* configuration from column definitions.
* @returns {Object} A configuration object consisting of key-value
* pairs where the key is the column title, and the value is a
* boolean indicating whether the column should be shown.
*/
Table.prototype.getColumnConfiguration = function() {
var configuration = {},
//Use existing persisted config, or default it
defaultConfig = this.defaultColumnConfiguration();
/**
* For each column header, define a configuration value
* specifying whether the column is visible or not. Default to
* existing (persisted) configuration if available
*/
this.getHeaders().forEach(function(columnTitle) {
configuration[columnTitle] = typeof defaultConfig[columnTitle] === 'undefined' ? true : defaultConfig[columnTitle];
});
return configuration;
};
return Table;
}
);

View File

@ -0,0 +1,354 @@
/*global define*/
define(
[],
function () {
"use strict";
function MCTTableController($scope, $timeout, element) {
var self = this;
this.$scope = $scope;
this.element = element;
this.$timeout = $timeout;
this.maxDisplayRows = 50;
$scope.visibleRows = [];
$scope.overrideRowPositioning = false;
/**
* Set default values for optional parameters on a given scope
*/
function setDefaults($scope) {
if (typeof $scope.enableFilter === 'undefined') {
$scope.enableFilter = true;
$scope.filters = {};
}
if (typeof $scope.enableSort === 'undefined') {
$scope.enableSort = true;
$scope.sortColumn = undefined;
$scope.sortDirection = undefined;
}
}
setDefaults($scope);
element.find('div').on('scroll', this.onScroll.bind(this));
$scope.toggleSort = function (key) {
if (!$scope.enableSort) {
return;
}
if ($scope.sortColumn !== key) {
$scope.sortColumn = key;
$scope.sortDirection = 'asc';
} else if ($scope.sortDirection === 'asc') {
$scope.sortDirection = 'desc';
} else if ($scope.sortDirection === 'desc') {
$scope.sortColumn = undefined;
$scope.sortDirection = undefined;
}
self.updateRows($scope.rows);
};
$scope.$watchCollection('filters', function () {
self.updateRows(self.$scope.rows);
});
$scope.$watchCollection('headers', this.updateHeaders.bind(this));
$scope.$watchCollection('rows', this.updateRows.bind(this));
}
/**
* On scroll, calculate which rows indexes are visible and
* ensure that an equal number of rows are preloaded for
* scrolling in either direction.
*/
MCTTableController.prototype.onScroll = function (event) {
var self = this,
topScroll = event.target.scrollTop,
bottomScroll = topScroll + event.target.offsetHeight,
firstVisible,
lastVisible,
totalVisible,
numberOffscreen,
start,
end;
if (this.$scope.displayRows.length < this.maxDisplayRows) {
return;
}
if (topScroll < this.$scope.headerHeight) {
firstVisible = 0;
} else {
firstVisible = Math.floor(
(topScroll - this.$scope.headerHeight) / this.$scope.rowHeight
);
}
lastVisible = Math.ceil(
(bottomScroll - this.$scope.headerHeight) / this.$scope.rowHeight
);
totalVisible = lastVisible - firstVisible;
numberOffscreen = this.maxDisplayRows - totalVisible;
start = firstVisible - Math.floor(numberOffscreen / 2);
end = lastVisible + Math.ceil(numberOffscreen / 2);
if (start < 0) {
start = 0;
end = this.$scope.visibleRows.length - 1;
} else if (end >= this.$scope.displayRows.length) {
end = this.$scope.displayRows.length - 1;
start = end - this.maxDisplayRows + 1;
}
if (this.$scope.visibleRows[0].rowIndex === start &&
this.$scope.visibleRows[this.$scope.visibleRows.length-1]
.rowIndex === end) {
return; // don't update if no changes are required.
}
this.$scope.visibleRows = this.$scope.displayRows.slice(start, end)
.map(function(row, i) {
return {
rowIndex: start + i,
offsetY: ((start + i) * self.$scope.rowHeight) +
self.$scope.headerHeight,
contents: row
};
});
this.$scope.$digest();
};
/**
* Update table headers with new headers. If filtering is
* enabled, reset filters. If sorting is enabled, reset
* sorting.
*/
MCTTableController.prototype.updateHeaders = function (newHeaders) {
if (!newHeaders){
return;
}
this.$scope.displayHeaders = newHeaders;
if (this.$scope.enableFilter) {
this.$scope.filters = {};
}
// Reset column sort information unless the new headers
// contain the column current sorted on.
if (this.$scope.enableSort && newHeaders.indexOf(this.$scope.sortColumn) === -1) {
this.$scope.sortColumn = undefined;
this.$scope.sortDirection = undefined;
}
this.updateRows(this.$scope.rows);
};
/**
* Read styles from the DOM and use them to calculate offsets
* for individual rows.
*/
MCTTableController.prototype.setElementSizes = function () {
var self = this,
thead = this.element.find('thead'),
tbody = this.element.find('tbody'),
firstRow = tbody.find('tr'),
column = firstRow.find('td'),
headerHeight = thead.prop('offsetHeight'),
//row height is hard-coded for now.
rowHeight = 20,
overallHeight = headerHeight + (rowHeight * (this.$scope.displayRows ? this.$scope.displayRows.length - 1 : 0));
this.$scope.columnWidths = [];
while (column.length) {
this.$scope.columnWidths.push(column.prop('offsetWidth'));
column = column.next();
}
this.$scope.headerHeight = headerHeight;
this.$scope.rowHeight = rowHeight;
this.$scope.totalHeight = overallHeight;
this.$scope.visibleRows = this.$scope.displayRows.slice(0, this.maxDisplayRows).map(function(row, i) {
return {
rowIndex: i,
offsetY: (i * self.$scope.rowHeight) + self.$scope.headerHeight,
contents: row
};
});
this.$scope.overrideRowPositioning = true;
};
/**
* Returns a new array which is a result of applying the sort
* criteria defined in $scope.
*
* Does not modify the array that was passed in.
*/
MCTTableController.prototype.sortRows = function(rowsToSort) {
/**
* Compare two variables, returning a number that represents
* which is larger. Similar to the default array sort
* comparator, but does not coerce all values to string before
* conversion. Strings are lowercased before comparison.
*/
function genericComparator(a, b) {
if (typeof a === "string" && typeof b === "string") {
a = a.toLowerCase();
b = b.toLowerCase();
}
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
if (!this.$scope.sortColumn || !this.$scope.sortDirection) {
return rowsToSort;
}
var sortKey = this.$scope.sortColumn,
sortDirectionMultiplier;
if (this.$scope.sortDirection === 'asc') {
sortDirectionMultiplier = 1;
} else if (this.$scope.sortDirection === 'desc') {
sortDirectionMultiplier = -1;
}
return rowsToSort.slice(0).sort(function(a, b) {
//If the values to compare can be compared as
// numbers, do so. String comparison of number
// values can cause inconsistencies
var valA = isNaN(a[sortKey].text) ? a[sortKey].text : parseFloat(a[sortKey].text),
valB = isNaN(b[sortKey].text) ? b[sortKey].text : parseFloat(b[sortKey].text);
return genericComparator(valA, valB) *
sortDirectionMultiplier;
});
};
/**
* Returns an object which contains the largest values
* for each key in the given set of rows. This is used to
* pre-calculate optimal column sizes without having to render
* every row.
*/
MCTTableController.prototype.findLargestRow = function(rows) {
var largestRow = rows.reduce(function (largestRow, row) {
Object.keys(row).forEach(function (key) {
var currentColumn = row[key].text,
currentColumnLength =
(currentColumn && currentColumn.length) ?
currentColumn.length :
currentColumn,
largestColumn = largestRow[key].text,
largestColumnLength =
(largestColumn && largestColumn.length) ?
largestColumn.length :
largestColumn;
if (currentColumnLength > largestColumnLength) {
largestRow[key] = JSON.parse(JSON.stringify(row[key]));
}
});
return largestRow;
}, JSON.parse(JSON.stringify(rows[0] || {})));
// Pad with characters to accomodate variable-width fonts,
// and remove characters that would allow word-wrapping.
largestRow = JSON.parse(JSON.stringify(largestRow));
Object.keys(largestRow).forEach(function(key) {
var padCharacters,
i;
largestRow[key].text = String(largestRow[key].text);
padCharacters = largestRow[key].text.length / 10;
for (i = 0; i < padCharacters; i++) {
largestRow[key].text = largestRow[key].text + 'W';
}
largestRow[key].text = largestRow[key].text
.replace(/[ \-_]/g, 'W');
});
return largestRow;
};
MCTTableController.prototype.resize = function (){
var largestRow = this.findLargestRow(this.$scope.displayRows);
this.$scope.visibleRows = [
{
rowIndex: 0,
offsetY: undefined,
contents: largestRow
}
];
this.$timeout(this.setElementSizes.bind(this), 0);
};
/**
* Update rows with new data. If filtering is enabled, rows
* will be sorted before display.
*/
MCTTableController.prototype.updateRows = function (newRows) {
var displayRows = newRows;
this.$scope.visibleRows = [];
this.$scope.overrideRowPositioning = false;
if (!this.$scope.displayHeaders) {
return;
}
if (this.$scope.enableFilter) {
displayRows = this.filterRows(displayRows);
}
if (this.$scope.enableSort) {
displayRows = this.sortRows(displayRows);
}
this.$scope.displayRows = displayRows;
this.resize();
};
/**
* Filter rows.
*/
MCTTableController.prototype.filterRows = function(rowsToFilter) {
var filters = {},
self = this;
/**
* Returns true if row matches all filters.
*/
function matchRow(filters, row) {
return Object.keys(filters).every(function(key) {
if (!row[key]) {
return false;
}
var testVal = String(row[key].text).toLowerCase();
return testVal.indexOf(filters[key]) !== -1;
});
}
if (!Object.keys(this.$scope.filters).length) {
return rowsToFilter;
}
Object.keys(this.$scope.filters).forEach(function(key) {
if (!self.$scope.filters[key]) {
return;
}
filters[key] = self.$scope.filters[key].toLowerCase();
});
return rowsToFilter.filter(matchRow.bind(null, filters));
};
return MCTTableController;
}
);

View File

@ -0,0 +1,214 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
/**
* This bundle adds a table view for displaying telemetry data.
* @namespace platform/features/table
*/
define(
[
'../Table',
'../NameColumn'
],
function (Table, NameColumn) {
"use strict";
/**
* The TableController is responsible for getting data onto the page
* in the table widget. This includes handling composition,
* configuration, and telemetry subscriptions.
* @memberof platform/features/table
* @param $scope
* @param telemetryHandler
* @param telemetryFormatter
* @constructor
*/
function TableController(
$scope,
telemetryHandler,
telemetryFormatter
) {
var self = this;
this.$scope = $scope;
this.columns = {}; //Range and Domain columns
this.handle = undefined;
//this.pending = false;
this.telemetryHandler = telemetryHandler;
this.table = new Table($scope.domainObject, telemetryFormatter);
this.changeListeners = [];
$scope.rows = [];
// Subscribe to telemetry when a domain object becomes available
this.$scope.$watch('domainObject', function(domainObject){
if (!domainObject)
return;
self.subscribe();
self.registerChangeListeners();
});
// Unsubscribe when the plot is destroyed
this.$scope.$on("$destroy", this.destroy.bind(this));
}
TableController.prototype.registerChangeListeners = function() {
//Defer registration of change listeners until domain object is
// available in order to avoid race conditions
this.changeListeners.forEach(function (listener) {
return listener && listener();
});
this.changeListeners = [];
// When composition changes, re-subscribe to the various
// telemetry subscriptions
this.changeListeners.push(this.$scope.$watchCollection('domainObject.getModel().composition', this.subscribe.bind(this)));
//Change of bounds in time conductor
this.changeListeners.push(this.$scope.$on('telemetry:display:bounds', this.subscribe.bind(this)));
};
/**
* Release the current subscription (called when scope is destroyed)
*/
TableController.prototype.destroy = function () {
if (this.handle) {
this.handle.unsubscribe();
this.handle = undefined;
}
};
/**
Create a new subscription. This is called when
*/
TableController.prototype.subscribe = function() {
var self = this;
/*if (this.pending){
return;
}*/
//this.pending = true;
if (this.handle) {
this.handle.unsubscribe();
}
this.$scope.rows = [];
//Noop because not supporting realtime data right now
function noop(){
//self.pending = false;
}
this.handle = this.$scope.domainObject && this.telemetryHandler.handle(
this.$scope.domainObject,
noop,
true // Lossless
);
this.handle.request({}, this.addHistoricalData.bind(this));
this.setup();
};
/**
* Add any historical data available
*/
TableController.prototype.addHistoricalData = function(domainObject, series) {
var i;
//this.pending = false;
for (i=0; i < series.getPointCount(); i++) {
this.updateRows(domainObject, this.handle.makeDatum(domainObject, series, i));
}
};
/**
* Set the established configuration on the domain object
* @private
*/
TableController.prototype.writeConfigToModel = function (configuration) {
this.$scope.domainObject.useCapability('mutation', function (model) {
model.configuration = model.configuration || {};
model.configuration.table = model.configuration.table || {};
model.configuration.table.columns = configuration;
});
};
/**
* Setup table columns based on domain object metadata
*/
TableController.prototype.setup = function() {
var handle = this.handle,
table = this.table,
self = this,
configuration;
if (handle) {
handle.promiseTelemetryObjects().then(function () {
table.buildColumns(handle.getMetadata());
if (table.columns.length > 0){
table.addColumn(new NameColumn(), 0);
}
self.filterColumns();
// When table column configuration changes, (due to being
// selected or deselected), filter columns appropriately.
self.changeListeners.push(self.$scope.$watchCollection(
'domainObject.getModel().configuration.table.columns',
self.filterColumns.bind(self)
));
});
}
};
/**
* Add data to rows
* @param object The object for which data is available (table may
* be composed of multiple objects)
* @param datum The data received from the telemetry source
*/
TableController.prototype.updateRows = function (object, datum) {
this.$scope.rows.push(this.table.getRowValues(object, datum));
};
/**
* When column configuration changes, update the visible headers
* accordingly.
*/
TableController.prototype.filterColumns = function () {
var config = this.table.getColumnConfiguration();
this.writeConfigToModel(config);
//Populate headers with visible columns (determined by configuration)
this.$scope.headers = Object.keys(config).filter(function(column) {
return config[column];
});
};
return TableController;
}
);

View File

@ -0,0 +1,94 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
function () {
"use strict";
/**
* Notes on implementation of plot options
*
* Multiple y-axes will have to be handled with multiple forms as
* they will need to be stored on distinct model object
*
* Likewise plot series options per-child will need to be separate
* forms.
*/
/**
* The LayoutController is responsible for supporting the
* Layout view. It arranges frames according to saved configuration
* and provides methods for updating these based on mouse
* movement.
* @memberof platform/features/plot
* @constructor
* @param {Scope} $scope the controller's Angular scope
*/
function TableOptionsController($scope) {
var self = this;
this.$scope = $scope;
this.domainObject = $scope.domainObject;
$scope.columnsForm = {};
this.domainObject.getCapability('mutation').listen(function (model) {
self.populateForm(model);
});
$scope.$watchCollection('configuration.table.columns', function(columns){
if (columns){
self.domainObject.useCapability('mutation', function(model) {
model.configuration.table.columns = columns;
});
self.domainObject.getCapability('persistence').persist();
}
});
}
TableOptionsController.prototype.populateForm = function (model) {
var columnsDefinition = (((model.configuration || {}).table || {}).columns || {}),
rows = [];
this.$scope.columnsForm = {
'name':'Columns',
'sections': [{
'name': 'Columns',
'rows': rows
}]};
Object.keys(columnsDefinition).forEach(function (key){
rows.push({
'name': key,
'control': 'checkbox',
'key': key
});
});
this.$scope.configuration = JSON.parse(JSON.stringify(model.configuration));
};
return TableOptionsController;
}
);

View File

@ -0,0 +1,24 @@
/*global define*/
define(
[],
function () {
"use strict";
function MCTTable($timeout) {
return {
restrict: "E",
templateUrl: "platform/features/table/res/templates/mct-data-table.html",
controller: 'MCTTableController',
scope: {
headers: "=",
rows: "=",
enableFilter: "=?",
enableSort: "=?"
}
};
}
return MCTTable;
}
);