Compare commits
	
		
			8 Commits
		
	
	
		
			2.1.4-ERT
			...
			pause-play
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e84aacd7c8 | ||
| 
						 | 
					161ebfa5f3 | ||
| 
						 | 
					acd1ee81de | ||
| 
						 | 
					3fcdf3cbe1 | ||
| 
						 | 
					31edff509a | ||
| 
						 | 
					f2f8132227 | ||
| 
						 | 
					fa1537ab45 | ||
| 
						 | 
					95dbe63b14 | 
@@ -45,9 +45,14 @@
 | 
			
		||||
 | 
			
		||||
            <div class="gl-plot-display-area has-local-controls has-cursor-guides">
 | 
			
		||||
                <div class="l-state-indicators">
 | 
			
		||||
                    <span class="l-state-indicators__alert-no-lad t-object-alert t-alert-unsynced icon-alert-triangle"
 | 
			
		||||
                    <span v-if="plotHistory.length"
 | 
			
		||||
                          class="l-state-indicators__alert-no-lad t-object-alert t-alert-unsynced icon-alert-triangle"
 | 
			
		||||
                          title="This plot is not currently displaying the latest data. Reset pan/zoom to view latest data."
 | 
			
		||||
                    ></span>
 | 
			
		||||
                    <span v-else
 | 
			
		||||
                          class="l-state-indicators__alert-no-lad t-object-alert t-alert-unsynced icon-alert-triangle"
 | 
			
		||||
                          title="This plot is not currently displaying the latest data. Resume to view latest data."
 | 
			
		||||
                    ></span>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <mct-ticks v-show="gridLines && !options.compact"
 | 
			
		||||
@@ -85,8 +90,8 @@
 | 
			
		||||
                        >
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="c-button-set c-button-set--strip-h"
 | 
			
		||||
                         :disabled="!plotHistory.length"
 | 
			
		||||
                    <div v-if="plotHistory.length"
 | 
			
		||||
                         class="c-button-set c-button-set--strip-h"
 | 
			
		||||
                    >
 | 
			
		||||
                        <button class="c-button icon-arrow-left"
 | 
			
		||||
                                title="Restore previous pan/zoom"
 | 
			
		||||
@@ -99,6 +104,22 @@
 | 
			
		||||
                        >
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div v-if="isRealTime"
 | 
			
		||||
                         class="c-button-set c-button-set--strip-h"
 | 
			
		||||
                    >
 | 
			
		||||
                        <button v-if="!isFrozen"
 | 
			
		||||
                                class="c-button icon-pause"
 | 
			
		||||
                                title="Pause incoming real-time data"
 | 
			
		||||
                                @click="pause()"
 | 
			
		||||
                        >
 | 
			
		||||
                        </button>
 | 
			
		||||
                        <button v-if="isFrozen"
 | 
			
		||||
                                class="c-button icon-arrow-right pause-play is-paused"
 | 
			
		||||
                                title="Resume displaying real-time data"
 | 
			
		||||
                                @click="play()"
 | 
			
		||||
                        >
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <!--Cursor guides-->
 | 
			
		||||
@@ -186,10 +207,14 @@ export default {
 | 
			
		||||
            xKeyOptions: [],
 | 
			
		||||
            config: {},
 | 
			
		||||
            pending: 0,
 | 
			
		||||
            isRealTime: this.openmct.time.clock() !== undefined,
 | 
			
		||||
            loaded: false
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
        isFrozen() {
 | 
			
		||||
            return this.config.xAxis.get('frozen') === true && this.config.yAxis.get('frozen') === true;
 | 
			
		||||
        },
 | 
			
		||||
        plotLegendPositionClass() {
 | 
			
		||||
            return `plot-legend-${this.config.legend.get('position')}`;
 | 
			
		||||
        },
 | 
			
		||||
@@ -227,6 +252,7 @@ export default {
 | 
			
		||||
            'configuration.filters',
 | 
			
		||||
            this.updateFiltersAndResubscribe
 | 
			
		||||
        );
 | 
			
		||||
        this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.updateStatus);
 | 
			
		||||
 | 
			
		||||
        this.openmct.objectViews.on('clearData', this.clearData);
 | 
			
		||||
        this.followTimeConductor();
 | 
			
		||||
