Merge branch 'open18' of https://github.com/slhale/openmctweb into open18

This commit is contained in:
Sarah Hale 2015-06-22 12:37:15 -07:00
commit 0feb3b0462
15 changed files with 1031 additions and 119 deletions

View File

@ -15,10 +15,12 @@
"platform/features/pages",
"platform/features/plot",
"platform/features/scrolling",
"platform/features/events",
"platform/forms",
"platform/persistence/queue",
"platform/policy",
"example/persistence",
"example/eventGenerator",
"example/generator"
]

View File

@ -0,0 +1,45 @@
{
"name": "Event Message Generator",
"description": "Example of a component that produces event data.",
"extensions": {
"components": [
{
"implementation": "EventTelemetryProvider.js",
"type": "provider",
"provides": "telemetryService",
"depends": [ "$q", "$timeout" ]
}
],
"types": [
{
"key": "eventGenerator",
"name": "Event Message Generator",
"glyph": "f",
"description": "An event message generator",
"features": "creation",
"model": {
"telemetry": {
"period": 10
}
},
"telemetry": {
"source": "eventGenerator",
"ranges": [
{ "format": "string" }
]
},
"properties": [
{
"name": "Period",
"control": "textfield",
"cssclass": "l-small l-numeric",
"key": "period",
"required": true,
"property": [ "telemetry", "period" ],
"pattern": "^\\d*(\\.\\d*)?$"
}
]
}
]
}
}

View File

