mirror of
https://github.com/nasa/openmct.git
synced 2025-02-20 17:33:23 +00:00
Refactoring based on feedback
Refactoring controller Migrating functions off controller onto service class Simplified modes Adding comments Removed unnecessary validation Fixing testing issues
This commit is contained in:
parent
4ae6da0334
commit
4cf6126d35
@ -30,6 +30,7 @@ define(['../../../platform/features/conductor-v2/conductor/src/timeSystems/Local
|
||||
|
||||
this.metadata = {
|
||||
key: 'test-lad',
|
||||
mode: 'LAD',
|
||||
cssclass: 'icon-clock',
|
||||
label: 'Latest Available Data',
|
||||
name: 'Latest available data',
|
||||
@ -38,9 +39,5 @@ define(['../../../platform/features/conductor-v2/conductor/src/timeSystems/Local
|
||||
}
|
||||
LADTickSource.prototype = Object.create(LocalClock.prototype);
|
||||
|
||||
LADTickSource.prototype.type = function () {
|
||||
return 'data';
|
||||
};
|
||||
|
||||
return LADTickSource;
|
||||
});
|
||||
|
@ -39,7 +39,7 @@ define([
|
||||
"key": "conductorService",
|
||||
"implementation": ConductorService,
|
||||
"depends": [
|
||||
"timeConductorService"
|
||||
"timeConductor"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -47,7 +47,7 @@ define([
|
||||
{
|
||||
"implementation": ConductorRepresenter,
|
||||
"depends": [
|
||||
"timeConductorService"
|
||||
"timeConductor"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -57,7 +57,7 @@ define([
|
||||
"provides": "telemetryService",
|
||||
"implementation": ConductorTelemetryDecorator,
|
||||
"depends": [
|
||||
"timeConductorService"
|
||||
"timeConductor"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -37,11 +37,11 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function ConductorRepresenter(
|
||||
conductorService,
|
||||
timeConductor,
|
||||
scope,
|
||||
element
|
||||
) {
|
||||
this.conductor = conductorService.conductor();
|
||||
this.conductor = timeConductor;
|
||||
this.scope = scope;
|
||||
this.element = element;
|
||||
|
||||
|
@ -36,8 +36,8 @@ define(
|
||||
* the service which exposes the global time conductor
|
||||
* @param {TelemetryService} telemetryService the decorated service
|
||||
*/
|
||||
function ConductorTelemetryDecorator(conductorService, telemetryService) {
|
||||
this.conductor = conductorService.conductor();
|
||||
function ConductorTelemetryDecorator(timeConductor, telemetryService) {
|
||||
this.conductor = timeConductor;
|
||||
this.telemetryService = telemetryService;
|
||||
|
||||
this.amendRequests = ConductorTelemetryDecorator.prototype.amendRequests.bind(this);
|
||||
|
@ -21,17 +21,19 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/ui/TimeConductorService",
|
||||
"./src/ui/TimeConductorViewService",
|
||||
"./src/ui/TimeConductorController",
|
||||
"./src/ui/MCTConductorAxis",
|
||||
"./src/TimeConductor",
|
||||
"./src/ui/MctConductorAxis",
|
||||
"./src/ui/NumberFormat",
|
||||
"text!./res/templates/time-conductor.html",
|
||||
"text!./res/templates/mode-selector/mode-selector.html",
|
||||
"text!./res/templates/mode-selector/mode-menu.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
TimeConductorService,
|
||||
TimeConductorViewService,
|
||||
TimeConductorController,
|
||||
TimeConductor,
|
||||
MCTConductorAxis,
|
||||
NumberFormat,
|
||||
timeConductorTemplate,
|
||||
@ -45,16 +47,15 @@ define([
|
||||
"services": [
|
||||
{
|
||||
"key": "timeConductor",
|
||||
"implementation": function (timeConductorService) {
|
||||
return timeConductorService.conductor();
|
||||
},
|
||||
"depends": [
|
||||
"timeConductorService"
|
||||
]
|
||||
"implementation": TimeConductor
|
||||
},
|
||||
{
|
||||
"key": "timeConductorService",
|
||||
"implementation": TimeConductorService
|
||||
"key": "timeConductorViewService",
|
||||
"implementation": TimeConductorViewService,
|
||||
"depends": [
|
||||
"timeConductor",
|
||||
"timeSystems[]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
@ -63,7 +64,8 @@ define([
|
||||
"implementation": TimeConductorController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"timeConductorService",
|
||||
"timeConductor",
|
||||
"timeConductorViewService",
|
||||
"timeSystems[]"
|
||||
]
|
||||
}
|
||||
@ -73,7 +75,7 @@ define([
|
||||
"key": "mctConductorAxis",
|
||||
"implementation": MCTConductorAxis,
|
||||
"depends": [
|
||||
"timeConductorService",
|
||||
"timeConductor",
|
||||
"formatService"
|
||||
]
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<!-- Holds inputs and ticks -->
|
||||
<div class="l-time-conductor-inputs-and-ticks l-row-elem flex-elem no-margin">
|
||||
<form class="l-time-conductor-inputs-holder"
|
||||
ng-submit="tcController.updateBoundsFromForm(formModel)">
|
||||
ng-submit="tcController.updateBoundsFromForm(boundsModel)">
|
||||
<span class="l-time-range-w start-w">
|
||||
<span class="l-time-range-input-w start-date">
|
||||
<span class="title"></span>
|
||||
@ -20,8 +20,8 @@
|
||||
format: timeSystemModel.format,
|
||||
validate: tcController.validation.validateStart
|
||||
}"
|
||||
ng-model="formModel"
|
||||
ng-blur="tcController.updateBoundsFromForm(formModel)"
|
||||
ng-model="boundsModel"
|
||||
ng-blur="tcController.updateBoundsFromForm(boundsModel)"
|
||||
field="'start'"
|
||||
class="time-range-input">
|
||||
</mct-control>
|
||||
@ -34,8 +34,8 @@
|
||||
format: timeSystemModel.deltaFormat,
|
||||
validate: tcController.validation.validateStartDelta
|
||||
}"
|
||||
ng-model="formModel"
|
||||
ng-blur="tcController.updateDeltasFromForm(formModel)"
|
||||
ng-model="boundsModel"
|
||||
ng-blur="tcController.updateDeltasFromForm(boundsModel)"
|
||||
field="'startDelta'"
|
||||
class="hrs-min-input">
|
||||
</mct-control>
|
||||
@ -50,8 +50,8 @@
|
||||
format: timeSystemModel.format,
|
||||
validate: tcController.validation.validateEnd
|
||||
}"
|
||||
ng-model="formModel"
|
||||
ng-blur="tcController.updateBoundsFromForm(formModel)"
|
||||
ng-model="boundsModel"
|
||||
ng-blur="tcController.updateBoundsFromForm(boundsModel)"
|
||||
ng-disabled="modeModel.selectedKey !== 'fixed'"
|
||||
field="'end'"
|
||||
class="time-range-input">
|
||||
@ -65,8 +65,8 @@
|
||||
format: timeSystemModel.deltaFormat,
|
||||
validate: tcController.validation.validateEndDelta
|
||||
}"
|
||||
ng-model="formModel"
|
||||
ng-blur="tcController.updateDeltasFromForm(formModel)"
|
||||
ng-model="boundsModel"
|
||||
ng-blur="tcController.updateDeltasFromForm(boundsModel)"
|
||||
field="'endDelta'"
|
||||
class="hrs-min-input">
|
||||
</mct-control>
|
||||
@ -100,7 +100,7 @@
|
||||
</mct-control>
|
||||
<!-- Zoom control -->
|
||||
<div class="l-time-conductor-zoom-w grows flex-elem l-flex-row">
|
||||
<span class="time-conductor-zoom-current-range flex-elem flex-fixed holder">Mars Minutes</span>
|
||||
<span class="time-conductor-zoom-current-range flex-elem flex-fixed holder"></span>
|
||||
<input class="time-conductor-zoom flex-elem" type="range" />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -148,9 +148,6 @@ define(['EventEmitter'], function (EventEmitter) {
|
||||
* Time System
|
||||
* */
|
||||
this.emit('timeSystem', this.system);
|
||||
// Do something with bounds here. Try and convert between
|
||||
// time systems? Or just set defaults when time system changes?
|
||||
// eg.
|
||||
this.bounds(bounds);
|
||||
} else if (arguments.length === 1) {
|
||||
throw new Error('Must set bounds when changing time system');
|
||||
|
@ -29,7 +29,8 @@ define(['./TickSource'], function (TickSource) {
|
||||
TickSource.call(this);
|
||||
|
||||
this.metadata = {
|
||||
key: 'real-time',
|
||||
key: 'local',
|
||||
mode: 'realtime',
|
||||
cssclass: 'icon-clock',
|
||||
label: 'Real-time',
|
||||
name: 'Real-time Mode',
|
||||
@ -84,9 +85,5 @@ define(['./TickSource'], function (TickSource) {
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
LocalClock.prototype.type = function () {
|
||||
return 'clock';
|
||||
};
|
||||
|
||||
return LocalClock;
|
||||
});
|
||||
|
@ -43,14 +43,5 @@ define([], function () {
|
||||
throw new Error('Not implemented');
|
||||
};
|
||||
|
||||
/**
|
||||
* What does this source tick on? A clock, or data availability.
|
||||
* Information is required to support time conductor modes.
|
||||
* @returns {string} type One of 'clock' or 'data'
|
||||
*/
|
||||
TickSource.prototype.type = function () {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
return TickSource;
|
||||
});
|
||||
|
@ -32,9 +32,7 @@ define(
|
||||
* labelled 'ticks'. It requires 'start' and 'end' integer values to
|
||||
* be specified as attributes.
|
||||
*/
|
||||
function MCTConductorAxis(conductorService, formatService) {
|
||||
var conductor = conductorService.conductor();
|
||||
|
||||
function MCTConductorAxis(conductor, formatService) {
|
||||
function link(scope, element, attrs, ngModelController) {
|
||||
var target = element[0].firstChild,
|
||||
height = target.offsetHeight,
|
||||
@ -45,25 +43,24 @@ define(
|
||||
.attr('width', '100%')
|
||||
.attr('height', height);
|
||||
var xAxis = d3.axisTop();
|
||||
var xScale = d3.scaleUtc();
|
||||
|
||||
// draw x axis with labels and move to the bottom of the chart area
|
||||
var axisElement = vis.append("g")
|
||||
.attr("transform", "translate(0," + (height - padding) + ")");
|
||||
|
||||
function setScale() {
|
||||
var xScale = undefined;
|
||||
var width = target.offsetWidth;
|
||||
var timeSystem = conductor.timeSystem();
|
||||
var bounds = conductor.bounds();
|
||||
|
||||
if (timeSystem.isUTCBased()) {
|
||||
xScale = d3.scaleUtc();
|
||||
xScale.domain([new Date(bounds.start), new Date(bounds.end)]);
|
||||
} else {
|
||||
xScale = d3.scaleLinear();
|
||||
xScale.domain([bounds.start, bounds.end]);
|
||||
}
|
||||
|
||||
xScale.range([padding, width - padding * 2]);
|
||||
xAxis.scale(xScale);
|
||||
axisElement.call(xAxis);
|
||||
}
|
||||
|
||||
@ -73,6 +70,13 @@ define(
|
||||
var format = formatService.getFormat(key);
|
||||
var b = conductor.bounds();
|
||||
|
||||
if (timeSystem.isUTCBased()) {
|
||||
xScale = d3.scaleUtc();
|
||||
} else {
|
||||
xScale = d3.scaleLinear();
|
||||
}
|
||||
|
||||
xAxis.scale(xScale);
|
||||
//Define a custom format function
|
||||
xAxis.tickFormat(function (tickValue) {
|
||||
// Normalize date representations to numbers
|
||||
@ -97,23 +101,16 @@ define(
|
||||
setScale();
|
||||
});
|
||||
|
||||
setScale();
|
||||
|
||||
if (conductor.timeSystem() !== undefined) {
|
||||
changeTimeSystem(conductor.timeSystem());
|
||||
setScale();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// Only show at the element level
|
||||
restrict: "E",
|
||||
|
||||
template: "<div class=\"l-axis-holder\" mct-resize=\"resize()\"></div>",
|
||||
|
||||
// ngOptions is terminal, so we need to be higher priority
|
||||
priority: 1000,
|
||||
|
||||
// Link function
|
||||
link: link
|
||||
};
|
||||
}
|
||||
|
@ -20,11 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'moment'
|
||||
], function (
|
||||
moment
|
||||
) {
|
||||
define([], function () {
|
||||
|
||||
/**
|
||||
* Formatter for basic numbers. Provides basic support for non-UTC
|
||||
|
@ -22,13 +22,11 @@
|
||||
|
||||
define(
|
||||
[
|
||||
'./modes/FixedMode',
|
||||
'./modes/FollowMode',
|
||||
'./TimeConductorValidation'
|
||||
],
|
||||
function (FixedMode, FollowMode, TimeConductorValidation) {
|
||||
function (TimeConductorValidation) {
|
||||
|
||||
function TimeConductorController($scope, conductorService, timeSystems) {
|
||||
function TimeConductorController($scope, timeConductor, conductorViewService, timeSystems) {
|
||||
|
||||
var self = this;
|
||||
|
||||
@ -39,112 +37,80 @@ define(
|
||||
self[key] = self[key].bind(self);
|
||||
});
|
||||
|
||||
this.conductorService = conductorService;
|
||||
this.conductor = conductorService.conductor();
|
||||
|
||||
this.conductor.on('bounds', this.setBounds);
|
||||
this.conductor.on('follow', function (follow){
|
||||
$scope.followMode = follow;
|
||||
});
|
||||
this.$scope = $scope;
|
||||
this.conductorViewService = conductorViewService;
|
||||
this.conductor = timeConductor;
|
||||
this.modes = conductorViewService.availableModes();
|
||||
this.validation = new TimeConductorValidation(this.conductor);
|
||||
|
||||
// Construct the provided time system definitions
|
||||
this._timeSystems = timeSystems.map(function (timeSystemConstructor){
|
||||
this.timeSystems = timeSystems.map(function (timeSystemConstructor){
|
||||
return timeSystemConstructor();
|
||||
});
|
||||
|
||||
this.modes = {
|
||||
'fixed': {
|
||||
cssclass: 'icon-calendar',
|
||||
label: 'Fixed',
|
||||
name: 'Fixed Timespan Mode',
|
||||
description: 'Query and explore data that falls between two fixed datetimes.'
|
||||
}
|
||||
};
|
||||
//Set the initial state of the view based on current time conductor
|
||||
this.initializeScope();
|
||||
|
||||
//Only show 'real-time mode' if a clock source is available
|
||||
if (this.timeSystemsForSourceType('clock').length > 0 ) {
|
||||
this.modes['realtime'] = {
|
||||
cssclass: 'icon-clock',
|
||||
label: 'Real-time',
|
||||
name: 'Real-time Mode',
|
||||
tickSourceType: 'clock',
|
||||
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.conductor.on('bounds', this.setFormFromBounds);
|
||||
this.conductor.on('follow', function (follow){
|
||||
$scope.followMode = follow;
|
||||
});
|
||||
this.conductor.on('timeSystem', this.changeTimeSystem);
|
||||
|
||||
//Only show 'real-time mode' if a clock source is available
|
||||
if (this.timeSystemsForSourceType('data').length > 0) {
|
||||
this.modes['latest'] = {
|
||||
cssclass: 'icon-database',
|
||||
label: 'LAD',
|
||||
name: 'LAD Mode',
|
||||
tickSourceType: 'data',
|
||||
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.validation = new TimeConductorValidation(this.conductor);
|
||||
this.$scope = $scope;
|
||||
|
||||
/*
|
||||
Set time Conductor bounds in the form
|
||||
*/
|
||||
$scope.formModel = this.conductor.bounds();
|
||||
|
||||
/*
|
||||
Represents the various time system options, and the currently
|
||||
selected time system in the view. Additionally holds the
|
||||
default format from the selected time system for convenience
|
||||
of access from the template.
|
||||
*/
|
||||
$scope.timeSystemModel = {};
|
||||
if (this.conductor.timeSystem()) {
|
||||
$scope.timeSystemModel.selected = this.conductor.timeSystem();
|
||||
$scope.timeSystemModel.format = this.conductor.timeSystem().formats()[0];
|
||||
$scope.timeSystemModel.deltaFormat = this.conductor.timeSystem().deltaFormat();
|
||||
}
|
||||
|
||||
/*
|
||||
Represents the various modes, and the currently
|
||||
selected mode in the view
|
||||
*/
|
||||
$scope.modeModel = {
|
||||
options: this.modes
|
||||
};
|
||||
|
||||
var mode = conductorService.mode();
|
||||
if (mode) {
|
||||
$scope.modeModel.selectedKey = mode.key();
|
||||
var deltas = mode.deltas && mode.deltas();
|
||||
if (deltas) {
|
||||
$scope.formModel.startDelta = deltas.start;
|
||||
$scope.formModel.endDelta = deltas.end;
|
||||
}
|
||||
|
||||
// Show filtered list of time systems available for the
|
||||
// current mode
|
||||
var tickSourceType = this.modes[mode.key()].tickSourceType;
|
||||
$scope.timeSystemModel.options = this.timeSystemsForSourceType(tickSourceType).map(function (t) {
|
||||
return t.metadata;
|
||||
});
|
||||
} else {
|
||||
// Default to fixed mode
|
||||
// If no mode selected, select fixed as the default
|
||||
if (!this.conductorViewService.mode()) {
|
||||
this.setMode('fixed');
|
||||
}
|
||||
|
||||
$scope.$watch('modeModel.selectedKey', this.setMode);
|
||||
$scope.$watch('timeSystem', this.setTimeSystem);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.initializeScope = function() {
|
||||
//Set time Conductor bounds in the form
|
||||
this.$scope.boundsModel = this.conductor.bounds();
|
||||
|
||||
//If conductor has a time system selected already, populate the
|
||||
//form from it
|
||||
this.$scope.timeSystemModel = {};
|
||||
if (this.conductor.timeSystem()) {
|
||||
this.setFormFromTimeSystem(this.conductor.timeSystem());
|
||||
}
|
||||
|
||||
//Represents the various modes, and the currently selected mode
|
||||
//in the view
|
||||
this.$scope.modeModel = {
|
||||
options: this.conductorViewService.availableModes()
|
||||
};
|
||||
|
||||
var mode = this.conductorViewService.mode();
|
||||
if (mode) {
|
||||
//If view already defines a mode (eg. controller is being
|
||||
// initialized after navigation), then pre-populate form.
|
||||
this.setFormFromMode(mode);
|
||||
var deltas = this.conductorViewService.deltas();
|
||||
if (deltas) {
|
||||
this.setFormFromDeltas(deltas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.setFormFromBounds(this.conductor.bounds());
|
||||
|
||||
// Watch scope for selection of mode or time system by user
|
||||
this.$scope.$watch('modeModel.selectedKey', this.setMode);
|
||||
this.$scope.$watch('timeSystem', this.changeTimeSystem);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the bounds change in the time conductor. Synchronizes
|
||||
* the bounds values in the time conductor with those in the form
|
||||
* @param bounds
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.setBounds = function (bounds) {
|
||||
this.$scope.formModel.start = bounds.start;
|
||||
this.$scope.formModel.end = bounds.end;
|
||||
TimeConductorController.prototype.setFormFromBounds = function (bounds) {
|
||||
this.$scope.boundsModel.start = bounds.start;
|
||||
this.$scope.boundsModel.end = bounds.end;
|
||||
if (!this.pendingUpdate) {
|
||||
this.pendingUpdate = true;
|
||||
requestAnimationFrame(function () {
|
||||
@ -154,148 +120,86 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
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;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.setFormFromDeltas = function (deltas) {
|
||||
/*
|
||||
* If the selected mode defines deltas, set them in the form
|
||||
*/
|
||||
if (deltas !== undefined) {
|
||||
this.$scope.boundsModel.startDelta = deltas.start;
|
||||
this.$scope.boundsModel.endDelta = deltas.end;
|
||||
} else {
|
||||
this.$scope.boundsModel.startDelta = 0;
|
||||
this.$scope.boundsModel.endDelta = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.setFormFromTimeSystem = function (timeSystem) {
|
||||
this.$scope.timeSystemModel.selected = timeSystem;
|
||||
this.$scope.timeSystemModel.format = timeSystem.formats()[0];
|
||||
this.$scope.timeSystemModel.deltaFormat = timeSystem.deltaFormat();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when form values are changed. Synchronizes the form with
|
||||
* the time conductor
|
||||
* @param formModel
|
||||
*/
|
||||
TimeConductorController.prototype.updateBoundsFromForm = function (formModel) {
|
||||
var newBounds = {
|
||||
start: formModel.start,
|
||||
end: formModel.end
|
||||
};
|
||||
|
||||
if (this.conductor.validateBounds(newBounds) === true) {
|
||||
this.conductor.bounds(newBounds);
|
||||
}
|
||||
TimeConductorController.prototype.updateBoundsFromForm = function (boundsModel) {
|
||||
this.conductor.bounds({
|
||||
start: boundsModel.start,
|
||||
end: boundsModel.end
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the delta values in the form change. Validates and
|
||||
* sets the new deltas on the Mode.
|
||||
* @param formModel
|
||||
* @param boundsModel
|
||||
* @see TimeConductorMode
|
||||
*/
|
||||
TimeConductorController.prototype.updateDeltasFromForm = function (formModel) {
|
||||
var mode = this.conductorService.mode(),
|
||||
deltas = mode.deltas();
|
||||
|
||||
if (deltas !== undefined && this.validation.validateDeltas(formModel.startDelta, formModel.endDelta)) {
|
||||
TimeConductorController.prototype.updateDeltasFromForm = function (boundsFormModel) {
|
||||
var deltas = {
|
||||
start: boundsFormModel.startDelta,
|
||||
end: boundsFormModel.endDelta
|
||||
}
|
||||
if (this.validation.validateStartDelta(deltas.start) && this.validation.validateEndDelta(deltas.end)) {
|
||||
//Sychronize deltas between form and mode
|
||||
mode.deltas({start: parseFloat(formModel.startDelta), end: parseFloat(formModel.endDelta)});
|
||||
this.conductorViewService.deltas(deltas);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.timeSystemsForSourceType = function(type){
|
||||
if (!type) {
|
||||
return this._timeSystems;
|
||||
} else {
|
||||
return this._timeSystems.filter(function (timeSystem){
|
||||
return timeSystem.tickSources().some(function (tickSource){
|
||||
return tickSource.type() === type;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TimeConductorController.prototype.selectTickSource = function (timeSystem, sourceType) {
|
||||
return timeSystem.tickSources().filter(function (source){
|
||||
return source.type() === sourceType;
|
||||
})[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (newModeKey !== oldModeKey) {
|
||||
var newMode = undefined;
|
||||
var timeSystems = [];
|
||||
var timeSystem = undefined;
|
||||
var $scope = this.$scope;
|
||||
var tickSourceType = this.modes[newModeKey].tickSourceType;
|
||||
|
||||
this.$scope.modeModel.selectedKey = newModeKey;
|
||||
|
||||
if (this.conductorService.mode()) {
|
||||
this.conductorService.mode().destroy();
|
||||
}
|
||||
|
||||
switch (newModeKey) {
|
||||
case 'fixed':
|
||||
timeSystems = this._timeSystems;
|
||||
timeSystem = timeSystems[0];
|
||||
newMode = new FixedMode(this.conductor, timeSystem, newModeKey);
|
||||
break;
|
||||
|
||||
case 'realtime':
|
||||
// Filter time systems to only those with clock tick
|
||||
// sources
|
||||
timeSystems = this.timeSystemsForSourceType(tickSourceType);
|
||||
|
||||
//Retain currently selected time system if available
|
||||
timeSystem = timeSystems.filter(function (t) {
|
||||
return t.metadata.key === $scope.timeSystemModel.selected.metadata.key;
|
||||
})[0];
|
||||
//Default to first available time system
|
||||
timeSystem = timeSystem || timeSystems[0];
|
||||
|
||||
newMode = new FollowMode(this.conductor, timeSystem, newModeKey);
|
||||
newMode.tickSource(this.selectTickSource(timeSystem, tickSourceType));
|
||||
break;
|
||||
|
||||
case 'latest':
|
||||
// Filter time systems to only those with data tick
|
||||
// sources
|
||||
timeSystems = this.timeSystemsForSourceType(tickSourceType);
|
||||
|
||||
//Retain currently selected time system if available
|
||||
timeSystem = timeSystems.filter(function (t) {
|
||||
return t.metadata.key === $scope.timeSystemModel.selected.metadata.key;
|
||||
})[0];
|
||||
//Default to first available time system
|
||||
timeSystem = timeSystem || timeSystems[0];
|
||||
|
||||
newMode = new FollowMode(this.conductor, timeSystem, newModeKey);
|
||||
newMode.tickSource(this.selectTickSource(timeSystem, tickSourceType));
|
||||
break;
|
||||
}
|
||||
newMode.initialize();
|
||||
this.setDeltasFromDefaults(newMode.defaults());
|
||||
|
||||
this.conductorService.mode(newMode);
|
||||
|
||||
//Synchronize scope with time system on mode
|
||||
this.$scope.timeSystemModel.options = timeSystems.map(function (t) {
|
||||
return t.metadata;
|
||||
});
|
||||
|
||||
this.setTimeSystem(timeSystem);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TimeConductorController.prototype.setDeltasFromDefaults = function (defaults) {
|
||||
var deltas = defaults.deltas;
|
||||
|
||||
/*
|
||||
* If the selected mode defines deltas, set them in the form
|
||||
*/
|
||||
if (deltas !== undefined) {
|
||||
this.$scope.formModel.startDelta = deltas.start;
|
||||
this.$scope.formModel.endDelta = deltas.end;
|
||||
} else {
|
||||
this.$scope.formModel.startDelta = 0;
|
||||
this.$scope.formModel.endDelta = 0;
|
||||
this.conductorViewService.mode(newModeKey);
|
||||
this.setFormFromMode(newModeKey);
|
||||
}
|
||||
};
|
||||
|
||||
@ -307,36 +211,23 @@ define(
|
||||
* @see TimeConductorController#setTimeSystem
|
||||
*/
|
||||
TimeConductorController.prototype.selectTimeSystemByKey = function(key){
|
||||
var selected = this._timeSystems.find(function (timeSystem){
|
||||
var selected = this.timeSystems.find(function (timeSystem){
|
||||
return timeSystem.metadata.key === key;
|
||||
});
|
||||
this.setTimeSystem(selected);
|
||||
this.conductor.timeSystem(selected, selected.defaults().bounds);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the selected time system. Will populate form with the default
|
||||
* bounds and deltas defined in the selected time system.
|
||||
*
|
||||
* @private
|
||||
* @param newTimeSystem
|
||||
*/
|
||||
TimeConductorController.prototype.setTimeSystem = function (newTimeSystem) {
|
||||
if (newTimeSystem && newTimeSystem !== this.$scope.timeSystemModel.selected) {
|
||||
|
||||
var mode = this.conductorService.mode();
|
||||
mode.timeSystem(newTimeSystem);
|
||||
var defaults = mode.defaults();
|
||||
|
||||
this.$scope.timeSystemModel.selected = newTimeSystem;
|
||||
this.$scope.timeSystemModel.format = newTimeSystem.formats()[0];
|
||||
this.$scope.timeSystemModel.deltaFormat = newTimeSystem.deltaFormat();
|
||||
|
||||
this.setDeltasFromDefaults(defaults);
|
||||
|
||||
// If current mode supports ticking, set an appropriate tick
|
||||
// source from the new time system
|
||||
if (mode.tickSource) {
|
||||
var tickSourceType = this.modes[mode.key()].tickSourceType;
|
||||
mode.tickSource(this.selectTickSource(newTimeSystem, tickSourceType));
|
||||
}
|
||||
TimeConductorController.prototype.changeTimeSystem = function (newTimeSystem) {
|
||||
if (newTimeSystem && (newTimeSystem !== this.$scope.timeSystemModel.selected)) {
|
||||
this.setFormFromDeltas((newTimeSystem.defaults() || {}).deltas);
|
||||
this.setFormFromTimeSystem(newTimeSystem);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,200 @@
|
||||
/*****************************************************************************
|
||||
* 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 () {
|
||||
|
||||
/**
|
||||
* Supports mode-specific time conductor behavior.
|
||||
*
|
||||
* @constructor
|
||||
* @param {TimeConductorMetadata} metadata
|
||||
*/
|
||||
function TimeConductorMode(metadata, conductor, timeSystems) {
|
||||
this.conductor = conductor;
|
||||
|
||||
this._metadata = metadata;
|
||||
this._deltas = undefined;
|
||||
this._tickSource = undefined;
|
||||
this._tickSourceUnlisten = undefined;
|
||||
this._timeSystems = timeSystems;
|
||||
this._availableTickSources = undefined;
|
||||
|
||||
this.changeTimeSystem = this.changeTimeSystem.bind(this);
|
||||
|
||||
//Set the time system initially
|
||||
if (conductor.timeSystem()) {
|
||||
this.changeTimeSystem(conductor.timeSystem());
|
||||
}
|
||||
|
||||
//Listen for subsequent changes to time system
|
||||
conductor.on('timeSystem', this.changeTimeSystem);
|
||||
|
||||
if (metadata.key === 'fixed') {
|
||||
//Fixed automatically supports all time systems
|
||||
this._availableTimeSystems = timeSystems;
|
||||
} else {
|
||||
this._availableTimeSystems = timeSystems.filter(function (timeSystem) {
|
||||
//Only include time systems that have tick sources that
|
||||
// support the current mode
|
||||
return timeSystem.tickSources().some(function (tickSource) {
|
||||
return metadata.key === tickSource.metadata.mode;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set the currently selected time system
|
||||
* @param timeSystem
|
||||
* @returns {TimeSystem} the currently selected time system
|
||||
*/
|
||||
TimeConductorMode.prototype.changeTimeSystem = function (timeSystem) {
|
||||
// On time system change, apply default deltas
|
||||
var defaults = timeSystem.defaults() || {
|
||||
bounds: {
|
||||
start: 0,
|
||||
end: 0
|
||||
},
|
||||
deltas: {
|
||||
start: 0,
|
||||
end: 0
|
||||
}
|
||||
};
|
||||
this.conductor.bounds(defaults.bounds);
|
||||
this.deltas(defaults.deltas);
|
||||
|
||||
// Tick sources are mode-specific, so restrict tick sources to only those supported by the current mode.
|
||||
var key = this._metadata.key;
|
||||
var tickSources = timeSystem.tickSources();
|
||||
if (tickSources) {
|
||||
this._availableTickSources = tickSources.filter(function (source){
|
||||
return source.metadata.mode === key;
|
||||
});
|
||||
}
|
||||
|
||||
// Set an appropriate tick source from the new time system
|
||||
this.tickSource(this.availableTickSources(timeSystem)[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {ModeMetadata}
|
||||
*/
|
||||
TimeConductorMode.prototype.metadata = function () {
|
||||
return this._metadata;
|
||||
};
|
||||
|
||||
TimeConductorMode.prototype.availableTimeSystems = function () {
|
||||
return this._availableTimeSystems;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tick sources are mode-specific. This returns a filtered list of the tick sources available in the currently selected mode
|
||||
* @param timeSystem
|
||||
* @returns {Array.<T>}
|
||||
*/
|
||||
TimeConductorMode.prototype.availableTickSources = function (timeSystem) {
|
||||
return this._availableTickSources;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get or set tick source. Setting tick source will also start
|
||||
* listening to it and unlisten from any existing tick source
|
||||
* @param tickSource
|
||||
* @returns {TickSource}
|
||||
*/
|
||||
TimeConductorMode.prototype.tickSource = function (tickSource) {
|
||||
if (arguments.length > 0) {
|
||||
if (this._tickSourceUnlisten) {
|
||||
this._tickSourceUnlisten();
|
||||
}
|
||||
this._tickSource = tickSource;
|
||||
if (tickSource) {
|
||||
this._tickSourceUnlisten = tickSource.listen(this.tick.bind(this));
|
||||
//Now following a tick source
|
||||
this.conductor.follow(true);
|
||||
} else {
|
||||
this.conductor.follow(false);
|
||||
}
|
||||
}
|
||||
return this._tickSource;
|
||||
};
|
||||
|
||||
TimeConductorMode.prototype.destroy = function () {
|
||||
this.conductor.off('timeSystem', this.changeTimeSystem);
|
||||
|
||||
if (this._tickSourceUnlisten) {
|
||||
this._tickSourceUnlisten();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* On change, the new deltas will be used to calculate and set the
|
||||
* bounds on the time conductor.
|
||||
* @param deltas
|
||||
* @returns {TimeSystemDeltas}
|
||||
*/
|
||||
TimeConductorMode.prototype.deltas = function (deltas) {
|
||||
if (arguments.length !== 0) {
|
||||
var oldEnd = this.conductor.bounds().end;
|
||||
|
||||
if (this._deltas && this._deltas.end !== undefined){
|
||||
//Calculate the previous raw end value (without delta)
|
||||
oldEnd = oldEnd - this._deltas.end;
|
||||
}
|
||||
|
||||
this._deltas = deltas;
|
||||
|
||||
var newBounds = {
|
||||
start: oldEnd - this._deltas.start,
|
||||
end: oldEnd + this._deltas.end
|
||||
};
|
||||
|
||||
this.conductor.bounds(newBounds);
|
||||
}
|
||||
return this._deltas;
|
||||
};
|
||||
|
||||
return TimeConductorMode;
|
||||
}
|
||||
);
|
@ -1,45 +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(
|
||||
['../TimeConductor'],
|
||||
function (TimeConductor) {
|
||||
|
||||
function TimeConductorService() {
|
||||
this._conductor = new TimeConductor();
|
||||
this._mode = undefined;
|
||||
}
|
||||
|
||||
TimeConductorService.prototype.mode = function (mode) {
|
||||
if (arguments.length === 1) {
|
||||
this._mode = mode;
|
||||
}
|
||||
return this._mode;
|
||||
};
|
||||
|
||||
TimeConductorService.prototype.conductor = function () {
|
||||
return this._conductor;
|
||||
};
|
||||
|
||||
return TimeConductorService;
|
||||
}
|
||||
);
|
@ -43,6 +43,9 @@ define(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation methods below are invoked directly from controls in the TimeConductor form
|
||||
*/
|
||||
TimeConductorValidation.prototype.validateStart = function (start) {
|
||||
var bounds = this.conductor.bounds();
|
||||
return this.conductor.validateBounds({start: start, end: bounds.end}) === true;
|
||||
@ -61,19 +64,6 @@ define(
|
||||
return !isNaN(endDelta) && endDelta >= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates the delta values in the form model. Deltas are offsets
|
||||
* from a fixed point in time, and are used in follow modes as the
|
||||
* primary determinant of conductor bounds.
|
||||
* @param formModel
|
||||
* @returns {*}
|
||||
*/
|
||||
TimeConductorValidation.prototype.validateDeltas = function (startDelta, endDelta) {
|
||||
// Validate that start Delta is some non-zero value, and that end
|
||||
// delta is zero or positive (ie. 'now' or some time in the future).
|
||||
return this.validateStartDelta(startDelta) && this.validateEndDelta(endDelta);
|
||||
};
|
||||
|
||||
return TimeConductorValidation;
|
||||
}
|
||||
);
|
||||
|
@ -0,0 +1,196 @@
|
||||
/*****************************************************************************
|
||||
* 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(
|
||||
[
|
||||
'./TimeConductorMode'
|
||||
],
|
||||
function (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.
|
||||
*
|
||||
* @param conductor
|
||||
* @param timeSystems
|
||||
* @constructor
|
||||
*/
|
||||
function TimeConductorViewService(conductor, timeSystems) {
|
||||
this._timeSystems = timeSystems = timeSystems.map(
|
||||
function (timeSystemConstructor) {
|
||||
return timeSystemConstructor();
|
||||
});
|
||||
|
||||
this._conductor = conductor;
|
||||
this._mode = 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._availableModes = {
|
||||
'fixed': {
|
||||
key: 'fixed',
|
||||
cssclass: 'icon-calendar',
|
||||
label: 'Fixed',
|
||||
name: 'Fixed Timespan Mode',
|
||||
description: 'Query and explore data that falls between two fixed datetimes.'
|
||||
}
|
||||
};
|
||||
|
||||
function timeSystemsForMode(sourceType) {
|
||||
return timeSystems.filter(function (timeSystem){
|
||||
return timeSystem.tickSources().some(function (tickSource){
|
||||
return tickSource.metadata.mode === sourceType;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//Only show 'real-time mode' if appropriate time systems available
|
||||
if (timeSystemsForMode('realtime').length > 0 ) {
|
||||
this._availableModes['realtime'] = {
|
||||
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.'
|
||||
};
|
||||
}
|
||||
|
||||
//Only show 'LAD mode' if appropriate time systems available
|
||||
if (timeSystemsForMode('LAD').length > 0) {
|
||||
this._availableModes['latest'] = {
|
||||
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.'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (arguments.length === 1) {
|
||||
var timeSystem = this._conductor.timeSystem();
|
||||
var modes = this.availableModes();
|
||||
var modeMetaData = modes[newModeKey];
|
||||
|
||||
if (this._mode) {
|
||||
this._mode.destroy();
|
||||
}
|
||||
|
||||
function contains(timeSystems, timeSystem) {
|
||||
return timeSystems.find(function (t) {
|
||||
return t.metadata.key === timeSystem.metadata.key;
|
||||
}) !== undefined;
|
||||
}
|
||||
this._mode = new TimeConductorMode(modeMetaData, this._conductor, this._timeSystems);
|
||||
if (!timeSystem || !contains(this._mode.availableTimeSystems(), timeSystem)) {
|
||||
timeSystem = this._mode.availableTimeSystems()[0];
|
||||
this._conductor.timeSystem(timeSystem, timeSystem.defaults().bounds);
|
||||
}
|
||||
}
|
||||
return this._mode ? this._mode.metadata().key : undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef {object} Delta
|
||||
* @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 {Delta} current value of the deltas
|
||||
*/
|
||||
TimeConductorViewService.prototype.deltas = function () {
|
||||
//Deltas stored on mode. Use .apply to preserve arguments
|
||||
return this._mode.deltas.apply(this._mode, 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._availableModes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Availability of time systems depends on the currently selected
|
||||
* mode. Time systems and tick sources are mode dependent
|
||||
*/
|
||||
TimeConductorViewService.prototype.availableTimeSystems = function () {
|
||||
return this._mode.availableTimeSystems();
|
||||
};
|
||||
|
||||
return TimeConductorViewService;
|
||||
}
|
||||
);
|
@ -1,70 +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(
|
||||
['./TimeConductorMode'],
|
||||
function (TimeConductorMode) {
|
||||
|
||||
/**
|
||||
* Handles time conductor behavior when it is in 'fixed' mode. In
|
||||
* fixed mode, the time conductor is bound by two dates and does not
|
||||
* progress.
|
||||
* @param conductor
|
||||
* @param timeSystems
|
||||
* @constructor
|
||||
*/
|
||||
function FixedMode(conductor, timeSystem, key) {
|
||||
TimeConductorMode.call(this, conductor, timeSystem, key);
|
||||
}
|
||||
|
||||
FixedMode.prototype = Object.create(TimeConductorMode.prototype);
|
||||
|
||||
FixedMode.prototype.initialize = function () {
|
||||
TimeConductorMode.prototype.initialize.apply(this);
|
||||
this.conductor.follow(false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines behavior to occur when selected time system changes. In
|
||||
* this case, sets default bounds on the time conductor.
|
||||
* @param timeSystem
|
||||
* @returns {*}
|
||||
*/
|
||||
FixedMode.prototype.timeSystem = function (timeSystem){
|
||||
TimeConductorMode.prototype.timeSystem.apply(this, arguments);
|
||||
|
||||
if (timeSystem) {
|
||||
var defaults = this.defaults();
|
||||
|
||||
var bounds = {
|
||||
start: defaults.bounds.start,
|
||||
end: defaults.bounds.end
|
||||
};
|
||||
|
||||
this.conductor.timeSystem(timeSystem, bounds);
|
||||
}
|
||||
return this._timeSystem;
|
||||
};
|
||||
|
||||
return FixedMode;
|
||||
}
|
||||
);
|
@ -1,149 +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(
|
||||
['./TimeConductorMode'],
|
||||
function (TimeConductorMode) {
|
||||
|
||||
/**
|
||||
* A parent class for Realtime and LAD modes, which both advance the
|
||||
* time conductor bounds over time. The event that advances the time
|
||||
* conductor is abstracted to a TickSource. Unlike FixedMode, the
|
||||
* two 'follow' modes define 'deltas' which are offsets from a fixed
|
||||
* end point. Thus, in follow mode, the end time of the conductor is
|
||||
* the mode relevant, with both offsets defined relative to it.
|
||||
* @constructor
|
||||
*/
|
||||
function FollowMode(conductor, timeSystem, key) {
|
||||
TimeConductorMode.call(this, conductor, timeSystem, key);
|
||||
|
||||
this._deltas = undefined;
|
||||
this._tickSource = undefined;
|
||||
this._tickSourceUnlisten = undefined;
|
||||
}
|
||||
|
||||
FollowMode.prototype = Object.create(TimeConductorMode.prototype);
|
||||
|
||||
FollowMode.prototype.initialize = function () {
|
||||
TimeConductorMode.prototype.initialize.apply(this);
|
||||
this.conductor.follow(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param time
|
||||
*/
|
||||
FollowMode.prototype.tick = function (time) {
|
||||
var deltas = this.deltas();
|
||||
this.conductor.bounds({
|
||||
start: time - deltas.start,
|
||||
end: time + deltas.end
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get or set tick source. Setting tick source will also start
|
||||
* listening to it and unlisten from any existing tick source
|
||||
* @param tickSource
|
||||
* @returns {TickSource}
|
||||
*/
|
||||
FollowMode.prototype.tickSource = function (tickSource) {
|
||||
if (tickSource) {
|
||||
if (this._tickSourceUnlisten) {
|
||||
this._tickSourceUnlisten();
|
||||
}
|
||||
this._tickSource = tickSource;
|
||||
this._tickSourceUnlisten = tickSource.listen(this.tick.bind(this));
|
||||
}
|
||||
return this._tickSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* On time system change, default the bounds values in the time
|
||||
* conductor, using the deltas associated with this mode.
|
||||
* @param timeSystem
|
||||
* @returns {TimeSystem}
|
||||
*/
|
||||
FollowMode.prototype.timeSystem = function (timeSystem) {
|
||||
TimeConductorMode.prototype.timeSystem.apply(this, arguments);
|
||||
|
||||
if (timeSystem) {
|
||||
var defaults = this.defaults();
|
||||
|
||||
if (arguments.length > 0) {
|
||||
var bounds = {
|
||||
start: defaults.bounds.start,
|
||||
end: defaults.bounds.end
|
||||
};
|
||||
|
||||
if (defaults.deltas) {
|
||||
bounds.start = bounds.end - defaults.deltas.start;
|
||||
bounds.end = bounds.end + defaults.deltas.end;
|
||||
this._deltas = JSON.parse(JSON.stringify(defaults.deltas));
|
||||
}
|
||||
|
||||
this.conductor.timeSystem(timeSystem, bounds);
|
||||
}
|
||||
}
|
||||
return this._timeSystem;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
* bounds on the time conductor.
|
||||
* @param deltas
|
||||
* @returns {TimeSystemDeltas}
|
||||
*/
|
||||
FollowMode.prototype.deltas = function (deltas) {
|
||||
if (arguments.length !== 0) {
|
||||
var oldEnd = this.conductor.bounds().end;
|
||||
|
||||
if (this._deltas && this._deltas.end){
|
||||
//Calculate the previous 'true' end value (without delta)
|
||||
oldEnd = oldEnd - this._deltas.end;
|
||||
}
|
||||
|
||||
this._deltas = deltas;
|
||||
|
||||
var newBounds = {
|
||||
start: oldEnd - this._deltas.start,
|
||||
end: oldEnd + this._deltas.end
|
||||
};
|
||||
|
||||
this.conductor.bounds(newBounds);
|
||||
}
|
||||
return this._deltas;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop listening to tick sources
|
||||
*/
|
||||
FollowMode.prototype.destroy = function () {
|
||||
if (this._tickSourceUnlisten) {
|
||||
this._tickSourceUnlisten();
|
||||
}
|
||||
};
|
||||
|
||||
return FollowMode;
|
||||
}
|
||||
);
|
@ -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(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Supports mode-specific time conductor behavior. This class
|
||||
* defines a parent with default behavior that specific modes are
|
||||
* expected to override.
|
||||
*
|
||||
* @interface
|
||||
* @constructor
|
||||
* @param {TimeConductorMetadata} metadata
|
||||
*/
|
||||
function TimeConductorMode(conductor, timeSystem, key) {
|
||||
this.conductor = conductor;
|
||||
this._timeSystem = timeSystem;
|
||||
this._key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function is called when mode becomes active (ie. is selected)
|
||||
*/
|
||||
TimeConductorMode.prototype.initialize = function () {
|
||||
this.timeSystem(this._timeSystem);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get or set the currently selected time system
|
||||
* @param timeSystem
|
||||
* @returns {TimeSystem} the currently selected time system
|
||||
*/
|
||||
TimeConductorMode.prototype.timeSystem = function (timeSystem) {
|
||||
if (arguments.length > 0) {
|
||||
this._timeSystem = timeSystem;
|
||||
}
|
||||
return this._timeSystem;
|
||||
};
|
||||
|
||||
TimeConductorMode.prototype.key = function () {
|
||||
return this._key;
|
||||
};
|
||||
|
||||
TimeConductorMode.prototype.defaults = function () {
|
||||
var timeSystem = this.timeSystem(),
|
||||
key = this.key();
|
||||
|
||||
if (timeSystem) {
|
||||
return timeSystem.defaults(key);
|
||||
}
|
||||
};
|
||||
|
||||
TimeConductorMode.prototype.destroy = function () {
|
||||
};
|
||||
|
||||
return TimeConductorMode;
|
||||
}
|
||||
);
|
@ -62,6 +62,7 @@ requirejs.config({
|
||||
"text": "bower_components/text/text",
|
||||
"uuid": "bower_components/node-uuid/uuid",
|
||||
"zepto": "bower_components/zepto/zepto.min",
|
||||
"d3": "bower_components/d3/d3.min"
|
||||
},
|
||||
|
||||
"shim": {
|
||||
@ -82,6 +83,9 @@ requirejs.config({
|
||||
},
|
||||
"zepto": {
|
||||
"exports": "Zepto"
|
||||
},
|
||||
"d3": {
|
||||
"exports": "d3"
|
||||
}
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user