From 6fd8f6cd4312203a33ba9e87a3af718b97ab4580 Mon Sep 17 00:00:00 2001 From: Nikhil Date: Fri, 20 Nov 2020 12:17:18 -0800 Subject: [PATCH] [VISTA] custom format tokens (#3469) * [VISTA] custom format tokens #3468 Co-authored-by: Deep Tailor --- src/api/telemetry/TelemetryAPI.js | 42 ++++++++-- .../displayLayout/CustomStringFormatter.js | 38 +++++++++ .../CustomStringFormatterSpec.js | 82 +++++++++++++++++++ .../components/TelemetryView.vue | 19 +++-- 4 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 src/plugins/displayLayout/CustomStringFormatter.js create mode 100644 src/plugins/displayLayout/CustomStringFormatterSpec.js diff --git a/src/api/telemetry/TelemetryAPI.js b/src/api/telemetry/TelemetryAPI.js index 26e01bd6e1..63d5c24112 100644 --- a/src/api/telemetry/TelemetryAPI.js +++ b/src/api/telemetry/TelemetryAPI.js @@ -21,12 +21,14 @@ *****************************************************************************/ define([ + '../../plugins/displayLayout/CustomStringFormatter', './TelemetryMetadataManager', './TelemetryValueFormatter', './DefaultMetadataProvider', 'objectUtils', 'lodash' ], function ( + CustomStringFormatter, TelemetryMetadataManager, TelemetryValueFormatter, DefaultMetadataProvider, @@ -142,6 +144,17 @@ define([ this.valueFormatterCache = new WeakMap(); } + /** + * Return Custom String Formatter + * + * @param {Object} valueMetadata valueMetadata for given telemetry object + * @param {string} format custom formatter string (eg: %.4f, <s etc.) + * @returns {CustomStringFormatter} + */ + TelemetryAPI.prototype.customStringFormatter = function (valueMetadata, format) { + return new CustomStringFormatter.default(this.openmct, valueMetadata, format); + }; + /** * Return true if the given domainObject is a telemetry object. A telemetry * object is any object which has telemetry metadata-- regardless of whether @@ -400,6 +413,17 @@ define([ return _.sortBy(options, sortKeys); }; + /** + * @private + */ + TelemetryAPI.prototype.getFormatService = function () { + if (!this.formatService) { + this.formatService = this.openmct.$injector.get('formatService'); + } + + return this.formatService; + }; + /** * Get a value formatter for a given valueMetadata. * @@ -407,19 +431,27 @@ define([ */ TelemetryAPI.prototype.getValueFormatter = function (valueMetadata) { if (!this.valueFormatterCache.has(valueMetadata)) { - if (!this.formatService) { - this.formatService = this.openmct.$injector.get('formatService'); - } - this.valueFormatterCache.set( valueMetadata, - new TelemetryValueFormatter(valueMetadata, this.formatService) + new TelemetryValueFormatter(valueMetadata, this.getFormatService()) ); } return this.valueFormatterCache.get(valueMetadata); }; + /** + * Get a value formatter for a given key. + * @param {string} key + * + * @returns {Format} + */ + TelemetryAPI.prototype.getFormatter = function (key) { + const formatMap = this.getFormatService().formatMap; + + return formatMap[key]; + }; + /** * Get a format map of all value formatters for a given piece of telemetry * metadata. diff --git a/src/plugins/displayLayout/CustomStringFormatter.js b/src/plugins/displayLayout/CustomStringFormatter.js new file mode 100644 index 0000000000..445cfd1edf --- /dev/null +++ b/src/plugins/displayLayout/CustomStringFormatter.js @@ -0,0 +1,38 @@ +import printj from 'printj'; + +export default class CustomStringFormatter { + constructor(openmct, valueMetadata, itemFormat) { + this.openmct = openmct; + + this.itemFormat = itemFormat; + this.valueMetadata = valueMetadata; + } + + format(datum) { + if (!this.itemFormat) { + return; + } + + if (!this.itemFormat.startsWith('&')) { + return printj.sprintf(this.itemFormat, datum[this.valueMetadata.key]); + } + + try { + const key = this.itemFormat.slice(1); + const customFormatter = this.openmct.telemetry.getFormatter(key); + if (!customFormatter) { + throw new Error('Custom Formatter not found'); + } + + return customFormatter.format(datum[this.valueMetadata.key]); + } catch (e) { + console.error(e); + + return datum[this.valueMetadata.key]; + } + } + + setFormat(itemFormat) { + this.itemFormat = itemFormat; + } +} diff --git a/src/plugins/displayLayout/CustomStringFormatterSpec.js b/src/plugins/displayLayout/CustomStringFormatterSpec.js new file mode 100644 index 0000000000..bd19078fb9 --- /dev/null +++ b/src/plugins/displayLayout/CustomStringFormatterSpec.js @@ -0,0 +1,82 @@ +import CustomStringFormatter from './CustomStringFormatter'; +import { createOpenMct, resetApplicationState } from 'utils/testing'; + +const CUSTOM_FORMATS = [ + { + key: 'sclk', + format: (value) => 2 * value + }, + { + key: 'lts', + format: (value) => 3 * value + } +]; + +const valueMetadata = { + key: "sin", + name: "Sine", + unit: "Hz", + formatString: "%0.2f", + hints: { + range: 1, + priority: 3 + }, + source: "sin" +}; + +const datum = { + name: "1 Sine Wave Generator", + utc: 1603930354000, + yesterday: 1603843954000, + sin: 0.587785209686822, + cos: -0.8090170253297632 +}; + +describe('CustomStringFormatter', function () { + let element; + let child; + let openmct; + let customStringFormatter; + + beforeEach((done) => { + openmct = createOpenMct(); + + element = document.createElement('div'); + child = document.createElement('div'); + element.appendChild(child); + CUSTOM_FORMATS.forEach(openmct.telemetry.addFormat.bind({openmct})); + openmct.on('start', done); + openmct.startHeadless(); + + spyOn(openmct.telemetry, 'getFormatter'); + openmct.telemetry.getFormatter.and.callFake((key) => CUSTOM_FORMATS.find(d => d.key === key)); + + customStringFormatter = new CustomStringFormatter(openmct, valueMetadata); + }); + + afterEach(() => { + return resetApplicationState(openmct); + }); + + it('adds custom format sclk', () => { + const format = openmct.telemetry.getFormatter('sclk'); + expect(format.key).toEqual('sclk'); + }); + + it('adds custom format lts', () => { + const format = openmct.telemetry.getFormatter('lts'); + expect(format.key).toEqual('lts'); + }); + + it('returns correct value for custom format sclk', () => { + customStringFormatter.setFormat('&sclk'); + const value = customStringFormatter.format(datum, valueMetadata); + expect(datum.sin * 2).toEqual(value); + }); + + it('returns correct value for custom format lts', () => { + customStringFormatter.setFormat('<s'); + const value = customStringFormatter.format(datum, valueMetadata); + expect(datum.sin * 3).toEqual(value); + }); +}); diff --git a/src/plugins/displayLayout/components/TelemetryView.vue b/src/plugins/displayLayout/components/TelemetryView.vue index 693e3d955c..cd1112b861 100644 --- a/src/plugins/displayLayout/components/TelemetryView.vue +++ b/src/plugins/displayLayout/components/TelemetryView.vue @@ -71,7 +71,6 @@