@@ -243,6 +269,7 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        followTimeConductor() {
 | 
			
		||||
            this.openmct.time.on('clock', this.updateRealTime);
 | 
			
		||||
            this.openmct.time.on('bounds', this.updateDisplayBounds);
 | 
			
		||||
            this.synchronized(true);
 | 
			
		||||
        },
 | 
			
		||||
@@ -371,6 +398,9 @@ export default {
 | 
			
		||||
            const displayRange = series.getDisplayRange(xKey);
 | 
			
		||||
            this.config.xAxis.set('range', displayRange);
 | 
			
		||||
        },
 | 
			
		||||
        updateRealTime(clock) {
 | 
			
		||||
            this.isRealTime = clock !== undefined;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
       * Track latest display bounds.  Forces update when not receiving ticks.
 | 
			
		||||
@@ -424,19 +454,28 @@ export default {
 | 
			
		||||
       * displays can update accordingly.
 | 
			
		||||
       */
 | 
			
		||||
        synchronized(value) {
 | 
			
		||||
            const isLocalClock = this.openmct.time.clock();
 | 
			
		||||
 | 
			
		||||
            if (typeof value !== 'undefined') {
 | 
			
		||||
                this._synchronized = value;
 | 
			
		||||
                const isUnsynced = !value && this.openmct.time.clock();
 | 
			
		||||
                const domainObject = this.openmct.legacyObject(this.domainObject);
 | 
			
		||||
                if (domainObject.getCapability('status')) {
 | 
			
		||||
                    domainObject.getCapability('status')
 | 
			
		||||
                        .set('timeconductor-unsynced', isUnsynced);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const isUnsynced = isLocalClock && !value;
 | 
			
		||||
                this.setStatus(isUnsynced);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return this._synchronized;
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        setStatus(isNotInSync) {
 | 
			
		||||
            const outOfSync = isNotInSync === true
 | 
			
		||||
                || this.isFrozen === true;
 | 
			
		||||
            if (outOfSync === true) {
 | 
			
		||||
                this.openmct.status.set(this.domainObject.identifier, 'timeconductor-unsynced');
 | 
			
		||||
            } else {
 | 
			
		||||
                this.openmct.status.set(this.domainObject.identifier, '');
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        initCanvas() {
 | 
			
		||||
            if (this.canvas) {
 | 
			
		||||
                this.stopListening(this.canvas);
 | 
			
		||||
@@ -729,7 +768,8 @@ export default {
 | 
			
		||||
            const ZOOM_AMT = 0.1;
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
 | 
			
		||||
            if (!this.positionOverPlot) {
 | 
			
		||||
            if (event.wheelDelta === undefined
 | 
			
		||||
                || !this.positionOverPlot) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -847,11 +887,13 @@ export default {
 | 
			
		||||
        freeze() {
 | 
			
		||||
            this.config.yAxis.set('frozen', true);
 | 
			
		||||
            this.config.xAxis.set('frozen', true);
 | 
			
		||||
            this.setStatus();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        clear() {
 | 
			
		||||
            this.config.yAxis.set('frozen', false);
 | 
			
		||||
            this.config.xAxis.set('frozen', false);
 | 
			
		||||
            this.setStatus();
 | 
			
		||||
            this.plotHistory = [];
 | 
			
		||||
            this.userViewportChangeEnd();
 | 
			
		||||
        },
 | 
			
		||||
@@ -881,6 +923,14 @@ export default {
 | 
			
		||||
            this.config.series.models[0].emit('change:yKey', yKey);
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        pause() {
 | 
			
		||||
            this.freeze();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        play() {
 | 
			
		||||
            this.clear();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        destroy() {
 | 
			
		||||
            configStore.deleteStore(this.config.id);
 | 
			
		||||
 | 
			
		||||
@@ -894,8 +944,16 @@ export default {
 | 
			
		||||
                this.filterObserver();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this.removeStatusListener) {
 | 
			
		||||
                this.removeStatusListener();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.openmct.time.off('clock', this.updateRealTime);
 | 
			
		||||
            this.openmct.time.off('bounds', this.updateDisplayBounds);
 | 
			
		||||
            this.openmct.objectViews.off('clearData', this.clearData);
 | 
			
		||||
        },
 | 
			
		||||
        updateStatus(status) {
 | 
			
		||||
            this.$emit('statusUpdated', status);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@
 | 
			
		||||
 | 
			
		||||
    <div ref="plotContainer"
 | 
			
		||||
         class="l-view-section u-style-receiver js-style-receiver"
 | 
			
		||||
         :class="{'s-status-timeconductor-unsynced': status && status === 'timeconductor-unsynced'}"
 | 
			
		||||
    >
 | 
			
		||||
        <div v-show="!!loading"
 | 
			
		||||
             class="c-loading--overlay loading"
 | 
			
		||||
@@ -64,6 +65,7 @@
 | 
			
		||||
                  :cursor-guide="cursorGuide"
 | 
			
		||||
                  :options="options"
 | 
			
		||||
                  @loadingUpdated="loadingUpdated"
 | 
			
		||||
                  @statusUpdated="setStatus"
 | 
			
		||||
        />
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -94,7 +96,8 @@ export default {
 | 
			
		||||
            // hideExportButtons: false
 | 
			
		||||
            cursorGuide: false,
 | 
			
		||||
            gridLines: !this.options.compact,
 | 
			
		||||
            loading: false
 | 
			
		||||
            loading: false,
 | 
			
		||||
            status: ''
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
@@ -131,6 +134,9 @@ export default {
 | 
			
		||||
 | 
			
		||||
        toggleGridLines() {
 | 
			
		||||
            this.gridLines = !this.gridLines;
 | 
			
		||||
        },
 | 
			
		||||
        setStatus(status) {
 | 
			
		||||
            this.status = status;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -313,6 +313,46 @@ describe("the plugin", function () {
 | 
			
		||||
            expect(options[0].value).toBe("Some attribute");
 | 
			
		||||
            expect(options[1].value).toBe("Another attribute");
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('hides the pause and play controls', () => {
 | 
			
		||||
            let pauseEl = element.querySelectorAll(".c-button-set .icon-pause");
 | 
			
		||||
            let playEl = element.querySelectorAll(".c-button-set .icon-arrow-right");
 | 
			
		||||
            expect(pauseEl.length).toBe(0);
 | 
			
		||||
            expect(playEl.length).toBe(0);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        describe('pause and play controls', () => {
 | 
			
		||||
            beforeEach(() => {
 | 
			
		||||
                openmct.time.clock('local', {
 | 
			
		||||
                    start: -1000,
 | 
			
		||||
                    end: 100
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Vue.nextTick();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('shows the pause controls', (done) => {
 | 
			
		||||
                Vue.nextTick(() => {
 | 
			
		||||
                    let pauseEl = element.querySelectorAll(".c-button-set .icon-pause");
 | 
			
		||||
                    expect(pauseEl.length).toBe(1);
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it('shows the play control if plot is paused', (done) => {
 | 
			
		||||
                let pauseEl = element.querySelector(".c-button-set .icon-pause");
 | 
			
		||||
                const clickEvent = createMouseEvent("click");
 | 
			
		||||
 | 
			
		||||
                pauseEl.dispatchEvent(clickEvent);
 | 
			
		||||
                Vue.nextTick(() => {
 | 
			
		||||
                    let playEl = element.querySelectorAll(".c-button-set .is-paused");
 | 
			
		||||
                    expect(playEl.length).toBe(1);
 | 
			
		||||
                    done();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe("The stacked plot view", () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,7 @@ export default {
 | 
			
		||||
 | 
			
		||||
            const onTickWidthChange = this.onTickWidthChange;
 | 
			
		||||
            const loadingUpdated = this.loadingUpdated;
 | 
			
		||||
            const setStatus = this.setStatus;
 | 
			
		||||
 | 
			
		||||
            const openmct = this.openmct;
 | 
			
		||||
            const object = this.object;
 | 
			
		||||
@@ -111,17 +112,23 @@ export default {
 | 
			
		||||
                    return {
 | 
			
		||||
                        ...getProps(),
 | 
			
		||||
                        onTickWidthChange,
 | 
			
		||||
                        loadingUpdated
 | 
			
		||||
                        loadingUpdated,
 | 
			
		||||
                        setStatus
 | 
			
		||||
                    };
 | 
			
		||||
                },
 | 
			
		||||
                template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver"><div v-show="!!loading" class="c-loading--overlay loading"></div><mct-plot :grid-lines="gridLines" :cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :options="options" @plotTickWidth="onTickWidthChange" @loadingUpdated="loadingUpdated"/></div>'
 | 
			
		||||
                template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver" :data-status="status" :class="{\'s-status-timeconductor-unsynced\': status && status === \'timeconductor-unsynced\'}"><div v-show="!!loading" class="c-loading--overlay loading"></div><mct-plot :grid-lines="gridLines" :cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :options="options" @plotTickWidth="onTickWidthChange" @statusUpdated="setStatus" @loadingUpdated="loadingUpdated"/></div>'
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        onTickWidthChange() {
 | 
			
		||||
            this.$emit('plotTickWidth', ...arguments);
 | 
			
		||||
        },
 | 
			
		||||
        setStatus(status) {
 | 
			
		||||
            this.status = status;
 | 
			
		||||
            this.updateComponentProp('status', status);
 | 
			
		||||
        },
 | 
			
		||||
        loadingUpdated(loaded) {
 | 
			
		||||
            this.loading = loaded;
 | 
			
		||||
            this.updateComponentProp('loading', loaded);
 | 
			
		||||
        },
 | 
			
		||||
        getProps() {
 | 
			
		||||
            return {
 | 
			
		||||
@@ -129,7 +136,8 @@ export default {
 | 
			
		||||
                cursorGuide: this.cursorGuide,
 | 
			
		||||
                plotTickWidth: this.plotTickWidth,
 | 
			
		||||
                loading: this.loading,
 | 
			
		||||
                options: this.options
 | 
			
		||||
                options: this.options,
 | 
			
		||||
                status: this.status
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -638,6 +638,16 @@
 | 
			
		||||
    box-shadow: $shdw;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@mixin smallerControlButtons() {
 | 
			
		||||
    .c-click-icon,
 | 
			
		||||
    .c-button,
 | 
			
		||||
    .c-icon-button {
 | 
			
		||||
        // Shrink buttons a bit when they appear in containers
 | 
			
		||||
        font-size: 0.9em;
 | 
			
		||||
        padding: 4px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@mixin wrappedInput() {
 | 
			
		||||
    // An input that is wrapped. Optionally includes a __label or icon element.
 | 
			
		||||
    // Based on .c-search.
 | 
			
		||||
 
 | 
			
		||||
@@ -129,14 +129,7 @@
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .c-click-icon,
 | 
			
		||||
    .c-button,
 | 
			
		||||
    .c-icon-button {
 | 
			
		||||
        // Shrink buttons a bit when they appear in a frame
 | 
			
		||||
        border-radius: $smallCr !important;
 | 
			
		||||
        font-size: 0.9em;
 | 
			
		||||
        padding: 5px;
 | 
			
		||||
    }
 | 
			
		||||
    @include smallerControlButtons;
 | 
			
		||||
 | 
			
		||||
    &.has-complex-content {
 | 
			
		||||
        > .c-so-view__view-large { display: block; }
 | 
			
		||||
 
 | 
			
		||||
@@ -22,5 +22,7 @@
 | 
			
		||||
        .c-plan {
 | 
			
		||||
            display: contents;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @include smallerControlButtons;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user