mirror of
https://github.com/nasa/openmct.git
synced 2025-05-03 09:12:51 +00:00
[Time Conductor] #933 Initial markup
This commit is contained in:
parent
652a50c700
commit
bca5eb0fdb
@ -18,6 +18,8 @@
|
|||||||
"node-uuid": "^1.4.7",
|
"node-uuid": "^1.4.7",
|
||||||
"comma-separated-values": "^3.6.4",
|
"comma-separated-values": "^3.6.4",
|
||||||
"FileSaver.js": "^0.0.2",
|
"FileSaver.js": "^0.0.2",
|
||||||
"zepto": "^1.1.6"
|
"zepto": "^1.1.6",
|
||||||
|
"eventemitter3": "^1.2.0",
|
||||||
|
"d3": "~4.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
main.js
11
main.js
@ -28,13 +28,15 @@ requirejs.config({
|
|||||||
"angular-route": "bower_components/angular-route/angular-route.min",
|
"angular-route": "bower_components/angular-route/angular-route.min",
|
||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/promise.min",
|
"es6-promise": "bower_components/es6-promise/promise.min",
|
||||||
|
"EventEmitter": "bower_components/eventemitter3/index",
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
"screenfull": "bower_components/screenfull/dist/screenfull.min",
|
"screenfull": "bower_components/screenfull/dist/screenfull.min",
|
||||||
"text": "bower_components/text/text",
|
"text": "bower_components/text/text",
|
||||||
"uuid": "bower_components/node-uuid/uuid",
|
"uuid": "bower_components/node-uuid/uuid",
|
||||||
"zepto": "bower_components/zepto/zepto.min"
|
"zepto": "bower_components/zepto/zepto.min",
|
||||||
|
"d3": "bower_components/d3/d3.min"
|
||||||
},
|
},
|
||||||
"shim": {
|
"shim": {
|
||||||
"angular": {
|
"angular": {
|
||||||
@ -43,6 +45,9 @@ requirejs.config({
|
|||||||
"angular-route": {
|
"angular-route": {
|
||||||
"deps": ["angular"]
|
"deps": ["angular"]
|
||||||
},
|
},
|
||||||
|
"EventEmitter": {
|
||||||
|
"exports": "EventEmitter"
|
||||||
|
},
|
||||||
"moment-duration-format": {
|
"moment-duration-format": {
|
||||||
"deps": ["moment"]
|
"deps": ["moment"]
|
||||||
},
|
},
|
||||||
@ -51,6 +56,9 @@ requirejs.config({
|
|||||||
},
|
},
|
||||||
"zepto": {
|
"zepto": {
|
||||||
"exports": "Zepto"
|
"exports": "Zepto"
|
||||||
|
},
|
||||||
|
"d3": {
|
||||||
|
"exports": "d3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -82,6 +90,7 @@ define([
|
|||||||
'./platform/features/pages/bundle',
|
'./platform/features/pages/bundle',
|
||||||
'./platform/features/plot/bundle',
|
'./platform/features/plot/bundle',
|
||||||
'./platform/features/timeline/bundle',
|
'./platform/features/timeline/bundle',
|
||||||
|
'./platform/features/conductor-v2/bundle',
|
||||||
'./platform/features/table/bundle',
|
'./platform/features/table/bundle',
|
||||||
'./platform/forms/bundle',
|
'./platform/forms/bundle',
|
||||||
'./platform/identity/bundle',
|
'./platform/identity/bundle',
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="holder l-flex-col flex-elem grows l-object-wrapper">
|
<div class="holder l-flex-col flex-elem grows l-object-wrapper l-controls-visible l-time-controller-visible">
|
||||||
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
|
||||||
<!-- Toolbar and Save/Cancel buttons -->
|
<!-- Toolbar and Save/Cancel buttons -->
|
||||||
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
|
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
|
||||||
@ -59,4 +59,9 @@
|
|||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- put time conductor in here? -->
|
||||||
|
<mct-representation mct-object="domainObject"
|
||||||
|
key="'time-conductor'"
|
||||||
|
class="abs holder flex-elem flex-fixed l-time-controller">
|
||||||
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
|
82
platform/features/conductor-v2/bundle.js
Normal file
82
platform/features/conductor-v2/bundle.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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/TimeConductor",
|
||||||
|
"./src/TimeConductorController",
|
||||||
|
"./src/MCTConductorAxis",
|
||||||
|
"text!./res/templates/time-conductor.html",
|
||||||
|
"text!./res/templates/mode-selector/mode-selector.html",
|
||||||
|
"text!./res/templates/mode-selector/mode-menu.html",
|
||||||
|
'legacyRegistry'
|
||||||
|
], function (
|
||||||
|
TimeConductor,
|
||||||
|
TimeConductorController,
|
||||||
|
MCTConductorAxis,
|
||||||
|
timeConductorTemplate,
|
||||||
|
modeSelectorTemplate,
|
||||||
|
modeMenuTemplate,
|
||||||
|
legacyRegistry
|
||||||
|
) {
|
||||||
|
|
||||||
|
legacyRegistry.register("platform/features/conductor-v2", {
|
||||||
|
"extensions": {
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"key": "timeConductor",
|
||||||
|
"implementation": TimeConductor
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controllers": [
|
||||||
|
{
|
||||||
|
"key": "TimeConductorController",
|
||||||
|
"implementation": TimeConductorController,
|
||||||
|
"depends": [
|
||||||
|
"$scope",
|
||||||
|
"timeConductor"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"key": "mctConductorAxis",
|
||||||
|
"implementation": MCTConductorAxis,
|
||||||
|
"depends": ["$timeout"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"representations": [
|
||||||
|
{
|
||||||
|
"key": "time-conductor",
|
||||||
|
"template": timeConductorTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mode-selector",
|
||||||
|
"template": modeSelectorTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mode-menu",
|
||||||
|
"template": modeMenuTemplate
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,80 @@
|
|||||||
|
<!--
|
||||||
|
Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
Administration. All rights reserved.
|
||||||
|
|
||||||
|
Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Open MCT Web includes source code licensed under additional open source
|
||||||
|
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
this source code distribution or the Licensing information page available
|
||||||
|
at runtime from the About dialog for additional information.
|
||||||
|
-->
|
||||||
|
<div class="contents">
|
||||||
|
<div class="pane left menu-items">
|
||||||
|
<ul>
|
||||||
|
<li ng-click="representation.mode='fixed'">
|
||||||
|
<a
|
||||||
|
ng-mouseover="representation.activeMetadata = {
|
||||||
|
glyph: '\ue604',
|
||||||
|
name: 'Fixed Time-Span',
|
||||||
|
description: 'Display data that falls between two fixed dates'
|
||||||
|
}"
|
||||||
|
ng-mouseleave="representation.activeMetadata = undefined">
|
||||||
|
<span class="ui-symbol icon type-icon">
|
||||||
|

|
||||||
|
</span>
|
||||||
|
Fixed Time-span
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li ng-click="representation.mode='realtime'">
|
||||||
|
<a
|
||||||
|
ng-mouseover="representation.activeMetadata = {
|
||||||
|
glyph: '\u0043',
|
||||||
|
name: 'Real-time Mode',
|
||||||
|
description: 'Monitor real-time streaming data as it comes in to the application. The Time Conductor will automatically advance itself based on a UTC clock.'
|
||||||
|
}"
|
||||||
|
ng-mouseleave="representation.activeMetadata = undefined">
|
||||||
|
<span class="ui-symbol icon type-icon">
|
||||||
|
C
|
||||||
|
</span>
|
||||||
|
Real-time
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li ng-click="representation.mode='latest'">
|
||||||
|
<a
|
||||||
|
ng-mouseover="representation.activeMetadata = {
|
||||||
|
glyph: '\u0044',
|
||||||
|
name: 'Latest Available Data',
|
||||||
|
description: 'Monitor real-time streaming data as it comes in to the application. In contrast to real-time mode the time conductor will only advance when data becomes available.'
|
||||||
|
}"
|
||||||
|
ng-mouseleave="representation.activeMetadata = undefined">
|
||||||
|
<span class="ui-symbol icon type-icon">
|
||||||
|
D
|
||||||
|
</span>
|
||||||
|
Latest Available Data
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="pane right menu-item-description">
|
||||||
|
<div class="desc-area ui-symbol icon type-icon">
|
||||||
|
{{representation.activeMetadata.glyph}}
|
||||||
|
</div>
|
||||||
|
<div class="desc-area title">
|
||||||
|
{{representation.activeMetadata.name}}
|
||||||
|
</div>
|
||||||
|
<div class="desc-area description">
|
||||||
|
{{representation.activeMetadata.description}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,50 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
.super-menu.mode-selector-menu {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
.super-menu.mode-selector-menu {
|
||||||
|
height: 200px;
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
.super-menu.mode-selector-menu .menu-item-description .desc-area.icon {
|
||||||
|
height: 20%;
|
||||||
|
font-size: 3em;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
.super-menu .mode-selector-menu .menu-item-description .desc-area.description {
|
||||||
|
height: 60%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<span ng-controller="ClickAwayController as modeController">
|
||||||
|
<div class="s-menu-btn"
|
||||||
|
ng-click="modeController.toggle()">
|
||||||
|
<span class="title-label">Fixed Time Span</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu super-menu mode-selector-menu"
|
||||||
|
ng-show="modeController.isActive()">
|
||||||
|
<mct-representation mct-object="domainObject"
|
||||||
|
key="'mode-menu'">
|
||||||
|
</mct-representation>
|
||||||
|
</div>
|
||||||
|
</span>
|
@ -0,0 +1,94 @@
|
|||||||
|
<style>
|
||||||
|
.time-system .menu{
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
.l-data-availability {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
background-color: #3b3b3b
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-time-range-inputs-elem {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-time-range-inputs-elem.l-flex-row {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.l-axis-holder {
|
||||||
|
height: 30px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-axis-holder svg, .l-axis-holder svg path,
|
||||||
|
.l-axis-holder svg line {
|
||||||
|
stroke: #A0A0A0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-axis-holder svg>g
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<!-- Parent holder for time conductor. follow-mode | fixed-mode -->
|
||||||
|
<div class="follow-mode"
|
||||||
|
ng-controller="TimeConductorController as tcController" class="l-flex-col">
|
||||||
|
<!-- Holds date selectors and ticks -->
|
||||||
|
<div class="l-conductor-dates">
|
||||||
|
<form class="l-time-range-inputs-holder l-flex-row flex-elem"
|
||||||
|
ng-submit="tcController.updateBoundsFromForm(formModel)">
|
||||||
|
<span class="l-time-range-inputs-elem t-inputs-w l-flex-row flex-elem">
|
||||||
|
<span class="l-time-range-input-w flex-elem start-date">
|
||||||
|
<mct-control key="'datetime-field'"
|
||||||
|
structure="{
|
||||||
|
format: 'utc',
|
||||||
|
validate: tcController.validateStart
|
||||||
|
}"
|
||||||
|
ng-model="formModel"
|
||||||
|
ng-blur="tcController.updateBoundsFromForm()"
|
||||||
|
field="'start'"
|
||||||
|
class="time-range-start">
|
||||||
|
</mct-control>
|
||||||
|
</span>
|
||||||
|
<span class="l-time-range-input-w flex-elem end-date"
|
||||||
|
ng-controller="ToggleController as t2">
|
||||||
|
<mct-control key="'datetime-field'"
|
||||||
|
structure="{
|
||||||
|
format: 'utc',
|
||||||
|
validate: tcController.validateEnd
|
||||||
|
}"
|
||||||
|
ng-model="formModel"
|
||||||
|
ng-blur="trCtrl.updateBoundsFromForm()"
|
||||||
|
field="'end'"
|
||||||
|
class="time-range-end">
|
||||||
|
</mct-control>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<input type="submit" class="hidden">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="l-conductor-ticks">
|
||||||
|
<mct-conductor-axis></mct-conductor-axis>
|
||||||
|
</div>
|
||||||
|
<!-- Holds data availability, time of interest -->
|
||||||
|
<div class="l-data-availability"></div>
|
||||||
|
<!-- Holds time system and session selectors, and zoom control -->
|
||||||
|
<div class="l-time-system-zoom">
|
||||||
|
<mct-representation
|
||||||
|
key="'mode-selector'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
class="holder flex-elem">
|
||||||
|
</mct-representation>
|
||||||
|
<mct-control
|
||||||
|
key="'menu-button'"
|
||||||
|
class="time-system"
|
||||||
|
ng-model="conductorModel.timeSystem"
|
||||||
|
structure="{
|
||||||
|
text: 'utc',
|
||||||
|
options: [
|
||||||
|
{name: 'utc', key:'utc', glyph:'\u0043'},
|
||||||
|
{name: 'scet', key:'scet', glyph:'\u0043'},
|
||||||
|
{name: 'sclk', key:'sclk', glyph:'\u0043'}
|
||||||
|
]}">
|
||||||
|
</mct-control>
|
||||||
|
</div>
|
||||||
|
</div>
|
100
platform/features/conductor-v2/src/MctConductorAxis.js
Normal file
100
platform/features/conductor-v2/src/MctConductorAxis.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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(
|
||||||
|
[
|
||||||
|
"zepto",
|
||||||
|
"d3"
|
||||||
|
],
|
||||||
|
function ($, d3) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mct-control will dynamically include the control
|
||||||
|
* for a form element based on a symbolic key. Individual
|
||||||
|
* controls are defined under the extension category
|
||||||
|
* `controls`; this allows plug-ins to introduce new form
|
||||||
|
* control types while still making use of the form
|
||||||
|
* generator to ensure an overall consistent form style.
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/forms
|
||||||
|
*/
|
||||||
|
function MCTConductorAxis($timeout) {
|
||||||
|
|
||||||
|
function link(scope, element, attrs, ngModelController) {
|
||||||
|
$timeout(function () {
|
||||||
|
var target = element[0].firstChild,
|
||||||
|
width = target.offsetWidth,
|
||||||
|
height = target.offsetHeight,
|
||||||
|
padding = 1;
|
||||||
|
|
||||||
|
var vis = d3.select(target)
|
||||||
|
.append('svg:svg')
|
||||||
|
//.attr('viewBox', '0 0 ' + width + ' ' +
|
||||||
|
// height)
|
||||||
|
.attr('width', '100%')
|
||||||
|
.attr('height', height);
|
||||||
|
//.attr('preserveAspectRatio', 'xMidYMid meet');
|
||||||
|
|
||||||
|
// define the x scale (horizontal)
|
||||||
|
var mindate = new Date(2012,0,1),
|
||||||
|
maxdate = new Date(2016,0,1);
|
||||||
|
|
||||||
|
var xScale = d3.scaleTime()
|
||||||
|
.domain([mindate, maxdate])
|
||||||
|
.range([padding, width - padding * 2]);
|
||||||
|
|
||||||
|
var xAxis = d3.axisTop()
|
||||||
|
.scale(xScale);
|
||||||
|
|
||||||
|
// draw x axis with labels and move to the bottom of the chart area
|
||||||
|
var axisElement = vis.append("g")
|
||||||
|
.attr("class", "xaxis") // give it a class so it can be used to select only xaxis labels below
|
||||||
|
.attr("transform", "translate(0," + (height - padding) + ")");
|
||||||
|
|
||||||
|
axisElement.call(xAxis);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Only show at the element level
|
||||||
|
restrict: "E",
|
||||||
|
|
||||||
|
template: "<div class=\"l-axis-holder\"></div>",
|
||||||
|
|
||||||
|
// ngOptions is terminal, so we need to be higher priority
|
||||||
|
priority: 1000,
|
||||||
|
|
||||||
|
// Link function
|
||||||
|
link: link,
|
||||||
|
|
||||||
|
// Pass through Angular's normal input field attributes
|
||||||
|
scope: {
|
||||||
|
// Used to choose which form control to use
|
||||||
|
start: "=",
|
||||||
|
end: "="
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return MCTConductorAxis;
|
||||||
|
}
|
||||||
|
);
|
183
platform/features/conductor-v2/src/TimeConductor.js
Normal file
183
platform/features/conductor-v2/src/TimeConductor.js
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public API for setting and querying time conductor state. The
|
||||||
|
* time conductor is the means by which the temporal bounds of a view
|
||||||
|
* are controlled. Time-sensitive views will typically respond to
|
||||||
|
* changes to bounds or other properties of the time conductor and
|
||||||
|
* update the data displayed based on the time conductor state.
|
||||||
|
*
|
||||||
|
* The TimeConductor extends the EventEmitter class. A number of events are
|
||||||
|
* fired when properties of the time conductor change, which are
|
||||||
|
* documented below.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function TimeConductor() {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
//The Time System
|
||||||
|
this.system = undefined;
|
||||||
|
//The Time Of Interest
|
||||||
|
this.toi = undefined;
|
||||||
|
|
||||||
|
this.boundsVal = {
|
||||||
|
start: undefined,
|
||||||
|
end: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
//Default to fixed mode
|
||||||
|
this.followMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeConductor.prototype = Object.create(EventEmitter.prototype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the given bounds. This can be used for pre-validation of
|
||||||
|
* bounds, for example by views validating user inputs.
|
||||||
|
* @param bounds The start and end time of the conductor.
|
||||||
|
* @returns {string | true} A validation error, or true if valid
|
||||||
|
*/
|
||||||
|
TimeConductor.prototype.validateBounds = function (bounds) {
|
||||||
|
if ((bounds.start === undefined) ||
|
||||||
|
(bounds.end === undefined) ||
|
||||||
|
isNaN(bounds.start) ||
|
||||||
|
isNaN(bounds.end)
|
||||||
|
) {
|
||||||
|
return "Start and end must be specified as integer values";
|
||||||
|
} else if (bounds.start > bounds.end) {
|
||||||
|
return "Specified start date exceeds end bound";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
function throwOnError(validationResult) {
|
||||||
|
if (validationResult !== true) {
|
||||||
|
throw new Error(validationResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 TimeConductor#follow
|
||||||
|
* @param {boolean} followMode
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
TimeConductor.prototype.follow = function (followMode) {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
this.followMode = followMode;
|
||||||
|
/**
|
||||||
|
* @event TimeConductor#follow The TimeConductor has toggled
|
||||||
|
* into or out of follow mode.
|
||||||
|
* @property {boolean} followMode true if follow mode is
|
||||||
|
* enabled, otherwise false.
|
||||||
|
*/
|
||||||
|
this.emit('follow', this.followMode);
|
||||||
|
}
|
||||||
|
return this.followMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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} end The end time displayed by the time conductor in ms since epoch.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Get or set the start and end time of the time conductor. Basic validation
|
||||||
|
* of bounds is performed.
|
||||||
|
*
|
||||||
|
* @param {TimeConductorBounds} newBounds
|
||||||
|
* @throws {Error} Validation error
|
||||||
|
* @fires TimeConductor#bounds
|
||||||
|
* @returns {TimeConductorBounds}
|
||||||
|
*/
|
||||||
|
TimeConductor.prototype.bounds = function (newBounds) {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
throwOnError(this.validateBounds(newBounds));
|
||||||
|
this.boundsVal = newBounds;
|
||||||
|
/**
|
||||||
|
* @event TimeConductor#bounds The start time, end time, or
|
||||||
|
* both have been updated
|
||||||
|
* @property {TimeConductorBounds} bounds
|
||||||
|
*/
|
||||||
|
this.emit('bounds', this.boundsVal);
|
||||||
|
}
|
||||||
|
return this.boundsVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or set the time system of the TimeConductor. Time systems determine
|
||||||
|
* units, epoch, and other aspects of time representation. When changing
|
||||||
|
* the time system in use, new valid bounds must also be provided.
|
||||||
|
* @param {TimeSystem} newTimeSystem
|
||||||
|
* @param {TimeConductorBounds} bounds
|
||||||
|
* @fires TimeConductor#timeSystem
|
||||||
|
* @returns {TimeSystem} The currently applied time system
|
||||||
|
*/
|
||||||
|
TimeConductor.prototype.timeSystem = function (newTimeSystem, bounds) {
|
||||||
|
if (arguments.length >= 2) {
|
||||||
|
this.system = newTimeSystem;
|
||||||
|
/**
|
||||||
|
* @event TimeConductor#timeSystem The time system used by the time
|
||||||
|
* conductor has changed. A change in Time System will always be
|
||||||
|
* followed by a bounds event specifying new query bounds
|
||||||
|
* @property {TimeSystem} The value of the currently applied
|
||||||
|
* 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');
|
||||||
|
}
|
||||||
|
return this.system;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or set the Time of Interest. The Time of Interest is the temporal
|
||||||
|
* focus of the current view. It can be manipulated by the user from the
|
||||||
|
* time conductor or from other views.
|
||||||
|
* @fires TimeConductor#timeOfInterest
|
||||||
|
* @param newTOI
|
||||||
|
* @returns {number} the current time of interest
|
||||||
|
*/
|
||||||
|
TimeConductor.prototype.timeOfInterest = function (newTOI) {
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
this.toi = newTOI;
|
||||||
|
/**
|
||||||
|
* @event TimeConductor#timeOfInterest The Time of Interest has moved.
|
||||||
|
* @property {number} Current time of interest
|
||||||
|
*/
|
||||||
|
this.emit('timeOfInterest', this.toi);
|
||||||
|
}
|
||||||
|
return this.toi;
|
||||||
|
};
|
||||||
|
|
||||||
|
return TimeConductor;
|
||||||
|
});
|
@ -0,0 +1,56 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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 () {
|
||||||
|
|
||||||
|
function TimeConductorController($scope, conductor) {
|
||||||
|
this.$scope = $scope;
|
||||||
|
this.conductor = conductor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Stuff to put on scope
|
||||||
|
- parameters
|
||||||
|
- formModel
|
||||||
|
*/
|
||||||
|
this.$scope.formModel = {
|
||||||
|
start: '2012-01-01 00:00:00.000Z',
|
||||||
|
end: '2016-01-01 00:00:00.000Z'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeConductorController.prototype.validateStart = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductorController.prototype.validateEnd = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeConductorController.prototype.updateBoundsFromForm = function () {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return TimeConductorController;
|
||||||
|
}
|
||||||
|
);
|
110
platform/features/conductor-v2/src/TimeConductorSpec.js
Normal file
110
platform/features/conductor-v2/src/TimeConductorSpec.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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) {
|
||||||
|
describe("The Time Conductor", function () {
|
||||||
|
var tc,
|
||||||
|
timeSystem,
|
||||||
|
bounds,
|
||||||
|
eventListener,
|
||||||
|
toi,
|
||||||
|
follow;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tc = new TimeConductor();
|
||||||
|
timeSystem = {};
|
||||||
|
bounds = {start: 0, end: 0};
|
||||||
|
eventListener = jasmine.createSpy("eventListener");
|
||||||
|
toi = 111;
|
||||||
|
follow = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Supports setting and querying of time of interest and and follow mode", function () {
|
||||||
|
expect(tc.timeOfInterest()).not.toBe(toi);
|
||||||
|
tc.timeOfInterest(toi);
|
||||||
|
expect(tc.timeOfInterest()).toBe(toi);
|
||||||
|
|
||||||
|
expect(tc.follow()).not.toBe(follow);
|
||||||
|
tc.follow(follow);
|
||||||
|
expect(tc.follow()).toBe(follow);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Allows setting of valid bounds", function () {
|
||||||
|
bounds = {start: 0, end: 1};
|
||||||
|
expect(tc.bounds()).not.toBe(bounds);
|
||||||
|
expect(tc.bounds.bind(tc, bounds)).not.toThrow();
|
||||||
|
expect(tc.bounds()).toBe(bounds);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Disallows setting of invalid bounds", function () {
|
||||||
|
bounds = {start: 1, end: 0};
|
||||||
|
expect(tc.bounds()).not.toBe(bounds);
|
||||||
|
expect(tc.bounds.bind(tc, bounds)).toThrow();
|
||||||
|
expect(tc.bounds()).not.toBe(bounds);
|
||||||
|
|
||||||
|
bounds = {start: 1};
|
||||||
|
expect(tc.bounds()).not.toBe(bounds);
|
||||||
|
expect(tc.bounds.bind(tc, bounds)).toThrow();
|
||||||
|
expect(tc.bounds()).not.toBe(bounds);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Allows setting of time system with bounds", function () {
|
||||||
|
expect(tc.timeSystem()).not.toBe(timeSystem);
|
||||||
|
expect(tc.timeSystem.bind(tc, timeSystem, bounds)).not.toThrow();
|
||||||
|
expect(tc.timeSystem()).toBe(timeSystem);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Disallows setting of time system without bounds", function () {
|
||||||
|
expect(tc.timeSystem()).not.toBe(timeSystem);
|
||||||
|
expect(tc.timeSystem.bind(tc, timeSystem)).toThrow();
|
||||||
|
expect(tc.timeSystem()).not.toBe(timeSystem);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Emits an event when time system changes", function () {
|
||||||
|
expect(eventListener).not.toHaveBeenCalled();
|
||||||
|
tc.on("timeSystem", eventListener);
|
||||||
|
tc.timeSystem(timeSystem, bounds);
|
||||||
|
expect(eventListener).toHaveBeenCalledWith(timeSystem);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Emits an event when time of interest changes", function () {
|
||||||
|
expect(eventListener).not.toHaveBeenCalled();
|
||||||
|
tc.on("timeOfInterest", eventListener);
|
||||||
|
tc.timeOfInterest(toi);
|
||||||
|
expect(eventListener).toHaveBeenCalledWith(toi);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Emits an event when bounds change", function () {
|
||||||
|
expect(eventListener).not.toHaveBeenCalled();
|
||||||
|
tc.on("bounds", eventListener);
|
||||||
|
tc.bounds(bounds);
|
||||||
|
expect(eventListener).toHaveBeenCalledWith(bounds);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Emits an event when follow mode changes", function () {
|
||||||
|
expect(eventListener).not.toHaveBeenCalled();
|
||||||
|
tc.on("follow", eventListener);
|
||||||
|
tc.follow(follow);
|
||||||
|
expect(eventListener).toHaveBeenCalledWith(follow);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -48,13 +48,14 @@ requirejs.config({
|
|||||||
"angular-route": "bower_components/angular-route/angular-route.min",
|
"angular-route": "bower_components/angular-route/angular-route.min",
|
||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/promise.min",
|
"es6-promise": "bower_components/es6-promise/promise.min",
|
||||||
|
"EventEmitter": "bower_components/eventemitter3/index",
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
"screenfull": "bower_components/screenfull/dist/screenfull.min",
|
"screenfull": "bower_components/screenfull/dist/screenfull.min",
|
||||||
"text": "bower_components/text/text",
|
"text": "bower_components/text/text",
|
||||||
"uuid": "bower_components/node-uuid/uuid",
|
"uuid": "bower_components/node-uuid/uuid",
|
||||||
"zepto": "bower_components/zepto/zepto.min"
|
"zepto": "bower_components/zepto/zepto.min",
|
||||||
},
|
},
|
||||||
|
|
||||||
"shim": {
|
"shim": {
|
||||||
@ -64,6 +65,9 @@ requirejs.config({
|
|||||||
"angular-route": {
|
"angular-route": {
|
||||||
"deps": [ "angular" ]
|
"deps": [ "angular" ]
|
||||||
},
|
},
|
||||||
|
"EventEmitter": {
|
||||||
|
"exports": "EventEmitter"
|
||||||
|
},
|
||||||
"moment-duration-format": {
|
"moment-duration-format": {
|
||||||
"deps": [ "moment" ]
|
"deps": [ "moment" ]
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user