mirror of
https://github.com/nasa/openmct.git
synced 2024-12-21 06:03:08 +00:00
Allow Data Visualization in inspector based on current selection (#7052) * visualize data in inspector per selection --------- Co-authored-by: David Tsay <3614296+davetsay@users.noreply.github.com> Co-authored-by: Khalid Adil <khalidadil29@gmail.com> Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
parent
b923af8705
commit
4f559fdccf
186
src/plugins/inspectorDataVisualization/DataVisualization.vue
Normal file
186
src/plugins/inspectorDataVisualization/DataVisualization.vue
Normal file
@ -0,0 +1,186 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="c-data-visualization-inspect-properties c-inspector__data-pivot c-data-visualization-inspector__flex-column"
|
||||
>
|
||||
<div class="c-inspect-properties">
|
||||
<div class="c-inspect-properties__header">Data Visualization</div>
|
||||
</div>
|
||||
|
||||
<div v-if="isLoading" class="c-inspector__data-pivot-placeholder">Loading...</div>
|
||||
|
||||
<div v-else-if="hasDataRanges">
|
||||
<div
|
||||
v-if="selectedDataRange !== undefined && hasDescription"
|
||||
class="c-inspector__data-pivot-coordinates-wrapper"
|
||||
>
|
||||
<span
|
||||
class="c-tree__item__type-icon c-object-label__type-icon"
|
||||
:class="description.icon"
|
||||
></span>
|
||||
<span class="c-inspector__data-pivot-coordinates">
|
||||
{{ description.text }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<select class="c-inspector__data-pivot-range-selector" v-model="selectedDataRangeIndex">
|
||||
<option
|
||||
v-for="(dataRange, index) in descendingDataRanges"
|
||||
:key="index"
|
||||
:value="index"
|
||||
:selected="selectedDataRangeIndex === index"
|
||||
>
|
||||
{{ displayDataRange(dataRange) }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else-if="dataRanges && dataRanges.length === 0"
|
||||
class="c-inspector__data-pivot-placeholder"
|
||||
>
|
||||
No data for the current {{ description.name }}
|
||||
</div>
|
||||
|
||||
<div v-else-if="hasPlaceholderText" class="c-inspector__data-pivot-placeholder">
|
||||
{{ placeholderText }}
|
||||
</div>
|
||||
|
||||
<template v-if="selectedBounds !== undefined">
|
||||
<NumericData
|
||||
:bounds="selectedBounds"
|
||||
:telemetry-keys="plotTelemetryKeys"
|
||||
:no-numeric-data-text="noNumericDataText"
|
||||
/>
|
||||
<Imagery v-if="hasImagery" :bounds="selectedBounds" :telemetry-keys="imageryTelemetryKeys" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import NumericData from './NumericData.vue';
|
||||
import Imagery from './Imagery.vue';
|
||||
|
||||
const TIMESTAMP_VIEW_BUFFER = 30 * 1000;
|
||||
const timestampBufferText = `${TIMESTAMP_VIEW_BUFFER / 1000} seconds`;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NumericData,
|
||||
Imagery
|
||||
},
|
||||
inject: ['timeFormatter', 'placeholderText', 'plotOptions', 'imageryOptions'],
|
||||
props: {
|
||||
description: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
dataRanges: {
|
||||
type: Array,
|
||||
default: () => undefined
|
||||
},
|
||||
plotTelemetryKeys: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedDataRangeIndex: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasPlaceholderText() {
|
||||
return this.placeholderText.length > 0;
|
||||
},
|
||||
descendingDataRanges() {
|
||||
return this.dataRanges?.slice().reverse();
|
||||
},
|
||||
hasDescription() {
|
||||
return this.description?.text?.length > 0;
|
||||
},
|
||||
hasDataRanges() {
|
||||
return this.dataRanges?.length > 0;
|
||||
},
|
||||
selectedDataRange() {
|
||||
if (!this.hasDataRanges || this.selectedDataRangeIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.descendingDataRanges[this.selectedDataRangeIndex];
|
||||
},
|
||||
selectedBounds() {
|
||||
if (this.selectedDataRange === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { start, end } = this.selectedDataRange.bounds;
|
||||
|
||||
if (start === end) {
|
||||
return {
|
||||
start: start - TIMESTAMP_VIEW_BUFFER,
|
||||
end: end + TIMESTAMP_VIEW_BUFFER
|
||||
};
|
||||
}
|
||||
|
||||
return this.selectedDataRange.bounds;
|
||||
},
|
||||
imageryTelemetryKeys() {
|
||||
return this.imageryOptions?.telemetryKeys;
|
||||
},
|
||||
hasImagery() {
|
||||
return this.imageryTelemetryKeys?.length;
|
||||
},
|
||||
noNumericDataText() {
|
||||
return this.plotOptions?.noNumericDataText;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
shortDate(date) {
|
||||
return date.slice(0, date.indexOf('.')).replace('T', ' ');
|
||||
},
|
||||
displayDataRange(dataRange) {
|
||||
const startTime = dataRange.bounds.start;
|
||||
const endTime = dataRange.bounds.end;
|
||||
if (startTime === endTime) {
|
||||
return `${this.shortDate(this.timeFormatter.format(startTime))} +/- ${timestampBufferText}`;
|
||||
}
|
||||
return `${this.shortDate(this.timeFormatter.format(startTime))} - ${this.shortDate(
|
||||
this.timeFormatter.format(endTime)
|
||||
)}`;
|
||||
},
|
||||
isSelectedDataRange(dataRange, index) {
|
||||
const selectedDataRange = this.descendingDataRanges[index];
|
||||
|
||||
return (
|
||||
dataRange.bounds.start === selectedDataRange.bounds.start &&
|
||||
dataRange.bounds.end === selectedDataRange.bounds.end
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
127
src/plugins/inspectorDataVisualization/Imagery.vue
Normal file
127
src/plugins/inspectorDataVisualization/Imagery.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="camerasWithImagesInBounds.length > 0"
|
||||
class="c-inspect-properties c-inspector__imagery-view"
|
||||
>
|
||||
<div class="c-inspect-properties__header">Imagery View</div>
|
||||
<div
|
||||
v-for="(camera, index) in camerasWithImagesInBounds"
|
||||
:key="index"
|
||||
class="c-imagery-view__camera-image-set"
|
||||
>
|
||||
<TelemetryFrame :bounds="bounds" :telemetry-object="camera">
|
||||
<div class="c-imagery-view__camera-image-list">
|
||||
<span
|
||||
v-for="(cameraImage, imageIndex) in camera.imagesInBounds"
|
||||
:key="imageIndex"
|
||||
class="c-imagery-view__camera-image"
|
||||
>
|
||||
<img :src="cameraImage.value" />
|
||||
<span class="c-imagery-view__camera-image-timestamp">
|
||||
{{ cameraImage.timestamp }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</TelemetryFrame>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TelemetryFrame from './TelemetryFrame.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TelemetryFrame
|
||||
},
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
bounds: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
telemetryKeys: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
camerasWithImagesInBounds: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
bounds() {
|
||||
this.getCameraImagesInBounds();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getCameraImagesInBounds();
|
||||
},
|
||||
methods: {
|
||||
async getCameraImagesInBounds() {
|
||||
this.camerasWithImagesInBounds = [];
|
||||
this.cameraImagesList = [];
|
||||
const { start, end } = this.bounds;
|
||||
const cameraObjectPromises = [];
|
||||
this.telemetryKeys.forEach((telemetryKey) => {
|
||||
const cameraPromise = this.openmct.objects.get(telemetryKey);
|
||||
cameraObjectPromises.push(cameraPromise);
|
||||
});
|
||||
const cameraObjects = await Promise.all(cameraObjectPromises);
|
||||
|
||||
const cameraTelemetryPromises = [];
|
||||
cameraObjects.forEach((cameraObject) => {
|
||||
const cameraTelemetryPromise = this.openmct.telemetry.request(cameraObject, {
|
||||
start,
|
||||
end
|
||||
});
|
||||
cameraTelemetryPromises.push(cameraTelemetryPromise);
|
||||
});
|
||||
const cameraImages = await Promise.all(cameraTelemetryPromises);
|
||||
|
||||
cameraObjects.forEach((cameraObject, index) => {
|
||||
cameraObject.images = cameraImages[index];
|
||||
});
|
||||
|
||||
cameraObjects.forEach((cameraObject) => {
|
||||
if (cameraObject.images.length > 0) {
|
||||
const imagesInBounds = cameraObject.images.filter((imageDetails) => {
|
||||
if (!imageDetails.timestamp) {
|
||||
return false;
|
||||
}
|
||||
const timestamp = Date.parse(imageDetails.timestamp);
|
||||
return timestamp >= start && timestamp <= end;
|
||||
});
|
||||
if (imagesInBounds.length > 0) {
|
||||
cameraObject.imagesInBounds = imagesInBounds;
|
||||
this.camerasWithImagesInBounds.push(cameraObject);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -0,0 +1,65 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="c-inspector__properties c-data-visualization-inspector__properties c-data-visualization-inspector__flex-column"
|
||||
>
|
||||
<DataVisualization
|
||||
:data-ranges="dataRanges"
|
||||
:plot-telemetry-keys="plotTelemetryKeys"
|
||||
:description="description"
|
||||
:is-loading="isLoading"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DataVisualization from './DataVisualization.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DataVisualization
|
||||
},
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
context: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dataRanges() {
|
||||
return this.context.dataRanges;
|
||||
},
|
||||
plotTelemetryKeys() {
|
||||
return this.context.telemetryKeys;
|
||||
},
|
||||
description() {
|
||||
return this.context.description;
|
||||
},
|
||||
isLoading() {
|
||||
return Boolean(this.context.loading);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -0,0 +1,94 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2023, 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 mount from 'utils/mount';
|
||||
|
||||
import InspectorDataVisualizationComponent from './InspectorDataVisualizationComponent.vue';
|
||||
|
||||
export default function InspectorDataVisualizationViewProvider(openmct, configuration) {
|
||||
const {
|
||||
type = 'mmgis',
|
||||
name = 'Data Visualization',
|
||||
placeholderText = '',
|
||||
plotOptions,
|
||||
imageryOptions
|
||||
} = configuration;
|
||||
|
||||
return {
|
||||
key: 'inspectorDataVisualizationView',
|
||||
name,
|
||||
|
||||
canView(selection) {
|
||||
const domainObject = selection?.[0]?.[0]?.context?.item;
|
||||
|
||||
return domainObject?.type === type;
|
||||
},
|
||||
|
||||
view(selection) {
|
||||
let _destroy = null;
|
||||
|
||||
const context = selection[0][0].context;
|
||||
const domainObject = context.item;
|
||||
const dataVisualizationContext = context?.dataVisualization ?? {};
|
||||
const timeFormatter = openmct.telemetry.getFormatter('iso');
|
||||
|
||||
return {
|
||||
show(element) {
|
||||
const { destroy } = mount(
|
||||
{
|
||||
components: {
|
||||
InspectorDataVisualization: InspectorDataVisualizationComponent
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
timeFormatter,
|
||||
placeholderText,
|
||||
plotOptions,
|
||||
imageryOptions
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
context: dataVisualizationContext
|
||||
};
|
||||
},
|
||||
template: `<InspectorDataVisualization :context="context" />`
|
||||
},
|
||||
{
|
||||
app: openmct.app,
|
||||
element
|
||||
}
|
||||
);
|
||||
_destroy = destroy;
|
||||
},
|
||||
destroy() {
|
||||
if (_destroy) {
|
||||
_destroy();
|
||||
}
|
||||
},
|
||||
priority() {
|
||||
return openmct.priority.HIGH;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
165
src/plugins/inspectorDataVisualization/NumericData.vue
Normal file
165
src/plugins/inspectorDataVisualization/NumericData.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="c-inspector__numeric-data">
|
||||
<div class="c-inspect-properties">
|
||||
<div class="c-inspect-properties__header">Numeric Data</div>
|
||||
</div>
|
||||
<div ref="numericDataView"></div>
|
||||
|
||||
<div v-if="!hasNumericData">
|
||||
{{ noNumericDataText }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import mount from 'utils/mount';
|
||||
import TelemetryFrame from './TelemetryFrame.vue';
|
||||
import Plot from '../plot/Plot.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject', 'timeFormatter'],
|
||||
props: {
|
||||
bounds: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
telemetryKeys: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
noNumericDataText: {
|
||||
type: String,
|
||||
default: 'No Numeric Data to display.'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
plotObjects: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
hasNumericData() {
|
||||
return this.plotObjects.length > 0;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
telemetryKeys: {
|
||||
handler() {
|
||||
this.renderNumericData();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
bounds: {
|
||||
handler() {
|
||||
this.renderNumericData();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.renderNumericData();
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.clearPlots();
|
||||
},
|
||||
methods: {
|
||||
renderNumericData() {
|
||||
this.clearPlots();
|
||||
|
||||
this.unregisterTimeContextList = [];
|
||||
this.elementsList = [];
|
||||
this.componentsList = [];
|
||||
|
||||
this.telemetryKeys.forEach(async (telemetryKey) => {
|
||||
const plotObject = await this.openmct.objects.get(telemetryKey);
|
||||
|
||||
this.plotObjects.push(plotObject);
|
||||
this.unregisterTimeContextList.push(this.setIndependentTimeContextForComponent(plotObject));
|
||||
this.renderPlot(plotObject);
|
||||
});
|
||||
},
|
||||
setIndependentTimeContextForComponent(plotObject) {
|
||||
const keyString = this.openmct.objects.makeKeyString(plotObject.identifier);
|
||||
|
||||
// get an independent time context for object
|
||||
this.openmct.time.getContextForView([plotObject]);
|
||||
// set the time context of the object to the selected time range
|
||||
return this.openmct.time.addIndependentContext(keyString, this.bounds);
|
||||
},
|
||||
renderPlot(plotObject) {
|
||||
const { vNode, destroy } = mount(
|
||||
{
|
||||
components: {
|
||||
TelemetryFrame,
|
||||
Plot
|
||||
},
|
||||
provide: {
|
||||
openmct: this.openmct,
|
||||
path: [plotObject]
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
plotObject,
|
||||
bounds: this.bounds
|
||||
};
|
||||
},
|
||||
template: `<TelemetryFrame
|
||||
:bounds="bounds"
|
||||
:telemetry-object="plotObject"
|
||||
>
|
||||
<Plot />
|
||||
</TelemetryFrame>`
|
||||
},
|
||||
{
|
||||
app: this.openmct.app
|
||||
}
|
||||
);
|
||||
|
||||
this.componentsList.push(destroy);
|
||||
this.elementsList.push(vNode.el);
|
||||
this.$refs.numericDataView.append(vNode.el);
|
||||
},
|
||||
clearPlots() {
|
||||
if (this.componentsList?.length) {
|
||||
this.componentsList.forEach((destroy) => destroy());
|
||||
delete this.componentsList;
|
||||
}
|
||||
|
||||
if (this.elementsList?.length) {
|
||||
this.elementsList.forEach((element) => element.remove());
|
||||
delete this.elementsList;
|
||||
}
|
||||
|
||||
if (this.plotObjects?.length) {
|
||||
this.plotObjects = [];
|
||||
}
|
||||
|
||||
if (this.unregisterTimeContextList?.length) {
|
||||
this.unregisterTimeContextList.forEach((unregisterTimeContext) => unregisterTimeContext());
|
||||
delete this.unregisterTimeContextList;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
124
src/plugins/inspectorDataVisualization/TelemetryFrame.vue
Normal file
124
src/plugins/inspectorDataVisualization/TelemetryFrame.vue
Normal file
@ -0,0 +1,124 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="c-telemetry-frame">
|
||||
<div class="c-telemetry-frame__title-bar">
|
||||
<span class="c-telemetry-frame__title">
|
||||
<span class="c-telemetry-frame__title-icon icon-telemetry"></span>
|
||||
<span class="title-text">{{ telemetryObject.name }}</span>
|
||||
</span>
|
||||
<button
|
||||
ref="menu-button"
|
||||
title="More options"
|
||||
class="l-browse-bar__actions c-icon-button icon-3-dots"
|
||||
@click="toggleMenu"
|
||||
></button>
|
||||
</div>
|
||||
<div
|
||||
v-if="showMenu"
|
||||
class="c-menu c-menu__inspector-telemetry-options"
|
||||
aria-label="Telemetry Options"
|
||||
@blur="showMenu = false"
|
||||
>
|
||||
<ul>
|
||||
<li
|
||||
v-if="telemetryObject.type === 'yamcs.telemetry'"
|
||||
role="menuitem"
|
||||
title="View Full Screen"
|
||||
class="icon-eye-open"
|
||||
@click="previewTelemetry"
|
||||
>
|
||||
View Full Screen
|
||||
</li>
|
||||
<li
|
||||
role="menuitem"
|
||||
title="Open in a new browser tab"
|
||||
class="icon-new-window"
|
||||
@click="openInNewTab"
|
||||
>
|
||||
Open In New Tab
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
provide() {
|
||||
return {
|
||||
domainObject: this.telemetryObject
|
||||
};
|
||||
},
|
||||
props: {
|
||||
bounds: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
telemetryObject: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showMenu: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleMenu() {
|
||||
this.showMenu = !this.showMenu;
|
||||
},
|
||||
async getTelemetryPath() {
|
||||
let sourceTelem;
|
||||
if (this.telemetryObject.type === 'yamcs.telemetry') {
|
||||
sourceTelem = this.openmct.objects.makeKeyString(this.telemetryObject.identifier);
|
||||
} else if (this.telemetryObject.type === 'yamcs.image') {
|
||||
sourceTelem = this.openmct.objects.makeKeyString(this.telemetryObject.identifier);
|
||||
}
|
||||
const telemetryPath = await this.openmct.objects.getOriginalPath(sourceTelem);
|
||||
return telemetryPath;
|
||||
},
|
||||
async openInNewTab() {
|
||||
const telemetryPath = await this.getTelemetryPath();
|
||||
const sourceTelemObject = telemetryPath[0];
|
||||
const timeBounds = this.bounds;
|
||||
const urlParams = {
|
||||
'tc.startBound': timeBounds?.start,
|
||||
'tc.endBound': timeBounds?.end,
|
||||
'tc.mode': 'fixed'
|
||||
};
|
||||
const newTabAction = this.openmct.actions.getAction('newTab');
|
||||
newTabAction.invoke([sourceTelemObject], urlParams);
|
||||
this.showMenu = false;
|
||||
},
|
||||
previewTelemetry() {
|
||||
const previewAction = this.openmct.actions.getAction('preview');
|
||||
previewAction.invoke([this.telemetryObject]);
|
||||
this.showMenu = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@ -0,0 +1,128 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2023, 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.
|
||||
*****************************************************************************/
|
||||
|
||||
//InspectorDataVisualizationComponent
|
||||
.c-data-visualization-inspector__flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.c-data-visualization-inspector__flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.c-data-visualization-inspect-properties + .c-data-visualization-inspect-properties {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
// DataVisualization
|
||||
.c-inspector__data-pivot-placeholder {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.c-inspector__data-pivot-coordinates-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.c-inspector__data-pivot-coordinates {
|
||||
margin-left: 6px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.c-inspector__data-pivot-range-selector {
|
||||
margin: 10px auto;
|
||||
height: 25px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.c-inspector__imagery-view {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.c-imagery-view__camera-image-set {
|
||||
grid-column: 1/3;
|
||||
}
|
||||
|
||||
.c-imagery-view__camera-image-list {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-gap: 10px;
|
||||
grid-auto-columns: min-content;
|
||||
overflow: auto;
|
||||
white-space: nowrap;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.c-imagery-view__camera-image {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.c-imagery-view__camera-image img {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
.c-imagery-view__camera-image-timestamp {
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
// Telemetry Frame
|
||||
.c-telemetry-frame {
|
||||
margin: 8px 0px;
|
||||
|
||||
&__title-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 6px 0px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
flex: 1;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
&__title-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.c-telemetry-frame .c-menu {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.c-inspector__data-pivot .c-plot {
|
||||
position: relative;
|
||||
min-height: 150px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.c-inspector__data-pivot .c-plot .c-plot--stacked-container {
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
.c-inspector__numeric-data .c-inspect-properties__header {
|
||||
margin-bottom: 10px;
|
||||
}
|
31
src/plugins/inspectorDataVisualization/plugin.js
Normal file
31
src/plugins/inspectorDataVisualization/plugin.js
Normal file
@ -0,0 +1,31 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2023, 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 InspectorDataVisualizationViewProvider from './InspectorDataVisualizationViewProvider';
|
||||
|
||||
export default function (options) {
|
||||
return function (openmct) {
|
||||
openmct.inspectorViews.addProvider(
|
||||
new InspectorDataVisualizationViewProvider(openmct, options)
|
||||
);
|
||||
};
|
||||
}
|
@ -83,7 +83,8 @@ define([
|
||||
'./timelist/plugin',
|
||||
'./faultManagement/FaultManagementPlugin',
|
||||
'../../example/exampleTags/plugin',
|
||||
'./inspectorViews/plugin'
|
||||
'./inspectorViews/plugin',
|
||||
'./inspectorDataVisualization/plugin'
|
||||
], function (
|
||||
_,
|
||||
UTCTimeSystem,
|
||||
@ -147,7 +148,8 @@ define([
|
||||
TimeList,
|
||||
FaultManagementPlugin,
|
||||
ExampleTags,
|
||||
InspectorViews
|
||||
InspectorViews,
|
||||
InspectorDataVisualization
|
||||
) {
|
||||
const plugins = {};
|
||||
|
||||
@ -232,6 +234,7 @@ define([
|
||||
plugins.Gauge = GaugePlugin.default;
|
||||
plugins.Timelist = TimeList.default;
|
||||
plugins.InspectorViews = InspectorViews.default;
|
||||
plugins.InspectorDataVisualization = InspectorDataVisualization.default;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
@ -58,6 +58,7 @@
|
||||
@import '../plugins/gauge/gauge.scss';
|
||||
@import '../plugins/faultManagement/fault-manager.scss';
|
||||
@import '../plugins/operatorStatus/operator-status';
|
||||
@import '../plugins/inspectorDataVisualization/inspector-data-visualization.scss';
|
||||
|
||||
#splash-screen {
|
||||
display: none;
|
||||
|
Loading…
Reference in New Issue
Block a user