[VISTA] custom format tokens (#3469)

* [VISTA] custom format tokens #3468

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
This commit is contained in:
Nikhil
2020-11-20 12:17:18 -08:00
committed by GitHub
parent 6375ecda34
commit 6fd8f6cd43
4 changed files with 169 additions and 12 deletions

View File

@ -21,12 +21,14 @@
*****************************************************************************/ *****************************************************************************/
define([ define([
'../../plugins/displayLayout/CustomStringFormatter',
'./TelemetryMetadataManager', './TelemetryMetadataManager',
'./TelemetryValueFormatter', './TelemetryValueFormatter',
'./DefaultMetadataProvider', './DefaultMetadataProvider',
'objectUtils', 'objectUtils',
'lodash' 'lodash'
], function ( ], function (
CustomStringFormatter,
TelemetryMetadataManager, TelemetryMetadataManager,
TelemetryValueFormatter, TelemetryValueFormatter,
DefaultMetadataProvider, DefaultMetadataProvider,
@ -142,6 +144,17 @@ define([
this.valueFormatterCache = new WeakMap(); this.valueFormatterCache = new WeakMap();
} }
/**
* Return Custom String Formatter
*
* @param {Object} valueMetadata valueMetadata for given telemetry object
* @param {string} format custom formatter string (eg: %.4f, &lts 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 * Return true if the given domainObject is a telemetry object. A telemetry
* object is any object which has telemetry metadata-- regardless of whether * object is any object which has telemetry metadata-- regardless of whether
@ -400,6 +413,17 @@ define([
return _.sortBy(options, sortKeys); 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. * Get a value formatter for a given valueMetadata.
* *
@ -407,19 +431,27 @@ define([
*/ */
TelemetryAPI.prototype.getValueFormatter = function (valueMetadata) { TelemetryAPI.prototype.getValueFormatter = function (valueMetadata) {
if (!this.valueFormatterCache.has(valueMetadata)) { if (!this.valueFormatterCache.has(valueMetadata)) {
if (!this.formatService) {
this.formatService = this.openmct.$injector.get('formatService');
}
this.valueFormatterCache.set( this.valueFormatterCache.set(
valueMetadata, valueMetadata,
new TelemetryValueFormatter(valueMetadata, this.formatService) new TelemetryValueFormatter(valueMetadata, this.getFormatService())
); );
} }
return this.valueFormatterCache.get(valueMetadata); 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 * Get a format map of all value formatters for a given piece of telemetry
* metadata. * metadata.

View File

@ -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;
}
}

View File

@ -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('&lts');
const value = customStringFormatter.format(datum, valueMetadata);
expect(datum.sin * 3).toEqual(value);
});
});

View File

@ -71,7 +71,6 @@
<script> <script>
import LayoutFrame from './LayoutFrame.vue'; import LayoutFrame from './LayoutFrame.vue';
import printj from 'printj';
import conditionalStylesMixin from "../mixins/objectStyles-mixin"; import conditionalStylesMixin from "../mixins/objectStyles-mixin";
import { getDefaultNotebook } from '@/plugins/notebook/utils/notebook-storage.js'; import { getDefaultNotebook } from '@/plugins/notebook/utils/notebook-storage.js';
@ -172,7 +171,11 @@ export default {
valueMetadata() { valueMetadata() {
return this.datum && this.metadata.value(this.item.value); return this.datum && this.metadata.value(this.item.value);
}, },
valueFormatter() { formatter() {
if (this.item.format) {
return this.customStringformatter;
}
return this.formats[this.item.value]; return this.formats[this.item.value];
}, },
telemetryValue() { telemetryValue() {
@ -180,11 +183,7 @@ export default {
return; return;
} }
if (this.item.format) { return this.formatter && this.formatter.format(this.datum);
return printj.sprintf(this.item.format, this.datum[this.valueMetadata.key]);
}
return this.valueFormatter && this.valueFormatter.format(this.datum);
}, },
telemetryClass() { telemetryClass() {
if (!this.datum) { if (!this.datum) {
@ -290,6 +289,10 @@ export default {
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject); this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject); this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
this.formats = this.openmct.telemetry.getFormatMap(this.metadata); this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
const valueMetadata = this.metadata.value(this.item.value);
this.customStringformatter = this.openmct.telemetry.customStringFormatter(valueMetadata, this.item.format);
this.requestHistoricalData(); this.requestHistoricalData();
this.subscribeToObject(); this.subscribeToObject();
@ -309,6 +312,8 @@ export default {
delete this.immediatelySelect; delete this.immediatelySelect;
}, },
updateTelemetryFormat(format) { updateTelemetryFormat(format) {
this.customStringformatter.setFormat(format);
this.$emit('formatChanged', this.item, format); this.$emit('formatChanged', this.item, format);
}, },
async getContextMenuActions() { async getContextMenuActions() {