Compare commits
	
		
			104 Commits
		
	
	
		
			release/3.
			...
			plotly-imp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ![Mandlik, Nikhil K. (ARC-TI)[KBR Wyle Services, LLC]](/assets/img/avatar_default.png)  | 75d8f64b70 | ||
|   | b9919c19ee | ||
|   | 076588441e | ||
|   | afe8382f8d | ||
|   | be18a764c0 | ||
|   | 6f4208c3fd | ||
|   | 15ad5f5719 | ||
|   | 76df729f2f | ||
|   | ee0b1f04bd | ||
|   | 352fe8ea7c | ||
|   | 29650f54de | ||
|   | 02d00aeb07 | ||
|   | fd21594e4a | ||
|   | 5d0beb4351 | ||
|   | f88d3bcaf3 | ||
|   | c1102ed4b1 | ||
|   | fcd8a9a9c9 | ||
|   | 5f729640b2 | ||
|   | 5fc12c771a | ||
|   | 7931177497 | ||
|   | 195aa0a95b | ||
|   | c252d435bf | ||
|   | 87aa5a4342 | ||
|   | bd98b81339 | ||
|   | 56794b0ed5 | ||
|   | 0398679abc | ||
|   | 1bc60f8108 | ||
|   | 122f3efa1f | ||
|   | 32791b442d | ||
|   | 7aaccdb286 | ||
|   | f49556adad | ||
|   | f726bfa31a | ||
|   | e9c6c5760e | ||
|   | 07c3dd6cfa | ||
|   | 651a369391 | ||
|   | ae67a2f438 | ||
|   | 1acda469a9 | ||
|   | d5b0ef735c | ||
|   | a6cac13dfc | ||
|   | 3d058151f2 | ||
|   | 76817193eb | ||
|   | 35ef4407be | ||
|   | f3526f9185 | ||
|   | 70649b0657 | ||
|   | 3b89bf0b8c | ||
|   | a314aa3c95 | ||
|   | dc5723c227 | ||
|   | 61fd7d4e4e | ||
|   | 32fc871e67 | ||
|   | 6b74a133d8 | ||
|   | ceaf4c2ef0 | ||
|   | 982b69e7e1 | ||
|   | 8e5182732d | ||
|   | 2d0b92cc38 | ||
|   | 75e846ea3f | ||
|   | 1b5dee981d | ||
|   | 4fee7f73e7 | ||
|   | 4308a4c9cf | ||
|   | abbffcfbf1 | ||
|   | 01710876fb | ||
|   | 9e3d97c85d | ||
|   | 519075001e | ||
|   | 96a48dd9ee | ||
|   | 550daae76f | ||
|   | b8fcb8ff14 | ||
|   | 373ddd0bf5 | ||
|   | d62cc6b3ee | ||
|   | 5116d38437 | ||
|   | 29771f2722 | ||
|   | 7bfe4bb25c | ||
|   | 510c637081 | ||
|   | d7c65fec4c | ||
|   | 626e2d8e80 | ||
|   | 1fe673c1f5 | ||
|   | d9b00574e7 | ||
|   | 7c48b3ba9a | ||
|   | b6e589eed4 | ||
|   | fb1813c14b | ||
|   | cce834f873 | ||
|   | ca60d02614 | ||
|   | 9520c09b49 | ||
|   | 0d70717b35 | ||
|   | f18da542d6 | ||
|   | e7c38d473b | ||
|   | 2f8db31a33 | ||
|   | 1c58d8c85f | ||
|   | baf426055c | ||
|   | aa3af520ea | ||
|   | 4a43893ccc | ||
|   | 77f50a41c9 | ||
|   | e4cd5f441f | ||
|   | a9cfb002fb | ||
|   | b603a5b722 | ||
|   | be165761c7 | ||
|   | da88cf58cc | ||
|   | bc2bd53f9b | ||
|   | 6b7fd5f22a | ||
|   | 4ee214a142 | ||
|   | 4af24db38a | ||
|   | 8db27809ef | ||
|   | 3116b1addd | ||
|   | 5f67c45b50 | ||
|   | 8158afc29a | ||
|   | 13b3acb7e0 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -41,3 +41,4 @@ npm-debug.log | ||||
| report.*.json | ||||
|  | ||||
| package-lock.json | ||||
| report.*.json | ||||
|   | ||||
| @@ -2,7 +2,6 @@ | ||||
|   "name": "openmct", | ||||
|   "version": "1.0.0-snapshot", | ||||
|   "description": "The Open MCT core platform", | ||||
|   "dependencies": {}, | ||||
|   "devDependencies": { | ||||
|     "angular": ">=1.8.0", | ||||
|     "angular-route": "1.4.14", | ||||
| @@ -61,6 +60,7 @@ | ||||
|     "node-bourbon": "^4.2.3", | ||||
|     "node-sass": "^4.9.2", | ||||
|     "painterro": "^1.0.35", | ||||
|     "plotly.js-dist": "^1.54.5", | ||||
|     "printj": "^1.2.1", | ||||
|     "raw-loader": "^0.5.1", | ||||
|     "request": "^2.69.0", | ||||
|   | ||||
| @@ -252,6 +252,7 @@ define([ | ||||
|         // Plugins that are installed by default | ||||
|  | ||||
|         this.install(this.plugins.Plot()); | ||||
|         this.install(this.plugins.PlotlyPlot()); | ||||
|         this.install(this.plugins.TelemetryTable()); | ||||
|         this.install(PreviewPlugin.default()); | ||||
|         this.install(LegacyIndicatorsPlugin()); | ||||
|   | ||||
| @@ -169,6 +169,7 @@ define([ | ||||
|                 .telemetry | ||||
|                 .request(this.domainObject, options) | ||||
|                 .then(function (points) { | ||||
|                     console.log('PlotSeries: total points', points.length); | ||||
|                     var newPoints = _(this.data) | ||||
|                         .concat(points) | ||||
|                         .sortBy(this.getXVal) | ||||
| @@ -395,6 +396,7 @@ define([ | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             console.log('PlotSeries: this.data.length', this.data.length); | ||||
|         }, | ||||
|         /** | ||||
|          * Updates filters, clears the plot series, unsubscribes and resubscribes | ||||
|   | ||||
							
								
								
									
										72
									
								
								src/plugins/plotlyPlot/PlotlyViewProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/plugins/plotlyPlot/PlotlyViewProvider.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2019, 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 PlotlyViewLayout from './components/PlotlyViewLayout.vue'; | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| export default function PlotlyViewProvider(openmct) { | ||||
|     return { | ||||
|         key: 'plotlyPlot', | ||||
|         name: 'Plotly Plot', | ||||
|         cssClass: 'icon-plot-overlay', | ||||
|         canView: function (domainObject) { | ||||
|             return domainObject.type === 'plotlyPlot'; | ||||
|         }, | ||||
|         canEdit: function (domainObject) { | ||||
|             return domainObject.type === 'plotlyPlot'; | ||||
|         }, | ||||
|         view: function (domainObject) { | ||||
|             let component; | ||||
|  | ||||
|             return { | ||||
|                 show: function (element, isEditing) { | ||||
|                     component =  new Vue({ | ||||
|                         provide: { | ||||
|                             openmct, | ||||
|                             domainObject | ||||
|                         }, | ||||
|                         el: element, | ||||
|                         components: { | ||||
|                             PlotlyViewLayout | ||||
|                         }, | ||||
|                         data() { | ||||
|                             return { | ||||
|                                 isEditing | ||||
|                             } | ||||
|                         }, | ||||
|                         template: '<plotly-view-layout :isEditing="isEditing"></plotly-view-layout>' | ||||
|                     }); | ||||
|                 }, | ||||
|                 onEditModeChange: function (isEditing) { | ||||
|                     component.isEditing = isEditing; | ||||
|                 }, | ||||
|                 destroy: function (element) { | ||||
|                     component.$destroy(); | ||||
|                     component = undefined; | ||||
|                 } | ||||
|             }; | ||||
|         }, | ||||
|         priority: function () { | ||||
|             return 1; | ||||
|         } | ||||
|     }; | ||||
| } | ||||
							
								
								
									
										370
									
								
								src/plugins/plotlyPlot/components/PlotlyViewLayout.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										370
									
								
								src/plugins/plotlyPlot/components/PlotlyViewLayout.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,370 @@ | ||||
| <template> | ||||
| <div :id="plotId" | ||||
|      class="l-view-section" | ||||
| > | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Plotly from 'plotly.js-dist'; | ||||
| import BoundedTableRowCollection from '../../telemetryTable/collections/BoundedTableRowCollection'; | ||||
| import TelemetryTableRow from '../../telemetryTable/TelemetryTableRow'; | ||||
| import TelemetryTableColumn from '../../telemetryTable/TelemetryTableColumn'; | ||||
| import { throttle } from 'lodash'; | ||||
|  | ||||
| export default { | ||||
|     inject: ['openmct', 'domainObject'], | ||||
|     data: function () { | ||||
|         return { | ||||
|             data: [], | ||||
|             bounds: this.openmct.time.bounds(), | ||||
|             plotData: {}, | ||||
|             outstandingRequests: 0, | ||||
|             subscriptions: {}, | ||||
|             plotComposition: undefined, | ||||
|             timestampKey: this.openmct.time.timeSystem().key, | ||||
|             yAxisLabel: '', | ||||
|             plotId: this.openmct.objects.makeKeyString(this.domainObject.identifier) | ||||
|         } | ||||
|     }, | ||||
|     computed: { | ||||
|         getContainerHeight: function () { | ||||
|             return this.plotElement.parentNode.offsetHeight - 5; | ||||
|         }, | ||||
|         getContainerWidth: function () { | ||||
|             return this.plotElement.parentNode.offsetWidth - 5; | ||||
|         } | ||||
|     }, | ||||
|     mounted() { | ||||
|         this.plotElement = document.getElementById(this.plotId); | ||||
|         this.openmct.time.on('bounds', this.updateDomain); | ||||
|         this.openmct.time.on('bounds', this.updateData); | ||||
|  | ||||
|         this.loadComposition(); | ||||
|         this.createPlot(); | ||||
|  | ||||
|         this.boundedRows = {}; | ||||
|         this.limitEvaluators = {}; | ||||
|         this.columnMaps = {}; | ||||
|         this.drawBuffers = {}; | ||||
|         this.telemetryObjects = []; | ||||
|         this.subscriptions = {}; | ||||
|         this.boundedRowsUnlisteners = {}; | ||||
|         this.traceIndices = {}; | ||||
|  | ||||
|         this.purgeDataOutsideRange = throttle(this.purgeDataOutsideRange, 5000); | ||||
|     }, | ||||
|     destroyed() { | ||||
|         Object.values(this.subscriptions) | ||||
|             .forEach(subscription => subscription()); | ||||
|  | ||||
|         this.openmct.time.off('bounds', this.updateDomain); | ||||
|         this.openmct.time.off('bounds', this.updateData); | ||||
|  | ||||
|         Object.values(this.boundedRowsUnlisteners).forEach((unlisteners) => { | ||||
|             unlisteners.forEach(unlistener => unlistener()); | ||||
|         }); | ||||
|  | ||||
|         this.plotComposition.off('add', this.addTelemetryObject); | ||||
|         this.plotComposition.off('remove', this.removeTelemetryObject); | ||||
|     }, | ||||
|     methods: { | ||||
|         loadComposition() { | ||||
|             this.plotComposition = this.openmct.composition.get(this.domainObject); | ||||
|             this.plotComposition.on('add', this.addTelemetryObject); | ||||
|             this.plotComposition.on('remove', this.removeTelemetryObject); | ||||
|             this.plotComposition.load() | ||||
|         }, | ||||
|         addTelemetryObject(telemetryObject) { | ||||
|             this.telemetryObjects.push(telemetryObject); | ||||
|             let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); | ||||
|             this.addTraceForObject(telemetryObject); | ||||
|  | ||||
|             this.requestData(telemetryObject); | ||||
|             let subscription = this.subscribe(telemetryObject); | ||||
|             this.subscriptions[keyString] = subscription; | ||||
|         }, | ||||
|         removeTelemetryObject(identifier) { | ||||
|             const keyString = this.openmct.objects.makeKeyString(identifier); | ||||
|             const index = this.telemetryObjects.findIndex(object => identifier.key === object.identifier.key); | ||||
|             this.unsubscribe(keyString); | ||||
|             this.removeTraceForObject(this.telemetryObjects[index]); | ||||
|             this.telemetryObjects = this.telemetryObjects.filter(object => !(identifier.key === object.identifier.key)); | ||||
|             if (!this.telemetryObjects.length) { | ||||
|                 Plotly.purge(this.plotElement); | ||||
|                 this.createPlot(); | ||||
|             } | ||||
|         }, | ||||
|         updateDomain(bounds, isTick) { | ||||
|             let newDomain = { | ||||
|                 'xaxis.range': [ | ||||
|                     bounds.start, | ||||
|                     bounds.end | ||||
|                 ] | ||||
|             }; | ||||
|             Plotly.relayout(this.plotElement, newDomain); | ||||
|         }, | ||||
|         updateData(bounds, isTick) { | ||||
|             if (!isTick) { | ||||
|                 this.clearData(); | ||||
|                 this.telemetryObjects.forEach(telemetryObject => this.requestData(telemetryObject)); | ||||
|             } | ||||
|         }, | ||||
|         clearData() { | ||||
|             this.telemetryObjects.forEach(telemetryObject => this.resetTraceForObject(telemetryObject)); | ||||
|         }, | ||||
|         requestData(telemetryObject) { | ||||
|             return this.openmct.telemetry.request(telemetryObject) | ||||
|                 .then(telemetryData => { | ||||
|                     const keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); | ||||
|                     let columnMap = this.columnMaps[keyString]; | ||||
|                     let limitEvaluator = this.limitEvaluators[keyString]; | ||||
|                     console.log('Plotly: total points', telemetryData.length); | ||||
|                     const telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator)); | ||||
|                     this.boundedRows[keyString].add(telemetryRows); | ||||
|                 }); | ||||
|         }, | ||||
|         subscribe(telemetryObject) { | ||||
|             const keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); | ||||
|             let columnMap = this.columnMaps[keyString]; | ||||
|             let limitEvaluator = this.limitEvaluators[keyString]; | ||||
|  | ||||
|             return this.openmct.telemetry.subscribe(telemetryObject, (datum) => { | ||||
|                 let newRow = new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator); | ||||
|                 this.boundedRows[keyString].add(newRow); | ||||
|             }); | ||||
|         }, | ||||
|         unsubscribe(keyString) { | ||||
|             this.subscriptions[keyString](); | ||||
|             delete this.subscriptions[keyString]; | ||||
|         }, | ||||
|         createPlot() { | ||||
|             let timeSystem = this.openmct.time.timeSystem(); | ||||
|             let bounds = this.openmct.time.bounds(); | ||||
|             let formatMetadata = { | ||||
|                 key: timeSystem.key, | ||||
|                 name: timeSystem.name, | ||||
|                 format: timeSystem.timeFormat | ||||
|             } | ||||
|             this.timeFormatter = this.openmct.telemetry.getValueFormatter(formatMetadata); | ||||
|             let xRange = [ | ||||
|                 bounds.start, | ||||
|                 bounds.end | ||||
|             ]; | ||||
|  | ||||
|             let layout = { | ||||
|                 hovermode: 'compare', | ||||
|                 hoverdistance: -1, | ||||
|                 autosize: true, | ||||
|                 showlegend: true, | ||||
|                 legend: { | ||||
|                     y: 1.07, | ||||
|                     "orientation": "h" | ||||
|                 }, | ||||
|                 height: this.getContainerHeight, | ||||
|                 font: { | ||||
|                     family: "'Helvetica Neue', Helvetica, Arial, sans-serif", | ||||
|                     size: "12px", | ||||
|                     color: "#aaa" | ||||
|                 }, | ||||
|                 xaxis: { | ||||
|                     title: timeSystem.name, | ||||
|                     type: 'date', | ||||
|                     zeroline: false, | ||||
|                     showgrid: false, | ||||
|                     range: xRange | ||||
|                 }, | ||||
|                 yaxis: { | ||||
|                     zeroline: false, | ||||
|                     showgrid: false, | ||||
|                     tickwidth: 3, | ||||
|                     tickcolor: 'transparent', | ||||
|                     autorange: true, | ||||
|                     visible: false | ||||
|                 }, | ||||
|                 margin: { | ||||
|                     l: 40, | ||||
|                     r: 5, | ||||
|                     b: 40, | ||||
|                     t: 0 | ||||
|                 }, | ||||
|                 paper_bgcolor: 'transparent', | ||||
|                 plot_bgcolor: 'transparent' | ||||
|             }; | ||||
|             Plotly.newPlot( | ||||
|                 this.plotElement, | ||||
|                 this.data, | ||||
|                 layout, | ||||
|                 { | ||||
|                     displayModeBar: true, // turns off hover-activated toolbar | ||||
|                     staticPlot: false // turns off hover effects on datapoints | ||||
|                 } | ||||
|             ); | ||||
|  | ||||
|         }, | ||||
|         purgeDataOutsideRange() { | ||||
|             const bounds = this.openmct.time.bounds(); | ||||
|             const pointsPerData = []; | ||||
|             this.data.forEach((data, index) => { | ||||
|                 const startIndex = this.getStartIndex(data, bounds.start); | ||||
|                 const endIndex = this.getEndIndex(data, bounds.end); | ||||
|                 data.x = data.x.slice(startIndex, endIndex); | ||||
|                 data.y = data.y.slice(startIndex, endIndex); | ||||
|                 this.$set(this.data, index, data); | ||||
|             }); | ||||
|  | ||||
|             console.log('Plotly: this.data.length', this.data[0].x.length); | ||||
|         }, | ||||
|         getEndIndex(data, time) { | ||||
|             let endIndex = data.x.length - 1; | ||||
|             let success = false; | ||||
|             let index = endIndex; | ||||
|             while(!success && index >= 0) { | ||||
|                 if (index === 0) { | ||||
|                     success = true; | ||||
|                     endIndex = 0; | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 success = data.x[index] <= time; | ||||
|                 if (success) { | ||||
|                     endIndex = index; | ||||
|                 } | ||||
|  | ||||
|                 index--; | ||||
|             } | ||||
|  | ||||
|             return endIndex; | ||||
|         }, | ||||
|         getStartIndex(data, time) { | ||||
|             let startIndex = 0; | ||||
|             data.x.some((x, index) => { | ||||
|                 const success = x >= time; | ||||
|                 if (success) { | ||||
|                     startIndex = index; | ||||
|                 } | ||||
|  | ||||
|                 return success; | ||||
|             }); | ||||
|  | ||||
|             return Math.max(0, startIndex - 3); | ||||
|         }, | ||||
|         resetTraceForObject(telemetryObject) { | ||||
|             this.removeTraceForObject(telemetryObject); | ||||
|             this.addTraceForObject(telemetryObject); | ||||
|         }, | ||||
|         removeTraceForObject(telemetryObject) { | ||||
|             let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); | ||||
|             let index = this.traceIndices[keyString]; | ||||
|             Plotly.deleteTraces(this.plotElement, index); | ||||
|  | ||||
|             delete this.traceIndices[keyString]; | ||||
|             this.recalculateTraceIndices(); | ||||
|  | ||||
|             this.boundedRowsUnlisteners[keyString].forEach((unlistener) => unlistener()); | ||||
|         }, | ||||
|         addTraceForObject(telemetryObject) { | ||||
|             let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier); | ||||
|             let boundedRows = new BoundedTableRowCollection(this.openmct); | ||||
|             this.boundedRows[keyString] = boundedRows; | ||||
|  | ||||
|             this.traceIndices[keyString] = Object.keys(this.traceIndices).length; | ||||
|             this.recalculateTraceIndices(); | ||||
|  | ||||
|             Plotly.addTraces(this.plotElement, { | ||||
|                 x: [], | ||||
|                 y: [], | ||||
|                 name: telemetryObject.name, | ||||
|                 type: "scattergl", | ||||
|                 mode: 'lines+markers', | ||||
|                 marker: { | ||||
|                     size: 5 | ||||
|                 }, | ||||
|                 line: { | ||||
|                     shape: 'linear', | ||||
|                     width: 1.5 | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             const metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values(); | ||||
|  | ||||
|             let columnMap = metadataValues.reduce((map, metadatum) => { | ||||
|                 let column = new TelemetryTableColumn(this.openmct, metadatum); | ||||
|                 map[metadatum.key] = column; | ||||
|                 return map; | ||||
|             }, {}); | ||||
|             const limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject); | ||||
|             const valueFormatter = this.openmct.telemetry.getValueFormatter(this.openmct.telemetry.getMetadata(telemetryObject).valuesForHints(['range'])[0]); | ||||
|             let layout_update = { | ||||
|                 yaxis: {title: valueFormatter.valueMetadata.name, visible: true} | ||||
|             }; | ||||
|             Plotly.update(this.plotElement, {}, layout_update) | ||||
|             this.columnMaps[keyString] = columnMap; | ||||
|             this.limitEvaluators[keyString] = limitEvaluator; | ||||
|  | ||||
|             let timeSystemKey = this.openmct.time.timeSystem().key; | ||||
|             let drawBuffer = { | ||||
|                 keyString, | ||||
|                 x: [], | ||||
|                 y: [] | ||||
|             }; | ||||
|  | ||||
|             this.drawBuffers[keyString] = drawBuffer; | ||||
|  | ||||
|             const addRow = (rows) => { | ||||
|                 if (rows instanceof Array) { | ||||
|                     rows.forEach(row => { | ||||
|                         drawBuffer.x.push(row.datum[timeSystemKey]); | ||||
|                         drawBuffer.y.push(valueFormatter.format(row.datum)); | ||||
|                     }) | ||||
|                 } else { | ||||
|                     drawBuffer.x.push(rows.datum[timeSystemKey]); | ||||
|                     drawBuffer.y.push(valueFormatter.format(rows.datum)); | ||||
|                 } | ||||
|                 this.scheduleDraw(); | ||||
|             } | ||||
|  | ||||
|             boundedRows.on('add', addRow); | ||||
|             this.boundedRowsUnlisteners[keyString] = []; | ||||
|  | ||||
|             this.boundedRowsUnlisteners[keyString].push(() => { | ||||
|                 boundedRows.off('add', addRow); | ||||
|             }) | ||||
|         }, | ||||
|         recalculateTraceIndices() { | ||||
|             Object.keys(this.traceIndices).forEach((key, indexOfKey) => { | ||||
|                 this.traceIndices[key] = indexOfKey; | ||||
|             }); | ||||
|         }, | ||||
|         scheduleDraw() { | ||||
|             if (!this.drawing) { | ||||
|                 this.drawing = true; | ||||
|                 requestAnimationFrame(() => { | ||||
|                     let dataForXAxes = []; | ||||
|                     let dataForYAxes = []; | ||||
|                     let traceIndices = []; | ||||
|                     Object.values(this.drawBuffers).forEach((drawBuffer) => { | ||||
|                         dataForXAxes.push(drawBuffer.x); | ||||
|                         dataForYAxes.push(drawBuffer.y); | ||||
|                         traceIndices.push(this.traceIndices[drawBuffer.keyString]); | ||||
|                         drawBuffer.x = []; | ||||
|                         drawBuffer.y = []; | ||||
|                     }); | ||||
|  | ||||
|                     this.purgeDataOutsideRange(); | ||||
|                     Plotly.extendTraces( | ||||
|                         this.plotElement, | ||||
|                         { | ||||
|                             x: dataForXAxes, | ||||
|                             y: dataForYAxes | ||||
|                         }, | ||||
|                         traceIndices, | ||||
|                     ); | ||||
|  | ||||
|                     this.drawing = false; | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										3
									
								
								src/plugins/plotlyPlot/components/plotly.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/plugins/plotlyPlot/components/plotly.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| .plot svg { | ||||
| } | ||||
|  | ||||
							
								
								
									
										17
									
								
								src/plugins/plotlyPlot/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/plugins/plotlyPlot/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| import PlotlyViewProvider from './PlotlyViewProvider'; | ||||
|  | ||||
| export default function plugin() { | ||||
|     return function install(openmct) { | ||||
|         openmct.objectViews.addProvider(new PlotlyViewProvider(openmct)); | ||||
|  | ||||
|         openmct.types.addType('plotlyPlot', { | ||||
|             name: "Plotly Plot", | ||||
|             description: "Simple plot rendered by plotly.js", | ||||
|             creatable: true, | ||||
|             cssClass: 'icon-plot-overlay', | ||||
|             initialize: function (domainObject) { | ||||
|                 domainObject.composition = []; | ||||
|             } | ||||
|         }); | ||||
|     }; | ||||
| } | ||||
| @@ -34,6 +34,7 @@ define([ | ||||
|     './URLIndicatorPlugin/URLIndicatorPlugin', | ||||
|     './telemetryMean/plugin', | ||||
|     './plot/plugin', | ||||
|     './plotlyPlot/plugin', | ||||
|     './telemetryTable/plugin', | ||||
|     './staticRootPlugin/plugin', | ||||
|     './notebook/plugin', | ||||
| @@ -69,6 +70,7 @@ define([ | ||||
|     URLIndicatorPlugin, | ||||
|     TelemetryMean, | ||||
|     PlotPlugin, | ||||
|     PlotlyPlotPlugin, | ||||
|     TelemetryTablePlugin, | ||||
|     StaticRootPlugin, | ||||
|     Notebook, | ||||
| @@ -177,8 +179,8 @@ define([ | ||||
|     plugins.ExampleImagery = ExampleImagery; | ||||
|     plugins.ImageryPlugin = ImageryPlugin; | ||||
|     plugins.Plot = PlotPlugin; | ||||
|     plugins.PlotlyPlot = PlotlyPlotPlugin.default; | ||||
|     plugins.TelemetryTable = TelemetryTablePlugin; | ||||
|  | ||||
|     plugins.SummaryWidget = SummaryWidget; | ||||
|     plugins.TelemetryMean = TelemetryMean; | ||||
|     plugins.URLIndicator = URLIndicatorPlugin; | ||||
|   | ||||
| @@ -73,6 +73,7 @@ define( | ||||
|              * @private | ||||
|              */ | ||||
|             addOne(row) { | ||||
|                 // console.log('SortedTableRowCollection addOne', row); | ||||
|                 if (this.sortOptions === undefined) { | ||||
|                     throw 'Please specify sort options'; | ||||
|                 } | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| @import "../plugins/folderView/components/list-item.scss"; | ||||
| @import "../plugins/folderView/components/list-view.scss"; | ||||
| @import "../plugins/imagery/components/imagery-view-layout.scss"; | ||||
| @import "../plugins/plotlyPlot/components/plotly.scss"; | ||||
| @import "../plugins/telemetryTable/components/table-row.scss"; | ||||
| @import "../plugins/telemetryTable/components/telemetry-filter-indicator.scss"; | ||||
| @import "../plugins/tabs/components/tabs.scss"; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user