* Release 2.0.3 * Fix tick values for plots ticks in log mode and null check (#5119) * [2297] When there is no display range or range, skip setting the range value when auto scale is turned off. * If the formatted value is a number and a float, set precision to 2 decimal points. * Fix value assignment * Use whole numbers in log mode * Revert whole numbers fix - need floats for values between 0 and 1. * Handle scrolling to focused image on resize/new data (#5121) * Scroll to focused image when view resizes - this will force scrolling to focused image when going to/from view large mode * Scroll to the right if there is no paused focused image * [LAD Tables] Use Telemetry Collections (#5127) * Use telemetry collections to handle bounds checks * added telemetry collection to alphanumeric telemetry view (#5131) * Added animation styling for POS and CAM; adjusted cutoff for isNewImage (#5116) * Added animation styling for POS and CAM; adjusted cutoff for isNewImage * Remove animation from POS and CAM * Fix transactions overwriting latest objects with stale objects on save (#5132) * use object (map) instead of set to track dirty objects * fix tests due to internals change Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov> * Gauge edit enabled 2.0.3 (#5133) * Gauge plugin #4896, add edit mode * Dynamic dial-type Gauge sizing by height and width (#5129) * Improve sizing strategy for gauges. * Do not install gauge by default for now Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov> Co-authored-by: Jamie Vigliotta <jamie.j.vigliotta@nasa.gov> Co-authored-by: Andrew Henry <akhenry@gmail.com> * [Telemetry Collections] Include data with start and end bounds (#5145) * Reverts forced precision for log plots axis labels (#5147) * Condition Widgets trigger hundreds of persistence calls (#5146) Co-authored-by: unlikelyzero <jchill2@gmail.com> * Update version for 2.0.4 (#5255) * Eliminate NaN conditions and clear stale duration (#5248) * Temp source map fix 2.0.4 (#5267) * use dev mode for production * mode -> production * added extra devtool options * wip * Imagery Fixes for release/2.0.4 (#5282) * Fallback for height * Remove duplicated requestHistory call since setDataTimeContext already invokes it on mount * Inverted datumIsNotValid and refactored requestHistory * Remove old datumIsNotValid func * Return false if datum is falsy * Corrected brightness/contrast input * Clone default values to avoid mutation * Changed index of imageTelemetry to an item within bounds * Implement clearData test for imagery differently * x-out clearData tests Co-authored-by: Joshi <simplyrender@gmail.com> * Imagery test fixes (#5293) * Fallback for height * Remove duplicated requestHistory call since setDataTimeContext already invokes it on mount * Inverted datumIsNotValid and refactored requestHistory * Remove old datumIsNotValid func * Return false if datum is falsy * Corrected brightness/contrast input * Clone default values to avoid mutation * Changed index of imageTelemetry to an item within bounds * Implement clearData test for imagery differently * x-out clearData tests * Set bounds on each test rather than the wrapper Co-authored-by: Michael Rogers <contact@mhrogers.com> * Imagery validation fix (#5295) * Remove check for duplicate images * Remove commented out code and add TODO * lint fix * Add missing tests * Use the master version and ignore release/2.0.4 changes Co-authored-by: Jamie V <jamie.j.vigliotta@nasa.gov> Co-authored-by: Michael Rogers <contact@mhrogers.com> Co-authored-by: David Tsay <3614296+davetsay@users.noreply.github.com> Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov> Co-authored-by: Charles Hacskaylo <charlesh88@gmail.com> Co-authored-by: Andrew Henry <akhenry@gmail.com> Co-authored-by: unlikelyzero <jchill2@gmail.com>
205 lines
7.7 KiB
JavaScript
205 lines
7.7 KiB
JavaScript
/*****************************************************************************
|
|
* Open MCT, Copyright (c) 2014-2022, 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.
|
|
*****************************************************************************/
|
|
|
|
const DEFAULT_DURATION_FORMATTER = 'duration';
|
|
|
|
export default {
|
|
inject: ['openmct', 'domainObject', 'objectPath'],
|
|
mounted() {
|
|
// listen
|
|
this.boundsChange = this.boundsChange.bind(this);
|
|
this.timeSystemChange = this.timeSystemChange.bind(this);
|
|
this.setDataTimeContext = this.setDataTimeContext.bind(this);
|
|
this.setDataTimeContext();
|
|
this.openmct.objectViews.on('clearData', this.clearData);
|
|
|
|
// set
|
|
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
|
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
|
this.imageHints = { ...this.metadata.valuesForHints(['image'])[0] };
|
|
this.durationFormatter = this.getFormatter(this.timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
|
this.imageFormatter = this.openmct.telemetry.getValueFormatter(this.imageHints);
|
|
this.imageDownloadNameHints = { ...this.metadata.valuesForHints(['imageDownloadName'])[0]};
|
|
|
|
// initialize
|
|
this.timeKey = this.timeSystem.key;
|
|
this.timeFormatter = this.getFormatter(this.timeKey);
|
|
|
|
// kickoff
|
|
this.subscribe();
|
|
},
|
|
beforeDestroy() {
|
|
if (this.unsubscribe) {
|
|
this.unsubscribe();
|
|
delete this.unsubscribe;
|
|
}
|
|
|
|
this.stopFollowingDataTimeContext();
|
|
this.openmct.objectViews.off('clearData', this.clearData);
|
|
},
|
|
methods: {
|
|
setDataTimeContext() {
|
|
this.stopFollowingDataTimeContext();
|
|
this.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
|
this.timeContext.on('bounds', this.boundsChange);
|
|
this.boundsChange(this.timeContext.bounds());
|
|
this.timeContext.on('timeSystem', this.timeSystemChange);
|
|
},
|
|
stopFollowingDataTimeContext() {
|
|
if (this.timeContext) {
|
|
this.timeContext.off('bounds', this.boundsChange);
|
|
this.timeContext.off('timeSystem', this.timeSystemChange);
|
|
}
|
|
},
|
|
isDatumValid(datum) {
|
|
//TODO: Add a check to see if there are duplicate images (identical image timestamp and url subsequently)
|
|
if (!datum) {
|
|
return false;
|
|
}
|
|
|
|
const datumTimeCheck = this.parseTime(datum);
|
|
const bounds = this.timeContext.bounds();
|
|
|
|
const isOutOfBounds = datumTimeCheck < bounds.start || datumTimeCheck > bounds.end;
|
|
|
|
return !isOutOfBounds;
|
|
},
|
|
formatImageUrl(datum) {
|
|
if (!datum) {
|
|
return;
|
|
}
|
|
|
|
return this.imageFormatter.format(datum);
|
|
},
|
|
formatTime(datum) {
|
|
if (!datum) {
|
|
return;
|
|
}
|
|
|
|
let dateTimeStr = this.timeFormatter.format(datum);
|
|
|
|
// Replace ISO "T" with a space to allow wrapping
|
|
return dateTimeStr.replace("T", " ");
|
|
},
|
|
getImageDownloadName(datum) {
|
|
let imageDownloadName = '';
|
|
if (datum) {
|
|
const key = this.imageDownloadNameHints.key;
|
|
imageDownloadName = datum[key];
|
|
}
|
|
|
|
return imageDownloadName;
|
|
},
|
|
parseTime(datum) {
|
|
if (!datum) {
|
|
return;
|
|
}
|
|
|
|
return this.timeFormatter.parse(datum);
|
|
},
|
|
boundsChange(bounds, isTick) {
|
|
if (isTick) {
|
|
return;
|
|
}
|
|
|
|
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
|
delete this.imageContainerWidth;
|
|
delete this.imageContainerHeight;
|
|
|
|
return this.requestHistory();
|
|
},
|
|
async requestHistory() {
|
|
this.requestCount++;
|
|
const requestId = this.requestCount;
|
|
const bounds = this.timeContext.bounds();
|
|
|
|
const data = await this.openmct.telemetry
|
|
.request(this.domainObject, bounds) || [];
|
|
// wait until new request resolves to do comparison
|
|
if (this.requestCount !== requestId) {
|
|
return this.imageHistory = [];
|
|
}
|
|
|
|
const imagery = data.filter(this.isDatumValid).map(this.normalizeDatum);
|
|
this.imageHistory = imagery;
|
|
},
|
|
clearData(domainObjectToClear) {
|
|
// global clearData button is accepted therefore no truthy check on inputted param
|
|
const clearDataForObjectSelected = Boolean(domainObjectToClear);
|
|
if (clearDataForObjectSelected) {
|
|
const idsEqual = this.openmct.objects.areIdsEqual(
|
|
domainObjectToClear.identifier,
|
|
this.domainObject.identifier
|
|
);
|
|
if (!idsEqual) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// splice array to encourage garbage collection
|
|
this.imageHistory.splice(0, this.imageHistory.length);
|
|
|
|
},
|
|
timeSystemChange() {
|
|
this.timeSystem = this.timeContext.timeSystem();
|
|
this.timeKey = this.timeSystem.key;
|
|
this.timeFormatter = this.getFormatter(this.timeKey);
|
|
this.durationFormatter = this.getFormatter(this.timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
|
},
|
|
subscribe() {
|
|
this.unsubscribe = this.openmct.telemetry
|
|
.subscribe(this.domainObject, (datum) => {
|
|
let parsedTimestamp = this.parseTime(datum);
|
|
let bounds = this.timeContext.bounds();
|
|
if (!(parsedTimestamp >= bounds.start && parsedTimestamp <= bounds.end)) {
|
|
return;
|
|
}
|
|
|
|
if (this.isDatumValid(datum)) {
|
|
this.imageHistory.push(this.normalizeDatum(datum));
|
|
}
|
|
});
|
|
},
|
|
normalizeDatum(datum) {
|
|
|
|
const formattedTime = this.formatTime(datum);
|
|
const url = this.formatImageUrl(datum);
|
|
const time = this.parseTime(formattedTime);
|
|
const imageDownloadName = this.getImageDownloadName(datum);
|
|
|
|
return {
|
|
...datum,
|
|
formattedTime,
|
|
url,
|
|
time,
|
|
imageDownloadName
|
|
};
|
|
},
|
|
getFormatter(key) {
|
|
let metadataValue = this.metadata.value(key) || { format: key };
|
|
let valueFormatter = this.openmct.telemetry.getValueFormatter(metadataValue);
|
|
|
|
return valueFormatter;
|
|
}
|
|
}
|
|
};
|