mirror of
https://github.com/nasa/openmct.git
synced 2025-06-26 03:00:13 +00:00
Compare commits
7 Commits
remove-ang
...
open1265-r
Author | SHA1 | Date | |
---|---|---|---|
3abb2f3070 | |||
1bc6ac8d0b | |||
453431e13b | |||
bbbbf1eab3 | |||
bde6ad9da2 | |||
7416cae097 | |||
59afbb9996 |
@ -1,48 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
"./src/LocalTimeSystem",
|
|
||||||
"./src/LocalTimeFormat",
|
|
||||||
'legacyRegistry'
|
|
||||||
], function (
|
|
||||||
LocalTimeSystem,
|
|
||||||
LocalTimeFormat,
|
|
||||||
legacyRegistry
|
|
||||||
) {
|
|
||||||
legacyRegistry.register("example/localTimeSystem", {
|
|
||||||
"extensions": {
|
|
||||||
"formats": [
|
|
||||||
{
|
|
||||||
"key": "local-format",
|
|
||||||
"implementation": LocalTimeFormat
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"timeSystems": [
|
|
||||||
{
|
|
||||||
"implementation": LocalTimeSystem,
|
|
||||||
"depends": ["$timeout"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,43 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(['../../../platform/features/conductor/core/src/timeSystems/LocalClock'], function (LocalClock) {
|
|
||||||
/**
|
|
||||||
* @implements TickSource
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function LADTickSource ($timeout, period) {
|
|
||||||
LocalClock.call(this, $timeout, period);
|
|
||||||
|
|
||||||
this.metadata = {
|
|
||||||
key: 'test-lad',
|
|
||||||
mode: 'lad',
|
|
||||||
cssClass: 'icon-clock',
|
|
||||||
label: 'Latest Available Data',
|
|
||||||
name: 'Latest available data',
|
|
||||||
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
LADTickSource.prototype = Object.create(LocalClock.prototype);
|
|
||||||
|
|
||||||
return LADTickSource;
|
|
||||||
});
|
|
@ -1,112 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'moment'
|
|
||||||
], function (
|
|
||||||
moment
|
|
||||||
) {
|
|
||||||
|
|
||||||
var DATE_FORMAT = "YYYY-MM-DD h:mm:ss.SSS a",
|
|
||||||
DATE_FORMATS = [
|
|
||||||
DATE_FORMAT,
|
|
||||||
"YYYY-MM-DD h:mm:ss a",
|
|
||||||
"YYYY-MM-DD h:mm a",
|
|
||||||
"YYYY-MM-DD"
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef Scale
|
|
||||||
* @property {number} min the minimum scale value, in ms
|
|
||||||
* @property {number} max the maximum scale value, in ms
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formatter for UTC timestamps. Interprets numeric values as
|
|
||||||
* milliseconds since the start of 1970.
|
|
||||||
*
|
|
||||||
* @implements {Format}
|
|
||||||
* @constructor
|
|
||||||
* @memberof platform/commonUI/formats
|
|
||||||
*/
|
|
||||||
function LocalTimeFormat() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an appropriate time format based on the provided value and
|
|
||||||
* the threshold required.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function getScaledFormat (d) {
|
|
||||||
var m = moment.utc(d);
|
|
||||||
/**
|
|
||||||
* Uses logic from d3 Time-Scales, v3 of the API. See
|
|
||||||
* https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Scales.md
|
|
||||||
*
|
|
||||||
* Licensed
|
|
||||||
*/
|
|
||||||
return [
|
|
||||||
[".SSS", function(m) { return m.milliseconds(); }],
|
|
||||||
[":ss", function(m) { return m.seconds(); }],
|
|
||||||
["hh:mma", function(m) { return m.minutes(); }],
|
|
||||||
["hha", function(m) { return m.hours(); }],
|
|
||||||
["ddd DD", function(m) {
|
|
||||||
return m.days() &&
|
|
||||||
m.date() != 1;
|
|
||||||
}],
|
|
||||||
["MMM DD", function(m) { return m.date() != 1; }],
|
|
||||||
["MMMM", function(m) {
|
|
||||||
return m.month();
|
|
||||||
}],
|
|
||||||
["YYYY", function() { return true; }]
|
|
||||||
].filter(function (row){
|
|
||||||
return row[1](m);
|
|
||||||
})[0][0];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* @param {Scale} [scale] Optionally provides context to the
|
|
||||||
* format request, allowing for scale-appropriate formatting.
|
|
||||||
* @returns {string} the formatted date
|
|
||||||
*/
|
|
||||||
LocalTimeFormat.prototype.format = function (value, scale) {
|
|
||||||
if (scale !== undefined){
|
|
||||||
var scaledFormat = getScaledFormat(value, scale);
|
|
||||||
if (scaledFormat) {
|
|
||||||
return moment.utc(value).format(scaledFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return moment(value).format(DATE_FORMAT);
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalTimeFormat.prototype.parse = function (text) {
|
|
||||||
return moment(text, DATE_FORMATS).valueOf();
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalTimeFormat.prototype.validate = function (text) {
|
|
||||||
return moment(text, DATE_FORMATS).isValid();
|
|
||||||
};
|
|
||||||
|
|
||||||
return LocalTimeFormat;
|
|
||||||
});
|
|
@ -1,79 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'../../../platform/features/conductor/core/src/timeSystems/TimeSystem',
|
|
||||||
'../../../platform/features/conductor/core/src/timeSystems/LocalClock',
|
|
||||||
'./LADTickSource'
|
|
||||||
], function (TimeSystem, LocalClock, LADTickSource) {
|
|
||||||
var THIRTY_MINUTES = 30 * 60 * 1000,
|
|
||||||
DEFAULT_PERIOD = 1000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This time system supports UTC dates and provides a ticking clock source.
|
|
||||||
* @implements TimeSystem
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function LocalTimeSystem ($timeout) {
|
|
||||||
TimeSystem.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some metadata, which will be used to identify the time system in
|
|
||||||
* the UI
|
|
||||||
* @type {{key: string, name: string, glyph: string}}
|
|
||||||
*/
|
|
||||||
this.metadata = {
|
|
||||||
'key': 'local',
|
|
||||||
'name': 'Local',
|
|
||||||
'glyph': '\u0043'
|
|
||||||
};
|
|
||||||
|
|
||||||
this.fmts = ['local-format'];
|
|
||||||
this.sources = [new LocalClock($timeout, DEFAULT_PERIOD), new LADTickSource($timeout, DEFAULT_PERIOD)];
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalTimeSystem.prototype = Object.create(TimeSystem.prototype);
|
|
||||||
|
|
||||||
LocalTimeSystem.prototype.formats = function () {
|
|
||||||
return this.fmts;
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalTimeSystem.prototype.deltaFormat = function () {
|
|
||||||
return 'duration';
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalTimeSystem.prototype.tickSources = function () {
|
|
||||||
return this.sources;
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalTimeSystem.prototype.defaults = function (key) {
|
|
||||||
var now = Math.ceil(Date.now() / 1000) * 1000;
|
|
||||||
return {
|
|
||||||
key: 'local-default',
|
|
||||||
name: 'Local 12 hour time system defaults',
|
|
||||||
deltas: {start: THIRTY_MINUTES, end: 0},
|
|
||||||
bounds: {start: now - THIRTY_MINUTES, end: now}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return LocalTimeSystem;
|
|
||||||
});
|
|
27
index.html
27
index.html
@ -28,7 +28,13 @@
|
|||||||
<script src="bower_components/requirejs/require.js">
|
<script src="bower_components/requirejs/require.js">
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
require(['openmct'], function (openmct) {
|
require([
|
||||||
|
'openmct',
|
||||||
|
'src/plugins/conductor/plugin'
|
||||||
|
], function (
|
||||||
|
openmct,
|
||||||
|
ConductorService
|
||||||
|
) {
|
||||||
[
|
[
|
||||||
'example/imagery',
|
'example/imagery',
|
||||||
'example/eventGenerator'
|
'example/eventGenerator'
|
||||||
@ -40,6 +46,25 @@
|
|||||||
openmct.install(openmct.plugins.Espresso());
|
openmct.install(openmct.plugins.Espresso());
|
||||||
openmct.install(openmct.plugins.Generator());
|
openmct.install(openmct.plugins.Generator());
|
||||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will be installed by default...somehow
|
||||||
|
*/
|
||||||
|
openmct.install(ConductorService());
|
||||||
|
|
||||||
|
var ONE_MINUTE = 60 * 1000;
|
||||||
|
var ONE_YEAR = 365 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// Will also provide a default configuration based on enabled time
|
||||||
|
// systems and tick sources.
|
||||||
|
openmct.install(openmct.plugins.Conductor({
|
||||||
|
menuOptions: [
|
||||||
|
// Default 'fixed' configuration shows last 30 mins of data. May also provide specific bounds.
|
||||||
|
{timeSystems: ['utc'], defaultOffsets: {start: 30 * ONE_MINUTE, end: 0}, zoomOutLimit: ONE_YEAR, zoomInLimit: ONE_MINUTE},
|
||||||
|
{tickSource: 'localClock', timeSystems: ['utc'], defaultOffsets: {start: 15 * ONE_MINUTE, end: 0}, zoomOut: ONE_YEAR, zoomIn: ONE_MINUTE},
|
||||||
|
{tickSource: 'latestAvailable', timeSystems: ['utc'], defaultOffsets: {start: 15 * 60 * 1000, end: 0}}
|
||||||
|
]
|
||||||
|
}));
|
||||||
openmct.start();
|
openmct.start();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -42,6 +42,7 @@ define([
|
|||||||
"type": "provider",
|
"type": "provider",
|
||||||
"implementation": FormatProvider,
|
"implementation": FormatProvider,
|
||||||
"depends": [
|
"depends": [
|
||||||
|
"openmct",
|
||||||
"formats[]"
|
"formats[]"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -89,22 +89,21 @@ define([
|
|||||||
* @param {Array.<function(new : Format)>} format constructors,
|
* @param {Array.<function(new : Format)>} format constructors,
|
||||||
* from the `formats` extension category.
|
* from the `formats` extension category.
|
||||||
*/
|
*/
|
||||||
function FormatProvider(formats) {
|
function FormatProvider(openmct, formats) {
|
||||||
var formatMap = {};
|
this.telemetryAPI = openmct.telemetry;
|
||||||
|
|
||||||
function addToMap(Format) {
|
function addToMap(Format) {
|
||||||
var key = Format.key;
|
var key = Format.key;
|
||||||
if (key && !formatMap[key]) {
|
if (key && !openmct.telemetry.getFormat(key)) {
|
||||||
formatMap[key] = new Format();
|
openmct.telemetry.addFormat(new Format());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formats.forEach(addToMap);
|
formats.forEach(addToMap);
|
||||||
this.formatMap = formatMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatProvider.prototype.getFormat = function (key) {
|
FormatProvider.prototype.getFormat = function (key) {
|
||||||
var format = this.formatMap[key];
|
var format = this.telemetryAPI.getFormat(key);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
throw new Error("FormatProvider: No format found for " + key);
|
throw new Error("FormatProvider: No format found for " + key);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ define([
|
|||||||
*
|
*
|
||||||
* Licensed
|
* Licensed
|
||||||
*/
|
*/
|
||||||
return [
|
var format = [
|
||||||
[".SSS", function (m) {
|
[".SSS", function (m) {
|
||||||
return m.milliseconds();
|
return m.milliseconds();
|
||||||
}],
|
}],
|
||||||
@ -93,62 +93,30 @@ define([
|
|||||||
].filter(function (row) {
|
].filter(function (row) {
|
||||||
return row[1](momentified);
|
return row[1](momentified);
|
||||||
})[0][0];
|
})[0][0];
|
||||||
|
|
||||||
|
if (format !== undefined) {
|
||||||
|
return moment.utc(value).format(scaledFormat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a description of the current range of the time conductor's
|
* @param {number} value The value to format.
|
||||||
* bounds.
|
* @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
* @param timeRange
|
* and plot axes. Specifies the smallest number on the scale.
|
||||||
* @returns {*}
|
* @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
|
* and plot axes. Specifies the largest number on the scale
|
||||||
|
* @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
|
* and plot axes. The number of labels on the scale.
|
||||||
|
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
|
||||||
|
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
||||||
|
* in the array.
|
||||||
*/
|
*/
|
||||||
UTCTimeFormat.prototype.timeUnits = function (timeRange) {
|
UTCTimeFormat.prototype.format = function (value, minValue, maxValue, count) {
|
||||||
var momentified = moment.duration(timeRange);
|
if (arguments.length > 1) {
|
||||||
|
return values.map(getScaledFormat);
|
||||||
return [
|
} else {
|
||||||
["Decades", function (r) {
|
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
||||||
return r.years() > 15;
|
|
||||||
}],
|
|
||||||
["Years", function (r) {
|
|
||||||
return r.years() > 1;
|
|
||||||
}],
|
|
||||||
["Months", function (r) {
|
|
||||||
return r.years() === 1 || r.months() > 1;
|
|
||||||
}],
|
|
||||||
["Days", function (r) {
|
|
||||||
return r.months() === 1 || r.days() > 1;
|
|
||||||
}],
|
|
||||||
["Hours", function (r) {
|
|
||||||
return r.days() === 1 || r.hours() > 1;
|
|
||||||
}],
|
|
||||||
["Minutes", function (r) {
|
|
||||||
return r.hours() === 1 || r.minutes() > 1;
|
|
||||||
}],
|
|
||||||
["Seconds", function (r) {
|
|
||||||
return r.minutes() === 1 || r.seconds() > 1;
|
|
||||||
}],
|
|
||||||
["Milliseconds", function (r) {
|
|
||||||
return true;
|
|
||||||
}]
|
|
||||||
].filter(function (row) {
|
|
||||||
return row[1](momentified);
|
|
||||||
})[0][0];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param value
|
|
||||||
* @param {Scale} [scale] Optionally provides context to the
|
|
||||||
* format request, allowing for scale-appropriate formatting.
|
|
||||||
* @returns {string} the formatted date
|
|
||||||
*/
|
|
||||||
UTCTimeFormat.prototype.format = function (value, scale) {
|
|
||||||
if (scale !== undefined) {
|
|
||||||
var scaledFormat = getScaledFormat(value, scale);
|
|
||||||
if (scaledFormat) {
|
|
||||||
return moment.utc(value).format(scaledFormat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
UTCTimeFormat.prototype.parse = function (text) {
|
UTCTimeFormat.prototype.parse = function (text) {
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([
|
||||||
"./src/ui/TimeConductorViewService",
|
|
||||||
"./src/ui/TimeConductorController",
|
"./src/ui/TimeConductorController",
|
||||||
"./src/ui/ConductorAxisController",
|
"./src/ui/ConductorAxisController",
|
||||||
"./src/ui/ConductorTOIController",
|
"./src/ui/ConductorTOIController",
|
||||||
@ -34,7 +33,6 @@ define([
|
|||||||
"text!./res/templates/time-of-interest.html",
|
"text!./res/templates/time-of-interest.html",
|
||||||
"legacyRegistry"
|
"legacyRegistry"
|
||||||
], function (
|
], function (
|
||||||
TimeConductorViewService,
|
|
||||||
TimeConductorController,
|
TimeConductorController,
|
||||||
ConductorAxisController,
|
ConductorAxisController,
|
||||||
ConductorTOIController,
|
ConductorTOIController,
|
||||||
@ -50,16 +48,6 @@ define([
|
|||||||
|
|
||||||
legacyRegistry.register("platform/features/conductor/core", {
|
legacyRegistry.register("platform/features/conductor/core", {
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"services": [
|
|
||||||
{
|
|
||||||
"key": "timeConductorViewService",
|
|
||||||
"implementation": TimeConductorViewService,
|
|
||||||
"depends": [
|
|
||||||
"openmct",
|
|
||||||
"timeSystems[]"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controllers": [
|
"controllers": [
|
||||||
{
|
{
|
||||||
"key": "TimeConductorController",
|
"key": "TimeConductorController",
|
||||||
@ -69,10 +57,8 @@ define([
|
|||||||
"$window",
|
"$window",
|
||||||
"$location",
|
"$location",
|
||||||
"openmct",
|
"openmct",
|
||||||
"timeConductorViewService",
|
"timeConductorService",
|
||||||
"formatService",
|
"formatService"
|
||||||
"DEFAULT_TIMECONDUCTOR_MODE",
|
|
||||||
"SHOW_TIMECONDUCTOR"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -81,7 +67,7 @@ define([
|
|||||||
"depends": [
|
"depends": [
|
||||||
"$scope",
|
"$scope",
|
||||||
"openmct",
|
"openmct",
|
||||||
"timeConductorViewService",
|
"timeConductorService",
|
||||||
"formatService"
|
"formatService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -22,19 +22,18 @@
|
|||||||
<div class="contents">
|
<div class="contents">
|
||||||
<div class="pane left menu-items">
|
<div class="pane left menu-items">
|
||||||
<ul>
|
<ul>
|
||||||
<li ng-repeat="(key, metadata) in ngModel.options"
|
<li ng-repeat="option in ngModel.options"
|
||||||
ng-click="ngModel.selectedKey=key">
|
ng-click="ngModel.selectedKey=key">
|
||||||
<a ng-mouseover="ngModel.activeMetadata = metadata"
|
<a ng-mouseover="ngModel.activeMetadata = option"
|
||||||
ng-mouseleave="ngModel.activeMetadata = undefined"
|
ng-mouseleave="ngModel.activeMetadata = undefined"
|
||||||
class="menu-item-a {{metadata.cssClass}}">
|
class="menu-item-a {{ngModel.activeMetadata.cssClass}}">
|
||||||
{{metadata.name}}
|
{{option.name}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="pane right menu-item-description">
|
<div class="pane right menu-item-description">
|
||||||
<div
|
<div class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssClass}}"></div>
|
||||||
class="desc-area ui-symbol icon type-icon {{ngModel.activeMetadata.cssClass}}"></div>
|
|
||||||
<div class="desc-area title">
|
<div class="desc-area title">
|
||||||
{{ngModel.activeMetadata.name}}
|
{{ngModel.activeMetadata.name}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,14 +19,13 @@
|
|||||||
this source code distribution or the Licensing information page available
|
this source code distribution or the Licensing information page available
|
||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<span ng-controller="ClickAwayController as modeController">
|
<span ng-controller="ClickAwayController as sourceController">
|
||||||
<div class="s-menu-button"
|
<div class="s-menu-button"
|
||||||
ng-click="modeController.toggle()">
|
ng-click="sourceController.toggle()">
|
||||||
<span class="title-label">{{ngModel.options[ngModel.selectedKey]
|
<span class="title-label">{{ngModel.sources[ngModel.selectedSource].name}}</span>
|
||||||
.label}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="menu super-menu mini mode-selector-menu"
|
<div class="menu super-menu mini mode-selector-menu"
|
||||||
ng-show="modeController.isActive()">
|
ng-show="sourceController.isActive()">
|
||||||
<mct-include key="'mode-menu'"
|
<mct-include key="'mode-menu'"
|
||||||
ng-model="ngModel">
|
ng-model="ngModel">
|
||||||
</mct-include>
|
</mct-include>
|
||||||
|
@ -99,7 +99,7 @@
|
|||||||
<div class="l-time-conductor-controls l-row-elem l-flex-row flex-elem">
|
<div class="l-time-conductor-controls l-row-elem l-flex-row flex-elem">
|
||||||
<mct-include
|
<mct-include
|
||||||
key="'mode-selector'"
|
key="'mode-selector'"
|
||||||
ng-model="modeModel"
|
ng-model="sourceModel"
|
||||||
class="holder flex-elem menus-up mode-selector">
|
class="holder flex-elem menus-up mode-selector">
|
||||||
</mct-include>
|
</mct-include>
|
||||||
<mct-control
|
<mct-control
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(['./TickSource'], function (TickSource) {
|
|
||||||
/**
|
|
||||||
* @implements TickSource
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function LocalClock($timeout, period) {
|
|
||||||
TickSource.call(this);
|
|
||||||
|
|
||||||
this.metadata = {
|
|
||||||
key: 'local',
|
|
||||||
mode: 'realtime',
|
|
||||||
cssClass: 'icon-clock',
|
|
||||||
label: 'Real-time',
|
|
||||||
name: 'Real-time Mode',
|
|
||||||
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
|
|
||||||
};
|
|
||||||
|
|
||||||
this.period = period;
|
|
||||||
this.$timeout = $timeout;
|
|
||||||
this.timeoutHandle = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalClock.prototype = Object.create(TickSource.prototype);
|
|
||||||
|
|
||||||
LocalClock.prototype.start = function () {
|
|
||||||
this.timeoutHandle = this.$timeout(this.tick.bind(this), this.period);
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalClock.prototype.stop = function () {
|
|
||||||
if (this.timeoutHandle) {
|
|
||||||
this.$timeout.cancel(this.timeoutHandle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LocalClock.prototype.tick = function () {
|
|
||||||
var now = Date.now();
|
|
||||||
this.listeners.forEach(function (listener) {
|
|
||||||
listener(now);
|
|
||||||
});
|
|
||||||
this.timeoutHandle = this.$timeout(this.tick.bind(this), this.period);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a listener for the local clock. When it ticks, the local
|
|
||||||
* clock will provide the current local system time
|
|
||||||
*
|
|
||||||
* @param listener
|
|
||||||
* @returns {function} a function for deregistering the provided listener
|
|
||||||
*/
|
|
||||||
LocalClock.prototype.listen = function (listener) {
|
|
||||||
var listeners = this.listeners;
|
|
||||||
listeners.push(listener);
|
|
||||||
|
|
||||||
if (listeners.length === 1) {
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
return function () {
|
|
||||||
listeners.splice(listeners.indexOf(listener));
|
|
||||||
if (listeners.length === 0) {
|
|
||||||
this.stop();
|
|
||||||
}
|
|
||||||
}.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
return LocalClock;
|
|
||||||
});
|
|
@ -1,50 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(["./LocalClock"], function (LocalClock) {
|
|
||||||
describe("The LocalClock class", function () {
|
|
||||||
var clock,
|
|
||||||
mockTimeout,
|
|
||||||
timeoutHandle = {};
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockTimeout = jasmine.createSpy("timeout");
|
|
||||||
mockTimeout.andReturn(timeoutHandle);
|
|
||||||
mockTimeout.cancel = jasmine.createSpy("cancel");
|
|
||||||
|
|
||||||
clock = new LocalClock(mockTimeout, 0);
|
|
||||||
clock.start();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("calls listeners on tick with current time", function () {
|
|
||||||
var mockListener = jasmine.createSpy("listener");
|
|
||||||
clock.listen(mockListener);
|
|
||||||
clock.tick();
|
|
||||||
expect(mockListener).toHaveBeenCalledWith(jasmine.any(Number));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("stops ticking when stop is called", function () {
|
|
||||||
clock.stop();
|
|
||||||
expect(mockTimeout.cancel).toHaveBeenCalledWith(timeoutHandle);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,47 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([], function () {
|
|
||||||
/**
|
|
||||||
* A tick source is an event generator such as a timing signal, or
|
|
||||||
* indicator of data availability, which can be used to advance the Time
|
|
||||||
* Conductor. Usage is simple, a listener registers a callback which is
|
|
||||||
* invoked when this source 'ticks'.
|
|
||||||
*
|
|
||||||
* @interface
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function TickSource() {
|
|
||||||
this.listeners = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param callback Function to be called when this tick source ticks.
|
|
||||||
* @returns an 'unlisten' function that will remove the callback from
|
|
||||||
* the registered listeners
|
|
||||||
*/
|
|
||||||
TickSource.prototype.listen = function (callback) {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
};
|
|
||||||
|
|
||||||
return TickSource;
|
|
||||||
});
|
|
@ -1,107 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([], function () {
|
|
||||||
/**
|
|
||||||
* @interface
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function TimeSystem() {
|
|
||||||
/**
|
|
||||||
* @typedef TimeSystemMetadata
|
|
||||||
* @property {string} key
|
|
||||||
* @property {string} name
|
|
||||||
* @property {string} description
|
|
||||||
*
|
|
||||||
* @type {TimeSystemMetadata}
|
|
||||||
*/
|
|
||||||
this.metadata = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time formats are defined as extensions. Time systems that implement
|
|
||||||
* this interface should provide an array of format keys supported by them.
|
|
||||||
*
|
|
||||||
* @returns {string[]} An array of time format keys
|
|
||||||
*/
|
|
||||||
TimeSystem.prototype.formats = function () {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef DeltaFormat
|
|
||||||
* @property {string} type the type of MctControl used to represent this
|
|
||||||
* field. Typically 'datetime-field' for UTC based dates, or 'textfield'
|
|
||||||
* otherwise
|
|
||||||
* @property {string} [format] An optional field specifying the
|
|
||||||
* Format to use for delta fields in this time system.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Specifies a format for deltas in this time system.
|
|
||||||
*
|
|
||||||
* @returns {DeltaFormat} a delta format specifier
|
|
||||||
*/
|
|
||||||
TimeSystem.prototype.deltaFormat = function () {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the tick sources supported by this time system. Tick sources
|
|
||||||
* are event generators that can be used to advance the time conductor
|
|
||||||
* @returns {TickSource[]} The tick sources supported by this time system.
|
|
||||||
*/
|
|
||||||
TimeSystem.prototype.tickSources = function () {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
};
|
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
* @typedef {object} TimeConductorZoom
|
|
||||||
* @property {number} min The largest time span that the time
|
|
||||||
* conductor can display in this time system. ie. the span of the time
|
|
||||||
* conductor in its most zoomed out state.
|
|
||||||
* @property {number} max The smallest time span that the time
|
|
||||||
* conductor can display in this time system. ie. the span of the time
|
|
||||||
* conductor bounds in its most zoomed in state.
|
|
||||||
*
|
|
||||||
* @typedef {object} TimeSystemDefault
|
|
||||||
* @property {TimeConductorDeltas} deltas The deltas to apply by default
|
|
||||||
* when this time system is active. Applies to real-time modes only
|
|
||||||
* @property {TimeConductorBounds} bounds The bounds to apply by default
|
|
||||||
* when this time system is active
|
|
||||||
* @property {TimeConductorZoom} zoom Default min and max zoom levels
|
|
||||||
* @returns {TimeSystemDefault[]} At least one set of default values for
|
|
||||||
* this time system.
|
|
||||||
*/
|
|
||||||
TimeSystem.prototype.defaults = function () {
|
|
||||||
throw new Error('Not implemented');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
TimeSystem.prototype.isUTCBased = function () {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return TimeSystem;
|
|
||||||
});
|
|
@ -137,7 +137,7 @@ define(
|
|||||||
ConductorAxisController.prototype.changeTimeSystem = function (timeSystem) {
|
ConductorAxisController.prototype.changeTimeSystem = function (timeSystem) {
|
||||||
this.timeSystem = timeSystem;
|
this.timeSystem = timeSystem;
|
||||||
|
|
||||||
var key = timeSystem.formats()[0];
|
var key = timeSystem.format;
|
||||||
if (key !== undefined) {
|
if (key !== undefined) {
|
||||||
var format = this.formatService.getFormat(key);
|
var format = this.formatService.getFormat(key);
|
||||||
var bounds = this.conductor.bounds();
|
var bounds = this.conductor.bounds();
|
||||||
@ -158,10 +158,7 @@ define(
|
|||||||
if (tickValue instanceof Date) {
|
if (tickValue instanceof Date) {
|
||||||
tickValue = tickValue.getTime();
|
tickValue = tickValue.getTime();
|
||||||
}
|
}
|
||||||
return format.format(tickValue, {
|
return format.format(tickValue, bounds.start, bounds.end);
|
||||||
min: bounds.start,
|
|
||||||
max: bounds.end
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
this.axisElement.call(this.xAxis);
|
this.axisElement.call(this.xAxis);
|
||||||
}
|
}
|
||||||
@ -210,7 +207,7 @@ define(
|
|||||||
* Initiate panning via a click + drag gesture on the time conductor
|
* Initiate panning via a click + drag gesture on the time conductor
|
||||||
* scale. Panning triggers a "pan" event
|
* scale. Panning triggers a "pan" event
|
||||||
* @param {number} delta the offset from the original click event
|
* @param {number} delta the offset from the original click event
|
||||||
* @see TimeConductorViewService#
|
* @see TimeConductorService
|
||||||
* @fires platform.features.conductor.ConductorAxisController~pan
|
* @fires platform.features.conductor.ConductorAxisController~pan
|
||||||
*/
|
*/
|
||||||
ConductorAxisController.prototype.pan = function (delta) {
|
ConductorAxisController.prototype.pan = function (delta) {
|
||||||
|
@ -32,7 +32,7 @@ define(['./ConductorAxisController'], function (ConductorAxisController) {
|
|||||||
controller: [
|
controller: [
|
||||||
'openmct',
|
'openmct',
|
||||||
'formatService',
|
'formatService',
|
||||||
'timeConductorViewService',
|
'timeConductorService',
|
||||||
'$scope',
|
'$scope',
|
||||||
'$element',
|
'$element',
|
||||||
ConductorAxisController
|
ConductorAxisController
|
||||||
|
@ -45,10 +45,8 @@ define(
|
|||||||
$window,
|
$window,
|
||||||
$location,
|
$location,
|
||||||
openmct,
|
openmct,
|
||||||
conductorViewService,
|
conductorService,
|
||||||
formatService,
|
formatService
|
||||||
DEFAULT_MODE,
|
|
||||||
SHOW_TIMECONDUCTOR
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -63,20 +61,14 @@ define(
|
|||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.$window = $window;
|
this.$window = $window;
|
||||||
this.$location = $location;
|
this.$location = $location;
|
||||||
this.conductorViewService = conductorViewService;
|
this.conductorService = conductorService;
|
||||||
this.conductor = openmct.conductor;
|
this.conductor = openmct.conductor;
|
||||||
this.modes = conductorViewService.availableModes();
|
this.modes = conductorService.availableModes();
|
||||||
this.validation = new TimeConductorValidation(this.conductor);
|
this.validation = new TimeConductorValidation(this.conductor);
|
||||||
this.formatService = formatService;
|
this.formatService = formatService;
|
||||||
|
|
||||||
//Check if the default mode defined is actually available
|
|
||||||
if (this.modes[DEFAULT_MODE] === undefined) {
|
|
||||||
DEFAULT_MODE = 'fixed';
|
|
||||||
}
|
|
||||||
this.DEFAULT_MODE = DEFAULT_MODE;
|
|
||||||
|
|
||||||
// Construct the provided time system definitions
|
// Construct the provided time system definitions
|
||||||
this.timeSystems = conductorViewService.systems;
|
this.sourceModel.sources = conductorService.availableTickSources();
|
||||||
|
|
||||||
this.initializeScope();
|
this.initializeScope();
|
||||||
var searchParams = JSON.parse(JSON.stringify(this.$location.search()));
|
var searchParams = JSON.parse(JSON.stringify(this.$location.search()));
|
||||||
@ -89,7 +81,7 @@ define(
|
|||||||
this.changeTimeSystem(this.conductor.timeSystem());
|
this.changeTimeSystem(this.conductor.timeSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
var deltas = this.conductorViewService.deltas();
|
var deltas = this.conductorService.deltas();
|
||||||
if (deltas) {
|
if (deltas) {
|
||||||
this.setFormFromDeltas(deltas);
|
this.setFormFromDeltas(deltas);
|
||||||
}
|
}
|
||||||
@ -107,8 +99,6 @@ define(
|
|||||||
//Respond to any subsequent conductor changes
|
//Respond to any subsequent conductor changes
|
||||||
this.conductor.on('bounds', this.changeBounds);
|
this.conductor.on('bounds', this.changeBounds);
|
||||||
this.conductor.on('timeSystem', this.changeTimeSystem);
|
this.conductor.on('timeSystem', this.changeTimeSystem);
|
||||||
|
|
||||||
this.$scope.showTimeConductor = SHOW_TIMECONDUCTOR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,14 +128,14 @@ define(
|
|||||||
//Represents the various modes, and the currently selected mode
|
//Represents the various modes, and the currently selected mode
|
||||||
//in the view
|
//in the view
|
||||||
this.$scope.modeModel = {
|
this.$scope.modeModel = {
|
||||||
options: this.conductorViewService.availableModes()
|
options: this.conductorService.availableModes()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Watch scope for selection of mode or time system by user
|
// Watch scope for selection of mode or time system by user
|
||||||
this.$scope.$watch('modeModel.selectedKey', this.setMode);
|
this.$scope.$watch('modeModel.selectedKey', this.setMode);
|
||||||
|
|
||||||
this.conductorViewService.on('pan', this.onPan);
|
this.conductorService.on('pan', this.onPan);
|
||||||
this.conductorViewService.on('pan-stop', this.onPanStop);
|
this.conductorService.on('pan-stop', this.onPanStop);
|
||||||
|
|
||||||
this.$scope.$on('$destroy', this.destroy);
|
this.$scope.$on('$destroy', this.destroy);
|
||||||
};
|
};
|
||||||
@ -158,7 +148,7 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (searchParams[SEARCH.TIME_SYSTEM] &&
|
if (searchParams[SEARCH.TIME_SYSTEM] &&
|
||||||
searchParams[SEARCH.TIME_SYSTEM] !== this.conductor.timeSystem().metadata.key) {
|
searchParams[SEARCH.TIME_SYSTEM] !== this.conductor.timeSystem().key) {
|
||||||
//Will select the specified time system on the conductor
|
//Will select the specified time system on the conductor
|
||||||
this.selectTimeSystemByKey(searchParams[SEARCH.TIME_SYSTEM]);
|
this.selectTimeSystemByKey(searchParams[SEARCH.TIME_SYSTEM]);
|
||||||
}
|
}
|
||||||
@ -198,8 +188,8 @@ define(
|
|||||||
this.conductor.off('bounds', this.changeBounds);
|
this.conductor.off('bounds', this.changeBounds);
|
||||||
this.conductor.off('timeSystem', this.changeTimeSystem);
|
this.conductor.off('timeSystem', this.changeTimeSystem);
|
||||||
|
|
||||||
this.conductorViewService.off('pan', this.onPan);
|
this.conductorService.off('pan', this.onPan);
|
||||||
this.conductorViewService.off('pan-stop', this.onPanStop);
|
this.conductorService.off('pan-stop', this.onPanStop);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,7 +201,7 @@ define(
|
|||||||
//If a zoom or pan is currently in progress, do not override form values.
|
//If a zoom or pan is currently in progress, do not override form values.
|
||||||
if (!this.zooming && !this.panning) {
|
if (!this.zooming && !this.panning) {
|
||||||
this.setFormFromBounds(bounds);
|
this.setFormFromBounds(bounds);
|
||||||
if (this.conductorViewService.mode() === 'fixed') {
|
if (this.conductorService.mode() === 'fixed') {
|
||||||
//Set bounds in URL on change
|
//Set bounds in URL on change
|
||||||
this.setParam(SEARCH.START_BOUND, bounds.start);
|
this.setParam(SEARCH.START_BOUND, bounds.start);
|
||||||
this.setParam(SEARCH.END_BOUND, bounds.end);
|
this.setParam(SEARCH.END_BOUND, bounds.end);
|
||||||
@ -244,21 +234,6 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* On mode change, populate form based on time systems available
|
|
||||||
* from the selected mode.
|
|
||||||
* @param mode
|
|
||||||
*/
|
|
||||||
TimeConductorController.prototype.setFormFromMode = function (mode) {
|
|
||||||
this.$scope.modeModel.selectedKey = mode;
|
|
||||||
//Synchronize scope with time system on mode
|
|
||||||
this.$scope.timeSystemModel.options =
|
|
||||||
this.conductorViewService.availableTimeSystems()
|
|
||||||
.map(function (t) {
|
|
||||||
return t.metadata;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the deltas change, update the values in the UI
|
* When the deltas change, update the values in the UI
|
||||||
* @private
|
* @private
|
||||||
@ -308,7 +283,7 @@ define(
|
|||||||
};
|
};
|
||||||
if (this.validation.validateStartDelta(deltas.start) && this.validation.validateEndDelta(deltas.end)) {
|
if (this.validation.validateStartDelta(deltas.start) && this.validation.validateEndDelta(deltas.end)) {
|
||||||
//Sychronize deltas between form and mode
|
//Sychronize deltas between form and mode
|
||||||
this.conductorViewService.deltas(deltas);
|
this.conductorService.deltas(deltas);
|
||||||
|
|
||||||
//Set Deltas in URL on change
|
//Set Deltas in URL on change
|
||||||
this.setParam(SEARCH.START_DELTA, deltas.start);
|
this.setParam(SEARCH.START_DELTA, deltas.start);
|
||||||
@ -316,39 +291,6 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the selected Time Conductor mode. This will call destroy
|
|
||||||
* and initialization functions on the relevant modes, setting
|
|
||||||
* default values for bound and deltas in the form.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param newModeKey
|
|
||||||
* @param oldModeKey
|
|
||||||
*/
|
|
||||||
TimeConductorController.prototype.setMode = function (newModeKey, oldModeKey) {
|
|
||||||
//Set mode in URL on change
|
|
||||||
this.setParam(SEARCH.MODE, newModeKey);
|
|
||||||
|
|
||||||
if (newModeKey !== oldModeKey) {
|
|
||||||
this.conductorViewService.mode(newModeKey);
|
|
||||||
this.setFormFromMode(newModeKey);
|
|
||||||
|
|
||||||
if (newModeKey === "fixed") {
|
|
||||||
this.setParam(SEARCH.START_DELTA, undefined);
|
|
||||||
this.setParam(SEARCH.END_DELTA, undefined);
|
|
||||||
} else {
|
|
||||||
this.setParam(SEARCH.START_BOUND, undefined);
|
|
||||||
this.setParam(SEARCH.END_BOUND, undefined);
|
|
||||||
|
|
||||||
var deltas = this.conductorViewService.deltas();
|
|
||||||
if (deltas) {
|
|
||||||
this.setParam(SEARCH.START_DELTA, deltas.start);
|
|
||||||
this.setParam(SEARCH.END_DELTA, deltas.end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Respond to time system selection from UI
|
* Respond to time system selection from UI
|
||||||
*
|
*
|
||||||
@ -432,7 +374,7 @@ define(
|
|||||||
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
|
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
|
||||||
var timeSpan = Math.pow((1 - sliderValue), 4) * (zoomDefaults.min - zoomDefaults.max);
|
var timeSpan = Math.pow((1 - sliderValue), 4) * (zoomDefaults.min - zoomDefaults.max);
|
||||||
|
|
||||||
var zoom = this.conductorViewService.zoom(timeSpan);
|
var zoom = this.conductorService.zoom(timeSpan);
|
||||||
|
|
||||||
this.$scope.boundsModel.start = zoom.bounds.start;
|
this.$scope.boundsModel.start = zoom.bounds.start;
|
||||||
this.$scope.boundsModel.end = zoom.bounds.end;
|
this.$scope.boundsModel.end = zoom.bounds.end;
|
||||||
@ -457,7 +399,7 @@ define(
|
|||||||
this.setDeltas(this.$scope.boundsModel);
|
this.setDeltas(this.$scope.boundsModel);
|
||||||
this.zooming = false;
|
this.zooming = false;
|
||||||
|
|
||||||
this.conductorViewService.emit('zoom-stop');
|
this.conductorService.emit('zoom-stop');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,25 +153,6 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {number} time some value that is valid in the current TimeSystem
|
|
||||||
*/
|
|
||||||
TimeConductorMode.prototype.tick = function (time) {
|
|
||||||
var deltas = this.deltas();
|
|
||||||
var startTime = time;
|
|
||||||
var endTime = time;
|
|
||||||
|
|
||||||
if (deltas) {
|
|
||||||
startTime = time - deltas.start;
|
|
||||||
endTime = time + deltas.end;
|
|
||||||
}
|
|
||||||
this.conductor.bounds({
|
|
||||||
start: startTime,
|
|
||||||
end: endTime
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get or set the current value for the deltas used by this time system.
|
* Get or set the current value for the deltas used by this time system.
|
||||||
* On change, the new deltas will be used to calculate and set the
|
* On change, the new deltas will be used to calculate and set the
|
||||||
|
@ -1,229 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[
|
|
||||||
'EventEmitter',
|
|
||||||
'./TimeConductorMode'
|
|
||||||
],
|
|
||||||
function (EventEmitter, TimeConductorMode) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class representing the state of the time conductor view. This
|
|
||||||
* exposes details of the UI that are not represented on the
|
|
||||||
* TimeConductor API itself such as modes and deltas.
|
|
||||||
*
|
|
||||||
* @memberof platform.features.conductor
|
|
||||||
* @param conductor
|
|
||||||
* @param timeSystems
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function TimeConductorViewService(openmct, timeSystems) {
|
|
||||||
|
|
||||||
EventEmitter.call(this);
|
|
||||||
|
|
||||||
this.systems = timeSystems.map(function (timeSystemConstructor) {
|
|
||||||
return timeSystemConstructor();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.conductor = openmct.conductor;
|
|
||||||
this.currentMode = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} ModeMetadata
|
|
||||||
* @property {string} key A unique identifying key for this mode
|
|
||||||
* @property {string} cssClass The css class for the glyph
|
|
||||||
* representing this mode
|
|
||||||
* @property {string} label A short label for this mode
|
|
||||||
* @property {string} name A longer name for the mode
|
|
||||||
* @property {string} description A description of the mode
|
|
||||||
*/
|
|
||||||
this.availModes = {
|
|
||||||
'fixed': {
|
|
||||||
key: 'fixed',
|
|
||||||
cssClass: 'icon-calendar',
|
|
||||||
label: 'Fixed',
|
|
||||||
name: 'Fixed Timespan Mode',
|
|
||||||
description: 'Query and explore data that falls between two fixed datetimes.'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function hasTickSource(sourceType, timeSystem) {
|
|
||||||
return timeSystem.tickSources().some(function (tickSource) {
|
|
||||||
return tickSource.metadata.mode === sourceType;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeSystemsForMode = function (sourceType) {
|
|
||||||
return this.systems.filter(hasTickSource.bind(this, sourceType));
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
//Only show 'real-time mode' if appropriate time systems available
|
|
||||||
if (timeSystemsForMode('realtime').length > 0) {
|
|
||||||
var realtimeMode = {
|
|
||||||
key: 'realtime',
|
|
||||||
cssClass: 'icon-clock',
|
|
||||||
label: 'Real-time',
|
|
||||||
name: 'Real-time Mode',
|
|
||||||
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
|
|
||||||
};
|
|
||||||
this.availModes[realtimeMode.key] = realtimeMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Only show 'LAD mode' if appropriate time systems available
|
|
||||||
if (timeSystemsForMode('lad').length > 0) {
|
|
||||||
var ladMode = {
|
|
||||||
key: 'lad',
|
|
||||||
cssClass: 'icon-database',
|
|
||||||
label: 'LAD',
|
|
||||||
name: 'LAD Mode',
|
|
||||||
description: 'Latest Available Data mode monitors real-time streaming data as it comes in. The Time Conductor and displays will only advance when data becomes available.'
|
|
||||||
};
|
|
||||||
this.availModes[ladMode.key] = ladMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeConductorViewService.prototype = Object.create(EventEmitter.prototype);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter/Setter for the Time Conductor Mode. Modes determine the
|
|
||||||
* behavior of the time conductor, especially with regards to the
|
|
||||||
* bounds and how they change with time.
|
|
||||||
*
|
|
||||||
* In fixed mode, the bounds do not change with time, but can be
|
|
||||||
* modified by the used
|
|
||||||
*
|
|
||||||
* In realtime mode, the bounds change with time. Bounds are not
|
|
||||||
* directly modifiable by the user, however deltas can be.
|
|
||||||
*
|
|
||||||
* In Latest Available Data (LAD) mode, the bounds are updated when
|
|
||||||
* data is received. As with realtime mode the
|
|
||||||
*
|
|
||||||
* @param {string} newModeKey One of 'fixed', 'realtime', or 'LAD'
|
|
||||||
* @returns {string} the current mode, one of 'fixed', 'realtime',
|
|
||||||
* or 'LAD'.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
TimeConductorViewService.prototype.mode = function (newModeKey) {
|
|
||||||
function contains(timeSystems, ts) {
|
|
||||||
return timeSystems.filter(function (t) {
|
|
||||||
return t.metadata.key === ts.metadata.key;
|
|
||||||
}).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments.length === 1) {
|
|
||||||
var timeSystem = this.conductor.timeSystem();
|
|
||||||
var modes = this.availableModes();
|
|
||||||
var modeMetaData = modes[newModeKey];
|
|
||||||
|
|
||||||
if (this.currentMode) {
|
|
||||||
this.currentMode.destroy();
|
|
||||||
}
|
|
||||||
this.currentMode = new TimeConductorMode(modeMetaData, this.conductor, this.systems);
|
|
||||||
|
|
||||||
// If no time system set on time conductor, or the currently selected time system is not available in
|
|
||||||
// the new mode, default to first available time system
|
|
||||||
if (!timeSystem || !contains(this.currentMode.availableTimeSystems(), timeSystem)) {
|
|
||||||
timeSystem = this.currentMode.availableTimeSystems()[0];
|
|
||||||
this.conductor.timeSystem(timeSystem, timeSystem.defaults().bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.currentMode ? this.currentMode.metadata().key : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {object} TimeConductorDeltas
|
|
||||||
* @property {number} start Used to set the start bound of the
|
|
||||||
* TimeConductor on tick. A positive value that will be subtracted
|
|
||||||
* from the value provided by a tick source to determine the start
|
|
||||||
* bound.
|
|
||||||
* @property {number} end Used to set the end bound of the
|
|
||||||
* TimeConductor on tick. A positive value that will be added
|
|
||||||
* from the value provided by a tick source to determine the start
|
|
||||||
* bound.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Deltas define the offset from the latest time value provided by
|
|
||||||
* the current tick source. Deltas are only valid in realtime or LAD
|
|
||||||
* modes.
|
|
||||||
*
|
|
||||||
* Realtime mode:
|
|
||||||
* - start: A time in ms before now which will be used to
|
|
||||||
* determine the 'start' bound on tick
|
|
||||||
* - end: A time in ms after now which will be used to determine
|
|
||||||
* the 'end' bound on tick
|
|
||||||
*
|
|
||||||
* LAD mode:
|
|
||||||
* - start: A time in ms before the timestamp of the last data
|
|
||||||
* received which will be used to determine the 'start' bound on
|
|
||||||
* tick
|
|
||||||
* - end: A time in ms after the timestamp of the last data received
|
|
||||||
* which will be used to determine the 'end' bound on tick
|
|
||||||
* @returns {TimeConductorDeltas} current value of the deltas
|
|
||||||
*/
|
|
||||||
TimeConductorViewService.prototype.deltas = function () {
|
|
||||||
//Deltas stored on mode. Use .apply to preserve arguments
|
|
||||||
return this.currentMode.deltas.apply(this.currentMode, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Availability of modes depends on the time systems and tick
|
|
||||||
* sources available. For example, Latest Available Data mode will
|
|
||||||
* not be available if there are no time systems and tick sources
|
|
||||||
* that support LAD mode.
|
|
||||||
* @returns {ModeMetadata[]}
|
|
||||||
*/
|
|
||||||
TimeConductorViewService.prototype.availableModes = function () {
|
|
||||||
return this.availModes;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Availability of time systems depends on the currently selected
|
|
||||||
* mode. Time systems and tick sources are mode dependent
|
|
||||||
*/
|
|
||||||
TimeConductorViewService.prototype.availableTimeSystems = function () {
|
|
||||||
return this.currentMode.availableTimeSystems();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An event to indicate that zooming is taking place
|
|
||||||
* @event platform.features.conductor.TimeConductorViewService~zoom
|
|
||||||
* @property {ZoomLevel} zoom the new zoom level.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Zoom to given time span. Will fire a zoom event with new zoom
|
|
||||||
* bounds. Zoom bounds emitted in this way are considered ephemeral
|
|
||||||
* and should be overridden by any time conductor bounds events. Does
|
|
||||||
* not set bounds globally.
|
|
||||||
* @param {number} zoom A time duration in ms
|
|
||||||
* @fires platform.features.conductor.TimeConductorViewService~zoom
|
|
||||||
* @see module:openmct.TimeConductor#bounds
|
|
||||||
*/
|
|
||||||
TimeConductorViewService.prototype.zoom = function (timeSpan) {
|
|
||||||
var zoom = this.currentMode.calculateZoom(timeSpan);
|
|
||||||
this.emit("zoom", zoom);
|
|
||||||
return zoom;
|
|
||||||
};
|
|
||||||
|
|
||||||
return TimeConductorViewService;
|
|
||||||
}
|
|
||||||
);
|
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(['./TimeConductorViewService'], function (TimeConductorViewService) {
|
define(['./TimeConductorService'], function (TimeConductorService) {
|
||||||
describe("The Time Conductor view service", function () {
|
describe("The Time Conductor view service", function () {
|
||||||
var mockTimeConductor;
|
var mockTimeConductor;
|
||||||
var basicTimeSystem;
|
var basicTimeSystem;
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
"./src/UTCTimeSystem",
|
|
||||||
"legacyRegistry"
|
|
||||||
], function (
|
|
||||||
UTCTimeSystem,
|
|
||||||
legacyRegistry
|
|
||||||
) {
|
|
||||||
legacyRegistry.register("platform/features/conductor/utcTimeSystem", {
|
|
||||||
"extensions": {
|
|
||||||
"timeSystems": [
|
|
||||||
{
|
|
||||||
"implementation": UTCTimeSystem,
|
|
||||||
"depends": ["$timeout"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,90 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'../../core/src/timeSystems/TimeSystem',
|
|
||||||
'../../core/src/timeSystems/LocalClock'
|
|
||||||
], function (TimeSystem, LocalClock) {
|
|
||||||
var FIFTEEN_MINUTES = 15 * 60 * 1000,
|
|
||||||
DEFAULT_PERIOD = 100;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This time system supports UTC dates and provides a ticking clock source.
|
|
||||||
* @implements TimeSystem
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function UTCTimeSystem($timeout) {
|
|
||||||
TimeSystem.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some metadata, which will be used to identify the time system in
|
|
||||||
* the UI
|
|
||||||
* @type {{key: string, name: string, cssClass: string}}
|
|
||||||
*/
|
|
||||||
this.metadata = {
|
|
||||||
'key': 'utc',
|
|
||||||
'name': 'UTC',
|
|
||||||
'cssClass': 'icon-clock'
|
|
||||||
};
|
|
||||||
|
|
||||||
this.fmts = ['utc'];
|
|
||||||
this.sources = [new LocalClock($timeout, DEFAULT_PERIOD)];
|
|
||||||
this.defaultValues = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
UTCTimeSystem.prototype = Object.create(TimeSystem.prototype);
|
|
||||||
|
|
||||||
UTCTimeSystem.prototype.formats = function () {
|
|
||||||
return this.fmts;
|
|
||||||
};
|
|
||||||
|
|
||||||
UTCTimeSystem.prototype.deltaFormat = function () {
|
|
||||||
return 'duration';
|
|
||||||
};
|
|
||||||
|
|
||||||
UTCTimeSystem.prototype.tickSources = function () {
|
|
||||||
return this.sources;
|
|
||||||
};
|
|
||||||
|
|
||||||
UTCTimeSystem.prototype.defaults = function (defaults) {
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
this.defaultValues = defaults;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.defaultValues === undefined) {
|
|
||||||
var now = Math.ceil(Date.now() / 1000) * 1000;
|
|
||||||
var ONE_MINUTE = 60 * 1 * 1000;
|
|
||||||
var FIFTY_YEARS = 50 * 365 * 24 * 60 * 60 * 1000;
|
|
||||||
|
|
||||||
this.defaultValues = {
|
|
||||||
key: 'utc-default',
|
|
||||||
name: 'UTC time system defaults',
|
|
||||||
deltas: {start: FIFTEEN_MINUTES, end: 0},
|
|
||||||
bounds: {start: now - FIFTEEN_MINUTES, end: now},
|
|
||||||
zoom: {min: FIFTY_YEARS, max: ONE_MINUTE}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return this.defaultValues;
|
|
||||||
};
|
|
||||||
|
|
||||||
return UTCTimeSystem;
|
|
||||||
});
|
|
@ -1,46 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* 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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(['./UTCTimeSystem'], function (UTCTimeSystem) {
|
|
||||||
describe("The UTCTimeSystem class", function () {
|
|
||||||
var timeSystem,
|
|
||||||
mockTimeout;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockTimeout = jasmine.createSpy("timeout");
|
|
||||||
timeSystem = new UTCTimeSystem(mockTimeout);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("defines at least one format", function () {
|
|
||||||
expect(timeSystem.formats().length).toBeGreaterThan(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("defines a tick source", function () {
|
|
||||||
var tickSources = timeSystem.tickSources();
|
|
||||||
expect(tickSources.length).toBeGreaterThan(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("defines some defaults", function () {
|
|
||||||
expect(timeSystem.defaults()).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -21,7 +21,7 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([
|
||||||
'./TimeConductor',
|
'./conductor/TimeConductor',
|
||||||
'./objects/ObjectAPI',
|
'./objects/ObjectAPI',
|
||||||
'./composition/CompositionAPI',
|
'./composition/CompositionAPI',
|
||||||
'./types/TypeRegistry',
|
'./types/TypeRegistry',
|
||||||
|
@ -50,10 +50,21 @@ define(['EventEmitter'], function (EventEmitter) {
|
|||||||
|
|
||||||
//Default to fixed mode
|
//Default to fixed mode
|
||||||
this.followMode = false;
|
this.followMode = false;
|
||||||
|
|
||||||
|
this.timeSystems = {};
|
||||||
|
this.tickSources = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeConductor.prototype = Object.create(EventEmitter.prototype);
|
TimeConductor.prototype = Object.create(EventEmitter.prototype);
|
||||||
|
|
||||||
|
TimeConductor.prototype.addTimeSystem = function (timeSystem) {
|
||||||
|
this.timeSystems[timeSystem.key] = timeSystem;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductor.prototype.addTickSource = function (tickSource) {
|
||||||
|
this.tickSources[tickSource.key] = tickSource;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the given bounds. This can be used for pre-validation of
|
* Validate the given bounds. This can be used for pre-validation of
|
||||||
* bounds, for example by views validating user inputs.
|
* bounds, for example by views validating user inputs.
|
||||||
@ -75,32 +86,6 @@ define(['EventEmitter'], function (EventEmitter) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get or set the follow mode of the time conductor. In follow mode the
|
|
||||||
* time conductor ticks, regularly updating the bounds from a timing
|
|
||||||
* source appropriate to the selected time system and mode of the time
|
|
||||||
* conductor.
|
|
||||||
* @fires module:openmct.TimeConductor~follow
|
|
||||||
* @param {boolean} followMode
|
|
||||||
* @returns {boolean}
|
|
||||||
* @memberof module:openmct.TimeConductor#
|
|
||||||
* @method follow
|
|
||||||
*/
|
|
||||||
TimeConductor.prototype.follow = function (followMode) {
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
this.followMode = followMode;
|
|
||||||
/**
|
|
||||||
* The TimeConductor has toggled into or out of follow mode.
|
|
||||||
* @event follow
|
|
||||||
* @memberof module:openmct.TimeConductor~
|
|
||||||
* @property {boolean} followMode true if follow mode is
|
|
||||||
* enabled, otherwise false.
|
|
||||||
*/
|
|
||||||
this.emit('follow', this.followMode);
|
|
||||||
}
|
|
||||||
return this.followMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} TimeConductorBounds
|
* @typedef {Object} TimeConductorBounds
|
||||||
* @property {number} start The start time displayed by the time conductor in ms since epoch. Epoch determined by current time system
|
* @property {number} start The start time displayed by the time conductor in ms since epoch. Epoch determined by current time system
|
@ -121,7 +121,7 @@ define([
|
|||||||
* @memberof module:openmct.TelemetryAPI~
|
* @memberof module:openmct.TelemetryAPI~
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var cachedFormatService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for retrieving telemetry data associated with a domain
|
* An interface for retrieving telemetry data associated with a domain
|
||||||
@ -138,6 +138,7 @@ define([
|
|||||||
this.metadataCache = new WeakMap();
|
this.metadataCache = new WeakMap();
|
||||||
this.formatMapCache = new WeakMap();
|
this.formatMapCache = new WeakMap();
|
||||||
this.valueFormatterCache = new WeakMap();
|
this.valueFormatterCache = new WeakMap();
|
||||||
|
this.formatMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,6 +282,13 @@ define([
|
|||||||
return _.sortByAll(options, sortKeys);
|
return _.sortByAll(options, sortKeys);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getFormatService() {
|
||||||
|
if (cachedFormatService === undefined) {
|
||||||
|
cachedFormatService = this.MCT.$injector.get('formatService');
|
||||||
|
}
|
||||||
|
return cachedFormatService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a value formatter for a given valueMetadata.
|
* Get a value formatter for a given valueMetadata.
|
||||||
*
|
*
|
||||||
@ -288,12 +296,10 @@ define([
|
|||||||
*/
|
*/
|
||||||
TelemetryAPI.prototype.getValueFormatter = function (valueMetadata) {
|
TelemetryAPI.prototype.getValueFormatter = function (valueMetadata) {
|
||||||
if (!this.valueFormatterCache.has(valueMetadata)) {
|
if (!this.valueFormatterCache.has(valueMetadata)) {
|
||||||
if (!this.formatService) {
|
var formatService = getFormatService.call(this);
|
||||||
this.formatService = this.MCT.$injector.get('formatService');
|
|
||||||
}
|
|
||||||
this.valueFormatterCache.set(
|
this.valueFormatterCache.set(
|
||||||
valueMetadata,
|
valueMetadata,
|
||||||
new TelemetryValueFormatter(valueMetadata, this.formatService)
|
new TelemetryValueFormatter(valueMetadata, formatService)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return this.valueFormatterCache.get(valueMetadata);
|
return this.valueFormatterCache.get(valueMetadata);
|
||||||
@ -334,5 +340,17 @@ define([
|
|||||||
return this.legacyProvider.limitEvaluator.apply(this.legacyProvider, arguments);
|
return this.legacyProvider.limitEvaluator.apply(this.legacyProvider, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TelemetryAPI.prototype.getFormat = function (formatKey) {
|
||||||
|
return this.formatMap[formatKey];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new formatter
|
||||||
|
* @param {Format} formatter
|
||||||
|
*/
|
||||||
|
TelemetryAPI.prototype.addFormat = function (format) {
|
||||||
|
this.formatMap[format.key] = format;
|
||||||
|
};
|
||||||
|
|
||||||
return TelemetryAPI;
|
return TelemetryAPI;
|
||||||
});
|
});
|
||||||
|
@ -45,7 +45,6 @@ define([
|
|||||||
'../example/scratchpad/bundle',
|
'../example/scratchpad/bundle',
|
||||||
'../example/taxonomy/bundle',
|
'../example/taxonomy/bundle',
|
||||||
'../example/worker/bundle',
|
'../example/worker/bundle',
|
||||||
'../example/localTimeSystem/bundle',
|
|
||||||
|
|
||||||
'../platform/commonUI/about/bundle',
|
'../platform/commonUI/about/bundle',
|
||||||
'../platform/commonUI/browse/bundle',
|
'../platform/commonUI/browse/bundle',
|
||||||
@ -68,7 +67,6 @@ define([
|
|||||||
'../platform/features/fixed/bundle',
|
'../platform/features/fixed/bundle',
|
||||||
'../platform/features/conductor/core/bundle',
|
'../platform/features/conductor/core/bundle',
|
||||||
'../platform/features/conductor/compatibility/bundle',
|
'../platform/features/conductor/compatibility/bundle',
|
||||||
'../platform/features/conductor/utcTimeSystem/bundle',
|
|
||||||
'../platform/features/imagery/bundle',
|
'../platform/features/imagery/bundle',
|
||||||
'../platform/features/layout/bundle',
|
'../platform/features/layout/bundle',
|
||||||
'../platform/features/my-items/bundle',
|
'../platform/features/my-items/bundle',
|
||||||
|
170
src/plugins/conductor/TimeConductorService.js
Normal file
170
src/plugins/conductor/TimeConductorService.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'EventEmitter'
|
||||||
|
],
|
||||||
|
function (EventEmitter) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing the state of the time conductor view. This
|
||||||
|
* exposes details of the UI that are not represented on the
|
||||||
|
* TimeConductor API itself such as modes and deltas.
|
||||||
|
*
|
||||||
|
* @memberof platform.features.conductor
|
||||||
|
* @param conductor
|
||||||
|
* @param timeSystems
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function TimeConductorService(openmct) {
|
||||||
|
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
this.conductor = openmct.conductor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeConductorService.prototype = Object.create(EventEmitter.prototype);
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {number} time some value that is valid in the current TimeSystem
|
||||||
|
*/
|
||||||
|
TimeConductorService.prototype.tick = function (time) {
|
||||||
|
var deltas = this.deltas();
|
||||||
|
var startTime = time;
|
||||||
|
var endTime = time;
|
||||||
|
|
||||||
|
if (deltas) {
|
||||||
|
startTime = time - deltas.start;
|
||||||
|
endTime = time + deltas.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newBounds = {
|
||||||
|
start: startTime,
|
||||||
|
end: endTime
|
||||||
|
};
|
||||||
|
|
||||||
|
this.conductor.boundsVal = newBounds;
|
||||||
|
this.conductor.emit('bounds', true);
|
||||||
|
|
||||||
|
// If a bounds change results in a TOI outside of the current
|
||||||
|
// bounds, unset it
|
||||||
|
if (this.conductor.toi < newBounds.start || this.conductor.toi > newBounds.end) {
|
||||||
|
this.conductor.timeOfInterest(undefined);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductorService.prototype.menuOptions = function (options) {
|
||||||
|
this.options = options;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductorService.prototype.activeTickSource = function (key) {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
if (this.activeTickSource !== undefined) {
|
||||||
|
this.activeTickSource.off('tick', this.tick);
|
||||||
|
}
|
||||||
|
var newTickSource = this.conductor.tickSource[key];
|
||||||
|
if (newTickSource) {
|
||||||
|
this.activeTickSource.on('tick', this.tick);
|
||||||
|
this.activeTickSource = newTickSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.activeTickSource;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} TimeConductorDeltas
|
||||||
|
* @property {number} start Used to set the start bound of the
|
||||||
|
* TimeConductor on tick. A positive value that will be subtracted
|
||||||
|
* from the value provided by a tick source to determine the start
|
||||||
|
* bound.
|
||||||
|
* @property {number} end Used to set the end bound of the
|
||||||
|
* TimeConductor on tick. A positive value that will be added
|
||||||
|
* from the value provided by a tick source to determine the start
|
||||||
|
* bound.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Deltas define the offset from the latest time value provided by
|
||||||
|
* the current tick source. Deltas are only valid in realtime or LAD
|
||||||
|
* modes.
|
||||||
|
*
|
||||||
|
* Realtime mode:
|
||||||
|
* - start: A time in ms before now which will be used to
|
||||||
|
* determine the 'start' bound on tick
|
||||||
|
* - end: A time in ms after now which will be used to determine
|
||||||
|
* the 'end' bound on tick
|
||||||
|
*
|
||||||
|
* LAD mode:
|
||||||
|
* - start: A time in ms before the timestamp of the last data
|
||||||
|
* received which will be used to determine the 'start' bound on
|
||||||
|
* tick
|
||||||
|
* - end: A time in ms after the timestamp of the last data received
|
||||||
|
* which will be used to determine the 'end' bound on tick
|
||||||
|
* @returns {TimeConductorDeltas} current value of the deltas
|
||||||
|
*/
|
||||||
|
TimeConductorService.prototype.deltas = function () {
|
||||||
|
// Get / Set deltas
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Availability of modes depends on the time systems and tick
|
||||||
|
* sources available. For example, Latest Available Data mode will
|
||||||
|
* not be available if there are no time systems and tick sources
|
||||||
|
* that support LAD mode.
|
||||||
|
* @returns {ModeMetadata[]}
|
||||||
|
*/
|
||||||
|
TimeConductorService.prototype.availableTickSources = function () {
|
||||||
|
var conductor = this.conductor;
|
||||||
|
//Return all tick sources
|
||||||
|
return _.uniq(this.options.map(function (option) {
|
||||||
|
return option.tickSource && conductor.tickSources(option.tickSource);
|
||||||
|
}.bind(this)));
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductorService.prototype.availableTimeSystems = function () {
|
||||||
|
return Object.values(this.conductor.timeSystems);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event to indicate that zooming is taking place
|
||||||
|
* @event platform.features.conductor.TimeConductorService~zoom
|
||||||
|
* @property {ZoomLevel} zoom the new zoom level.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Zoom to given time span. Will fire a zoom event with new zoom
|
||||||
|
* bounds. Zoom bounds emitted in this way are considered ephemeral
|
||||||
|
* and should be overridden by any time conductor bounds events. Does
|
||||||
|
* not set bounds globally.
|
||||||
|
* @param {number} zoom A time duration in ms
|
||||||
|
* @fires platform.features.conductor.TimeConductorService~zoom
|
||||||
|
* @see module:openmct.TimeConductor#bounds
|
||||||
|
*/
|
||||||
|
TimeConductorService.prototype.zoom = function (timeSpan) {
|
||||||
|
var zoom = this.currentMode.calculateZoom(timeSpan);
|
||||||
|
this.emit("zoom", zoom);
|
||||||
|
return zoom;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TimeConductorService;
|
||||||
|
}
|
||||||
|
);
|
15
src/plugins/conductor/plugin.js
Normal file
15
src/plugins/conductor/plugin.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
define([
|
||||||
|
'./TimeConductorService'
|
||||||
|
], function (TimeConductorService) {
|
||||||
|
return function ConductorAPIPlugin() {
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.legacyExtension("services", {
|
||||||
|
"key": "timeConductorService",
|
||||||
|
"implementation": TimeConductorService,
|
||||||
|
"depends": [
|
||||||
|
"openmct"
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
define([
|
define([
|
||||||
'lodash',
|
'lodash',
|
||||||
'../../platform/features/conductor/utcTimeSystem/src/UTCTimeSystem',
|
'./utcTimeSystem/plugin',
|
||||||
'../../example/generator/plugin'
|
'../../example/generator/plugin'
|
||||||
], function (
|
], function (
|
||||||
_,
|
_,
|
||||||
@ -46,65 +46,20 @@ define([
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
plugins.UTCTimeSystem = function () {
|
plugins.UTCTimeSystem = UTCTimeSystem;
|
||||||
return function (openmct) {
|
|
||||||
openmct.legacyExtension("timeSystems", {
|
|
||||||
"implementation": UTCTimeSystem,
|
|
||||||
"depends": ["$timeout"]
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var conductorInstalled = false;
|
|
||||||
|
|
||||||
plugins.Conductor = function (options) {
|
plugins.Conductor = function (options) {
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDefaults(openmct, timeConductorViewService) {
|
|
||||||
var defaults = {};
|
|
||||||
var timeSystem = timeConductorViewService.systems.find(function (ts) {
|
|
||||||
return ts.metadata.key === options.defaultTimeSystem;
|
|
||||||
});
|
|
||||||
if (timeSystem !== undefined) {
|
|
||||||
defaults = timeSystem.defaults();
|
|
||||||
|
|
||||||
if (options.defaultTimespan !== undefined) {
|
|
||||||
defaults.deltas.start = options.defaultTimespan;
|
|
||||||
defaults.bounds.start = defaults.bounds.end - options.defaultTimespan;
|
|
||||||
timeSystem.defaults(defaults);
|
|
||||||
}
|
|
||||||
|
|
||||||
openmct.conductor.timeSystem(timeSystem, defaults.bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return function (openmct) {
|
return function (openmct) {
|
||||||
openmct.legacyExtension('constants', {
|
openmct.legacyExtension('runs', {
|
||||||
key: 'DEFAULT_TIMECONDUCTOR_MODE',
|
implementation: function applyDefaults(timeConductorService) {
|
||||||
value: options.showConductor ? 'fixed' : 'realtime',
|
timeConductorService.menuOptions(options.menuOptions);
|
||||||
priority: conductorInstalled ? 'mandatory' : 'fallback'
|
},
|
||||||
|
depends: ["timeConductorService"]
|
||||||
});
|
});
|
||||||
if (options.showConductor !== undefined) {
|
|
||||||
openmct.legacyExtension('constants', {
|
|
||||||
key: 'SHOW_TIMECONDUCTOR',
|
|
||||||
value: options.showConductor,
|
|
||||||
priority: conductorInstalled ? 'mandatory' : 'fallback'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.defaultTimeSystem !== undefined || options.defaultTimespan !== undefined) {
|
|
||||||
openmct.legacyExtension('runs', {
|
|
||||||
implementation: applyDefaults,
|
|
||||||
depends: ["openmct", "timeConductorViewService"]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!conductorInstalled) {
|
|
||||||
openmct.legacyRegistry.enable('platform/features/conductor/core');
|
|
||||||
openmct.legacyRegistry.enable('platform/features/conductor/compatibility');
|
|
||||||
}
|
|
||||||
conductorInstalled = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
65
src/plugins/utcTimeSystem/LocalClock.js
Normal file
65
src/plugins/utcTimeSystem/LocalClock.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT 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 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([], function () {
|
||||||
|
function LocalClock(tickPeriod) {
|
||||||
|
//Metadata
|
||||||
|
this.key = 'localClock';
|
||||||
|
this.name = 'A local time source';
|
||||||
|
this.cssClass = 'icon-clock';
|
||||||
|
|
||||||
|
//Members
|
||||||
|
this.listeners = {};
|
||||||
|
this.tickPeriod = tickPeriod;
|
||||||
|
this.tick = this.tick.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalClock.prototype.tick = function () {
|
||||||
|
this.listeners['tick'].forEach(Date.now());
|
||||||
|
this.timeout = setTimeout(this.tick, this.tickPeriod);
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalClock.prototype.on = function (event, listener) {
|
||||||
|
this.listeners[event] = this.listeners[event] || [];
|
||||||
|
this.listeners[event].push(listener);
|
||||||
|
if (timeout === undefined) {
|
||||||
|
setTimeout(this.tick, this.tickPeriod);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
LocalClock.prototype.off = function (event, listener) {
|
||||||
|
if (this.listeners[event]) {
|
||||||
|
this.listeners[event] = this.listeners[event].filter(function (l) {
|
||||||
|
return l === listener;
|
||||||
|
});
|
||||||
|
var isEmpty = Object.keys(this.listeners).all(function (key){
|
||||||
|
return this.listeners[key] === undefined || this.listeners[key].length === 0
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
clearTimeout(this.timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return LocalClock;
|
||||||
|
});
|
131
src/plugins/utcTimeSystem/UTCTimeFormat.js
Normal file
131
src/plugins/utcTimeSystem/UTCTimeFormat.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT 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 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'moment'
|
||||||
|
], function (
|
||||||
|
moment
|
||||||
|
) {
|
||||||
|
|
||||||
|
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS",
|
||||||
|
DATE_FORMATS = [
|
||||||
|
DATE_FORMAT,
|
||||||
|
"YYYY-MM-DD HH:mm:ss",
|
||||||
|
"YYYY-MM-DD HH:mm",
|
||||||
|
"YYYY-MM-DD"
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Scale
|
||||||
|
* @property {number} min the minimum scale value, in ms
|
||||||
|
* @property {number} max the maximum scale value, in ms
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatter for UTC timestamps. Interprets numeric values as
|
||||||
|
* milliseconds since the start of 1970.
|
||||||
|
*
|
||||||
|
* @implements {Format}
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/commonUI/formats
|
||||||
|
*/
|
||||||
|
function UTCTimeFormat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an appropriate time format based on the provided value and
|
||||||
|
* the threshold required.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function getScaledFormat(d) {
|
||||||
|
var momentified = moment.utc(d);
|
||||||
|
/**
|
||||||
|
* Uses logic from d3 Time-Scales, v3 of the API. See
|
||||||
|
* https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Scales.md
|
||||||
|
*
|
||||||
|
* Licensed
|
||||||
|
*/
|
||||||
|
var format = [
|
||||||
|
[".SSS", function (m) {
|
||||||
|
return m.milliseconds();
|
||||||
|
}],
|
||||||
|
[":ss", function (m) {
|
||||||
|
return m.seconds();
|
||||||
|
}],
|
||||||
|
["HH:mm", function (m) {
|
||||||
|
return m.minutes();
|
||||||
|
}],
|
||||||
|
["HH", function (m) {
|
||||||
|
return m.hours();
|
||||||
|
}],
|
||||||
|
["ddd DD", function (m) {
|
||||||
|
return m.days() &&
|
||||||
|
m.date() !== 1;
|
||||||
|
}],
|
||||||
|
["MMM DD", function (m) {
|
||||||
|
return m.date() !== 1;
|
||||||
|
}],
|
||||||
|
["MMMM", function (m) {
|
||||||
|
return m.month();
|
||||||
|
}],
|
||||||
|
["YYYY", function () {
|
||||||
|
return true;
|
||||||
|
}]
|
||||||
|
].filter(function (row) {
|
||||||
|
return row[1](momentified);
|
||||||
|
})[0][0];
|
||||||
|
|
||||||
|
if (format !== undefined) {
|
||||||
|
return moment.utc(value).format(scaledFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} value The value to format.
|
||||||
|
* @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
|
* and plot axes. Specifies the smallest number on the scale.
|
||||||
|
* @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
|
* and plot axes. Specifies the largest number on the scale
|
||||||
|
* @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor
|
||||||
|
* and plot axes. The number of labels on the scale.
|
||||||
|
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
|
||||||
|
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
||||||
|
* in the array.
|
||||||
|
*/
|
||||||
|
UTCTimeFormat.prototype.format = function (value, minValue, maxValue, count) {
|
||||||
|
if (arguments.length > 1) {
|
||||||
|
return values.map(getScaledFormat);
|
||||||
|
} else {
|
||||||
|
return moment.utc(value).format(DATE_FORMAT) + "Z";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UTCTimeFormat.prototype.parse = function (text) {
|
||||||
|
return moment.utc(text, DATE_FORMATS).valueOf();
|
||||||
|
};
|
||||||
|
|
||||||
|
UTCTimeFormat.prototype.validate = function (text) {
|
||||||
|
return moment.utc(text, DATE_FORMATS).isValid();
|
||||||
|
};
|
||||||
|
|
||||||
|
return UTCTimeFormat;
|
||||||
|
});
|
83
src/plugins/utcTimeSystem/UTCTimeFormatSpec.js
Normal file
83
src/plugins/utcTimeSystem/UTCTimeFormatSpec.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
"./UTCTimeFormat",
|
||||||
|
"moment"
|
||||||
|
], function (
|
||||||
|
UTCTimeFormat,
|
||||||
|
moment
|
||||||
|
) {
|
||||||
|
describe("The UTCTimeFormat class", function () {
|
||||||
|
var format;
|
||||||
|
var scale;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
format = new UTCTimeFormat();
|
||||||
|
scale = {min: 0, max: 0};
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Provides an appropriately scaled time format based on the input" +
|
||||||
|
" time", function () {
|
||||||
|
var TWO_HUNDRED_MS = 200;
|
||||||
|
var THREE_SECONDS = 3000;
|
||||||
|
var FIVE_MINUTES = 5 * 60 * 1000;
|
||||||
|
var ONE_HOUR_TWENTY_MINS = (1 * 60 * 60 * 1000) + (20 * 60 * 1000);
|
||||||
|
var TEN_HOURS = (10 * 60 * 60 * 1000);
|
||||||
|
|
||||||
|
var JUNE_THIRD = moment.utc("2016-06-03", "YYYY-MM-DD");
|
||||||
|
var APRIL = moment.utc("2016-04", "YYYY-MM");
|
||||||
|
var TWENTY_SIXTEEN = moment.utc("2016", "YYYY");
|
||||||
|
|
||||||
|
expect(format.format(TWO_HUNDRED_MS, scale)).toBe(".200");
|
||||||
|
expect(format.format(THREE_SECONDS, scale)).toBe(":03");
|
||||||
|
expect(format.format(FIVE_MINUTES, scale)).toBe("00:05");
|
||||||
|
expect(format.format(ONE_HOUR_TWENTY_MINS, scale)).toBe("01:20");
|
||||||
|
expect(format.format(TEN_HOURS, scale)).toBe("10");
|
||||||
|
|
||||||
|
expect(format.format(JUNE_THIRD, scale)).toBe("Fri 03");
|
||||||
|
expect(format.format(APRIL, scale)).toBe("April");
|
||||||
|
expect(format.format(TWENTY_SIXTEEN, scale)).toBe("2016");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Returns appropriate time units for a given time span", function () {
|
||||||
|
var ONE_DAY = 1000 * 60 * 60 * 24;
|
||||||
|
var FIVE_DAYS = 5 * ONE_DAY;
|
||||||
|
var FIVE_MONTHS = 60 * ONE_DAY;
|
||||||
|
|
||||||
|
var ONE_YEAR = 365 * ONE_DAY;
|
||||||
|
var SEVEN_YEARS = 7 * ONE_YEAR;
|
||||||
|
var TWO_DECADES = 20 * ONE_YEAR;
|
||||||
|
|
||||||
|
//A span of one day should show a zoom label of "Hours"
|
||||||
|
expect(format.timeUnits(ONE_DAY)).toEqual("Hours");
|
||||||
|
//Multiple days should display "Days"
|
||||||
|
expect(format.timeUnits(FIVE_DAYS)).toEqual("Days");
|
||||||
|
expect(format.timeUnits(FIVE_MONTHS)).toEqual("Days");
|
||||||
|
//A span of one year should show a zoom level of "Months".
|
||||||
|
// Multiple years will show "Years"
|
||||||
|
expect(format.timeUnits(ONE_YEAR)).toEqual("Months");
|
||||||
|
expect(format.timeUnits(SEVEN_YEARS)).toEqual("Years");
|
||||||
|
expect(format.timeUnits(TWO_DECADES)).toEqual("Decades");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
21
src/plugins/utcTimeSystem/plugin.js
Normal file
21
src/plugins/utcTimeSystem/plugin.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
define([
|
||||||
|
'./UTCTimeFormat',
|
||||||
|
'./LocalClock'
|
||||||
|
], function (
|
||||||
|
UtcTimeFormat,
|
||||||
|
LocalClock
|
||||||
|
) {
|
||||||
|
return function UtcTimeSystemPlugin(options) {
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.telemetry.addFormat(new UtcTimeFormat());
|
||||||
|
openmct.conductor.addTimeSystem({
|
||||||
|
key: 'utc',
|
||||||
|
name: 'UTC',
|
||||||
|
timeFormat: 'utc',
|
||||||
|
durationFormat: 'duration',
|
||||||
|
utcBased: true
|
||||||
|
});
|
||||||
|
openmct.conductor.addTickSource(new LocalClock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
Reference in New Issue
Block a user