Compare commits
	
		
			10 Commits
		
	
	
		
			one-weird-
			...
			condition-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | bfa604efa0 | ||
|   | e75befafbd | ||
|   | d7d06b59ea | ||
|   | 8b4a55a7ec | ||
|   | 2519e601d7 | ||
|   | b7b205621b | ||
|   | 3d2d932323 | ||
|   | ce28dd2b9f | ||
|   | 286a533dad | ||
|   | 378a4ca282 | 
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "openmct", | ||||
|   "version": "2.0.3-SNAPSHOT", | ||||
|   "version": "2.0.3", | ||||
|   "description": "The Open MCT core platform", | ||||
|   "devDependencies": { | ||||
|     "@babel/eslint-parser": "7.16.3", | ||||
|   | ||||
| @@ -232,6 +232,7 @@ define([ | ||||
|         this.actions = new api.ActionsAPI(this); | ||||
|  | ||||
|         this.status = new api.StatusAPI(this); | ||||
|         this.styleManager = new api.StyleManagerAPI(this); | ||||
|  | ||||
|         this.priority = api.PriorityAPI; | ||||
|  | ||||
| @@ -241,8 +242,6 @@ define([ | ||||
|         this.branding = BrandingAPI.default; | ||||
|  | ||||
|         // Plugins that are installed by default | ||||
|  | ||||
|         this.install(this.plugins.Gauge()); | ||||
|         this.install(this.plugins.Plot()); | ||||
|         this.install(this.plugins.Chart()); | ||||
|         this.install(this.plugins.TelemetryTable.default()); | ||||
|   | ||||
| @@ -31,6 +31,7 @@ define([ | ||||
|     './objects/ObjectAPI', | ||||
|     './priority/PriorityAPI', | ||||
|     './status/StatusAPI', | ||||
|     './styles/StyleManagerAPI', | ||||
|     './telemetry/TelemetryAPI', | ||||
|     './time/TimeAPI', | ||||
|     './types/TypeRegistry', | ||||
| @@ -46,6 +47,7 @@ define([ | ||||
|     ObjectAPI, | ||||
|     PriorityAPI, | ||||
|     StatusAPI, | ||||
|     StyleManagerAPI, | ||||
|     TelemetryAPI, | ||||
|     TimeAPI, | ||||
|     TypeRegistry, | ||||
| @@ -62,6 +64,7 @@ define([ | ||||
|         ObjectAPI: ObjectAPI, | ||||
|         PriorityAPI: PriorityAPI.default, | ||||
|         StatusAPI: StatusAPI.default, | ||||
|         StyleManagerAPI: StyleManagerAPI.default, | ||||
|         TelemetryAPI: TelemetryAPI, | ||||
|         TimeAPI: TimeAPI.default, | ||||
|         TypeRegistry: TypeRegistry, | ||||
|   | ||||
| @@ -22,12 +22,14 @@ | ||||
|  | ||||
| export default class Transaction { | ||||
|     constructor(objectAPI) { | ||||
|         this.dirtyObjects = new Set(); | ||||
|         this.dirtyObjects = {}; | ||||
|         this.objectAPI = objectAPI; | ||||
|     } | ||||
|  | ||||
|     add(object) { | ||||
|         this.dirtyObjects.add(object); | ||||
|         const key = this.objectAPI.makeKeyString(object.identifier); | ||||
|  | ||||
|         this.dirtyObjects[key] = object; | ||||
|     } | ||||
|  | ||||
|     cancel() { | ||||
| @@ -37,7 +39,8 @@ export default class Transaction { | ||||
|     commit() { | ||||
|         const promiseArray = []; | ||||
|         const save = this.objectAPI.save.bind(this.objectAPI); | ||||
|         this.dirtyObjects.forEach(object => { | ||||
|  | ||||
|         Object.values(this.dirtyObjects).forEach(object => { | ||||
|             promiseArray.push(this.createDirtyObjectPromise(object, save)); | ||||
|         }); | ||||
|  | ||||
| @@ -48,7 +51,9 @@ export default class Transaction { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             action(object) | ||||
|                 .then((success) => { | ||||
|                     this.dirtyObjects.delete(object); | ||||
|                     const key = this.objectAPI.makeKeyString(object.identifier); | ||||
|  | ||||
|                     delete this.dirtyObjects[key]; | ||||
|                     resolve(success); | ||||
|                 }) | ||||
|                 .catch(reject); | ||||
| @@ -57,7 +62,8 @@ export default class Transaction { | ||||
|  | ||||
|     getDirtyObject(identifier) { | ||||
|         let dirtyObject; | ||||
|         this.dirtyObjects.forEach(object => { | ||||
|  | ||||
|         Object.values(this.dirtyObjects).forEach(object => { | ||||
|             const areIdsEqual = this.objectAPI.areIdsEqual(object.identifier, identifier); | ||||
|             if (areIdsEqual) { | ||||
|                 dirtyObject = object; | ||||
| @@ -67,14 +73,11 @@ export default class Transaction { | ||||
|         return dirtyObject; | ||||
|     } | ||||
|  | ||||
|     start() { | ||||
|         this.dirtyObjects = new Set(); | ||||
|     } | ||||
|  | ||||
|     _clear() { | ||||
|         const promiseArray = []; | ||||
|         const refresh = this.objectAPI.refresh.bind(this.objectAPI); | ||||
|         this.dirtyObjects.forEach(object => { | ||||
|  | ||||
|         Object.values(this.dirtyObjects).forEach(object => { | ||||
|             promiseArray.push(this.createDirtyObjectPromise(object, refresh)); | ||||
|         }); | ||||
|  | ||||
|   | ||||
| @@ -34,24 +34,24 @@ describe("Transaction Class", () => { | ||||
|     }); | ||||
|  | ||||
|     it('has no dirty objects', () => { | ||||
|         expect(transaction.dirtyObjects.size).toEqual(0); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(0); | ||||
|     }); | ||||
|  | ||||
|     it('add(), adds object to dirtyObjects', () => { | ||||
|         const mockDomainObjects = createMockDomainObjects(); | ||||
|         transaction.add(mockDomainObjects[0]); | ||||
|         expect(transaction.dirtyObjects.size).toEqual(1); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(1); | ||||
|     }); | ||||
|  | ||||
|     it('cancel(), clears all dirtyObjects', (done) => { | ||||
|         const mockDomainObjects = createMockDomainObjects(3); | ||||
|         mockDomainObjects.forEach(transaction.add.bind(transaction)); | ||||
|  | ||||
|         expect(transaction.dirtyObjects.size).toEqual(3); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(3); | ||||
|  | ||||
|         transaction.cancel() | ||||
|             .then(success => { | ||||
|                 expect(transaction.dirtyObjects.size).toEqual(0); | ||||
|                 expect(Object.keys(transaction.dirtyObjects).length).toEqual(0); | ||||
|             }).finally(done); | ||||
|     }); | ||||
|  | ||||
| @@ -59,12 +59,12 @@ describe("Transaction Class", () => { | ||||
|         const mockDomainObjects = createMockDomainObjects(3); | ||||
|         mockDomainObjects.forEach(transaction.add.bind(transaction)); | ||||
|  | ||||
|         expect(transaction.dirtyObjects.size).toEqual(3); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(3); | ||||
|         spyOn(objectAPI, 'save').and.callThrough(); | ||||
|  | ||||
|         transaction.commit() | ||||
|             .then(success => { | ||||
|                 expect(transaction.dirtyObjects.size).toEqual(0); | ||||
|                 expect(Object.keys(transaction.dirtyObjects).length).toEqual(0); | ||||
|                 expect(objectAPI.save.calls.count()).toEqual(3); | ||||
|             }).finally(done); | ||||
|     }); | ||||
| @@ -73,7 +73,7 @@ describe("Transaction Class", () => { | ||||
|         const mockDomainObjects = createMockDomainObjects(); | ||||
|         transaction.add(mockDomainObjects[0]); | ||||
|  | ||||
|         expect(transaction.dirtyObjects.size).toEqual(1); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(1); | ||||
|         const dirtyObject = transaction.getDirtyObject(mockDomainObjects[0].identifier); | ||||
|  | ||||
|         expect(dirtyObject).toEqual(mockDomainObjects[0]); | ||||
| @@ -82,7 +82,7 @@ describe("Transaction Class", () => { | ||||
|     it('getDirtyObject(), returns empty dirtyObject for no active transaction', () => { | ||||
|         const mockDomainObjects = createMockDomainObjects(); | ||||
|  | ||||
|         expect(transaction.dirtyObjects.size).toEqual(0); | ||||
|         expect(Object.keys(transaction.dirtyObjects).length).toEqual(0); | ||||
|         const dirtyObject = transaction.getDirtyObject(mockDomainObjects[0].identifier); | ||||
|  | ||||
|         expect(dirtyObject).toEqual(undefined); | ||||
|   | ||||
							
								
								
									
										67
									
								
								src/api/styles/StyleManagerAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/api/styles/StyleManagerAPI.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /***************************************************************************** | ||||
|  * 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| import EventEmitter from 'EventEmitter'; | ||||
|  | ||||
| export default class StyleManagerAPI extends EventEmitter { | ||||
|     constructor(openmct) { | ||||
|         super(); | ||||
|  | ||||
|         this._openmct = openmct; | ||||
|         this._styleCache = {}; | ||||
|  | ||||
|         this.get = this.get.bind(this); | ||||
|         this.set = this.set.bind(this); | ||||
|         this.observe = this.observe.bind(this); | ||||
|     } | ||||
|  | ||||
|     get(identifier) { | ||||
|         let keyString = this._openmct.objects.makeKeyString(identifier); | ||||
|  | ||||
|         return this._styleCache[keyString]; | ||||
|     } | ||||
|  | ||||
|     set(identifier, value) { | ||||
|         let keyString = this._openmct.objects.makeKeyString(identifier); | ||||
|  | ||||
|         this._styleCache[keyString] = value; | ||||
|         this.emit(keyString, value); | ||||
|     } | ||||
|  | ||||
|     delete(identifier) { | ||||
|         let keyString = this._openmct.objects.makeKeyString(identifier); | ||||
|  | ||||
|         this._styleCache[keyString] = undefined; | ||||
|         this.emit(keyString, undefined); | ||||
|         delete this._styleCache[keyString]; | ||||
|     } | ||||
|  | ||||
|     observe(identifier, callback) { | ||||
|         let key = this._openmct.objects.makeKeyString(identifier); | ||||
|  | ||||
|         this.on(key, callback); | ||||
|  | ||||
|         return () => { | ||||
|             this.off(key, callback); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2022, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
| @@ -114,14 +113,12 @@ export default { | ||||
|         this.metadata = this.openmct.telemetry.getMetadata(this.domainObject); | ||||
|         this.formats = this.openmct.telemetry.getFormatMap(this.metadata); | ||||
|         this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier); | ||||
|         this.bounds = this.openmct.time.bounds(); | ||||
|  | ||||
|         this.limitEvaluator = this.openmct | ||||
|             .telemetry | ||||
|             .limitEvaluator(this.domainObject); | ||||
|  | ||||
|         this.openmct.time.on('timeSystem', this.updateTimeSystem); | ||||
|         this.openmct.time.on('bounds', this.updateBounds); | ||||
|  | ||||
|         this.timestampKey = this.openmct.time.timeSystem().key; | ||||
|  | ||||
| @@ -135,72 +132,39 @@ export default { | ||||
|  | ||||
|         this.valueKey = this.valueMetadata ? this.valueMetadata.key : undefined; | ||||
|  | ||||
|         this.unsubscribe = this.openmct | ||||
|             .telemetry | ||||
|             .subscribe(this.domainObject, this.setLatestValues); | ||||
|  | ||||
|         this.requestHistory(); | ||||
|         this.telemetryCollection = this.openmct.telemetry.requestCollection(this.domainObject, { | ||||
|             size: 1, | ||||
|             strategy: 'latest' | ||||
|         }); | ||||
|         this.telemetryCollection.on('add', this.setLatestValues); | ||||
|         this.telemetryCollection.on('clear', this.resetValues); | ||||
|         this.telemetryCollection.load(); | ||||
|  | ||||
|         if (this.hasUnits) { | ||||
|             this.setUnit(); | ||||
|         } | ||||
|     }, | ||||
|     destroyed() { | ||||
|         this.unsubscribe(); | ||||
|         this.openmct.time.off('timeSystem', this.updateTimeSystem); | ||||
|         this.openmct.time.off('bounds', this.updateBounds); | ||||
|         this.telemetryCollection.off('add', this.setLatestValues); | ||||
|         this.telemetryCollection.off('clear', this.resetValues); | ||||
|     }, | ||||
|     methods: { | ||||
|         updateView() { | ||||
|             if (!this.updatingView) { | ||||
|                 this.updatingView = true; | ||||
|                 requestAnimationFrame(() => { | ||||
|                     let newTimestamp = this.getParsedTimestamp(this.latestDatum); | ||||
|  | ||||
|                     if (this.shouldUpdate(newTimestamp)) { | ||||
|                         this.timestamp = newTimestamp; | ||||
|                         this.datum = this.latestDatum; | ||||
|                     } | ||||
|  | ||||
|                     this.timestamp = this.getParsedTimestamp(this.latestDatum); | ||||
|                     this.datum = this.latestDatum; | ||||
|                     this.updatingView = false; | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         setLatestValues(datum) { | ||||
|             this.latestDatum = datum; | ||||
|  | ||||
|         setLatestValues(data) { | ||||
|             this.latestDatum = data[data.length - 1]; | ||||
|             this.updateView(); | ||||
|         }, | ||||
|         shouldUpdate(newTimestamp) { | ||||
|             return this.inBounds(newTimestamp) | ||||
|                 && (this.timestamp === undefined || newTimestamp > this.timestamp); | ||||
|         }, | ||||
|         requestHistory() { | ||||
|             this.openmct | ||||
|                 .telemetry | ||||
|                 .request(this.domainObject, { | ||||
|                     start: this.bounds.start, | ||||
|                     end: this.bounds.end, | ||||
|                     size: 1, | ||||
|                     strategy: 'latest' | ||||
|                 }) | ||||
|                 .then((array) => this.setLatestValues(array[array.length - 1])) | ||||
|                 .catch((error) => { | ||||
|                     console.warn('Error fetching data', error); | ||||
|                 }); | ||||
|         }, | ||||
|         updateBounds(bounds, isTick) { | ||||
|             this.bounds = bounds; | ||||
|             if (!isTick) { | ||||
|                 this.resetValues(); | ||||
|                 this.requestHistory(); | ||||
|             } | ||||
|         }, | ||||
|         inBounds(timestamp) { | ||||
|             return timestamp >= this.bounds.start && timestamp <= this.bounds.end; | ||||
|         }, | ||||
|         updateTimeSystem(timeSystem) { | ||||
|             this.resetValues(); | ||||
|             this.timestampKey = timeSystem.key; | ||||
|         }, | ||||
|         updateViewContext() { | ||||
| @@ -241,4 +205,3 @@ export default { | ||||
|     } | ||||
| }; | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,7 @@ describe("The LAD Table", () => { | ||||
|  | ||||
|     let openmct; | ||||
|     let ladPlugin; | ||||
|     let historicalProvider; | ||||
|     let parent; | ||||
|     let child; | ||||
|     let telemetryCount = 3; | ||||
| @@ -81,6 +82,13 @@ describe("The LAD Table", () => { | ||||
|  | ||||
|         spyOn(openmct.objects, 'get').and.returnValue(Promise.resolve({})); | ||||
|  | ||||
|         historicalProvider = { | ||||
|             request: () => { | ||||
|                 return Promise.resolve([]); | ||||
|             } | ||||
|         }; | ||||
|         spyOn(openmct.telemetry, 'findRequestProvider').and.returnValue(historicalProvider); | ||||
|  | ||||
|         openmct.time.bounds({ | ||||
|             start: bounds.start, | ||||
|             end: bounds.end | ||||
| @@ -147,7 +155,7 @@ describe("The LAD Table", () => { | ||||
|         // add another telemetry object as composition in lad table to test multi rows | ||||
|         mockObj.ladTable.composition.push(anotherTelemetryObj.identifier); | ||||
|  | ||||
|         beforeEach(async () => { | ||||
|         beforeEach(async (done) => { | ||||
|             let telemetryRequestResolve; | ||||
|             let telemetryObjectResolve; | ||||
|             let anotherTelemetryObjectResolve; | ||||
| @@ -166,11 +174,12 @@ describe("The LAD Table", () => { | ||||
|                 callBack(); | ||||
|             }); | ||||
|  | ||||
|             openmct.telemetry.request.and.callFake(() => { | ||||
|             historicalProvider.request = () => { | ||||
|                 telemetryRequestResolve(mockTelemetry); | ||||
|  | ||||
|                 return telemetryRequestPromise; | ||||
|             }); | ||||
|             }; | ||||
|  | ||||
|             openmct.objects.get.and.callFake((obj) => { | ||||
|                 if (obj.key === 'telemetry-object') { | ||||
|                     telemetryObjectResolve(mockObj.telemetry); | ||||
| @@ -195,6 +204,8 @@ describe("The LAD Table", () => { | ||||
|  | ||||
|             await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise]); | ||||
|             await Vue.nextTick(); | ||||
|  | ||||
|             done(); | ||||
|         }); | ||||
|  | ||||
|         it("should show one row per object in the composition", () => { | ||||
|   | ||||
| @@ -25,6 +25,7 @@ import EventEmitter from 'EventEmitter'; | ||||
| export default class StyleRuleManager extends EventEmitter { | ||||
|     constructor(styleConfiguration, openmct, callback, suppressSubscriptionOnEdit) { | ||||
|         super(); | ||||
|  | ||||
|         this.openmct = openmct; | ||||
|         this.callback = callback; | ||||
|         this.refreshData = this.refreshData.bind(this); | ||||
| @@ -152,6 +153,7 @@ export default class StyleRuleManager extends EventEmitter { | ||||
|  | ||||
|     updateDomainObjectStyle() { | ||||
|         if (this.callback) { | ||||
|             this.emit('updateStyles', this.currentStyle); | ||||
|             this.callback(Object.assign({}, this.currentStyle)); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ | ||||
|     :href="url" | ||||
| > | ||||
|     <div class="c-condition-widget__label"> | ||||
|         {{ internalDomainObject.conditionalLabel || internalDomainObject.label }} | ||||
|         {{ label }} | ||||
|     </div> | ||||
| </component> | ||||
| </template> | ||||
| @@ -39,10 +39,16 @@ export default { | ||||
|     inject: ['openmct', 'domainObject'], | ||||
|     data: function () { | ||||
|         return { | ||||
|             internalDomainObject: this.domainObject | ||||
|             internalDomainObject: this.domainObject, | ||||
|             conditionalLabel: '' | ||||
|         }; | ||||
|     }, | ||||
|     computed: { | ||||
|         label() { | ||||
|             return this.conditionalLabel.length | ||||
|                 ? this.conditionalLabel | ||||
|                 : this.internalDomainObject.label; | ||||
|         }, | ||||
|         urlDefined() { | ||||
|             return this.internalDomainObject.url && this.internalDomainObject.url.length > 0; | ||||
|         }, | ||||
| @@ -52,13 +58,31 @@ export default { | ||||
|     }, | ||||
|     mounted() { | ||||
|         this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', this.updateInternalDomainObject); | ||||
|  | ||||
|         this.unobserve = this.openmct.styleManager.observe(this.internalDomainObject.identifier, this.observeStyleManagerChanges.bind(this)); | ||||
|     }, | ||||
|     beforeDestroy() { | ||||
|         if (this.unlisten) { | ||||
|             this.unlisten(); | ||||
|         } | ||||
|  | ||||
|         if (this.unobserve) { | ||||
|             this.openmct.styleManager.delete(this.internalDomainObject.identifier); | ||||
|             this.unobserve(); | ||||
|         } | ||||
|     }, | ||||
|     methods: { | ||||
|         observeStyleManagerChanges(styleManager) { | ||||
|             if (styleManager) { | ||||
|                 this.styleManager = styleManager; | ||||
|                 this.styleManager.on('updateStyles', this.updateConditionLabel); | ||||
|             } else { | ||||
|                 this.styleManager.off('updateStyles', this.updateConditionLabel); | ||||
|             } | ||||
|         }, | ||||
|         updateConditionLabel(styleObj = {}) { | ||||
|             this.conditionalLabel = styleObj.output || ''; | ||||
|         }, | ||||
|         updateInternalDomainObject(domainObject) { | ||||
|             this.internalDomainObject = domainObject; | ||||
|         } | ||||
|   | ||||
| @@ -222,20 +222,18 @@ export default { | ||||
|                 .then(this.setObject); | ||||
|         } | ||||
|  | ||||
|         this.openmct.time.on("bounds", this.refreshData); | ||||
|  | ||||
|         this.status = this.openmct.status.get(this.item.identifier); | ||||
|         this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus); | ||||
|     }, | ||||
|     beforeDestroy() { | ||||
|         this.removeSubscription(); | ||||
|         this.removeStatusListener(); | ||||
|  | ||||
|         if (this.removeSelectable) { | ||||
|             this.removeSelectable(); | ||||
|         } | ||||
|  | ||||
|         this.openmct.time.off("bounds", this.refreshData); | ||||
|         this.telemetryCollection.off('add', this.setLatestValues); | ||||
|         this.telemetryCollection.off('clear', this.refreshData); | ||||
|  | ||||
|         if (this.mutablePromise) { | ||||
|             this.mutablePromise.then(() => { | ||||
| @@ -253,34 +251,9 @@ export default { | ||||
|  | ||||
|             return `At ${timeFormatter.format(this.datum)} ${this.domainObject.name} had a value of ${this.telemetryValue}${unit}`; | ||||
|         }, | ||||
|         requestHistoricalData() { | ||||
|             let bounds = this.openmct.time.bounds(); | ||||
|             let options = { | ||||
|                 start: bounds.start, | ||||
|                 end: bounds.end, | ||||
|                 size: 1, | ||||
|                 strategy: 'latest' | ||||
|             }; | ||||
|             this.openmct.telemetry.request(this.domainObject, options) | ||||
|                 .then(data => { | ||||
|                     if (data.length > 0) { | ||||
|                         this.latestDatum = data[data.length - 1]; | ||||
|                         this.updateView(); | ||||
|                     } | ||||
|                 }); | ||||
|         }, | ||||
|         subscribeToObject() { | ||||
|             this.subscription = this.openmct.telemetry.subscribe(this.domainObject, function (datum) { | ||||
|                 const key = this.openmct.time.timeSystem().key; | ||||
|                 const datumTimeStamp = datum[key]; | ||||
|                 if (this.openmct.time.clock() !== undefined | ||||
|                     || (datumTimeStamp | ||||
|                         && (this.openmct.time.bounds().end >= datumTimeStamp)) | ||||
|                 ) { | ||||
|                     this.latestDatum = datum; | ||||
|                     this.updateView(); | ||||
|                 } | ||||
|             }.bind(this)); | ||||
|         setLatestValues(data) { | ||||
|             this.latestDatum = data[data.length - 1]; | ||||
|             this.updateView(); | ||||
|         }, | ||||
|         updateView() { | ||||
|             if (!this.updatingView) { | ||||
| @@ -291,17 +264,10 @@ export default { | ||||
|                 }); | ||||
|             } | ||||
|         }, | ||||
|         removeSubscription() { | ||||
|             if (this.subscription) { | ||||
|                 this.subscription(); | ||||
|                 this.subscription = undefined; | ||||
|             } | ||||
|         }, | ||||
|         refreshData(bounds, isTick) { | ||||
|             if (!isTick) { | ||||
|                 this.latestDatum = undefined; | ||||
|                 this.updateView(); | ||||
|                 this.requestHistoricalData(this.domainObject); | ||||
|             } | ||||
|         }, | ||||
|         setObject(domainObject) { | ||||
| @@ -315,8 +281,13 @@ export default { | ||||
|             const valueMetadata = this.metadata.value(this.item.value); | ||||
|             this.customStringformatter = this.openmct.telemetry.customStringFormatter(valueMetadata, this.item.format); | ||||
|  | ||||
|             this.requestHistoricalData(); | ||||
|             this.subscribeToObject(); | ||||
|             this.telemetryCollection = this.openmct.telemetry.requestCollection(this.domainObject, { | ||||
|                 size: 1, | ||||
|                 strategy: 'latest' | ||||
|             }); | ||||
|             this.telemetryCollection.on('add', this.setLatestValues); | ||||
|             this.telemetryCollection.on('clear', this.refreshData); | ||||
|             this.telemetryCollection.load(); | ||||
|  | ||||
|             this.currentObjectPath = this.objectPath.slice(); | ||||
|             this.currentObjectPath.unshift(this.domainObject); | ||||
|   | ||||
| @@ -53,6 +53,8 @@ describe('Gauge plugin', () => { | ||||
|         openmct = createOpenMct(); | ||||
|         openmct.on('start', done); | ||||
|  | ||||
|         openmct.install(openmct.plugins.Gauge()); | ||||
|  | ||||
|         openmct.startHeadless(); | ||||
|     }); | ||||
|  | ||||
| @@ -190,28 +192,27 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-gauge__curval'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-dial'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.js-gauge-dial-range'); | ||||
|             const valueElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct min max values', () => { | ||||
|             expect(gaugeHolder.querySelector('.c-gauge__range').textContent).toEqual(`${minValue} ${maxValue}`); | ||||
|             expect(gaugeHolder.querySelector('.js-gauge-dial-range').textContent).toEqual(`${minValue} ${maxValue}`); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct current value', (done) => { | ||||
|             function WatchUpdateValue() { | ||||
|                 const textElement = gaugeHolder.querySelector('.c-gauge__curval-text'); | ||||
|                 const textElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|                 expect(Number(textElement.textContent).toFixed(gaugeViewObject.configuration.gaugeController.precision)).toBe(randomValue.toFixed(gaugeViewObject.configuration.gaugeController.precision)); | ||||
|                 done(); | ||||
|             } | ||||
| @@ -326,28 +327,27 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-gauge__curval'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-dial'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.js-gauge-dial-range'); | ||||
|             const valueElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct min max values', () => { | ||||
|             expect(gaugeHolder.querySelector('.c-gauge__range').textContent).toEqual(`${minValue} ${maxValue}`); | ||||
|             expect(gaugeHolder.querySelector('.js-gauge-dial-range').textContent).toEqual(`${minValue} ${maxValue}`); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct current value', (done) => { | ||||
|             function WatchUpdateValue() { | ||||
|                 const textElement = gaugeHolder.querySelector('.c-gauge__curval-text'); | ||||
|                 const textElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|                 expect(Number(textElement.textContent).toFixed(gaugeViewObject.configuration.gaugeController.precision)).toBe(randomValue.toFixed(gaugeViewObject.configuration.gaugeController.precision)); | ||||
|                 done(); | ||||
|             } | ||||
| @@ -462,28 +462,27 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-meter'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-meter__bg'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.js-gauge-meter-range'); | ||||
|             const valueElement = gaugeHolder.querySelector('.js-meter-current-value'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct min max values', () => { | ||||
|             expect(gaugeHolder.querySelector('.c-gauge__range').textContent).toEqual(`${maxValue} ${minValue}`); | ||||
|             expect(gaugeHolder.querySelector('.js-gauge-meter-range').textContent).toEqual(`${maxValue} ${minValue}`); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct current value', (done) => { | ||||
|             function WatchUpdateValue() { | ||||
|                 const textElement = gaugeHolder.querySelector('.c-gauge__curval-text'); | ||||
|                 const textElement = gaugeHolder.querySelector('.js-meter-current-value'); | ||||
|                 expect(Number(textElement.textContent).toFixed(gaugeViewObject.configuration.gaugeController.precision)).toBe(randomValue.toFixed(gaugeViewObject.configuration.gaugeController.precision)); | ||||
|                 done(); | ||||
|             } | ||||
| @@ -560,17 +559,16 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-meter'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-meter__bg'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.js-gauge-meter-range'); | ||||
|             const valueElement = gaugeHolder.querySelector('.js-meter-current-value'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
| @@ -643,17 +641,16 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-meter'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-meter__bg'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
| @@ -772,28 +769,27 @@ describe('Gauge plugin', () => { | ||||
|         }); | ||||
|  | ||||
|         it('renders gauge element', () => { | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.c-gauge'); | ||||
|             const gaugeElement = gaugeHolder.querySelectorAll('.js-gauge-wrapper'); | ||||
|             expect(gaugeElement.length).toBe(1); | ||||
|         }); | ||||
|  | ||||
|         it('renders major elements', () => { | ||||
|             const wrapperElement = gaugeHolder.querySelector('.c-gauge__wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.c-gauge__range'); | ||||
|             const curveElement = gaugeHolder.querySelector('.c-gauge__curval'); | ||||
|             const dialElement = gaugeHolder.querySelector('.c-dial'); | ||||
|             const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); | ||||
|             const rangeElement = gaugeHolder.querySelector('.js-gauge-dial-range'); | ||||
|             const valueElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|  | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && curveElement && dialElement); | ||||
|             const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); | ||||
|  | ||||
|             expect(hasMajorElements).toBe(true); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct min max values', () => { | ||||
|             expect(gaugeHolder.querySelector('.c-gauge__range').textContent).toEqual(`${gaugeViewObject.configuration.gaugeController.min} ${gaugeViewObject.configuration.gaugeController.max}`); | ||||
|             expect(gaugeHolder.querySelector('.js-gauge-dial-range').textContent).toEqual(`${gaugeViewObject.configuration.gaugeController.min} ${gaugeViewObject.configuration.gaugeController.max}`); | ||||
|         }); | ||||
|  | ||||
|         it('renders correct current value', (done) => { | ||||
|             function WatchUpdateValue() { | ||||
|                 const textElement = gaugeHolder.querySelector('.c-gauge__curval-text'); | ||||
|                 const textElement = gaugeHolder.querySelector('.js-dial-current-value'); | ||||
|                 expect(Number(textElement.textContent).toFixed(gaugeViewObject.configuration.gaugeController.precision)).toBe(randomValue.toFixed(gaugeViewObject.configuration.gaugeController.precision)); | ||||
|                 done(); | ||||
|             } | ||||
|   | ||||
| @@ -32,7 +32,9 @@ export default function GaugeViewProvider(openmct) { | ||||
|             return domainObject.type === 'gauge'; | ||||
|         }, | ||||
|         canEdit: function (domainObject) { | ||||
|             return false; | ||||
|             if (domainObject.type === 'gauge') { | ||||
|                 return true; | ||||
|             } | ||||
|         }, | ||||
|         view: function (domainObject) { | ||||
|             let component; | ||||
|   | ||||
| @@ -21,168 +21,259 @@ | ||||
| *****************************************************************************/ | ||||
| <template> | ||||
| <div | ||||
|     class="c-gauge" | ||||
|     class="c-gauge__wrapper js-gauge-wrapper" | ||||
|     :class="`c-gauge--${gaugeType}`" | ||||
| > | ||||
|     <div class="c-gauge__wrapper"> | ||||
|         <template v-if="typeDial"> | ||||
|             <svg | ||||
|                 class="c-gauge__range" | ||||
|                 viewBox="0 0 512 512" | ||||
|             > | ||||
|                 <text | ||||
|                     v-if="displayMinMax" | ||||
|                     font-size="35" | ||||
|                     transform="translate(105 455) rotate(-45)" | ||||
|                 >{{ rangeLow }}</text> | ||||
|                 <text | ||||
|                     v-if="displayMinMax" | ||||
|                     font-size="35" | ||||
|                     transform="translate(407 455) rotate(45)" | ||||
|                     text-anchor="end" | ||||
|                 >{{ rangeHigh }}</text> | ||||
|             </svg> | ||||
|     <template v-if="typeDial"> | ||||
|         <svg | ||||
|             width="0" | ||||
|             height="0" | ||||
|             class="c-dial__clip-paths" | ||||
|         > | ||||
|             <defs> | ||||
|                 <clipPath | ||||
|                     id="gaugeBgMask" | ||||
|                     clipPathUnits="objectBoundingBox" | ||||
|                 > | ||||
|                     <path d="M0.853553 0.853553C0.944036 0.763071 1 0.638071 1 0.5C1 0.223858 0.776142 0 0.5 0C0.223858 0 0 0.223858 0 0.5C0 0.638071 0.0559644 0.763071 0.146447 0.853553L0.285934 0.714066C0.23115 0.659281 0.197266 0.583598 0.197266 0.5C0.197266 0.332804 0.332804 0.197266 0.5 0.197266C0.667196 0.197266 0.802734 0.332804 0.802734 0.5C0.802734 0.583598 0.76885 0.659281 0.714066 0.714066L0.853553 0.853553Z" /> | ||||
|                 </clipPath> | ||||
|                 <clipPath | ||||
|                     id="gaugeValueMask" | ||||
|                     clipPathUnits="objectBoundingBox" | ||||
|                 > | ||||
|                     <path d="M0.18926 0.81074C0.109735 0.731215 0.0605469 0.621351 0.0605469 0.5C0.0605469 0.257298 0.257298 0.0605469 0.5 0.0605469C0.742702 0.0605469 0.939453 0.257298 0.939453 0.5C0.939453 0.621351 0.890265 0.731215 0.81074 0.81074L0.714066 0.714066C0.76885 0.659281 0.802734 0.583599 0.802734 0.5C0.802734 0.332804 0.667196 0.197266 0.5 0.197266C0.332804 0.197266 0.197266 0.332804 0.197266 0.5C0.197266 0.583599 0.23115 0.659281 0.285934 0.714066L0.18926 0.81074Z" /> | ||||
|                 </clipPath> | ||||
|             </defs> | ||||
|         </svg> | ||||
|  | ||||
|         <svg | ||||
|             class="c-dial__range c-gauge__range js-gauge-dial-range" | ||||
|             viewBox="0 0 512 512" | ||||
|         > | ||||
|             <text | ||||
|                 v-if="displayMinMax" | ||||
|                 font-size="35" | ||||
|                 transform="translate(105 455) rotate(-45)" | ||||
|             >{{ rangeLow }}</text> | ||||
|             <text | ||||
|                 v-if="displayMinMax" | ||||
|                 font-size="35" | ||||
|                 transform="translate(407 455) rotate(45)" | ||||
|                 text-anchor="end" | ||||
|             >{{ rangeHigh }}</text> | ||||
|         </svg> | ||||
|  | ||||
|         <svg | ||||
|             class="c-dial__current-value-text-wrapper" | ||||
|             viewBox="0 0 512 512" | ||||
|         > | ||||
|             <svg | ||||
|                 v-if="displayCurVal" | ||||
|                 class="c-gauge__curval" | ||||
|                 class="c-dial__current-value-text-sizer" | ||||
|                 :viewBox="curValViewBox" | ||||
|             > | ||||
|                 <text | ||||
|                     class="c-gauge__curval-text" | ||||
|                     class="c-dial__current-value-text js-dial-current-value" | ||||
|                     lengthAdjust="spacing" | ||||
|                     text-anchor="middle" | ||||
|                     style="transform: translate(50%, 70%)" | ||||
|                 >{{ curVal }}</text> | ||||
|             </svg> | ||||
|         </svg> | ||||
|  | ||||
|             <div class="c-dial"> | ||||
|                 <svg | ||||
|                     class="c-dial__bg" | ||||
|                     viewBox="0 0 512 512" | ||||
|                 > | ||||
|                     <path d="M256,0C114.6,0,0,114.6,0,256S114.6,512,256,512,512,397.4,512,256,397.4,0,256,0Zm0,412A156,156,0,1,1,412,256,155.9,155.9,0,0,1,256,412Z" /> | ||||
|                 </svg> | ||||
|         <svg | ||||
|             class="c-dial__bg" | ||||
|             viewBox="0 0 10 10" | ||||
|         > | ||||
|  | ||||
|                 <svg | ||||
|                     v-if="limitHigh && dialHighLimitDeg < 270" | ||||
|                     class="c-dial__limit-high" | ||||
|                     viewBox="0 0 512 512" | ||||
|                     :class="{ | ||||
|                         'c-high-limit-clip--90': dialHighLimitDeg > 90, | ||||
|                         'c-high-limit-clip--180': dialHighLimitDeg >= 180 | ||||
|                     }" | ||||
|                 > | ||||
|                     <path | ||||
|                         d="M100,256A156,156,0,1,1,366.3,366.3L437,437a255.2,255.2,0,0,0,75-181C512,114.6,397.4,0,256,0S0,114.6,0,256A255.2,255.2,0,0,0,75,437l70.7-70.7A155.5,155.5,0,0,1,100,256Z" | ||||
|                         :style="`transform: rotate(${dialHighLimitDeg}deg)`" | ||||
|                     /> | ||||
|                 </svg> | ||||
|             <g | ||||
|                 v-if="limitLow !== null && dialLowLimitDeg < getLimitDegree('low', 'max')" | ||||
|                 class="c-dial__limit-low" | ||||
|                 :style="`transform: rotate(${dialLowLimitDeg}deg)`" | ||||
|             > | ||||
|                 <rect | ||||
|                     v-if="dialLowLimitDeg >= getLimitDegree('low', 'q1')" | ||||
|                     class="c-dial__low-limit__low" | ||||
|                     x="5" | ||||
|                     y="5" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="dialLowLimitDeg >= getLimitDegree('low', 'q2')" | ||||
|                     class="c-dial__low-limit__mid" | ||||
|                     x="5" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="dialLowLimitDeg >= getLimitDegree('low', 'q3')" | ||||
|                     class="c-dial__low-limit__high" | ||||
|                     x="0" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|             </g> | ||||
|  | ||||
|                 <svg | ||||
|                     v-if="limitLow && dialLowLimitDeg < 270" | ||||
|                     class="c-dial__limit-low" | ||||
|                     viewBox="0 0 512 512" | ||||
|                     :class="{ | ||||
|                         'c-dial-clip--90': dialLowLimitDeg < 90, | ||||
|                         'c-dial-clip--180': dialLowLimitDeg >= 90 && dialLowLimitDeg < 180 | ||||
|                     }" | ||||
|                 > | ||||
|                     <path | ||||
|                         d="M256,100c86.2,0,156,69.8,156,156s-69.8,156-156,156c-43.1,0-82.1-17.5-110.3-45.7L75,437 c46.3,46.3,110.3,75,181,75c141.4,0,256-114.6,256-256S397.4,0,256,0C185.3,0,121.3,28.7,75,75l70.7,70.7 C173.9,117.5,212.9,100,256,100z" | ||||
|                         :style="`transform: rotate(${dialLowLimitDeg}deg)`" | ||||
|                     /> | ||||
|                 </svg> | ||||
|             <g | ||||
|                 v-if="limitHigh !== null && dialHighLimitDeg < getLimitDegree('high', 'max')" | ||||
|                 class="c-dial__limit-high" | ||||
|                 :style="`transform: rotate(${dialHighLimitDeg}deg)`" | ||||
|             > | ||||
|                 <rect | ||||
|                     v-if="dialHighLimitDeg <= getLimitDegree('high', 'max')" | ||||
|                     class="c-dial__high-limit__low" | ||||
|                     x="0" | ||||
|                     y="5" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="dialHighLimitDeg <= getLimitDegree('high', 'q2')" | ||||
|                     class="c-dial__high-limit__mid" | ||||
|                     x="0" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="dialHighLimitDeg <= getLimitDegree('high', 'q3')" | ||||
|                     class="c-dial__high-limit__high" | ||||
|                     x="5" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|             </g> | ||||
|         </svg> | ||||
|  | ||||
|                 <svg | ||||
|                     class="c-dial__value" | ||||
|                     viewBox="0 0 512 512" | ||||
|                     :class="{ | ||||
|                         'c-dial-clip--90': degValue < 90 && typeFilledDial, | ||||
|                         'c-dial-clip--180': degValue >= 90 && degValue < 180 && typeFilledDial | ||||
|                     }" | ||||
|                 > | ||||
|                     <path | ||||
|                         v-if="typeFilledDial && degValue > 0" | ||||
|                         d="M256,31A224.3,224.3,0,0,0,98.3,95.5l48.4,49.2a156,156,0,1,1-1,221.6L96.9,415.1A224.4,224.4,0,0,0,256,481c124.3,0,225-100.7,225-225S380.3,31,256,31Z" | ||||
|                         :style="`transform: rotate(${degValue}deg)`" | ||||
|                     /> | ||||
|                     <path | ||||
|                         v-if="typeNeedleDial && valueInBounds" | ||||
|                         d="M256,86c-93.9,0-170,76.1-170,170c0,43.9,16.6,83.9,43.9,114.1l-38.7,38.7c-3.3,3.3-3.3,8.7,0,12s8.7,3.3,12,0 l38.7-38.7C172.1,409.4,212.1,426,256,426c93.9,0,170-76.1,170-170S349.9,86,256,86z M256,411.7c-86,0-155.7-69.7-155.7-155.7 S170,100.3,256,100.3S411.7,170,411.7,256S342,411.7,256,411.7z" | ||||
|                         :style="`transform: rotate(${degValue}deg)`" | ||||
|                     /> | ||||
|                 </svg> | ||||
|         <svg | ||||
|             v-if="typeFilledDial" | ||||
|             class="c-dial__filled-value-wrapper" | ||||
|             viewBox="0 0 10 10" | ||||
|         > | ||||
|             <g | ||||
|                 class="c-dial__filled-value" | ||||
|                 :style="`transform: rotate(${degValueFilledDial}deg)`" | ||||
|             > | ||||
|                 <rect | ||||
|                     v-if="degValue >= getLimitDegree('low', 'q1')" | ||||
|                     class="c-dial__filled-value__low" | ||||
|                     x="5" | ||||
|                     y="5" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="degValue >= getLimitDegree('low', 'q2')" | ||||
|                     class="c-dial__filled-value__mid" | ||||
|                     x="5" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|                 <rect | ||||
|                     v-if="degValue >= getLimitDegree('low', 'q3')" | ||||
|                     class="c-dial__filled-value__high" | ||||
|                     x="0" | ||||
|                     y="0" | ||||
|                     width="5" | ||||
|                     height="5" | ||||
|                 /> | ||||
|             </g> | ||||
|         </svg> | ||||
|  | ||||
|         <svg | ||||
|             v-if="valueInBounds && typeNeedleDial" | ||||
|             class="c-dial__needle-value-wrapper" | ||||
|             viewBox="0 0 10 10" | ||||
|         > | ||||
|             <g | ||||
|                 class="c-dial__needle-value" | ||||
|                 :style="`transform: rotate(${degValue}deg)`" | ||||
|             > | ||||
|                 <path d="M4.90234 9.39453L5.09766 9.39453L5.30146 8.20874C6.93993 8.05674 8.22265 6.67817 8.22266 5C8.22266 3.22018 6.77982 1.77734 5 1.77734C3.22018 1.77734 1.77734 3.22018 1.77734 5C1.77734 6.67817 3.06007 8.05674 4.69854 8.20874L4.90234 9.39453Z" /> | ||||
|             </g> | ||||
|         </svg> | ||||
|     </template> | ||||
|  | ||||
|     <template v-if="typeMeter"> | ||||
|         <div class="c-meter"> | ||||
|             <div | ||||
|                 v-if="displayMinMax" | ||||
|                 class="c-gauge__range c-meter__range js-gauge-meter-range" | ||||
|             > | ||||
|                 <div class="c-meter__range__high">{{ rangeHigh }}</div> | ||||
|                 <div class="c-meter__range__low">{{ rangeLow }}</div> | ||||
|             </div> | ||||
|         </template> | ||||
|             <div class="c-meter__bg"> | ||||
|                 <template v-if="typeMeterVertical"> | ||||
|                     <div | ||||
|                         class="c-meter__value" | ||||
|                         :style="`transform: translateY(${meterValueToPerc}%)`" | ||||
|                     ></div> | ||||
|  | ||||
|         <template v-if="typeMeter"> | ||||
|             <div class="c-meter"> | ||||
|                 <div | ||||
|                     v-if="displayMinMax" | ||||
|                     class="c-gauge__range c-meter__range" | ||||
|                     <div | ||||
|                         v-if="limitHigh !== null && meterHighLimitPerc > 0" | ||||
|                         class="c-meter__limit-high" | ||||
|                         :style="`height: ${meterHighLimitPerc}%`" | ||||
|                     ></div> | ||||
|  | ||||
|                     <div | ||||
|                         v-if="limitLow !== null && meterLowLimitPerc > 0" | ||||
|                         class="c-meter__limit-low" | ||||
|                         :style="`height: ${meterLowLimitPerc}%`" | ||||
|                     ></div> | ||||
|                 </template> | ||||
|  | ||||
|                 <template v-if="typeMeterHorizontal"> | ||||
|                     <div | ||||
|                         class="c-meter__value" | ||||
|                         :style="`transform: translateX(${meterValueToPerc * -1}%)`" | ||||
|                     ></div> | ||||
|  | ||||
|                     <div | ||||
|                         v-if="limitHigh !== null && meterHighLimitPerc > 0" | ||||
|                         class="c-meter__limit-high" | ||||
|                         :style="`width: ${meterHighLimitPerc}%`" | ||||
|                     ></div> | ||||
|  | ||||
|                     <div | ||||
|                         v-if="limitLow !== null && meterLowLimitPerc > 0" | ||||
|                         class="c-meter__limit-low" | ||||
|                         :style="`width: ${meterLowLimitPerc}%`" | ||||
|                     ></div> | ||||
|                 </template> | ||||
|  | ||||
|                 <svg | ||||
|                     class="c-meter__current-value-text-wrapper" | ||||
|                     viewBox="0 0 512 512" | ||||
|                 > | ||||
|                     <div class="c-meter__range__high">{{ rangeHigh }}</div> | ||||
|                     <div class="c-meter__range__low">{{ rangeLow }}</div> | ||||
|                 </div> | ||||
|                 <div class="c-meter__bg"> | ||||
|                     <template v-if="typeMeterVertical"> | ||||
|                         <div | ||||
|                             class="c-meter__value" | ||||
|                             :style="`transform: translateY(${meterValueToPerc}%)`" | ||||
|                         ></div> | ||||
|  | ||||
|                         <div | ||||
|                             v-if="limitHigh && meterHighLimitPerc > 0" | ||||
|                             class="c-meter__limit-high" | ||||
|                             :style="`height: ${meterHighLimitPerc}%`" | ||||
|                         ></div> | ||||
|  | ||||
|                         <div | ||||
|                             v-if="limitLow && meterLowLimitPerc > 0" | ||||
|                             class="c-meter__limit-low" | ||||
|                             :style="`height: ${meterLowLimitPerc}%`" | ||||
|                         ></div> | ||||
|                     </template> | ||||
|  | ||||
|                     <template v-if="typeMeterHorizontal"> | ||||
|                         <div | ||||
|                             class="c-meter__value" | ||||
|                             :style="`transform: translateX(${meterValueToPerc * -1}%)`" | ||||
|                         ></div> | ||||
|  | ||||
|                         <div | ||||
|                             v-if="limitHigh && meterHighLimitPerc > 0" | ||||
|                             class="c-meter__limit-high" | ||||
|                             :style="`width: ${meterHighLimitPerc}%`" | ||||
|                         ></div> | ||||
|  | ||||
|                         <div | ||||
|                             v-if="limitLow && meterLowLimitPerc > 0" | ||||
|                             class="c-meter__limit-low" | ||||
|                             :style="`width: ${meterLowLimitPerc}%`" | ||||
|                         ></div> | ||||
|                     </template> | ||||
|  | ||||
|                     <svg | ||||
|                         v-if="displayCurVal" | ||||
|                         class="c-gauge__curval" | ||||
|                         class="c-meter__current-value-text-sizer" | ||||
|                         :viewBox="curValViewBox" | ||||
|                         preserveAspectRatio="xMidYMid meet" | ||||
|                     > | ||||
|                         <text | ||||
|                             class="c-gauge__curval-text" | ||||
|                             text-anchor="middle" | ||||
|                             class="c-dial__current-value-text js-meter-current-value" | ||||
|                             lengthAdjust="spacing" | ||||
|                             text-anchor="middle" | ||||
|                             style="transform: translate(50%, 70%)" | ||||
|                         >{{ curVal }}</text> | ||||
|                     </svg> | ||||
|                 </div> | ||||
|                 </svg> | ||||
|             </div> | ||||
|         </template> | ||||
|     </div> | ||||
|         </div> | ||||
|     </template> | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { DIAL_VALUE_DEG_OFFSET, getLimitDegree } from '../gauge-limit-util'; | ||||
|  | ||||
| const LIMIT_PADDING_IN_PERCENT = 10; | ||||
|  | ||||
| export default { | ||||
| @@ -209,6 +300,13 @@ export default { | ||||
|         degValue() { | ||||
|             return this.percentToDegrees(this.valToPercent(this.curVal)); | ||||
|         }, | ||||
|         degValueFilledDial() { | ||||
|             if (this.curVal > this.rangeHigh) { | ||||
|                 return this.percentToDegrees(100); | ||||
|             } | ||||
|  | ||||
|             return this.percentToDegrees(this.valToPercent(this.curVal)); | ||||
|         }, | ||||
|         dialHighLimitDeg() { | ||||
|             return this.percentToDegrees(this.valToPercent(this.limitHigh)); | ||||
|         }, | ||||
| @@ -299,6 +397,7 @@ export default { | ||||
|         this.openmct.time.off('timeSystem', this.setTimeSystem); | ||||
|     }, | ||||
|     methods: { | ||||
|         getLimitDegree: getLimitDegree, | ||||
|         addTelemetryObjectAndSubscribe(domainObject) { | ||||
|             this.telemetryObject = domainObject; | ||||
|             this.request(); | ||||
| @@ -340,7 +439,7 @@ export default { | ||||
|             return this.gaugeType.indexOf(str) !== -1; | ||||
|         }, | ||||
|         percentToDegrees(vPercent) { | ||||
|             return this.round((vPercent / 100) * 270, 2); | ||||
|             return this.round(((vPercent / 100) * 270) + DIAL_VALUE_DEG_OFFSET, 2); | ||||
|         }, | ||||
|         removeFromComposition(telemetryObject = this.telemetryObject) { | ||||
|             let composition = this.domainObject.composition.filter(id => | ||||
| @@ -453,7 +552,7 @@ export default { | ||||
|         valToPercent(vValue) { | ||||
|             // Used by dial | ||||
|             if (vValue >= this.rangeHigh && this.typeFilledDial) { | ||||
|                 // Don't peg at 100% if the gaugeType isn't a filled shape | ||||
|                 // For filled dial, clip values over the high range to prevent over-rotation | ||||
|                 return 100; | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
|         :class="model.cssClass" | ||||
|     > | ||||
|         <ToggleSwitch | ||||
|             :id="'gaugeToggle'" | ||||
|             :checked="isUseTelemetryLimits" | ||||
|             label="Use telemetry limits for minimum and maximum ranges" | ||||
|             @change="toggleUseTelemetryLimits" | ||||
|   | ||||
							
								
								
									
										39
									
								
								src/plugins/gauge/gauge-limit-util.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/plugins/gauge/gauge-limit-util.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| const GAUGE_LIMITS = { | ||||
|     q1: 0, | ||||
|     q2: 90, | ||||
|     q3: 180, | ||||
|     q4: 270 | ||||
| }; | ||||
|  | ||||
| export const DIAL_VALUE_DEG_OFFSET = 45; | ||||
|  | ||||
| // type: low, high | ||||
| // quadrant: low, mid, high, max | ||||
| export function getLimitDegree(type, quadrant) { | ||||
|     if (quadrant === 'max') { | ||||
|         return GAUGE_LIMITS.q4 + DIAL_VALUE_DEG_OFFSET; | ||||
|     } | ||||
|  | ||||
|     return type === 'low' | ||||
|         ? getLowLimitDegree(quadrant) | ||||
|         : getHighLimitDegree(quadrant) | ||||
|     ; | ||||
| } | ||||
|  | ||||
| function getLowLimitDegree(quadrant) { | ||||
|     return GAUGE_LIMITS[quadrant] + DIAL_VALUE_DEG_OFFSET; | ||||
| } | ||||
|  | ||||
| function getHighLimitDegree(quadrant) { | ||||
|     if (quadrant === 'q1') { | ||||
|         return GAUGE_LIMITS.q4 + DIAL_VALUE_DEG_OFFSET; | ||||
|     } | ||||
|  | ||||
|     if (quadrant === 'q2') { | ||||
|         return GAUGE_LIMITS.q3 + DIAL_VALUE_DEG_OFFSET; | ||||
|     } | ||||
|  | ||||
|     if (quadrant === 'q3') { | ||||
|         return GAUGE_LIMITS.q2 + DIAL_VALUE_DEG_OFFSET; | ||||
|     } | ||||
| } | ||||
| @@ -1,9 +1,3 @@ | ||||
| $dialClip: polygon(0 0, 100% 0, 100% 100%, 50% 50%, 0 100%); | ||||
| $dialClip90: polygon(0 0, 50% 50%, 0 100%); | ||||
| $dialClip180: polygon(0 0, 100% 0, 0 100%); | ||||
| $limitHighClip90: polygon(0 0, 100% 0, 100% 100%); | ||||
| $limitHighClip180: polygon(100% 0, 100% 100%, 0 100%); | ||||
|  | ||||
| .is-object-type-gauge { | ||||
|   overflow: hidden; | ||||
| } | ||||
| @@ -13,10 +7,8 @@ $limitHighClip180: polygon(100% 0, 100% 100%, 0 100%); | ||||
|  | ||||
|   &.invalid, | ||||
|   &.invalid.req { @include validationState($glyph-icon-x, $colorFormInvalid); } | ||||
|  | ||||
|   &.valid, | ||||
|   &.valid.req { @include validationState($glyph-icon-check, $colorFormValid); } | ||||
|  | ||||
|   &.req { @include validationState($glyph-icon-asterisk, $colorFormRequired); } | ||||
| } | ||||
|  | ||||
| @@ -37,92 +29,47 @@ $limitHighClip180: polygon(100% 0, 100% 100%, 0 100%); | ||||
|     @include abs(); | ||||
|     overflow: hidden; | ||||
|   } | ||||
|  | ||||
|   svg { | ||||
|     path { | ||||
|       transform-origin: center; | ||||
|     } | ||||
|  | ||||
|     &.c-gauge__curval { | ||||
|       @include abs(); | ||||
|       fill: $colorGaugeTextValue; | ||||
|       position: absolute; | ||||
|       width: 100%; | ||||
|       height: 100%; | ||||
|       z-index: 2; | ||||
|  | ||||
|       .c-gauge__curval-text { | ||||
|         font-family: $heroFont; | ||||
|         transform: translate(50%, 75%); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &[class*='dial'] { | ||||
|     // Square aspect ratio | ||||
|     width: 100%; | ||||
|     padding-bottom: 100%; | ||||
|   } | ||||
|  | ||||
|   &[class*='meter'] { | ||||
|     @include abs(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /********************************************** DIAL GAUGE */ | ||||
| .c-dial { | ||||
|   // Dial elements | ||||
|   @include abs(); | ||||
|   clip-path: $dialClip; | ||||
| svg[class*='c-dial'] { | ||||
|   max-height: 100%; | ||||
|   max-width: 100%; | ||||
|   position: absolute; | ||||
|  | ||||
|   svg, | ||||
|   &__ticks, | ||||
|   &__bg, | ||||
|   &[class*='__limit'], | ||||
|   &__value { | ||||
|     @include abs(); | ||||
|   } | ||||
|  | ||||
|   .c-high-limit-clip--90 { | ||||
|     clip-path: $limitHighClip90; | ||||
|   } | ||||
|  | ||||
|   .c-high-limit-clip--180 { | ||||
|     clip-path: $limitHighClip180; | ||||
|   } | ||||
|  | ||||
|   &__limit-high path { fill: $colorGaugeLimitHigh; } | ||||
|   &__limit-low path { fill: $colorGaugeLimitLow; } | ||||
|  | ||||
|   &__value, | ||||
|   &__limit-low { | ||||
|     &.c-dial-clip--90 { | ||||
|       clip-path: $dialClip90; | ||||
|     } | ||||
|  | ||||
|     &.c-dial-clip--180 { | ||||
|       clip-path: $dialClip180; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &__value { | ||||
|     path, | ||||
|     polygon { | ||||
|       fill: $colorGaugeValue; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &__bg { | ||||
|     path { | ||||
|       fill: $colorGaugeBg; | ||||
|     } | ||||
|   g { | ||||
|     transform-origin: center; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .c-gauge--dial-needle .c-dial__value { | ||||
|   path { | ||||
| .c-dial { | ||||
|   &__bg { | ||||
|     background: $colorGaugeBg; | ||||
|     clip-path: url(#gaugeBgMask); | ||||
|   } | ||||
|  | ||||
|   &__limit-high rect { fill: $colorGaugeLimitHigh; } | ||||
|   &__limit-low rect { fill: $colorGaugeLimitLow; } | ||||
|  | ||||
|   &__filled-value-wrapper { | ||||
|     clip-path: url(#gaugeValueMask); | ||||
|   } | ||||
|  | ||||
|   &__needle-value-wrapper { | ||||
|     clip-path: url(#gaugeValueMask); | ||||
|   } | ||||
|  | ||||
|   &__filled-value { fill: $colorGaugeValue; } | ||||
|  | ||||
|   &__needle-value { | ||||
|     fill: $colorGaugeValue; | ||||
|     transition: transform $transitionTimeGauge; | ||||
|   } | ||||
|  | ||||
|   &__current-value-text { | ||||
|     fill: $colorGaugeTextValue; | ||||
|     font-family: $heroFont; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /********************************************** METER GAUGE */ | ||||
| @@ -131,6 +78,13 @@ $limitHighClip180: polygon(100% 0, 100% 100%, 0 100%); | ||||
|   @include abs(); | ||||
|   display: flex; | ||||
|  | ||||
|   svg { | ||||
|     // current-value-text | ||||
|     position: absolute; | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|   } | ||||
|  | ||||
|   &__range { | ||||
|     display: flex; | ||||
|     flex: 0 0 auto; | ||||
|   | ||||
| @@ -143,13 +143,13 @@ | ||||
|                 <!-- spacecraft position fresh --> | ||||
|                 <div | ||||
|                     v-if="relatedTelemetry.hasRelatedTelemetry && isSpacecraftPositionFresh" | ||||
|                     class="c-imagery__age icon-check c-imagery--new" | ||||
|                     class="c-imagery__age icon-check c-imagery--new no-animation" | ||||
|                 >POS</div> | ||||
|  | ||||
|                 <!-- camera position fresh --> | ||||
|                 <div | ||||
|                     v-if="relatedTelemetry.hasRelatedTelemetry && isCameraPositionFresh" | ||||
|                     class="c-imagery__age icon-check c-imagery--new" | ||||
|                     class="c-imagery__age icon-check c-imagery--new no-animation" | ||||
|                 >CAM</div> | ||||
|             </div> | ||||
|             <div class="h-local-controls"> | ||||
| @@ -331,6 +331,16 @@ export default { | ||||
|         }, | ||||
|         isImageNew() { | ||||
|             let cutoff = FIVE_MINUTES; | ||||
|             if (this.imageFreshnessOptions) { | ||||
|                 const { fadeOutDelayTime, fadeOutDurationTime} = this.imageFreshnessOptions; | ||||
|                 // convert css duration to IS8601 format for parsing | ||||
|                 const isoFormattedDuration = 'PT' + fadeOutDurationTime.toUpperCase(); | ||||
|                 const isoFormattedDelay = 'PT' + fadeOutDelayTime.toUpperCase(); | ||||
|                 const parsedDuration = moment.duration(isoFormattedDuration).asMilliseconds(); | ||||
|                 const parsedDelay = moment.duration(isoFormattedDelay).asMilliseconds(); | ||||
|                 cutoff = parsedDuration + parsedDelay; | ||||
|             } | ||||
|  | ||||
|             let age = this.numericDuration; | ||||
|  | ||||
|             return age < cutoff && !this.refreshCSS; | ||||
| @@ -514,6 +524,8 @@ export default { | ||||
|                 if (!this.isPaused) { | ||||
|                     this.setFocusedImage(imageIndex); | ||||
|                     this.scrollToRight(); | ||||
|                 } else { | ||||
|                     this.scrollToFocused(); | ||||
|                 } | ||||
|             }, | ||||
|             deep: true | ||||
| @@ -977,6 +989,7 @@ export default { | ||||
|  | ||||
|             this.setSizedImageDimensions(); | ||||
|             this.calculateViewHeight(); | ||||
|             this.scrollToFocused(); | ||||
|         }, | ||||
|         setSizedImageDimensions() { | ||||
|             this.focusedImageNaturalAspectRatio = this.$refs.focusedImage.naturalWidth / this.$refs.focusedImage.naturalHeight; | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| @use 'sass:math'; | ||||
|  | ||||
| @keyframes fade-out { | ||||
|     from { | ||||
|         background-color: rgba($colorOk, 0.5); | ||||
| @@ -138,6 +140,9 @@ | ||||
|         animation-timing-function: ease-in; | ||||
|         animation-iteration-count: 1; | ||||
|         animation-fill-mode: forwards; | ||||
|         &.no-animation { | ||||
|             animation: none; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -211,7 +216,7 @@ | ||||
|     } | ||||
|  | ||||
|     .c-thumb { | ||||
|         $w: $imageThumbsD / 2; | ||||
|         $w: math.div($imageThumbsD, 2); | ||||
|         min-width: $w; | ||||
|         width: $w; | ||||
|  | ||||
|   | ||||
| @@ -204,6 +204,8 @@ export default { | ||||
|  | ||||
|         updateTicks(forceRegeneration = false) { | ||||
|             const range = this.axis.get('displayRange'); | ||||
|             const logMode = this.axis.get('logMode'); | ||||
|  | ||||
|             if (!range) { | ||||
|                 delete this.min; | ||||
|                 delete this.max; | ||||
| @@ -231,7 +233,7 @@ export default { | ||||
|                     step: newTicks[1] - newTicks[0] | ||||
|                 }; | ||||
|  | ||||
|                 newTicks = getFormattedTicks(newTicks, format); | ||||
|                 newTicks = getFormattedTicks(newTicks, format, logMode); | ||||
|  | ||||
|                 this.ticks = newTicks; | ||||
|                 this.shouldCheckWidth = true; | ||||
|   | ||||
| @@ -215,6 +215,10 @@ export default class YAxisModel extends Model { | ||||
|  | ||||
|             const _range = this.get('displayRange'); | ||||
|  | ||||
|             if (!_range) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (this.get('logMode')) { | ||||
|                 _range.min = antisymlog(_range.min, 10); | ||||
|                 _range.max = antisymlog(_range.max, 10); | ||||
|   | ||||
| @@ -132,12 +132,6 @@ export default { | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (this.object && this.object.type === 'conditionWidget' && keys.includes('output')) { | ||||
|                 this.openmct.objects.mutate(this.object, 'conditionalLabel', styleObj.output); | ||||
|             } else { | ||||
|                 this.openmct.objects.mutate(this.object, 'conditionalLabel', ''); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|   | ||||
| @@ -131,12 +131,17 @@ export function commonSuffix(a, b) { | ||||
|     return a.slice(a.length - breakpoint); | ||||
| } | ||||
|  | ||||
| export function getFormattedTicks(newTicks, format) { | ||||
| export function getFormattedTicks(newTicks, format, formatFloat) { | ||||
|     newTicks = newTicks | ||||
|         .map(function (tickValue) { | ||||
|             let formattedValue = format(tickValue); | ||||
|             if (formatFloat === true && typeof formattedValue === 'number' && !Number.isInteger(formattedValue)) { | ||||
|                 formattedValue = parseFloat(formattedValue).toFixed(2); | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 value: tickValue, | ||||
|                 text: format(tickValue) | ||||
|                 text: formattedValue | ||||
|             }; | ||||
|         }); | ||||
|  | ||||
|   | ||||
| @@ -127,6 +127,10 @@ export default { | ||||
|     }, | ||||
|     methods: { | ||||
|         clear() { | ||||
|             if (this.domainObject) { | ||||
|                 this.openmct.styleManager.delete(this.domainObject.identifier); | ||||
|             } | ||||
|  | ||||
|             if (this.currentView) { | ||||
|                 this.currentView.destroy(); | ||||
|                 if (this.$refs.objectViewWrapper) { | ||||
| @@ -213,12 +217,6 @@ export default { | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (this.domainObject && this.domainObject.type === 'conditionWidget' && keys.includes('output')) { | ||||
|                 this.openmct.objects.mutate(this.domainObject, 'conditionalLabel', styleObj.output); | ||||
|             } else { | ||||
|                 this.openmct.objects.mutate(this.domainObject, 'conditionalLabel', ''); | ||||
|             } | ||||
|         }, | ||||
|         updateView(immediatelySelect) { | ||||
|             this.clear(); | ||||
| @@ -310,8 +308,10 @@ export default { | ||||
|             this.initObjectStyles(); | ||||
|         }, | ||||
|         initObjectStyles() { | ||||
|             this.styleRuleManager = this.openmct.styleManager.get(this.domainObject.identifier); | ||||
|             if (!this.styleRuleManager) { | ||||
|                 this.styleRuleManager = new StyleRuleManager((this.domainObject.configuration && this.domainObject.configuration.objectStyles), this.openmct, this.updateStyle.bind(this), true); | ||||
|                 this.openmct.styleManager.set(this.domainObject.identifier, this.styleRuleManager); | ||||
|             } else { | ||||
|                 this.styleRuleManager.updateObjectStyleConfig(this.domainObject.configuration && this.domainObject.configuration.objectStyles); | ||||
|             } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user