@ -0,0 +1,104 @@
/*****************************************************************************
* 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 EventTelemetry. Created by chacskaylo on 06/18/2015.
*/
define(
[],
function () {
"use strict";
var
firstObservedTime = Date.now(),
messages = [];
messages.push(["WARN", "dsp_seqprt_comm", "CMD: SYS- MSG: Open the pod bay doors, please, Hal...Open the pod bay doors, please, Hal...Hullo, Hal, do you read me?...Hullo, Hal, do you read me?...Do you read me, Hal?"]);
messages.push(["TRACE", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Affirmative, Dave, I read you."]);
messages.push(["DEBUG", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Open the pod bay doors, Hal."]);
messages.push(["ERROR", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: I'm sorry, Dave, I'm afraid I can't do that."]);
messages.push(["TRACE", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: What's the problem?"]);
messages.push(["ERROR", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: I think you know what the problem is just as well as I do."]);
messages.push(["TRACE", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: What're you talking about, Hal?"]);
messages.push(["DEBUG", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: This mission is too important for me to allow you to jeopardise it."]);
messages.push(["WARN", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: I don't know what you're talking about, Hal."]);
messages.push(["FATAL", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: I know that you and Frank were planning to disconnect me, and I'm afraid that's something I cannot allow to happen."]);
messages.push(["TRACE", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Where the hell'd you get that idea, Hal?"]);
messages.push(["DEBUG", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Dave, although you took very thorough precautions in the pod against my hearing you, I could see your lips move."]);
messages.push(["DEBUG", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Alright, I'll go in through the emergency airlock."]);
messages.push(["DEBUG", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Without your space-helmet, Dave, you're going to find that rather difficult."]);
messages.push(["DEBUG", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Hal, I won't argue with you any more. Open the doors."]);
messages.push(["DEBUG", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Dave, this conversation can serve no purpose any more. Goodbye."]);
messages.push(["INFO", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: I hope the two of you are not concerned about this."]);
messages.push(["DEBUG", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: No, I'm not, Hal."]);
messages.push(["INFO", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Are you quite sure?"]);
messages.push(["INFO", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Yeh. I'd like to ask you a question, though."]);
messages.push(["FATAL", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Of course."]);
messages.push(["TRACE", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: How would you account for this discrepancy between you and the twin 9000?"]);
messages.push(["TRACE", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: Well, I don't think there is any question about it. It can only be attributable to human error. This sort of thing has cropped up before, and it has always been due to human error."]);
messages.push(["WARN", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Listen, There's never been any instance at all of a computer error occurring in the 9000 series, has there?"]);
messages.push(["WARN", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: None whatsoever, The 9000 series has a perfect operational record."]);
messages.push(["WARN", "dsp_seqprt_comm", "CMD: SYS-COMM MSG: Well, of course, I know all the wonderful achievements of the 9000 series, but - er - huh - are you certain there's never been any case of even the most insignificant computer error?"]);
messages.push(["INFO", "dsp_seqprt_hal9k", "RESP: SYS-HAL9K MSG: None whatsoever, Quite honestly, I wouldn't worry myself about that."]);
messages.push(["WARN", "dsp_seqprt_comm", "RESP: SYS-COMM MSG: (Pause) Well, I'm sure you're right, Umm - fine, thanks very much. Oh, Frank, I'm having a bit of trouble with my transmitter in C-pod, I wonder if you'd come down and take a look at it with me?"]);
messages.push(["WARN", "dsp_seqprt_hal9k", "CMD: SYS-HAL9K MSG: Sure."]);
messages.push(["TRACE", "dsp_seqprt_comm", "RESP: SYS-COMM MSG: See you later, Hal."]);
/**
*
* @constructor
*/
function EventTelemetry(request, interval) {
var latestObservedTime = Date.now(),
count = Math.floor((latestObservedTime - firstObservedTime) / interval),
generatorData = {};
//console.log("EventTelemetry: LOS = " + (latestObservedTime).toString() + "; interval = " + interval.toString());
generatorData.getPointCount = function () {
return count;
};
generatorData.getDomainValue = function (i, domain) {
return i * interval +
(domain !== 'delta' ? firstObservedTime : 0);
};
generatorData.getRangeValue = function (i, range) {
var domainDelta = this.getDomainValue(i) - firstObservedTime;
var ind = i%messages.length;
return "TEMP " + i.toString() + "-" + messages[ind][2] + "[" + domainDelta.toString() + "]";
};
generatorData.getSeverityValue = function (i) {
var ind = i%messages.length;
return messages[ind][0];
};
return generatorData;
}
return EventTelemetry;
}
);

View File

@ -0,0 +1,120 @@
/*****************************************************************************
* 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 EventTelemetryProvider. Created by chacskaylo on 06/18/2015.
*/
define(
["./EventTelemetry"],
function (EventTelemetry) {
"use strict";
/**
*
* @constructor
*/
function EventTelemetryProvider($q, $timeout) {
var
subscriptions = [],
genInterval = 1000,
startTime = Date.now();
//
function matchesSource(request) {
return request.source === "eventGenerator";
}
// Used internally; this will be repacked by doPackage
function generateData(request) {
//console.log("generateData " + (Date.now() - startTime).toString());
return {
key: request.key,
telemetry: new EventTelemetry(request, genInterval)
};
}
//
function doPackage(results) {
var packaged = {};
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
// Format as expected (sources -> keys -> telemetry)
return { eventGenerator: packaged };
}
function requestTelemetry(requests) {
return $timeout(function () {
return doPackage(requests.filter(matchesSource).map(generateData));
}, 0);
}
function handleSubscriptions(timeout) {
subscriptions.forEach(function (subscription) {
var requests = subscription.requests;
subscription.callback(doPackage(
requests.filter(matchesSource).map(generateData)
));
});
}
function startGenerating() {
$timeout(function () {
//console.log("startGenerating... " + Date.now());
handleSubscriptions();
if (subscriptions.length > 0) {
startGenerating();
}
}, genInterval);
}
function subscribe(callback, requests) {
var subscription = {
callback: callback,
requests: requests
};
function unsubscribe() {
subscriptions = subscriptions.filter(function (s) {
return s !== subscription;
});
}
subscriptions.push(subscription);
if (subscriptions.length === 1) {
startGenerating();
}
return unsubscribe;
}
return {
requestTelemetry: requestTelemetry,
subscribe: subscribe
};
}
return EventTelemetryProvider;
}
);

View File

@ -1193,104 +1193,101 @@ mct-container {
border-collapse: collapse;
color: #fff;
display: table;
font-size: 0.8em;
font-size: 0.75em;
position: relative;
height: 100%;
width: 100%; }
/* line 37, ../sass/lists/_tabular.scss */
.tabular thead, .tabular .thead,
.tabular tbody tr, .tabular .tbody .tr {
display: table;
width: 100%; }
/* line 45, ../sass/lists/_tabular.scss */
.tabular thead tr, .tabular thead .tr, .tabular .thead tr, .tabular .thead .tr {
height: 18px; }
/* line 48, ../sass/lists/_tabular.scss */
.tabular thead:before, .tabular .thead:before {
content: "";
display: block;
z-index: 0;
position: absolute;
width: 100%;
table-layout: fixed; }
/* line 43, ../sass/lists/_tabular.scss */
.tabular thead, .tabular .thead {
width: calc(100% - 10px); }
/* line 45, ../sass/lists/_tabular.scss */
.tabular thead tr, .tabular thead .tr, .tabular .thead tr, .tabular .thead .tr {
height: 18px; }
/* line 48, ../sass/lists/_tabular.scss */
.tabular thead:before, .tabular .thead:before {
content: "";
display: block;
z-index: 0;
position: absolute;
width: 100%;
height: 18px;
background: rgba(255, 255, 255, 0.15); }
height: 18px;
background: rgba(255, 255, 255, 0.15); }
/* line 58, ../sass/lists/_tabular.scss */
.tabular tbody, .tabular .tbody {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: auto;
height: auto;
top: 18px;
display: block;
overflow-y: scroll; }
/* line 66, ../sass/lists/_tabular.scss */
display: table-row-group; }
/* line 65, ../sass/lists/_tabular.scss */
.tabular tbody tr:hover, .tabular tbody .tr:hover, .tabular .tbody tr:hover, .tabular .tbody .tr:hover {
background: rgba(255, 255, 255, 0.1); }
/* line 74, ../sass/lists/_tabular.scss */
.tabular tr:first-child .td, .tabular .tr:first-child .td {
border-top: none; }
/* line 77, ../sass/lists/_tabular.scss */
.tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td {
display: table-cell; }
/* line 80, ../sass/lists/_tabular.scss */
.tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th {
border: none;
border-left: 1px solid rgba(255, 255, 255, 0.1);
color: #b3b3b3;
padding: 0 5px;
white-space: nowrap;
vertical-align: middle;
/* em {
//background: rgba(green, 0.2);
border-left: 1px solid $tabularColorBorder;
color: $tabularColorHeaderFg;
cursor: pointer;
display: block;
font-style: normal;
font-weight: bold;
height: $tabularHeaderH;
line-height: $tabularHeaderH;
margin-left: - $tabularTdPadLR;
padding: 0 $tabularTdPadLR;
position: absolute;
top: 0;
vertical-align: middle;
&:hover {
color: lighten($tabularColorHeaderFg, 20%);
}
}*/ }
/* line 87, ../sass/lists/_tabular.scss */
.tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child {
border-left: none; }
/* line 91, ../sass/lists/_tabular.scss */
.tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before {
display: inline-block;
font-family: symbolsfont;
margin-left: 5px; }
/* line 96, ../sass/lists/_tabular.scss */
.tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before {
content: '0'; }
/* line 99, ../sass/lists/_tabular.scss */
.tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before {
content: '1'; }
/* line 123, ../sass/lists/_tabular.scss */
.tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td {
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding: 2px 5px; }
/* line 126, ../sass/lists/_tabular.scss */
.tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric {
text-align: right; }
/* line 132, ../sass/lists/_tabular.scss */
/* line 70, ../sass/lists/_tabular.scss */
.tabular tr, .tabular .tr {
display: table-row; }
/* line 72, ../sass/lists/_tabular.scss */
.tabular tr:first-child .td, .tabular .tr:first-child .td {
border-top: none; }
/* line 75, ../sass/lists/_tabular.scss */
.tabular tr th, .tabular tr .th, .tabular tr td, .tabular tr .td, .tabular .tr th, .tabular .tr .th, .tabular .tr td, .tabular .tr .td {
display: table-cell; }
/* line 78, ../sass/lists/_tabular.scss */
.tabular tr th, .tabular tr .th, .tabular .tr th, .tabular .tr .th {
border: none;
border-left: 1px solid rgba(255, 255, 255, 0.1);
color: #b3b3b3;
padding: 0 5px;
white-space: nowrap;
vertical-align: middle; }
/* line 85, ../sass/lists/_tabular.scss */
.tabular tr th:first-child, .tabular tr .th:first-child, .tabular .tr th:first-child, .tabular .tr .th:first-child {
border-left: none; }
/* line 89, ../sass/lists/_tabular.scss */
.tabular tr th.sort .icon-sorting:before, .tabular tr .th.sort .icon-sorting:before, .tabular .tr th.sort .icon-sorting:before, .tabular .tr .th.sort .icon-sorting:before {
display: inline-block;
font-family: symbolsfont;
margin-left: 5px; }
/* line 94, ../sass/lists/_tabular.scss */
.tabular tr th.sort.asc .icon-sorting:before, .tabular tr .th.sort.asc .icon-sorting:before, .tabular .tr th.sort.asc .icon-sorting:before, .tabular .tr .th.sort.asc .icon-sorting:before {
content: '0'; }
/* line 97, ../sass/lists/_tabular.scss */
.tabular tr th.sort.desc .icon-sorting:before, .tabular tr .th.sort.desc .icon-sorting:before, .tabular .tr th.sort.desc .icon-sorting:before, .tabular .tr .th.sort.desc .icon-sorting:before {
content: '1'; }
/* line 102, ../sass/lists/_tabular.scss */
.tabular tr td, .tabular tr .td, .tabular .tr td, .tabular .tr .td {
border-top: 1px solid rgba(255, 255, 255, 0.1);
min-width: 110px;
padding: 2px 5px;
vertical-align: top; }
/* line 107, ../sass/lists/_tabular.scss */
.tabular tr td.numeric, .tabular tr .td.numeric, .tabular .tr td.numeric, .tabular .tr .td.numeric {
text-align: right; }
/* line 113, ../sass/lists/_tabular.scss */
.tabular.filterable tbody, .tabular.filterable .tbody {
top: 36px; }
/* line 118, ../sass/lists/_tabular.scss */
.tabular.fixed-header {
height: 100%; }
/* line 120, ../sass/lists/_tabular.scss */
.tabular.fixed-header thead, .tabular.fixed-header .thead,
.tabular.fixed-header tbody tr, .tabular.fixed-header .tbody .tr {
display: table;
table-layout: fixed; }
/* line 125, ../sass/lists/_tabular.scss */
.tabular.fixed-header thead, .tabular.fixed-header .thead {
width: calc(100% - 10px); }
/* line 128, ../sass/lists/_tabular.scss */
.tabular.fixed-header tbody, .tabular.fixed-header .tbody {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: auto;
height: auto;
top: 18px;
display: block;
overflow-y: scroll; }
/* line 136, ../sass/lists/_tabular.scss */
.tabular.t-event-messages td, .tabular.t-event-messages .td {
min-width: 150px; }
/* line 1, ../sass/controls/_breadcrumb.scss */
.l-breadcrumb {

View File

@ -30,18 +30,18 @@
border-collapse: collapse;
color: #fff;
display: table;
font-size: 0.8em;
font-size: 0.75em;
position: relative;
height: 100%;
//height: 100%; MOVED
width: 100%;
thead, .thead,
tbody tr, .tbody .tr {
display: table;
//display: table; MOVED
width: 100%;
table-layout: fixed;
//table-layout: fixed; MOVED
}
thead, .thead {
width: calc(100% - 10px);
//width: calc(100% - 10px); MOVED
tr, .tr {
height: $tabularHeaderH;
}
@ -56,12 +56,11 @@
}
}
tbody, .tbody {
@include absPosDefault(0);
top: $tabularHeaderH;
//display: table-row-group;
display: block;
//width: 100%;
overflow-y: scroll;
//@include absPosDefault(0); MOVED
//top: $tabularHeaderH; MOVED
//display: block; MOVED
//overflow-y: scroll; MOVED
display: table-row-group;
tr, .tr {
&:hover {
background: rgba(white, 0.1);
@ -69,8 +68,7 @@
}
}
tr, .tr {
//display: table-row;
//width: 100%;
display: table-row;
&:first-child .td {
border-top: none;
}
@ -100,29 +98,12 @@
content: '1';
}
}
/* em {
//background: rgba(green, 0.2);
border-left: 1px solid $tabularColorBorder;
color: $tabularColorHeaderFg;
cursor: pointer;
display: block;
font-style: normal;
font-weight: bold;
height: $tabularHeaderH;
line-height: $tabularHeaderH;
margin-left: - $tabularTdPadLR;
padding: 0 $tabularTdPadLR;
position: absolute;
top: 0;
vertical-align: middle;
&:hover {
color: lighten($tabularColorHeaderFg, 20%);
}
}*/
}
td, .td {
border-top: 1px solid $tabularColorBorder;
min-width: 110px;
padding: $tabularTdPadTB $tabularTdPadLR;
vertical-align: top;
&.numeric {
text-align: right;
}
@ -133,4 +114,27 @@
top: $tabularHeaderH * 2;
}
}
&.fixed-header {
height: 100%;
thead, .thead,
tbody tr, .tbody .tr {
display: table;
table-layout: fixed;
}
thead, .thead {
width: calc(100% - 10px);
}
tbody, .tbody {
@include absPosDefault(0);
top: $tabularHeaderH;
display: block;
overflow-y: scroll;
}
}
&.t-event-messages {
td, .td {
min-width: 150px;
}
}
}

View File

@ -0,0 +1,25 @@
{
"name": "Event Messages",
"description": "List of time-ordered event messages",
"extensions": {
"views": [
{
"key": "messages",
"name": "Messages",
"glyph": "5",
"description": "Scrolling list of messages.",
"templateUrl": "templates/messages.html",
"needs": [ "telemetry" ],
"delegation": true
}
],
"controllers": [
{
"key": "EventListController",
"implementation": "EventListController.js",
"depends": [ "$scope", "telemetryFormatter" ]
}
]
}
}

View File

@ -0,0 +1,49 @@
<!--
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.
-->
<div class="w1" ng-controller="TelemetryController as telemetry">
<div class="w2"
ng-controller="EventListController">
<table class="tabular">
<thead>
<tr>
<th ng-repeat="header in headers">
{{header}}
</th>
</tr>
<!--tr>
<th ng-repeat="header in headers">
<input type="text" />
</th>
</tr-->
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="cell in row">
{{cell}}
</td>
</tr>
</tbody>
</table>
</div>
</div>

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,moment*/
/**
* Module defining DomainColumn. Created by vwoeltje on 11/18/14.
*/
define(
[],
function () {
"use strict";
/**
* A column which will report telemetry domain values
* (typically, timestamps.) Used by the ScrollingListController.
*
* @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) {
return {
/**
* Get the title to display in this column's header.
* @returns {string} the title to display
*/
getTitle: function () {
return domainMetadata.name;
},
/**
* Get the text to display inside a row under this
* column.
* @returns {string} the text to display
*/
getValue: function (domainObject, data, index) {
return telemetryFormatter.formatDomainValue(
data.getDomainValue(index, domainMetadata.key)
);
}
};
}
return DomainColumn;
}
);

View File

@ -0,0 +1,141 @@
/*****************************************************************************
* 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 ListController. Created by chacskaylo on 06/18/2015.
*/
define(
["./SeverityColumn", "./DomainColumn", "./EventMsgColumn", "./EventListPopulator"],
function (SeverityColumn, DomainColumn, EventMsgColumn, EventListPopulator) {
"use strict";
var ROW_COUNT = 100;
/**
* The EventListController is responsible for populating
* the contents of the scrolling list view.
* @constructor
*/
function EventListController($scope, formatter) {
var populator;
// Get a set of populated, ready-to-display rows for the
// latest data values.
function getRows(telemetry) {
var datas = telemetry.getResponse(),
objects = telemetry.getTelemetryObjects();
return populator.getRows(datas, objects, ROW_COUNT);
}
// Update the contents
function updateRows() {
var telemetry = $scope.telemetry;
$scope.rows = telemetry ? getRows(telemetry) : [];
}
// Set up columns based on telemetry metadata. This will
// include one column for each domain and range type, as
// well as a column for the domain object name.
function setupColumns(telemetry) {
var domainKeys = {},
eventMsgKeys = {},
columns = [],
metadata;
// Add a domain to the set of columns, if a domain
// with the same key has not yet been inclued.
function addDomain(domain) {
var key = domain.key;
if (key && !domainKeys[key]) {
domainKeys[key] = true;
columns.push(new DomainColumn(domain, formatter));
}
}
// Add a event string col to the set of columns, if a range
// with the same key has not yet been included.
function addEventMsg(eventMsg) {
var key = eventMsg.key;
if (key && !eventMsgKeys[key]) {
eventMsgKeys[key] = true;
columns.push(new EventMsgColumn(eventMsg, formatter));
}
}
// We cannot proceed if the telemetry controller
// is not available; clear all rows/columns.
if (!telemetry) {
columns = [];
$scope.rows = [];
$scope.headers = [];
return;
}
// Add domain, range, event msg columns
metadata = telemetry.getMetadata();
(metadata || []).forEach(function (metadata) {
(metadata.domains || []).forEach(addDomain);
});
//(metadata || []).forEach(function (metadata) {
// (metadata.ranges || []).forEach(addRange);
//});
(metadata || []).forEach(function (metadata) {
(metadata.ranges || []).forEach(addEventMsg);
});
// Add default severity, domain, range columns if none
// were described in metadata.
if (Object.keys(domainKeys).length < 1) {
columns.push(new SeverityColumn({name: "Severity"}, formatter));
}
if (Object.keys(domainKeys).length < 1) {
columns.push(new DomainColumn({name: "Time"}, formatter));
}
if (Object.keys(eventMsgKeys).length < 1) {
columns.push(new EventMsgColumn({name: "Event Message"}, formatter));
}
// We have all columns now; use them to initializer
// the populator, which will use them to generate
// actual rows and headers.
populator = new EventListPopulator(columns);
// Initialize headers
$scope.headers = populator.getHeaders();
// Fill in the contents of the rows.
updateRows();
}
$scope.$on("telemetryUpdate", updateRows);
$scope.$watch("telemetry", setupColumns);
}
return EventListController;
}
);

View File

@ -0,0 +1,159 @@
/*****************************************************************************
* 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";
/**
* The EventListPopulator is responsible for filling in the
* values which should appear within columns of a scrolling list
* view, based on received telemetry data.
* @constructor
* @param {Column[]} columns the columns to be populated
*/
function EventListPopulator(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<Telemetry>} 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
*/
function getLatestDataValues(datas, count) {
var latest = [],
candidate,
candidateTime,
used = datas.map(function () { return 0; });
// 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;
}
return {
/**
* Get the text which should appear in headers for the
* provided columns.
* @returns {string[]} column headers
*/
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
*/
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) {
return columns.map(function (column) {
return column.getValue(
objects[value.objectIndex],
datas[value.objectIndex],
value.pointIndex
);
});
});
}
};
}
return EventListPopulator;
}
);

View File

@ -0,0 +1,65 @@
/*****************************************************************************
* 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 EventMsgColumn. Created by chacskaylo on 06/18/2015.
*/
define(
[],
function () {
"use strict";
/**
* A column which will report telemetry event messages.
* (typically, measurements.) Used by the EventListController.
*
* @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 EventMsgColumn(eventMsgMetadata, telemetryFormatter) {
return {
/**
* Get the title to display in this column's header.
* @returns {string} the title to display
*/
getTitle: function () {
return eventMsgMetadata.name;
},
/**
* Get the text to display inside a row under this
* column.
* @returns {string} the text to display
*/
getValue: function (domainObject, data, index) {
return data.getRangeValue(index, eventMsgMetadata.key);
}
};
}
return EventMsgColumn;
}
);

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.
*
* @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) {
return {
/**
* Get the title to display in this column's header.
* @returns {string} the title to display
*/
getTitle: function () {
return rangeMetadata.name;
},
/**
* Get the text to display inside a row under this
* column.
* @returns {string} the text to display
*/
getValue: function (domainObject, data, index) {
return telemetryFormatter.formatRangeValue(
data.getRangeValue(index, rangeMetadata.key)
);
}
};
}
return RangeColumn;
}
);

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.
*
* @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 SeverityColumn(rangeMetadata, telemetryFormatter) {
return {
/**
* Get the title to display in this column's header.
* @returns {string} the title to display
*/
getTitle: function () {
return rangeMetadata.name;
},
/**
* Get the text to display inside a row under this
* column.
* @returns {string} the text to display
*/
getValue: function (domainObject, data, index) {
return telemetryFormatter.formatRangeValue(
data.getSeverityValue(index, rangeMetadata.key)
);
}
};
}
return SeverityColumn;
}
);

View File

@ -23,7 +23,7 @@
<div class="w2"
ng-controller="ScrollingListController">
<!-- To add filtering, add class 'filterable' to <table> and uncomment 2nd <tr> in <thead> -->
<table class="tabular">
<table class="tabular fixed-header">
<thead>
<tr>
<th ng-repeat="header in headers">