diff --git a/API.md b/API.md index b51d9038a6..619c1c6787 100644 --- a/API.md +++ b/API.md @@ -352,6 +352,59 @@ request object with a start and end time is included below: } ``` + +### Telemetry Formats + +Telemetry format objects define how to interpret and display telemetry data. +They have a simple structure: + +* `key`: A `string` that uniquely identifies this formatter. +* `format`: A `function` that takes a raw telemetry value, and returns a human-readable +`string` representation of that value. It has one required argument, and three +optional arguments that provide context and can be used for returning scaled +representations of a value. An example of this is representing time values in a +scale such as the time conductor scale. There are multiple ways of representing +a point in time, and by providing a minimum scale value, maximum scale value, +and a count, it's possible to provide more useful representations of time given +the provided limitations. + * `value`: The raw telemetry value in its native type. + * `minValue`: An __optional__ argument specifying the minimum displayed value. + * `maxValue`: An __optional__ argument specifying the maximum displayed value. + * `count`: An __optional__ argument specifying the number of displayed values. +* `parse`: A `function` that takes a `string` representation of a telemetry value, +and returns the value in its native type. It accepts one argument: + * `text`: A `string` representation of a telemetry value. +* `validate`: A `function` that takes a `string` representation of a telemetry +value, and returns a `boolean` value indicating whether the provided string can be +parsed. + +#### Registering Formats + +Formats are registered with the Telemetry API using the `addFormat` function. eg. + +``` javascript +openmct.telemetry.addFormat({ + key: 'number-to-string', + format: function (number) { + return number + ''; + }, + parse: function (text) { + return Number(text); + }, + validate: function (text) { + return !isNaN(text); + } +}); +``` + +#### Examples of Formats in Use +* The [NumberFormat](https://github.com/nasa/openmct/blob/time-api-redo/platform/features/conductor/core/src/ui/NumberFormat.js) +provides an example of a simple format available by default +in OpenMCT. +* The [UTCTimeFormat](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/UTCTimeFormat.js) +is a more complex implementation of a format that uses the optional context +arguments in `format` to provide scale-appropriate values. + ### Telemetry Data Telemetry data is provided to Open MCT by _[Telemetry Providers](#telemetry-providers)_ @@ -390,10 +443,390 @@ openmct.telemetry.addProvider({ }) ``` +## Time API +Open MCT provides API for managing the temporal state of the application. Central +to this is the concept of "time bounds". Views in Open MCT will typically show +telemetry data for some prescribed date range, and the Time API provides a way +to centrally manage these bounds. + +The Time API exposes a number of methods for querying and setting the temporal +state of the application, and emits events to inform listeners when the state changes. + +Because the data displayed tends to be time domain data, Open MCT must always +have at least one time system installed and activated. When you download Open MCT, +it will be pre-configured to use the UTC time system, which is installed and +activated, along with other default plugins, in `index.html`. Installing and +activating a time system is simple, and is covered +[in the next section](#defining-and-registering-time-systems). + +### Time Systems and Bounds +#### Defining and Registering Time Systems +The time bounds of an Open MCT application are defined as numbers, and a Time +System gives meaning and context to these numbers so that they can be correctly +interpreted. Time Systems are javscript objects that provide some information +about the current time reference frame. An example of defining and registering +a new time system is given below: + +``` javascript +openmct.time.addTimeSystem({ + key: 'utc', + name: 'UTC Time', + cssClass = 'icon-clock', + timeFormat = 'utc', + durationFormat = 'duration', + isUTCBased = true +}); +``` + +The example above defines a new utc based time system. In fact, this time system +is configured and activated by default from `index.html` in the default +installation of Open MCT if you download the source from GitHub. Some details of +each of the required properties is provided below. + +* `key`: A `string` that uniquely identifies this time system. +* `name`: A `string` providing a brief human readable label. If the [Time Conductor](#the-time-conductor) +plugin is enabled, this name will identify the time system in a dropdown menu. +* `cssClass`: A class name `string` that will be applied to the time system when +it appears in the UI. This will be used to represent the time system with an icon. +There are a number of built-in icon classes [available in Open MCT](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss), +or a custom class can be used here. +* `timeFormat`: A `string` corresponding to the key of a registered +[telemetry time format](#telemetry-formats). The format will be used for +displaying discrete timestamps from telemetry streams when this time system is +activated. If the [UTCTimeSystem](#included-plugins) is enabled, then the `utc` +format can be used if this is a utc-based time system +* `durationFormat`: A `string` corresponding to the key of a registered +[telemetry time format](#telemetry-formats). The format will be used for +displaying time ranges, for example `00:15:00` might be used to represent a time +period of fifteen minutes. These are used by the Time Conductor plugin to specify +relative time offsets. If the [UTCTimeSystem](#included-plugins) is enabled, +then the `duration` format can be used if this is a utc-based time system +* `isUTCBased`: A `boolean` that defines whether this time system represents +numbers in UTC terrestrial time. + +#### Getting and Setting the Active Time System + +Once registered, a time system can be activated using a key, or an instance of +the time system itself. + +```javascript +openmct.time.timeSystem('utc'); +``` + +A time system can be immediately activated upon registration: + +```javascript +var utcTimeSystem = { + key: 'utc', + name: 'UTC Time', + cssClass = 'icon-clock', + timeFormat = 'utc', + durationFormat = 'duration', + isUTCBased = true +}; +openmct.time.addTimeSystem(utcTimeSystem); +openmct.time.timeSystem(utcTimeSystem); +``` + +Setting the active time system will trigger a [time system event](#time-events). + +### Time Bounds + +The TimeAPI provides a getter/setter for querying and setting time bounds. Time +bounds are simply an object with a `start` and an end `end` attribute. + +* `start`: A `number` representing a moment in time in the active [Time System](#defining-and-registering-time-systems). +This will be used as the beginning of the time period displayed by time-responsive +telemetry views. +* `end`: A `number` representing a moment in time in the active [Time System](#defining-and-registering-time-systems). +This will be used as the end of the time period displayed by time-responsive +telemetry views. + +If invoked with bounds, it will set the new time bounds system-wide. If invoked +without any parameters, it will return the current application-wide time bounds. + +``` javascript +const ONE_HOUR = 60 * 60 * 1000; +let now = Date.now(); +openmct.time.bounds({start: now - ONE_HOUR, now); +``` + +To respond to bounds change events, simply register a callback against the `bounds` +event. For more information on the bounds event, please see the section on [Time Events](#time-events). + +## Clocks + +The Time API can be set to follow a clock source which will cause the bounds +to be updated automatically whenever the clock source "ticks". A clock is simply +an object that supports registration of listeners and periodically invokes its +listeners with a number. Open MCT supports registration of new clock sources that +tick on almost anything. A tick occurs when the clock invokes callback functions +registered by its listeners with a new time value. + +An example of a clock source is the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js) +which emits the current time in UTC every 100ms. Clocks can tick on anything. For +example, a clock could be defined to provide the timestamp of any new data +received via a telemetry subscription. This would have the effect of advancing +the bounds of views automatically whenever data is received. A clock could also +be defined to tick on some remote timing source. + +The values provided by clocks are simple `number`s, which are interpreted in the +context of the active [Time System](#defining-and-registering-time-systems). + +### Defining and registering clocks +A clock is an object that defines certain required metadata and functions: + +* `key`: A `string` uniquely identifying this clock. This can be used later to +reference the clock in places such as the [Time Conductor configuration](#time-conductor-configuration) +* `cssClass`: A `string` identifying a CSS class to apply to this clock when it's +displayed in the UI. This will be used to represent the time system with an icon. +There are a number of built-in icon classes [available in Open MCT](https://github.com/nasa/openmct/blob/master/platform/commonUI/general/res/sass/_glyphs.scss), +or a custom class can be used here. +* `name`: A `string` providing a human-readable identifier for the clock source. +This will be displayed in the clock selector menu in the Time Conductor UI +component, if active. +* `description`: An __optional__ `string` providing a longer description of the +clock. The description will be visible in the clock selection menu in the Time +Conductor plugin. +* `on`: A `function` supporting registration of a new callback that will be +invoked when the clock next ticks. It will be invoked with two arguments: + * `eventName`: A `string` specifying the event to listen on. For now, clocks + support one event - `tick`. + * `callback`: A `function` that will be invoked when this clock ticks. The + function must be invoked with one parameter - a `number` representing a valid + time in the current time system. +* `off`: A `function` that allows deregistration of a tick listener. It accepts +the same arguments as `on`. +* `currentValue`: A `function` that returns a `number` representing a point in +time in the active time system. It should be the last value provided by a tick, +or some default value if no ticking has yet occurred. + +A new clock can be registered using the `addClock` function exposed by the Time +API: + +```javascript +var someClock = { + key: 'someClock', + cssClass: 'icon-clock', + name: 'Some clock', + description: "Presumably does something useful", + on: function (event, callback) { + // Some function that registers listeners, and updates them on a tick + }, + off: function (event, callback) { + // Some function that unregisters listeners. + }, + currentValue: function () { + // A function that returns the last ticked value for the clock + } +} + +openmct.time.addClock(someClock); +``` + +An example clock implementation is provided in the form of the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js) + +#### Getting and setting active clock + +Once registered a clock can be activated by calling the `clock` function on the +Time API passing in the key or instance of a registered clock. Only one clock +may be active at once, so activating a clock will deactivate any currently +active clock. Setting the clock will also trigger a ['clock' event](#time-events). + +``` +openmct.time.clock(someClock); +``` + +Upon being activated, a clock's `on` function will be immediately called to subscribe +to `tick` events. + +The currently active clock (if any) can be retrieved by calling the same +function without any arguments. + +#### Stopping an active clock + +The `stopClock` method can be used to stop an active clock, and to clear it. It +will stop the clock from ticking, and set the active clock to `undefined`. + +``` javascript +openmct.time.stopClock(); +``` + +#### Clock Offsets + +When a clock is active, the time bounds of the application will be updated +automatically each time the clock "ticks". The bounds are calculated based on +the current value provided by the active clock (via its `tick` event, or its +`currentValue()` method). + +Unlike bounds, which represent absolute time values, clock offsets represent +relative time spans. Offsets are defined as an object with two properties: + +* `start`: A `number` that must be < 0 and which is used to calculate the start +bounds on each clock tick. The start offset will be calculated relative to the +value provided by a clock's tick callback, or its `currentValue()` function. +* `end`: A `number` that must be >=0 and which is used to calculate the end +bounds on each clock tick. + +The `clockOffsets` function can be used to get or set clock offsets. For example, +to show the last fifteen minutes in a ms-based time system: + +```javascript +var FIFTEEN_MINUTES = 15 * 60 * 1000; + +openmct.time.clockOffsets({ + start: -FIFTEEN_MINUTES, + end: 0 +}) +``` + +__Note:__ Setting the clock offsets will trigger an immediate bounds change, as +new bounds will be calculated based on the `currentValue()` of the active clock. +Clock offsets are only relevant when a clock source is active. + +## Time Events +The time API supports the registration of listeners that will be invoked when the +application's temporal state changes. Events listeners can be registered using +the `on` function. They can be deregistered using the `off` function. The arguments +accepted by the `on` and `off` functions are: + +* `event`: A `string` naming the event to subscribe to. Event names correspond to +the property of the Time API you're interested in. A [full list of time events](#list-of-time-events) +is provided later. + +As an example, the code to listen to bounds change events looks like: + +``` javascript +openmct.time.on('bounds', function callback (newBounds, tick) { + // Do something with new bounds +}); +``` + +#### List of Time Events +The events supported by the Time API are: + +* `bounds`: Listen for changes to current bounds. The callback will be invoked +with two arguments: + * `bounds`: A [bounds](#getting-and-setting-bounds) bounds object representing + a new time period bound by the specified start and send times. + * `tick`: A `boolean` indicating whether or not this bounds change is due to a + "tick" from a [clock source](#clocks). This information can be useful when + determining a strategy for fetching telemetry data in response to a bounds + change event. For example, if the bounds change was automatic, and is due + to a tick then it's unlikely that you would need to perform a historical + data query. It should be sufficient to just show any new telemetry received + via subscription since the last tick, and optionally to discard any older + data that now falls outside of the currently set bounds. If `tick` is false, + then the bounds change was not due to an automatic tick, and a query for + historical data may be necessary, depending on your data caching strategy, + and how significantly the start bound has changed. +* `timeSystem`: Listen for changes to the active [time system](#defining-and-registering-time-systems). +The callback will be invoked with a single argument - the newly active time system. + * `timeSystem`: The newly active [time system](#defining-and-registering-time-systems) object. +* `clock`: Listen for changes to the active clock. When invoked, the callback +will be provided with the new clock. + * `clock`: The newly active [clock](#clocks), or `undefined` if an active clock + has been deactivated. +* `clockOffsets`: Listen for changes to active clock offsets. When invoked the +callback will be provided with the new clock offsets. + * `clockOffsets`: A [clock offsets](#clock-offsets) object. + + +## The Time Conductor +The Time Conductor provides a user interface for managing time bounds in Open MCT. +It allows a user to select from configured time systems and clocks, and to set bounds +and clock offsets. + +If activated, the time conductor must be provided with configuration options, +detailed below. + +#### Time Conductor Configuration +The time conductor is configured by specifying the options that will be +available to the user from the menus in the time conductor. These will determine +the clocks available from the conductor, the time systems available for each +clock, and some default bounds and clock offsets for each combination of clock +and time system. By default, the conductor always supports a `fixed` mode where +no clock is active. To specify configuration for fixed mode, simply leave out a +`clock` attribute in the configuration entry object. + +Configuration is provided as an `array` of menu options. Each entry of the +array is an object with some properties specifying configuration. The configuration +options specified are slightly different depending on whether or not it is for +an active clock mode. + +__Configuration for Fixed Time Mode (no active clock)__ + +* `timeSystem`: A `string`, the key for the time system that this configuration +relates to. +* `bounds`: A [`Time Bounds`](#time-bounds) object. These bounds will be applied +when the user selects the time system specified in the previous `timeSystem` +property. +* `zoomOutLimit`: An __optional__ `number` specifying the longest period of time +that can be represented by the conductor when zooming. If a `zoomOutLimit` is +provided, then a `zoomInLimit` must also be provided. If provided, the zoom +slider will automatically become available in the Time Conductor UI. +* `zoomInLimit`: An __optional__ `number` specifying the shortest period of time +that can be represented by the conductor when zooming. If a `zoomInLimit` is +provided, then a `zoomOutLimit` must also be provided. If provided, the zoom +slider will automatically become available in the Time Conductor UI. + +__Configuration for Active Clock__ + +* `clock`: A `string`, the `key` of the clock that this configuration applies to. +* `timeSystem`: A `string`, the key for the time system that this configuration +relates to. Separate configuration must be provided for each time system that you +wish to be available to users when they select the specified clock. +* `clockOffsets`: A [`clockOffsets`](#clock-offsets) object that will be +automatically applied when the combination of clock and time system specified in +this configuration is selected from the UI. + +#### Example conductor configuration +An example time conductor configuration is provided below. It sets up some +default options for the [UTCTimeSystem](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/UTCTimeSystem.js) +and [LocalTimeSystem](https://github.com/nasa/openmct/blob/master/src/plugins/localTimeSystem/LocalTimeSystem.js), +in both fixed mode, and for the [LocalClock](https://github.com/nasa/openmct/blob/master/src/plugins/utcTimeSystem/LocalClock.js) +source. In this configutation, the local clock supports both the UTCTimeSystem +and LocalTimeSystem. Configuration for fixed bounds mode is specified by omitting +a clock key. + +``` javascript +const ONE_YEAR = 365 * 24 * 60 * 60 * 1000; +const ONE_MINUTE = 60 * 1000; + +openmct.install(openmct.plugins.Conductor({ + menuOptions: [ + // 'Fixed' bounds mode configuation for the UTCTimeSystem + { + timeSystem: 'utc', + bounds: {start: Date.now() - 30 * ONE_MINUTE, end: Date.now()}, + zoomOutLimit: ONE_YEAR, + zoomInLimit: ONE_MINUTE + }, + // Configuration for the LocalClock in the UTC time system + { + clock: 'local', + timeSystem: 'utc', + clockOffsets: {start: - 30 * ONE_MINUTE, end: 0}, + zoomOutLimit: ONE_YEAR, + zoomInLimit: ONE_MINUTE + }, + //Configuration for the LocaLClock in the Local time system + { + clock: 'local', + timeSystem: 'local', + clockOffsets: {start: - 15 * ONE_MINUTE, end: 0} + } + ] +})); +``` + ## Included Plugins Open MCT is packaged along with a few general-purpose plugins: +* `openmct.plugins.Conductor` provides a user interface for working with time +within the application. If activated, configuration must be provided. This is +detailed in the section on [Time Conductor Configuration](#time-conductor-configuration). * `openmct.plugins.CouchDB` is an adapter for using CouchDB for persistence of user-created objects. This is a constructor that takes the URL for the CouchDB database as a parameter, e.g. diff --git a/example/localTimeSystem/src/LocalTimeSystem.js b/example/localTimeSystem/src/LocalTimeSystem.js deleted file mode 100644 index ee309d09b0..0000000000 --- a/example/localTimeSystem/src/LocalTimeSystem.js +++ /dev/null @@ -1,79 +0,0 @@ -/***************************************************************************** - * Open MCT Web, Copyright (c) 2014-2015, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT Web is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT Web includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define([ - '../../../platform/features/conductor/core/src/timeSystems/TimeSystem', - '../../../platform/features/conductor/core/src/timeSystems/LocalClock', - './LADTickSource' -], function (TimeSystem, LocalClock, LADTickSource) { - var THIRTY_MINUTES = 30 * 60 * 1000, - DEFAULT_PERIOD = 1000; - - /** - * This time system supports UTC dates and provides a ticking clock source. - * @implements TimeSystem - * @constructor - */ - function LocalTimeSystem ($timeout) { - TimeSystem.call(this); - - /** - * Some metadata, which will be used to identify the time system in - * the UI - * @type {{key: string, name: string, glyph: string}} - */ - this.metadata = { - 'key': 'local', - 'name': 'Local', - 'glyph': '\u0043' - }; - - this.fmts = ['local-format']; - this.sources = [new LocalClock($timeout, DEFAULT_PERIOD), new LADTickSource($timeout, DEFAULT_PERIOD)]; - } - - LocalTimeSystem.prototype = Object.create(TimeSystem.prototype); - - LocalTimeSystem.prototype.formats = function () { - return this.fmts; - }; - - LocalTimeSystem.prototype.deltaFormat = function () { - return 'duration'; - }; - - LocalTimeSystem.prototype.tickSources = function () { - return this.sources; - }; - - LocalTimeSystem.prototype.defaults = function (key) { - var now = Math.ceil(Date.now() / 1000) * 1000; - return { - key: 'local-default', - name: 'Local 12 hour time system defaults', - deltas: {start: THIRTY_MINUTES, end: 0}, - bounds: {start: now - THIRTY_MINUTES, end: now} - }; - }; - - return LocalTimeSystem; -}); diff --git a/index.html b/index.html index 4f29358da3..f0c938f9a8 100644 --- a/index.html +++ b/index.html @@ -28,6 +28,8 @@ diff --git a/openmct.js b/openmct.js index 112b70adaa..4c578b9b3f 100644 --- a/openmct.js +++ b/openmct.js @@ -100,11 +100,5 @@ define([ return new Main().run(defaultRegistry); }); - // For now, install conductor by default - openmct.install(openmct.plugins.Conductor({ - showConductor: false - })); - - return openmct; }); diff --git a/platform/commonUI/formats/bundle.js b/platform/commonUI/formats/bundle.js index 51a04d695e..0aea5e531e 100644 --- a/platform/commonUI/formats/bundle.js +++ b/platform/commonUI/formats/bundle.js @@ -22,13 +22,9 @@ define([ "./src/FormatProvider", - "./src/UTCTimeFormat", - "./src/DurationFormat", 'legacyRegistry' ], function ( FormatProvider, - UTCTimeFormat, - DurationFormat, legacyRegistry ) { @@ -46,22 +42,6 @@ define([ ] } ], - "formats": [ - { - "key": "utc", - "implementation": UTCTimeFormat - }, - { - "key": "duration", - "implementation": DurationFormat - } - ], - "constants": [ - { - "key": "DEFAULT_TIME_FORMAT", - "value": "utc" - } - ], "licenses": [ { "name": "d3", diff --git a/platform/commonUI/formats/src/FormatProvider.js b/platform/commonUI/formats/src/FormatProvider.js index e9b7e93bc9..70bbac508e 100644 --- a/platform/commonUI/formats/src/FormatProvider.js +++ b/platform/commonUI/formats/src/FormatProvider.js @@ -30,19 +30,23 @@ define([ * An object used to convert between numeric values and text values, * typically used to display these values to the user and to convert * user input to a numeric format, particularly for time formats. - * @interface {Format} + * @interface Format */ - /** * Parse text (typically user input) to a numeric value. * Behavior is undefined when the text cannot be parsed; * `validate` should be called first if the text may be invalid. - * @method parse + * @method Format#parse * @memberof Format# * @param {string} text the text to parse * @returns {number} the parsed numeric value */ + /** + * @property {string} key A unique identifier for this formatter. + * @memberof Format# + */ + /** * Determine whether or not some text (typically user input) can * be parsed to a numeric value by this format. @@ -58,10 +62,12 @@ define([ * @method format * @memberof Format# * @param {number} value the numeric value to format - * @param {number} [threshold] Optionally provides context to the - * format request, allowing for scale-appropriate formatting. This value - * should be the minimum unit to be represented by this format, in ms. For - * example, to display seconds, a threshold of 1 * 1000 should be provided. + * @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor + * and plot axes. Specifies the smallest number on the scale. + * @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor + * and plot axes. Specifies the largest number on the scale + * @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor + * and plot axes. The number of labels on the scale. * @returns {string} the text representation of the value */ diff --git a/platform/commonUI/formats/test/UTCTimeFormatSpec.js b/platform/commonUI/formats/test/UTCTimeFormatSpec.js deleted file mode 100644 index 967cd7137f..0000000000 --- a/platform/commonUI/formats/test/UTCTimeFormatSpec.js +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2014-2017, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define( - ['../src/UTCTimeFormat', 'moment'], - function (UTCTimeFormat, moment) { - - describe("The UTCTimeFormat", function () { - var format; - - beforeEach(function () { - format = new UTCTimeFormat(); - }); - - it("formats UTC timestamps", function () { - var timestamp = 12345670000, - formatted = format.format(timestamp); - expect(formatted).toEqual(jasmine.any(String)); - expect(moment.utc(formatted).valueOf()).toEqual(timestamp); - }); - - it("displays with millisecond precision", function () { - var timestamp = 12345670789, - formatted = format.format(timestamp); - expect(moment.utc(formatted).valueOf()).toEqual(timestamp); - }); - - it("validates time inputs", function () { - expect(format.validate("1977-05-25 11:21:22")).toBe(true); - expect(format.validate("garbage text")).toBe(false); - }); - - it("parses valid input", function () { - var text = "1977-05-25 11:21:22", - parsed = format.parse(text); - expect(parsed).toEqual(jasmine.any(Number)); - expect(parsed).toEqual(moment.utc(text).valueOf()); - }); - }); - } -); diff --git a/platform/features/conductor/compatibility/src/ConductorRepresenter.js b/platform/features/conductor/compatibility/src/ConductorRepresenter.js index e267c9d2f4..6969e86ff5 100644 --- a/platform/features/conductor/compatibility/src/ConductorRepresenter.js +++ b/platform/features/conductor/compatibility/src/ConductorRepresenter.js @@ -41,7 +41,7 @@ define( scope, element ) { - this.conductor = openmct.conductor; + this.timeAPI = openmct.time; this.scope = scope; this.element = element; @@ -51,24 +51,25 @@ define( } ConductorRepresenter.prototype.boundsListener = function (bounds) { + var timeSystem = this.timeAPI.timeSystem(); this.scope.$broadcast('telemetry:display:bounds', { start: bounds.start, end: bounds.end, - domain: this.conductor.timeSystem().metadata.key - }, this.conductor.follow()); + domain: timeSystem.key + }, this.timeAPI.clock() !== undefined); }; ConductorRepresenter.prototype.timeSystemListener = function (timeSystem) { - var bounds = this.conductor.bounds(); + var bounds = this.timeAPI.bounds(); this.scope.$broadcast('telemetry:display:bounds', { start: bounds.start, end: bounds.end, - domain: timeSystem.metadata.key - }, this.conductor.follow()); + domain: timeSystem.key + }, this.timeAPI.clock() !== undefined); }; ConductorRepresenter.prototype.followListener = function () { - this.boundsListener(this.conductor.bounds()); + this.boundsListener(this.timeAPI.bounds()); }; // Handle a specific representation of a specific domain object @@ -76,16 +77,16 @@ define( if (representation.key === 'browse-object') { this.destroy(); - this.conductor.on("bounds", this.boundsListener); - this.conductor.on("timeSystem", this.timeSystemListener); - this.conductor.on("follow", this.followListener); + this.timeAPI.on("bounds", this.boundsListener); + this.timeAPI.on("timeSystem", this.timeSystemListener); + this.timeAPI.on("follow", this.followListener); } }; ConductorRepresenter.prototype.destroy = function destroy() { - this.conductor.off("bounds", this.boundsListener); - this.conductor.off("timeSystem", this.timeSystemListener); - this.conductor.off("follow", this.followListener); + this.timeAPI.off("bounds", this.boundsListener); + this.timeAPI.off("timeSystem", this.timeSystemListener); + this.timeAPI.off("follow", this.followListener); }; return ConductorRepresenter; diff --git a/platform/features/conductor/core/bundle.js b/platform/features/conductor/core/bundle.js index e99e54d22b..5c6b4a68fa 100644 --- a/platform/features/conductor/core/bundle.js +++ b/platform/features/conductor/core/bundle.js @@ -21,12 +21,12 @@ *****************************************************************************/ define([ - "./src/ui/TimeConductorViewService", "./src/ui/TimeConductorController", "./src/ui/ConductorAxisController", "./src/ui/ConductorTOIController", + "./src/ui/ConductorTOIDirective", "./src/ui/TimeOfInterestController", - "./src/ui/MctConductorAxis", + "./src/ui/ConductorAxisDirective", "./src/ui/NumberFormat", "text!./res/templates/time-conductor.html", "text!./res/templates/mode-selector/mode-selector.html", @@ -34,12 +34,12 @@ define([ "text!./res/templates/time-of-interest.html", "legacyRegistry" ], function ( - TimeConductorViewService, TimeConductorController, ConductorAxisController, ConductorTOIController, + ConductorTOIDirective, TimeOfInterestController, - MCTConductorAxis, + ConductorAxisDirective, NumberFormat, timeConductorTemplate, modeSelectorTemplate, @@ -50,16 +50,6 @@ define([ legacyRegistry.register("platform/features/conductor/core", { "extensions": { - "services": [ - { - "key": "timeConductorViewService", - "implementation": TimeConductorViewService, - "depends": [ - "openmct", - "timeSystems[]" - ] - } - ], "controllers": [ { "key": "TimeConductorController", @@ -67,12 +57,9 @@ define([ "depends": [ "$scope", "$window", - "$location", "openmct", - "timeConductorViewService", "formatService", - "DEFAULT_TIMECONDUCTOR_MODE", - "SHOW_TIMECONDUCTOR" + "CONDUCTOR_CONFIG" ] }, { @@ -81,7 +68,6 @@ define([ "depends": [ "$scope", "openmct", - "timeConductorViewService", "formatService" ] }, @@ -97,12 +83,16 @@ define([ ], "directives": [ { - "key": "mctConductorAxis", - "implementation": MCTConductorAxis, + "key": "conductorAxis", + "implementation": ConductorAxisDirective, "depends": [ "openmct", "formatService" ] + }, + { + "key": "conductorToi", + "implementation": ConductorTOIDirective } ], "stylesheets": [ @@ -151,13 +141,6 @@ define([ "link": "https://github.com/d3/d3/blob/master/LICENSE" } ], - "constants": [ - { - "key": "DEFAULT_TIMECONDUCTOR_MODE", - "value": "realtime", - "priority": "fallback" - } - ], "formats": [ { "key": "number", diff --git a/platform/features/conductor/core/res/templates/mode-selector/mode-menu.html b/platform/features/conductor/core/res/templates/mode-selector/mode-menu.html index db6242a154..32c026de9d 100644 --- a/platform/features/conductor/core/res/templates/mode-selector/mode-menu.html +++ b/platform/features/conductor/core/res/templates/mode-selector/mode-menu.html @@ -22,8 +22,8 @@