[Tables] #707 Supporting realtime telemetry tables

Added real-time table type
This commit is contained in:
Henry 2016-03-08 13:29:16 -08:00
parent 20f1dcef45
commit a4eb9d6a94
6 changed files with 94 additions and 69 deletions

View File

@ -36,8 +36,7 @@ define(
function EventTelemetryProvider($q, $timeout) {
var
subscriptions = [],
genInterval = 1000,
startTime = Date.now();
genInterval = 1000;
//
function matchesSource(request) {
@ -80,7 +79,6 @@ define(
function startGenerating() {
$timeout(function () {
//console.log("startGenerating... " + Date.now());
handleSubscriptions();
if (subscriptions.length > 0) {
startGenerating();
@ -93,7 +91,8 @@ define(
callback: callback,
requests: requests
};
console.log("subscribe... " + Date.now() / 1000 + " request:" +
" " + requests[0].id);
function unsubscribe() {
subscriptions = subscriptions.filter(function (s) {
return s !== subscription;
@ -101,7 +100,6 @@ define(
}
subscriptions.push(subscription);
if (subscriptions.length === 1) {
startGenerating();
}

View File

@ -23,7 +23,7 @@
define([
"./src/directives/MCTTable",
"./src/controllers/RTTableController",
"./src/controllers/RTTelemetryTableController",
"./src/controllers/TelemetryTableController",
"./src/controllers/TableOptionsController",
'../../commonUI/regions/src/Region',
@ -31,8 +31,8 @@ define([
"legacyRegistry"
], function (
MCTTable,
RTTelemetryTableController,
TelemetryTableController,
RTTableController,
TableOptionsController,
Region,
InspectorRegion,
@ -61,7 +61,7 @@ define([
"types": [
{
"key": "table",
"name": "Table",
"name": "Historical Telemetry Table",
"glyph": "\ue605",
"description": "A table for displaying telemetry data",
"features": "creation",
@ -80,6 +80,29 @@ define([
"views": [
"table"
]
},
{
"key": "rttable",
"name": "Real-time Telemetry Table",
"glyph": "\ue605",
"description": "A table for displaying realtime telemetry" +
" data",
"features": "creation",
"delegates": [
"telemetry"
],
"inspector": tableInspector,
"contains": [
{
"has": "telemetry"
}
],
"model": {
"composition": []
},
"views": [
"realtime"
]
}
],
"controllers": [
@ -89,8 +112,8 @@ define([
"depends": ["$scope", "telemetryHandler", "telemetryFormatter"]
},
{
"key": "RTTableController",
"implementation": RTTableController,
"key": "RTTelemetryTableController",
"implementation": RTTelemetryTableController,
"depends": ["$scope", "telemetryHandler", "telemetryFormatter"]
},
{
@ -102,7 +125,7 @@ define([
],
"views": [
{
"name": "Table",
"name": "Historical Table",
"key": "table",
"glyph": "\ue605",
"templateUrl": "templates/table.html",
@ -113,7 +136,7 @@ define([
"editable": true
},
{
"name": "Scrolling",
"name": "Real-time Table",
"key": "realtime",
"glyph": "\ue605",
"templateUrl": "templates/rt-table.html",

View File

@ -1,4 +1,4 @@
<div ng-controller="RTTableController">
<div ng-controller="RTTelemetryTableController">
<mct-table
headers="headers"
rows="rows"

View File

@ -12,7 +12,7 @@ define(
this.element = element;
this.$timeout = $timeout;
this.maxDisplayRows = 50;
element.find('div').on('scroll', this.onScroll.bind(this));
element.find('div').on('scroll', this.setVisibleRows.bind(this));
this.scrollable = element.find('div')[0];
$scope.visibleRows = [];
@ -66,11 +66,10 @@ define(
}
/**
* On scroll, calculate which rows indexes are visible and
* ensure that an equal number of rows are preloaded for
* scrolling in either direction.
* Re-synchronize between data rows and visible rows, based on array
* content and scroll state.
*/
MCTTableController.prototype.onScroll = function (event) {
MCTTableController.prototype.setVisibleRows = function () {
var self = this,
target = this.scrollable,
topScroll = target.scrollTop,
@ -82,40 +81,53 @@ define(
start,
end;
//No need to scroll
if (this.$scope.displayRows.length < this.maxDisplayRows) {
return;
}
if (topScroll < this.$scope.headerHeight) {
firstVisible = 0;
//Check whether need to resynchronize visible with display
// rows (if data added)
if (this.$scope.visibleRows.length != this.$scope.displayRows.length){
start = 0;
end = this.$scope.displayRows.length-1;
} else {
//Data is in sync, and no need to calculate scroll,
// so do nothing.
return;
}
} else {
firstVisible = Math.floor(
(topScroll - this.$scope.headerHeight) / this.$scope.rowHeight
//rows has exceeded display maximum, so may be necessary to
// scroll
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;
end = Math.min(this.maxDisplayRows, this.$scope.displayRows.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.
}
}
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.
}
//Set visible rows from display rows, based on calculated offset.
this.$scope.visibleRows = this.$scope.displayRows.slice(start, end)
.map(function(row, i) {
return {
@ -176,16 +188,7 @@ define(
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.onScroll();
this.setVisibleRows();
this.$scope.overrideRowPositioning = true;
};
@ -316,13 +319,13 @@ define(
* will be sorted before display.
*/
MCTTableController.prototype.updateRows = function (newRows) {
console.log('updateRows');
this.$scope.visibleRows = [];
this.$scope.overrideRowPositioning = false;
if (!this.$scope.displayHeaders) {
return;
}
this.filterAndSort(newRows || []);
this.resize();
};

View File

@ -27,8 +27,8 @@
*/
define(
[
'./TableController',
'../Table',
'./TelemetryTableController',
'../TableConfiguration',
'../NameColumn'
],
function (TableController, Table, NameColumn) {
@ -44,16 +44,17 @@ define(
* @param telemetryFormatter
* @constructor
*/
function RTTableController($scope, telemetryHandler, telemetryFormatter) {
function RTTelemetryTableController($scope, telemetryHandler, telemetryFormatter) {
TableController.call(this, $scope, telemetryHandler, telemetryFormatter);
}
RTTableController.prototype = Object.create(TableController.prototype);
RTTelemetryTableController.prototype = Object.create(TableController.prototype);
/**
Create a new subscription. This is called when
Create a new telemetry subscription.
*/
RTTableController.prototype.subscribe = function() {
RTTelemetryTableController.prototype.subscribe = function() {
console.trace();
var self = this;
if (this.handle) {
@ -90,10 +91,10 @@ define(
* be composed of multiple objects)
* @param datum The data received from the telemetry source
*/
RTTableController.prototype.updateRows = function (object, datum) {
RTTelemetryTableController.prototype.updateRows = function (object, datum) {
this.$scope.$broadcast('newRow', this.table.getRowValues(object, datum));
};
return RTTableController;
return RTTelemetryTableController;
}
);

View File

@ -82,7 +82,7 @@ define(
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)));
//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)));
@ -103,7 +103,7 @@ define(
Create a new subscription. This is called when
*/
TelemetryTableController.prototype.subscribe = function() {
console.trace();
if (this.handle) {
this.handle.unsubscribe();
}