mirror of
https://github.com/nasa/openmct.git
synced 2025-06-28 11:51:10 +00:00
Compare commits
7 Commits
5211-tests
...
bar-graph-
Author | SHA1 | Date | |
---|---|---|---|
b3a774ffa6 | |||
225d3883d1 | |||
bef5fc2e47 | |||
77663ac2b3 | |||
90b98a5c97 | |||
e056b79033 | |||
5362344529 |
@ -28,15 +28,6 @@ define([
|
|||||||
domain: 2
|
domain: 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: "cos",
|
|
||||||
name: "Cosine",
|
|
||||||
unit: "deg",
|
|
||||||
formatString: '%0.2f',
|
|
||||||
hints: {
|
|
||||||
domain: 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Need to enable "LocalTimeSystem" plugin to make use of this
|
// Need to enable "LocalTimeSystem" plugin to make use of this
|
||||||
// {
|
// {
|
||||||
// key: "local",
|
// key: "local",
|
||||||
@ -118,100 +109,6 @@ define([
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
'example.spectral-generator': {
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
key: "name",
|
|
||||||
name: "Name",
|
|
||||||
format: "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "utc",
|
|
||||||
name: "Time",
|
|
||||||
format: "utc",
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "wavelength",
|
|
||||||
name: "Wavelength",
|
|
||||||
unit: "Hz",
|
|
||||||
formatString: '%0.2f',
|
|
||||||
hints: {
|
|
||||||
domain: 2,
|
|
||||||
spectralAttribute: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "cos",
|
|
||||||
name: "Cosine",
|
|
||||||
unit: "deg",
|
|
||||||
formatString: '%0.2f',
|
|
||||||
hints: {
|
|
||||||
range: 2,
|
|
||||||
spectralAttribute: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'example.spectral-aggregate-generator': {
|
|
||||||
values: [
|
|
||||||
{
|
|
||||||
key: "name",
|
|
||||||
name: "Name",
|
|
||||||
format: "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "utc",
|
|
||||||
name: "Time",
|
|
||||||
format: "utc",
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ch1",
|
|
||||||
name: "Channel 1",
|
|
||||||
format: "string",
|
|
||||||
hints: {
|
|
||||||
range: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ch2",
|
|
||||||
name: "Channel 2",
|
|
||||||
format: "string",
|
|
||||||
hints: {
|
|
||||||
range: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ch3",
|
|
||||||
name: "Channel 3",
|
|
||||||
format: "string",
|
|
||||||
hints: {
|
|
||||||
range: 3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ch4",
|
|
||||||
name: "Channel 4",
|
|
||||||
format: "string",
|
|
||||||
hints: {
|
|
||||||
range: 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "ch5",
|
|
||||||
name: "Channel 5",
|
|
||||||
format: "string",
|
|
||||||
hints: {
|
|
||||||
range: 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
|
|
||||||
], function (
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
function SpectralAggregateGeneratorProvider() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function pointForTimestamp(timestamp, count, name) {
|
|
||||||
return {
|
|
||||||
name: name,
|
|
||||||
utc: String(Math.floor(timestamp / count) * count),
|
|
||||||
ch1: String(Math.floor(timestamp / count) % 1),
|
|
||||||
ch2: String(Math.floor(timestamp / count) % 2),
|
|
||||||
ch3: String(Math.floor(timestamp / count) % 3),
|
|
||||||
ch4: String(Math.floor(timestamp / count) % 4),
|
|
||||||
ch5: String(Math.floor(timestamp / count) % 5)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SpectralAggregateGeneratorProvider.prototype.supportsSubscribe = function (domainObject) {
|
|
||||||
return domainObject.type === 'example.spectral-aggregate-generator';
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralAggregateGeneratorProvider.prototype.subscribe = function (domainObject, callback) {
|
|
||||||
var count = 5000;
|
|
||||||
|
|
||||||
var interval = setInterval(function () {
|
|
||||||
var now = Date.now();
|
|
||||||
var datum = pointForTimestamp(now, count, domainObject.name);
|
|
||||||
callback(datum);
|
|
||||||
}, count);
|
|
||||||
|
|
||||||
return function () {
|
|
||||||
clearInterval(interval);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralAggregateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) {
|
|
||||||
return domainObject.type === 'example.spectral-aggregate-generator';
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralAggregateGeneratorProvider.prototype.request = function (domainObject, options) {
|
|
||||||
var start = options.start;
|
|
||||||
var end = Math.min(Date.now(), options.end); // no future values
|
|
||||||
var count = 5000;
|
|
||||||
if (options.strategy === 'latest' || options.size === 1) {
|
|
||||||
start = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = [];
|
|
||||||
while (start <= end && data.length < 5000) {
|
|
||||||
data.push(pointForTimestamp(start, count, domainObject.name));
|
|
||||||
start += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
return SpectralAggregateGeneratorProvider;
|
|
||||||
|
|
||||||
});
|
|
@ -1,102 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'./WorkerInterface'
|
|
||||||
], function (
|
|
||||||
WorkerInterface
|
|
||||||
) {
|
|
||||||
|
|
||||||
var REQUEST_DEFAULTS = {
|
|
||||||
amplitude: 1,
|
|
||||||
wavelength: 1,
|
|
||||||
period: 10,
|
|
||||||
offset: 0,
|
|
||||||
dataRateInHz: 1,
|
|
||||||
randomness: 0,
|
|
||||||
phase: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
function SpectralGeneratorProvider() {
|
|
||||||
this.workerInterface = new WorkerInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
SpectralGeneratorProvider.prototype.canProvideTelemetry = function (domainObject) {
|
|
||||||
return domainObject.type === 'example.spectral-generator';
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralGeneratorProvider.prototype.supportsRequest =
|
|
||||||
SpectralGeneratorProvider.prototype.supportsSubscribe =
|
|
||||||
SpectralGeneratorProvider.prototype.canProvideTelemetry;
|
|
||||||
|
|
||||||
SpectralGeneratorProvider.prototype.makeWorkerRequest = function (domainObject, request = {}) {
|
|
||||||
var props = [
|
|
||||||
'amplitude',
|
|
||||||
'wavelength',
|
|
||||||
'period',
|
|
||||||
'offset',
|
|
||||||
'dataRateInHz',
|
|
||||||
'phase',
|
|
||||||
'randomness'
|
|
||||||
];
|
|
||||||
|
|
||||||
var workerRequest = {};
|
|
||||||
|
|
||||||
props.forEach(function (prop) {
|
|
||||||
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
|
|
||||||
workerRequest[prop] = domainObject.telemetry[prop];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request && Object.prototype.hasOwnProperty.call(request, prop)) {
|
|
||||||
workerRequest[prop] = request[prop];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(workerRequest, prop)) {
|
|
||||||
workerRequest[prop] = REQUEST_DEFAULTS[prop];
|
|
||||||
}
|
|
||||||
|
|
||||||
workerRequest[prop] = Number(workerRequest[prop]);
|
|
||||||
});
|
|
||||||
|
|
||||||
workerRequest.name = domainObject.name;
|
|
||||||
|
|
||||||
return workerRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralGeneratorProvider.prototype.request = function (domainObject, request) {
|
|
||||||
var workerRequest = this.makeWorkerRequest(domainObject, request);
|
|
||||||
workerRequest.start = request.start;
|
|
||||||
workerRequest.end = request.end;
|
|
||||||
workerRequest.spectra = true;
|
|
||||||
|
|
||||||
return this.workerInterface.request(workerRequest);
|
|
||||||
};
|
|
||||||
|
|
||||||
SpectralGeneratorProvider.prototype.subscribe = function (domainObject, callback) {
|
|
||||||
var workerRequest = this.makeWorkerRequest(domainObject, {});
|
|
||||||
workerRequest.spectra = true;
|
|
||||||
|
|
||||||
return this.workerInterface.subscribe(workerRequest, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
return SpectralGeneratorProvider;
|
|
||||||
});
|
|
@ -54,21 +54,8 @@
|
|||||||
var start = Date.now();
|
var start = Date.now();
|
||||||
var step = 1000 / data.dataRateInHz;
|
var step = 1000 / data.dataRateInHz;
|
||||||
var nextStep = start - (start % step) + step;
|
var nextStep = start - (start % step) + step;
|
||||||
let work;
|
|
||||||
if (data.spectra) {
|
|
||||||
work = function (now) {
|
|
||||||
while (nextStep < now) {
|
|
||||||
const messageCopy = Object.create(message);
|
|
||||||
message.data.start = nextStep - (60 * 1000);
|
|
||||||
message.data.end = nextStep;
|
|
||||||
onRequest(messageCopy);
|
|
||||||
nextStep += step;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextStep;
|
function work(now) {
|
||||||
};
|
|
||||||
} else {
|
|
||||||
work = function (now) {
|
|
||||||
while (nextStep < now) {
|
while (nextStep < now) {
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
id: message.id,
|
id: message.id,
|
||||||
@ -77,7 +64,6 @@
|
|||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
||||||
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
|
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
|
||||||
wavelength: wavelength(start, nextStep),
|
|
||||||
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
|
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -85,7 +71,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nextStep;
|
return nextStep;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions[message.id] = work;
|
subscriptions[message.id] = work;
|
||||||
@ -126,21 +111,13 @@
|
|||||||
utc: nextStep,
|
utc: nextStep,
|
||||||
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
||||||
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
|
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
|
||||||
wavelength: wavelength(start, nextStep),
|
|
||||||
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
|
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
id: message.id,
|
id: message.id,
|
||||||
data: request.spectra ? {
|
data: data
|
||||||
wavelength: data.map((item) => {
|
|
||||||
return item.wavelength;
|
|
||||||
}),
|
|
||||||
cos: data.map((item) => {
|
|
||||||
return item.cos;
|
|
||||||
})
|
|
||||||
} : data
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,10 +131,6 @@
|
|||||||
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function wavelength(start, nextStep) {
|
|
||||||
return (nextStep - start) / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendError(error, message) {
|
function sendError(error, message) {
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
error: error.name + ': ' + error.message,
|
error: error.name + ': ' + error.message,
|
||||||
|
@ -24,15 +24,11 @@ define([
|
|||||||
"./GeneratorProvider",
|
"./GeneratorProvider",
|
||||||
"./SinewaveLimitProvider",
|
"./SinewaveLimitProvider",
|
||||||
"./StateGeneratorProvider",
|
"./StateGeneratorProvider",
|
||||||
"./SpectralGeneratorProvider",
|
|
||||||
"./SpectralAggregateGeneratorProvider",
|
|
||||||
"./GeneratorMetadataProvider"
|
"./GeneratorMetadataProvider"
|
||||||
], function (
|
], function (
|
||||||
GeneratorProvider,
|
GeneratorProvider,
|
||||||
SinewaveLimitProvider,
|
SinewaveLimitProvider,
|
||||||
StateGeneratorProvider,
|
StateGeneratorProvider,
|
||||||
SpectralGeneratorProvider,
|
|
||||||
SpectralAggregateGeneratorProvider,
|
|
||||||
GeneratorMetadataProvider
|
GeneratorMetadataProvider
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -65,37 +61,6 @@ define([
|
|||||||
|
|
||||||
openmct.telemetry.addProvider(new StateGeneratorProvider());
|
openmct.telemetry.addProvider(new StateGeneratorProvider());
|
||||||
|
|
||||||
openmct.types.addType("example.spectral-generator", {
|
|
||||||
name: "Spectral Generator",
|
|
||||||
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
|
||||||
cssClass: "icon-generator-telemetry",
|
|
||||||
creatable: true,
|
|
||||||
initialize: function (object) {
|
|
||||||
object.telemetry = {
|
|
||||||
period: 10,
|
|
||||||
amplitude: 1,
|
|
||||||
wavelength: 1,
|
|
||||||
frequency: 1,
|
|
||||||
offset: 0,
|
|
||||||
dataRateInHz: 1,
|
|
||||||
phase: 0,
|
|
||||||
randomness: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
openmct.telemetry.addProvider(new SpectralGeneratorProvider());
|
|
||||||
|
|
||||||
openmct.types.addType("example.spectral-aggregate-generator", {
|
|
||||||
name: "Spectral Aggregate Generator",
|
|
||||||
description: "For development use. Generates example streaming telemetry data using a simple state algorithm.",
|
|
||||||
cssClass: "icon-generator-telemetry",
|
|
||||||
creatable: true,
|
|
||||||
initialize: function (object) {
|
|
||||||
object.telemetry = {};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
openmct.telemetry.addProvider(new SpectralAggregateGeneratorProvider());
|
|
||||||
|
|
||||||
openmct.types.addType("generator", {
|
openmct.types.addType("generator", {
|
||||||
name: "Sine Wave Generator",
|
name: "Sine Wave Generator",
|
||||||
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||||
|
@ -263,6 +263,7 @@ define([
|
|||||||
// Plugins that are installed by default
|
// Plugins that are installed by default
|
||||||
|
|
||||||
this.install(this.plugins.Plot());
|
this.install(this.plugins.Plot());
|
||||||
|
this.install(this.plugins.Chart());
|
||||||
this.install(this.plugins.TelemetryTable.default());
|
this.install(this.plugins.TelemetryTable.default());
|
||||||
this.install(PreviewPlugin.default());
|
this.install(PreviewPlugin.default());
|
||||||
this.install(LegacyIndicatorsPlugin());
|
this.install(LegacyIndicatorsPlugin());
|
||||||
|
@ -23,24 +23,20 @@
|
|||||||
import { BAR_GRAPH_KEY } from './BarGraphConstants';
|
import { BAR_GRAPH_KEY } from './BarGraphConstants';
|
||||||
|
|
||||||
export default function BarGraphCompositionPolicy(openmct) {
|
export default function BarGraphCompositionPolicy(openmct) {
|
||||||
function hasAggregateDomainAndRange(metadata) {
|
function hasRange(metadata) {
|
||||||
const rangeValues = metadata.valuesForHints(['range']);
|
const rangeValues = metadata.valuesForHints(['range']);
|
||||||
|
|
||||||
return rangeValues.length > 0;
|
return rangeValues.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasBarGraphTelemetry(domainObject) {
|
function hasBarGraphTelemetry(domainObject) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(domainObject, 'telemetry')) {
|
if (!openmct.telemetry.isTelemetryObject(domainObject)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||||
|
|
||||||
return metadata.values().length > 0 && hasAggregateDomainAndRange(metadata);
|
return metadata.values().length > 0 && hasRange(metadata);
|
||||||
}
|
|
||||||
|
|
||||||
function hasNoChildren(parentObject) {
|
|
||||||
return parentObject.composition && parentObject.composition.length < 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
@ -1,5 +1,3 @@
|
|||||||
export const BAR_GRAPH_VIEW = 'bar-graph.view';
|
export const BAR_GRAPH_VIEW = 'bar-graph.view';
|
||||||
export const BAR_GRAPH_KEY = 'telemetry.plot.bar-graph';
|
export const BAR_GRAPH_KEY = 'telemetry.plot.bar-graph';
|
||||||
export const BAR_GRAPH_INSPECTOR_KEY = 'telemetry.plot.bar-graph.inspector';
|
export const BAR_GRAPH_INSPECTOR_KEY = 'telemetry.plot.bar-graph.inspector';
|
||||||
export const SUBSCRIBE = 'subscribe';
|
|
||||||
export const UNSUBSCRIBE = 'unsubscribe';
|
|
@ -12,6 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div ref="plot"
|
<div ref="plot"
|
||||||
class="c-bar-chart"
|
class="c-bar-chart"
|
||||||
|
@plotly_relayout="zoom"
|
||||||
></div>
|
></div>
|
||||||
<div v-if="false"
|
<div v-if="false"
|
||||||
ref="localControl"
|
ref="localControl"
|
||||||
@ -28,8 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Plotly from 'plotly.js-basic-dist';
|
import Plotly from 'plotly-basic';
|
||||||
import { SUBSCRIBE, UNSUBSCRIBE } from './BarGraphConstants';
|
|
||||||
|
|
||||||
const MULTI_AXES_X_PADDING_PERCENT = {
|
const MULTI_AXES_X_PADDING_PERCENT = {
|
||||||
LEFT: 8,
|
LEFT: 8,
|
||||||
@ -79,8 +79,6 @@ export default {
|
|||||||
this.registerListeners();
|
this.registerListeners();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.$refs.plot.removeAllListeners();
|
|
||||||
|
|
||||||
if (this.plotResizeObserver) {
|
if (this.plotResizeObserver) {
|
||||||
this.plotResizeObserver.unobserve(this.$refs.plotWrapper);
|
this.plotResizeObserver.unobserve(this.$refs.plotWrapper);
|
||||||
clearTimeout(this.resizeTimer);
|
clearTimeout(this.resizeTimer);
|
||||||
@ -203,8 +201,6 @@ export default {
|
|||||||
return yaxis;
|
return yaxis;
|
||||||
},
|
},
|
||||||
registerListeners() {
|
registerListeners() {
|
||||||
this.$refs.plot.on('plotly_relayout', this.zoom);
|
|
||||||
|
|
||||||
this.removeBarColorListener = this.openmct.objects.observe(
|
this.removeBarColorListener = this.openmct.objects.observe(
|
||||||
this.domainObject,
|
this.domainObject,
|
||||||
'configuration.barStyles',
|
'configuration.barStyles',
|
||||||
@ -226,7 +222,7 @@ export default {
|
|||||||
this.updatePlot();
|
this.updatePlot();
|
||||||
|
|
||||||
this.isZoomed = false;
|
this.isZoomed = false;
|
||||||
this.$emit(SUBSCRIBE);
|
this.$emit('subscribe');
|
||||||
},
|
},
|
||||||
barColorChanged() {
|
barColorChanged() {
|
||||||
const colors = [];
|
const colors = [];
|
||||||
@ -285,7 +281,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.isZoomed = true;
|
this.isZoomed = true;
|
||||||
this.$emit(UNSUBSCRIBE);
|
this.$emit('unsubscribe');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -25,12 +25,13 @@
|
|||||||
class="c-plot c-bar-chart-view"
|
class="c-plot c-bar-chart-view"
|
||||||
:data="trace"
|
:data="trace"
|
||||||
:plot-axis-title="plotAxisTitle"
|
:plot-axis-title="plotAxisTitle"
|
||||||
|
@subscribe="subscribeToAll"
|
||||||
|
@unsubscribe="removeAllSubscriptions"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as SPECTRAL_AGGREGATE from './BarGraphConstants';
|
import ColorPalette from '../../plot/lib/ColorPalette';
|
||||||
import ColorPalette from '../lib/ColorPalette';
|
|
||||||
import BarGraph from './BarGraphPlot.vue';
|
import BarGraph from './BarGraphPlot.vue';
|
||||||
import Color from "@/plugins/plot/lib/Color";
|
import Color from "@/plugins/plot/lib/Color";
|
||||||
|
|
||||||
@ -40,18 +41,16 @@ export default {
|
|||||||
},
|
},
|
||||||
inject: ['openmct', 'domainObject'],
|
inject: ['openmct', 'domainObject'],
|
||||||
data() {
|
data() {
|
||||||
|
this.telemetryObjects = {};
|
||||||
|
this.telemetryObjectFormats = {};
|
||||||
|
this.subscriptions = [];
|
||||||
|
this.composition = {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
composition: {},
|
|
||||||
currentDomainObject: this.domainObject,
|
|
||||||
subscriptions: [],
|
|
||||||
telemetryObjects: {},
|
|
||||||
trace: []
|
trace: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
activeClock() {
|
|
||||||
return this.openmct.time.activeClock;
|
|
||||||
},
|
|
||||||
plotAxisTitle() {
|
plotAxisTitle() {
|
||||||
const { xAxisMetadata = {}, yAxisMetadata = {} } = this.trace[0] || {};
|
const { xAxisMetadata = {}, yAxisMetadata = {} } = this.trace[0] || {};
|
||||||
const xAxisUnit = xAxisMetadata.units ? `(${xAxisMetadata.units})` : '';
|
const xAxisUnit = xAxisMetadata.units ? `(${xAxisMetadata.units})` : '';
|
||||||
@ -68,20 +67,11 @@ export default {
|
|||||||
this.loadComposition();
|
this.loadComposition();
|
||||||
|
|
||||||
this.openmct.time.on('bounds', this.refreshData);
|
this.openmct.time.on('bounds', this.refreshData);
|
||||||
this.openmct.time.on('clock', this.clockChanged);
|
|
||||||
|
|
||||||
this.$refs.barGraph.$on(SPECTRAL_AGGREGATE.SUBSCRIBE, this.subscribeToAll);
|
|
||||||
this.$refs.barGraph.$on(SPECTRAL_AGGREGATE.UNSUBSCRIBE, this.removeAllSubscriptions);
|
|
||||||
|
|
||||||
this.unobserve = this.openmct.objects.observe(this.currentDomainObject, '*', this.updateDomainObject);
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.$refs.barGraph.$off();
|
|
||||||
this.openmct.time.off('bounds', this.refreshData);
|
this.openmct.time.off('bounds', this.refreshData);
|
||||||
this.openmct.time.off('clock', this.clockChanged);
|
|
||||||
|
|
||||||
this.removeAllSubscriptions();
|
this.removeAllSubscriptions();
|
||||||
this.unobserve();
|
|
||||||
|
|
||||||
if (!this.composition) {
|
if (!this.composition) {
|
||||||
return;
|
return;
|
||||||
@ -94,21 +84,16 @@ export default {
|
|||||||
addTelemetryObject(telemetryObject) {
|
addTelemetryObject(telemetryObject) {
|
||||||
const key = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
const key = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||||
|
|
||||||
if (!this.domainObject.configuration.barStyles) {
|
|
||||||
this.domainObject.configuration.barStyles = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// check to see if we've set a bar color
|
// check to see if we've set a bar color
|
||||||
if (!this.domainObject.configuration.barStyles[key] || !this.domainObject.configuration.barStyles[key].color) {
|
if (!this.domainObject.configuration.barStyles[key] || !this.domainObject.configuration.barStyles[key].color) {
|
||||||
const color = this.colorPalette.getNextColor().asHexString();
|
const color = this.colorPalette.getNextColor().asHexString();
|
||||||
this.domainObject.configuration.barStyles[key] = {
|
|
||||||
name: telemetryObject.name,
|
|
||||||
color
|
|
||||||
};
|
|
||||||
this.openmct.objects.mutate(
|
this.openmct.objects.mutate(
|
||||||
this.domainObject,
|
this.domainObject,
|
||||||
`configuration.barStyles[${this.key}]`,
|
`configuration.barStyles[${key}]`,
|
||||||
this.domainObject.configuration.barStyles[key]
|
{
|
||||||
|
name: telemetryObject.name,
|
||||||
|
color
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let color = this.domainObject.configuration.barStyles[key].color;
|
let color = this.domainObject.configuration.barStyles[key].color;
|
||||||
@ -120,6 +105,9 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.telemetryObjects[key] = telemetryObject;
|
this.telemetryObjects[key] = telemetryObject;
|
||||||
|
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
|
const formats = this.openmct.telemetry.getFormatMap(metadata);
|
||||||
|
this.telemetryObjectFormats[key] = formats;
|
||||||
|
|
||||||
this.requestDataFor(telemetryObject);
|
this.requestDataFor(telemetryObject);
|
||||||
this.subscribeToObject(telemetryObject);
|
this.subscribeToObject(telemetryObject);
|
||||||
@ -144,10 +132,6 @@ export default {
|
|||||||
|
|
||||||
this.trace = isInTrace ? newTrace : newTrace.concat([trace]);
|
this.trace = isInTrace ? newTrace : newTrace.concat([trace]);
|
||||||
},
|
},
|
||||||
clockChanged() {
|
|
||||||
this.removeAllSubscriptions();
|
|
||||||
this.subscribeToAll();
|
|
||||||
},
|
|
||||||
getAxisMetadata(telemetryObject) {
|
getAxisMetadata(telemetryObject) {
|
||||||
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
const metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
||||||
const yAxisMetadata = metadata.valuesForHints(['range'])[0];
|
const yAxisMetadata = metadata.valuesForHints(['range'])[0];
|
||||||
@ -159,21 +143,19 @@ export default {
|
|||||||
yAxisMetadata
|
yAxisMetadata
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getOptions(telemetryObject) {
|
getOptions() {
|
||||||
const { start, end } = this.openmct.time.bounds();
|
const { start, end } = this.openmct.time.bounds();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
end,
|
end,
|
||||||
start,
|
start
|
||||||
startTime: null,
|
|
||||||
spectra: true
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
loadComposition() {
|
loadComposition() {
|
||||||
this.composition = this.openmct.composition.get(this.currentDomainObject);
|
this.composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
|
||||||
if (!this.composition) {
|
if (!this.composition) {
|
||||||
this.addTelemetryObject(this.currentDomainObject);
|
this.addTelemetryObject(this.domainObject);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -202,6 +184,7 @@ export default {
|
|||||||
removeTelemetryObject(identifier) {
|
removeTelemetryObject(identifier) {
|
||||||
const key = this.openmct.objects.makeKeyString(identifier);
|
const key = this.openmct.objects.makeKeyString(identifier);
|
||||||
delete this.telemetryObjects[key];
|
delete this.telemetryObjects[key];
|
||||||
|
delete this.this.telemetryObjectFormats[key];
|
||||||
if (this.domainObject.configuration.barStyles[key]) {
|
if (this.domainObject.configuration.barStyles[key]) {
|
||||||
delete this.domainObject.configuration.barStyles[key];
|
delete this.domainObject.configuration.barStyles[key];
|
||||||
}
|
}
|
||||||
@ -210,13 +193,17 @@ export default {
|
|||||||
|
|
||||||
this.trace = this.trace.filter(t => t.key !== key);
|
this.trace = this.trace.filter(t => t.key !== key);
|
||||||
},
|
},
|
||||||
processData(telemetryObject, data, axisMetadata) {
|
addDataToGraph(telemetryObject, data, axisMetadata) {
|
||||||
const key = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
const key = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||||
|
|
||||||
if (data.message) {
|
if (data.message) {
|
||||||
this.openmct.notifications.alert(data.message);
|
this.openmct.notifications.alert(data.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.isDataInTimeRange(data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let xValues = [];
|
let xValues = [];
|
||||||
let yValues = [];
|
let yValues = [];
|
||||||
|
|
||||||
@ -224,10 +211,10 @@ export default {
|
|||||||
axisMetadata.xAxisMetadata.forEach((metadata) => {
|
axisMetadata.xAxisMetadata.forEach((metadata) => {
|
||||||
xValues.push(metadata.name);
|
xValues.push(metadata.name);
|
||||||
if (data[metadata.key]) {
|
if (data[metadata.key]) {
|
||||||
//TODO: Format the data?
|
const formattedValue = this.format(key, metadata.key, data);
|
||||||
yValues.push(data[metadata.key]);
|
yValues.push(formattedValue);
|
||||||
} else {
|
} else {
|
||||||
yValues.push('');
|
yValues.push(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -248,12 +235,23 @@ export default {
|
|||||||
|
|
||||||
this.addTrace(trace, key);
|
this.addTrace(trace, key);
|
||||||
},
|
},
|
||||||
|
isDataInTimeRange(data) {
|
||||||
|
const timeSystemKey = this.openmct.time.timeSystem().key;
|
||||||
|
const currentTimestamp = data[timeSystemKey];
|
||||||
|
|
||||||
|
return currentTimestamp && this.openmct.time.bounds().end >= currentTimestamp;
|
||||||
|
},
|
||||||
|
format(telemetryObjectKey, metadataKey, data) {
|
||||||
|
const formats = this.telemetryObjectFormats[telemetryObjectKey];
|
||||||
|
|
||||||
|
return formats[metadataKey].format(data);
|
||||||
|
},
|
||||||
requestDataFor(telemetryObject) {
|
requestDataFor(telemetryObject) {
|
||||||
const axisMetadata = this.getAxisMetadata(telemetryObject);
|
const axisMetadata = this.getAxisMetadata(telemetryObject);
|
||||||
this.openmct.telemetry.request(telemetryObject, this.getOptions(telemetryObject))
|
this.openmct.telemetry.request(telemetryObject)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
data.forEach((datum) => {
|
data.forEach((datum) => {
|
||||||
this.processData(telemetryObject, datum, axisMetadata);
|
this.addDataToGraph(telemetryObject, datum, axisMetadata);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -262,10 +260,10 @@ export default {
|
|||||||
|
|
||||||
this.removeSubscription(key);
|
this.removeSubscription(key);
|
||||||
|
|
||||||
const options = this.getOptions(telemetryObject);
|
const options = this.getOptions();
|
||||||
const axisMetadata = this.getAxisMetadata(telemetryObject);
|
const axisMetadata = this.getAxisMetadata(telemetryObject);
|
||||||
const unsubscribe = this.openmct.telemetry.subscribe(telemetryObject,
|
const unsubscribe = this.openmct.telemetry.subscribe(telemetryObject,
|
||||||
data => this.processData(telemetryObject, data, axisMetadata)
|
data => this.addDataToGraph(telemetryObject, data, axisMetadata)
|
||||||
, options);
|
, options);
|
||||||
|
|
||||||
this.subscriptions.push({
|
this.subscriptions.push({
|
||||||
@ -276,9 +274,6 @@ export default {
|
|||||||
subscribeToAll() {
|
subscribeToAll() {
|
||||||
const telemetryObjects = Object.values(this.telemetryObjects);
|
const telemetryObjects = Object.values(this.telemetryObjects);
|
||||||
telemetryObjects.forEach(this.subscribeToObject);
|
telemetryObjects.forEach(this.subscribeToObject);
|
||||||
},
|
|
||||||
updateDomainObject(newDomainObject) {
|
|
||||||
this.currentDomainObject = newDomainObject;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -44,7 +44,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ColorSwatch from '../../ColorSwatch.vue';
|
import ColorSwatch from '../../../plot/ColorSwatch.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
49
src/plugins/charts/plugin.js
Normal file
49
src/plugins/charts/plugin.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2021, 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 { BAR_GRAPH_KEY } from '../charts/barGraph/BarGraphConstants';
|
||||||
|
import BarGraphViewProvider from '../charts/barGraph/BarGraphViewProvider';
|
||||||
|
import BarGraphInspectorViewProvider from '../charts/barGraph/inspector/BarGraphInspectorViewProvider';
|
||||||
|
import BarGraphCompositionPolicy from '../charts/barGraph/BarGraphCompositionPolicy';
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.types.addType(BAR_GRAPH_KEY, {
|
||||||
|
key: BAR_GRAPH_KEY,
|
||||||
|
name: "Bar Graph",
|
||||||
|
cssClass: "icon-bar-chart",
|
||||||
|
description: "View data as a bar graph. Can be added to Display Layouts.",
|
||||||
|
creatable: true,
|
||||||
|
initialize: function (domainObject) {
|
||||||
|
domainObject.composition = [];
|
||||||
|
domainObject.configuration = {
|
||||||
|
barStyles: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority: 891
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.objectViews.addProvider(new BarGraphViewProvider(openmct));
|
||||||
|
openmct.inspectorViews.addProvider(new BarGraphInspectorViewProvider(openmct));
|
||||||
|
openmct.composition.addPolicy(new BarGraphCompositionPolicy(openmct).allow);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
151
src/plugins/charts/pluginSpec.js
Normal file
151
src/plugins/charts/pluginSpec.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2021, 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 {createOpenMct, resetApplicationState} from "utils/testing";
|
||||||
|
import { BAR_GRAPH_VIEW, BAR_GRAPH_KEY } from '../charts/barGraph/BarGraphConstants';
|
||||||
|
import BarGraphPlugin from './plugin';
|
||||||
|
|
||||||
|
describe("the plugin", function () {
|
||||||
|
let element;
|
||||||
|
let child;
|
||||||
|
let openmct;
|
||||||
|
let telemetryPromise;
|
||||||
|
let telemetryPromiseResolve;
|
||||||
|
let mockObjectPath;
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
mockObjectPath = [
|
||||||
|
{
|
||||||
|
name: 'mock folder',
|
||||||
|
type: 'fake-folder',
|
||||||
|
identifier: {
|
||||||
|
key: 'mock-folder',
|
||||||
|
namespace: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mock parent folder',
|
||||||
|
type: 'time-strip',
|
||||||
|
identifier: {
|
||||||
|
key: 'mock-parent-folder',
|
||||||
|
namespace: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const testTelemetry = [
|
||||||
|
{
|
||||||
|
'utc': 1,
|
||||||
|
'some-key': 'some-value 1',
|
||||||
|
'some-other-key': 'some-other-value 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'utc': 2,
|
||||||
|
'some-key': 'some-value 2',
|
||||||
|
'some-other-key': 'some-other-value 2'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'utc': 3,
|
||||||
|
'some-key': 'some-value 3',
|
||||||
|
'some-other-key': 'some-other-value 3'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
openmct = createOpenMct();
|
||||||
|
|
||||||
|
telemetryPromise = new Promise((resolve) => {
|
||||||
|
telemetryPromiseResolve = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
spyOn(openmct.telemetry, 'request').and.callFake(() => {
|
||||||
|
telemetryPromiseResolve(testTelemetry);
|
||||||
|
|
||||||
|
return telemetryPromise;
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.install(new BarGraphPlugin());
|
||||||
|
|
||||||
|
element = document.createElement("div");
|
||||||
|
element.style.width = "640px";
|
||||||
|
element.style.height = "480px";
|
||||||
|
child = document.createElement("div");
|
||||||
|
child.style.width = "640px";
|
||||||
|
child.style.height = "480px";
|
||||||
|
element.appendChild(child);
|
||||||
|
document.body.appendChild(element);
|
||||||
|
|
||||||
|
spyOn(window, 'ResizeObserver').and.returnValue({
|
||||||
|
observe() {},
|
||||||
|
disconnect() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.time.timeSystem("utc", {
|
||||||
|
start: 0,
|
||||||
|
end: 4
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.types.addType("test-object", {
|
||||||
|
creatable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.on("start", done);
|
||||||
|
openmct.startHeadless();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach((done) => {
|
||||||
|
openmct.time.timeSystem('utc', {
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
});
|
||||||
|
resetApplicationState(openmct).then(done).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("the bar graph", () => {
|
||||||
|
const mockObject = {
|
||||||
|
name: 'A bar graph',
|
||||||
|
key: BAR_GRAPH_KEY,
|
||||||
|
creatable: true
|
||||||
|
};
|
||||||
|
|
||||||
|
it('defines a bar graph type with the correct key', () => {
|
||||||
|
const objectDef = openmct.types.get(BAR_GRAPH_KEY).definition;
|
||||||
|
expect(objectDef.key).toEqual(mockObject.key);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('is creatable', () => {
|
||||||
|
const objectDef = openmct.types.get(BAR_GRAPH_KEY).definition;
|
||||||
|
expect(objectDef.creatable).toEqual(mockObject.creatable);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("the bar graph view", () => {
|
||||||
|
it("provides view for objects with telemetry", () => {
|
||||||
|
const testObject = {
|
||||||
|
id: "test-object",
|
||||||
|
type: BAR_GRAPH_KEY
|
||||||
|
};
|
||||||
|
|
||||||
|
const applicableViews = openmct.objectViews.get(testObject, mockObjectPath);
|
||||||
|
let plotView = applicableViews.find((viewProvider) => viewProvider.key === BAR_GRAPH_VIEW);
|
||||||
|
expect(plotView).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -19,18 +19,12 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import { BAR_GRAPH_KEY } from './barGraph/BarGraphConstants';
|
|
||||||
import PlotViewProvider from './PlotViewProvider';
|
import PlotViewProvider from './PlotViewProvider';
|
||||||
import SpectralPlotViewProvider from './spectralPlot/SpectralPlotViewProvider';
|
|
||||||
import BarGraphViewProvider from './barGraph/BarGraphViewProvider';
|
|
||||||
import OverlayPlotViewProvider from './overlayPlot/OverlayPlotViewProvider';
|
import OverlayPlotViewProvider from './overlayPlot/OverlayPlotViewProvider';
|
||||||
import StackedPlotViewProvider from './stackedPlot/StackedPlotViewProvider';
|
import StackedPlotViewProvider from './stackedPlot/StackedPlotViewProvider';
|
||||||
import PlotsInspectorViewProvider from './inspector/PlotsInspectorViewProvider';
|
import PlotsInspectorViewProvider from './inspector/PlotsInspectorViewProvider';
|
||||||
import BarGraphInspectorViewProvider from './barGraph/inspector/BarGraphInspectorViewProvider';
|
|
||||||
import OverlayPlotCompositionPolicy from './overlayPlot/OverlayPlotCompositionPolicy';
|
import OverlayPlotCompositionPolicy from './overlayPlot/OverlayPlotCompositionPolicy';
|
||||||
import StackedPlotCompositionPolicy from './stackedPlot/StackedPlotCompositionPolicy';
|
import StackedPlotCompositionPolicy from './stackedPlot/StackedPlotCompositionPolicy';
|
||||||
import SpectralPlotCompositionPolicy from './spectralPlot/SpectralPlotCompositionPolicy';
|
|
||||||
import BarGraphCompositionPolicy from './barGraph/BarGraphCompositionPolicy';
|
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
@ -64,48 +58,15 @@ export default function () {
|
|||||||
},
|
},
|
||||||
priority: 890
|
priority: 890
|
||||||
});
|
});
|
||||||
openmct.types.addType('telemetry.plot.spectral', {
|
|
||||||
key: "telemetry.plot.spectral",
|
|
||||||
name: "Spectral Plot",
|
|
||||||
cssClass: "icon-plot-stacked",
|
|
||||||
description: "View Spectra on Y Axes with non-time domain on the X axis. Can be added to Display Layouts.",
|
|
||||||
//Temporarily disabling spectral plots
|
|
||||||
creatable: false,
|
|
||||||
initialize: function (domainObject) {
|
|
||||||
domainObject.composition = [];
|
|
||||||
domainObject.configuration = {};
|
|
||||||
},
|
|
||||||
priority: 890
|
|
||||||
});
|
|
||||||
|
|
||||||
openmct.types.addType(BAR_GRAPH_KEY, {
|
|
||||||
key: BAR_GRAPH_KEY,
|
|
||||||
name: "Bar Graph",
|
|
||||||
cssClass: "icon-bar-chart",
|
|
||||||
description: "View data as a bar graph. Can be added to Display Layouts.",
|
|
||||||
creatable: true,
|
|
||||||
initialize: function (domainObject) {
|
|
||||||
domainObject.composition = [];
|
|
||||||
domainObject.configuration = {
|
|
||||||
plotType: 'bar'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
priority: 891
|
|
||||||
});
|
|
||||||
|
|
||||||
openmct.objectViews.addProvider(new StackedPlotViewProvider(openmct));
|
openmct.objectViews.addProvider(new StackedPlotViewProvider(openmct));
|
||||||
openmct.objectViews.addProvider(new OverlayPlotViewProvider(openmct));
|
openmct.objectViews.addProvider(new OverlayPlotViewProvider(openmct));
|
||||||
openmct.objectViews.addProvider(new PlotViewProvider(openmct));
|
openmct.objectViews.addProvider(new PlotViewProvider(openmct));
|
||||||
openmct.objectViews.addProvider(new SpectralPlotViewProvider(openmct));
|
|
||||||
openmct.objectViews.addProvider(new BarGraphViewProvider(openmct));
|
|
||||||
|
|
||||||
openmct.inspectorViews.addProvider(new PlotsInspectorViewProvider(openmct));
|
openmct.inspectorViews.addProvider(new PlotsInspectorViewProvider(openmct));
|
||||||
openmct.inspectorViews.addProvider(new BarGraphInspectorViewProvider(openmct));
|
|
||||||
|
|
||||||
openmct.composition.addPolicy(new OverlayPlotCompositionPolicy(openmct).allow);
|
openmct.composition.addPolicy(new OverlayPlotCompositionPolicy(openmct).allow);
|
||||||
openmct.composition.addPolicy(new StackedPlotCompositionPolicy(openmct).allow);
|
openmct.composition.addPolicy(new StackedPlotCompositionPolicy(openmct).allow);
|
||||||
openmct.composition.addPolicy(new SpectralPlotCompositionPolicy(openmct).allow);
|
|
||||||
openmct.composition.addPolicy(new BarGraphCompositionPolicy(openmct).allow);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,12 +24,10 @@ import {createMouseEvent, createOpenMct, resetApplicationState, spyOnBuiltins} f
|
|||||||
import PlotVuePlugin from "./plugin";
|
import PlotVuePlugin from "./plugin";
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import StackedPlot from "./stackedPlot/StackedPlot.vue";
|
import StackedPlot from "./stackedPlot/StackedPlot.vue";
|
||||||
// import SpectralPlot from "./spectralPlot/SpectralPlot.vue";
|
|
||||||
import configStore from "./configuration/ConfigStore";
|
import configStore from "./configuration/ConfigStore";
|
||||||
import EventEmitter from "EventEmitter";
|
import EventEmitter from "EventEmitter";
|
||||||
import PlotOptions from "./inspector/PlotOptions.vue";
|
import PlotOptions from "./inspector/PlotOptions.vue";
|
||||||
import PlotConfigurationModel from "./configuration/PlotConfigurationModel";
|
import PlotConfigurationModel from "./configuration/PlotConfigurationModel";
|
||||||
import { BAR_GRAPH_VIEW, BAR_GRAPH_KEY } from './barGraph/BarGraphConstants';
|
|
||||||
|
|
||||||
describe("the plugin", function () {
|
describe("the plugin", function () {
|
||||||
let element;
|
let element;
|
||||||
@ -314,38 +312,6 @@ describe("the plugin", function () {
|
|||||||
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-stacked");
|
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-stacked");
|
||||||
expect(plotView).toBeDefined();
|
expect(plotView).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("provides a spectral plot view for objects with telemetry", () => {
|
|
||||||
const testTelemetryObject = {
|
|
||||||
id: "test-object",
|
|
||||||
type: "telemetry.plot.spectral",
|
|
||||||
telemetry: {
|
|
||||||
values: [{
|
|
||||||
key: "a-very-fine-key"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
|
|
||||||
let plotView = applicableViews.find((viewProvider) => viewProvider.key === "plot-spectral");
|
|
||||||
expect(plotView).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides a spectral aggregate plot view for objects with telemetry", () => {
|
|
||||||
const testTelemetryObject = {
|
|
||||||
id: "test-object",
|
|
||||||
type: BAR_GRAPH_KEY,
|
|
||||||
telemetry: {
|
|
||||||
values: [{
|
|
||||||
key: "lots-of-aggregate-telemetry"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
|
|
||||||
let plotView = applicableViews.find((viewProvider) => viewProvider.key === BAR_GRAPH_VIEW);
|
|
||||||
expect(plotView).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("The single plot view", () => {
|
describe("The single plot view", () => {
|
||||||
@ -496,146 +462,6 @@ describe("the plugin", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* disabling this until we develop the plot view
|
|
||||||
describe("The spectral plot view", () => {
|
|
||||||
let testTelemetryObject;
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let testTelemetryObject2;
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let config;
|
|
||||||
let spectralPlotObject;
|
|
||||||
let component;
|
|
||||||
let mockComposition;
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
let plotViewComponentObject;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
const getFunc = openmct.$injector.get;
|
|
||||||
spyOn(openmct.$injector, "get")
|
|
||||||
.withArgs("exportImageService").and.returnValue({
|
|
||||||
exportPNG: () => {},
|
|
||||||
exportJPG: () => {}
|
|
||||||
})
|
|
||||||
.and.callFake(getFunc);
|
|
||||||
|
|
||||||
spectralPlotObject = {
|
|
||||||
identifier: {
|
|
||||||
namespace: "",
|
|
||||||
key: "test-spectral-plot"
|
|
||||||
},
|
|
||||||
type: "telemetry.plot.spectral",
|
|
||||||
name: "Test Spectral Plot"
|
|
||||||
};
|
|
||||||
|
|
||||||
testTelemetryObject = {
|
|
||||||
identifier: {
|
|
||||||
namespace: "",
|
|
||||||
key: "test-object"
|
|
||||||
},
|
|
||||||
type: "test-object",
|
|
||||||
name: "Test Object",
|
|
||||||
telemetry: {
|
|
||||||
values: [{
|
|
||||||
key: "utc",
|
|
||||||
format: "utc",
|
|
||||||
name: "Time",
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "some-key",
|
|
||||||
name: "Some attribute",
|
|
||||||
hints: {
|
|
||||||
range: 1
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "some-other-key",
|
|
||||||
name: "Another attribute",
|
|
||||||
hints: {
|
|
||||||
range: 2
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
testTelemetryObject2 = {
|
|
||||||
identifier: {
|
|
||||||
namespace: "",
|
|
||||||
key: "test-object2"
|
|
||||||
},
|
|
||||||
type: "test-object",
|
|
||||||
name: "Test Object2",
|
|
||||||
telemetry: {
|
|
||||||
values: [{
|
|
||||||
key: "utc",
|
|
||||||
format: "utc",
|
|
||||||
name: "Time",
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "wavelength",
|
|
||||||
name: "Wavelength",
|
|
||||||
hints: {
|
|
||||||
range: 1
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "some-other-key2",
|
|
||||||
name: "Another attribute2",
|
|
||||||
hints: {
|
|
||||||
range: 2
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mockComposition = new EventEmitter();
|
|
||||||
mockComposition.load = () => {
|
|
||||||
mockComposition.emit('add', testTelemetryObject);
|
|
||||||
|
|
||||||
return [testTelemetryObject];
|
|
||||||
};
|
|
||||||
|
|
||||||
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
|
|
||||||
|
|
||||||
let viewContainer = document.createElement("div");
|
|
||||||
child.append(viewContainer);
|
|
||||||
component = new Vue({
|
|
||||||
el: viewContainer,
|
|
||||||
components: {
|
|
||||||
SpectralPlot
|
|
||||||
},
|
|
||||||
provide: {
|
|
||||||
openmct: openmct,
|
|
||||||
domainObject: spectralPlotObject,
|
|
||||||
composition: openmct.composition.get(spectralPlotObject)
|
|
||||||
},
|
|
||||||
template: "<spectral-plot></spectral-plot>"
|
|
||||||
});
|
|
||||||
|
|
||||||
cleanupFirst.push(() => {
|
|
||||||
component.$destroy();
|
|
||||||
component = undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
return telemetryPromise
|
|
||||||
.then(Vue.nextTick())
|
|
||||||
.then(() => {
|
|
||||||
plotViewComponentObject = component.$root.$children[0];
|
|
||||||
const configId = openmct.objects.makeKeyString(testTelemetryObject.identifier);
|
|
||||||
config = configStore.get(configId);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Renders a collapsed legend for every telemetry", () => {
|
|
||||||
let legend = element.querySelectorAll(".plot-wrapper-collapsed-legend .plot-series-name");
|
|
||||||
expect(legend.length).toBe(1);
|
|
||||||
expect(legend[0].innerHTML).toEqual("Test Object");
|
|
||||||
});
|
|
||||||
|
|
||||||
}); */
|
|
||||||
|
|
||||||
describe("The stacked plot view", () => {
|
describe("The stacked plot view", () => {
|
||||||
let testTelemetryObject;
|
let testTelemetryObject;
|
||||||
let testTelemetryObject2;
|
let testTelemetryObject2;
|
||||||
@ -1165,39 +991,4 @@ describe("the plugin", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("the spectral plot", () => {
|
|
||||||
const mockObject = {
|
|
||||||
name: 'A Very Nice Spectral Plot',
|
|
||||||
key: 'telemetry.plot.spectral',
|
|
||||||
creatable: true
|
|
||||||
};
|
|
||||||
|
|
||||||
it('defines a spectral plot object type with the correct key', () => {
|
|
||||||
const objectDef = openmct.types.get('telemetry.plot.spectral').definition;
|
|
||||||
expect(objectDef.key).toEqual(mockObject.key);
|
|
||||||
});
|
|
||||||
|
|
||||||
xit('is creatable', () => {
|
|
||||||
const objectDef = openmct.types.get('telemetry.plot.spectral').definition;
|
|
||||||
expect(objectDef.creatable).toEqual(mockObject.creatable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("the aggregate spectral plot", () => {
|
|
||||||
const mockObject = {
|
|
||||||
name: 'An Even Nicer Aggregate Spectral Plot',
|
|
||||||
key: BAR_GRAPH_KEY,
|
|
||||||
creatable: true
|
|
||||||
};
|
|
||||||
|
|
||||||
it('defines a spectral plot object type with the correct key', () => {
|
|
||||||
const objectDef = openmct.types.get(BAR_GRAPH_KEY).definition;
|
|
||||||
expect(objectDef.key).toEqual(mockObject.key);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is creatable', () => {
|
|
||||||
const objectDef = openmct.types.get(BAR_GRAPH_KEY).definition;
|
|
||||||
expect(objectDef.creatable).toEqual(mockObject.creatable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@ -36,6 +36,7 @@ define([
|
|||||||
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
||||||
'./telemetryMean/plugin',
|
'./telemetryMean/plugin',
|
||||||
'./plot/plugin',
|
'./plot/plugin',
|
||||||
|
'./charts/plugin',
|
||||||
'./telemetryTable/plugin',
|
'./telemetryTable/plugin',
|
||||||
'./staticRootPlugin/plugin',
|
'./staticRootPlugin/plugin',
|
||||||
'./notebook/plugin',
|
'./notebook/plugin',
|
||||||
@ -87,6 +88,7 @@ define([
|
|||||||
URLIndicatorPlugin,
|
URLIndicatorPlugin,
|
||||||
TelemetryMean,
|
TelemetryMean,
|
||||||
PlotPlugin,
|
PlotPlugin,
|
||||||
|
ChartPlugin,
|
||||||
TelemetryTablePlugin,
|
TelemetryTablePlugin,
|
||||||
StaticRootPlugin,
|
StaticRootPlugin,
|
||||||
Notebook,
|
Notebook,
|
||||||
@ -189,6 +191,7 @@ define([
|
|||||||
plugins.ExampleImagery = ExampleImagery;
|
plugins.ExampleImagery = ExampleImagery;
|
||||||
plugins.ImageryPlugin = ImageryPlugin;
|
plugins.ImageryPlugin = ImageryPlugin;
|
||||||
plugins.Plot = PlotPlugin.default;
|
plugins.Plot = PlotPlugin.default;
|
||||||
|
plugins.Chart = ChartPlugin.default;
|
||||||
plugins.TelemetryTable = TelemetryTablePlugin;
|
plugins.TelemetryTable = TelemetryTablePlugin;
|
||||||
|
|
||||||
plugins.SummaryWidget = SummaryWidget;
|
plugins.SummaryWidget = SummaryWidget;
|
||||||
|
@ -42,6 +42,8 @@ const webpackConfig = {
|
|||||||
"csv": "comma-separated-values",
|
"csv": "comma-separated-values",
|
||||||
"EventEmitter": "eventemitter3",
|
"EventEmitter": "eventemitter3",
|
||||||
"bourbon": "bourbon.scss",
|
"bourbon": "bourbon.scss",
|
||||||
|
"plotly-basic": "plotly.js-basic-dist",
|
||||||
|
"plotly-gl2d": "plotly.js-gl2d-dist",
|
||||||
"vue": vueFile,
|
"vue": vueFile,
|
||||||
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
||||||
"printj": path.join(__dirname, "node_modules/printj/dist/printj.min.js"),
|
"printj": path.join(__dirname, "node_modules/printj/dist/printj.min.js"),
|
||||||
|
Reference in New Issue
Block a user