Merge pull request #1699 from nasa/imagery-issue-1676

Imagery issue #1676
This commit is contained in:
Pete Richards 2017-09-12 11:28:40 -07:00 committed by GitHub
commit 54b975f242
8 changed files with 107 additions and 63 deletions

View File

@ -21,7 +21,7 @@
*****************************************************************************/
/************************** FEATURES */
$enableImageryThumbs: false; // Set to true if historical imagery thumbnails are supported
$enableImageryThumbs: true; // Set to true if historical imagery thumbnails are supported
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
$bodyMargin: 10px;
@ -82,7 +82,7 @@ $tabularTdPadTB: 2px;
/*************** Imagery */
$imageMainControlBarH: 25px;
$imageThumbsD: 120px;
$imageThumbsWrapperH: $imageThumbsD * 1.4;
$imageThumbsWrapperH: 155px;
$imageThumbPad: 1px;
/*************** Ticks */
$ticksH: 25px;

View File

@ -9,7 +9,6 @@
@if $enableImageryThumbs == true {
bottom: $interiorMargin*2 + $imageThumbsWrapperH;
}
min-height: 100px;
min-width: 150px;
.l-image-main {
background-color: $colorPlotBg;
@ -22,7 +21,9 @@
.l-image-thumbs-wrapper {
top: auto;
height: $imageThumbsWrapperH;
min-height: $imageThumbsWrapperH;
max-height: 60%;
box-sizing: border-box;
}
.l-date,
@ -82,9 +83,8 @@
/*************************************** THUMBS */
.l-image-thumbs-wrapper {
//@include test(green);
overflow-x: auto;
overflow-y: hidden;
overflow-x: hidden;
overflow-y: auto;
padding-bottom: $interiorMargin;
white-space: nowrap;
}
@ -92,8 +92,17 @@
.l-image-thumb-item {
@include transition(background-color, 0.25s);
box-sizing: border-box;
cursor: pointer;
direction: ltr;
display: inline-block;
float: left;
font-size: 0.8em;
padding: 1px;
position: relative;
margin-left: $interiorMarginSm;
position: relative;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
.l-thumb,
.l-date,
.l-time {
@ -103,14 +112,7 @@
.l-time {
padding: 2px 3px;
}
cursor: pointer;
direction: ltr;
display: inline-block;
font-size: 0.8em;
margin-left: $interiorMarginSm;
text-align: left;
width: $imageThumbsD + $imageThumbPad*2;
white-space: normal;
&:hover {
background: $colorThumbHoverBg;
.l-date,
@ -184,7 +186,8 @@
/*************************************** WHEN IN FRAME */
.frame .t-imagery {
.l-image-main-wrapper {
bottom: 0;
bottom: 0 !important;
height: 100% !important;
.l-image-main-controlbar {
font-size: 0.7em;
}
@ -194,7 +197,8 @@
}
}
}
.l-image-thumbs-wrapper {
.l-image-thumbs-wrapper,
mct-splitter {
display: none;
}
}

View File

@ -117,9 +117,7 @@ define(
// Apply styles to child elements
function updateChildren(children) {
if (alias) {
position = userWidthPreference || position;
}
position = userWidthPreference || position;
// Pick out correct elements to update, flowing from
// selected anchor edge.
@ -182,7 +180,9 @@ define(
}
function setUserWidthPreference(value) {
userWidthPreference = value;
if (alias) {
userWidthPreference = value;
}
}
function persistToLocalStorage(value) {

View File

@ -25,14 +25,12 @@ define([
"./src/controllers/ImageryController",
"./src/directives/MCTBackgroundImage",
"text!./res/templates/imagery.html",
"text!./res/templates/imageryTimeline.html",
'legacyRegistry'
], function (
ImageryViewPolicy,
ImageryController,
MCTBackgroundImage,
imageryTemplate,
imageryTimelineTemplate,
legacyRegistry
) {
@ -50,17 +48,6 @@ define([
"telemetry"
],
"editable": false
},
{
"name": "Historical Imagery",
"key": "historical-imagery",
"cssClass": "icon-image",
"template": imageryTimelineTemplate,
"priority": "preferred",
"needs": [
"telemetry"
],
"editable": false
}
],
"policies": [

View File

@ -1,5 +1,6 @@
<div class="t-imagery" ng-controller="ImageryController as imagery">
<div class="l-image-main-wrapper l-flex-col"
<mct-split-pane class='abs' anchor="bottom" alias="imagery">
<div class="split-pane-component l-image-main-wrapper l-flex-col"
ng-mouseenter="showLocalControls = true;"
ng-mouseleave="showLocalControls = false;">
<div class="l-local-controls s-local-controls s-wrapper-transluc l-flex-row"
@ -55,4 +56,14 @@
</div>
</div>
</div>
<mct-splitter></mct-splitter>
<div class="split-pane-component l-image-thumbs-wrapper">
<div class="l-image-thumb-item" ng-class="{selected: image.selected}" ng-repeat="image in imageHistory track by $index"
ng-click="imagery.setSelectedImage(image)" ng-init="imagery.scrollToBottom()">
<img class="l-thumb"
ng-src={{imagery.getImageUrl(image)}}>
<div class="l-time">{{imagery.getTime(image)}}</div>
</div>
</div>
</mct-split-pane>
</div>

View File

@ -1,8 +0,0 @@
<div class="l-image-thumbs-wrapper" ng-controller="ImageryController as imagery">
<div class="l-image-thumb-item" ng-repeat="image in imageHistory track by $index">
<img class="l-thumb" ng-init="imagery.scrollToRight()"
ng-src={{imagery.getImageUrl(image)}} >
<div class="l-time">{{imagery.getTime(image)}}</div>
</div>
</div>

View File

@ -48,9 +48,8 @@ define(
this.zone = "";
this.imageUrl = "";
this.requestCount = 0;
this.scrollable = $(element[0]);
this.scrollable = $(".l-image-thumbs-wrapper");
this.autoScroll = openmct.time.clock() ? true : false;
this.$scope.imageHistory = [];
this.$scope.filters = {
brightness: 100,
@ -63,6 +62,7 @@ define(
this.updateHistory = this.updateHistory.bind(this);
this.onBoundsChange = this.onBoundsChange.bind(this);
this.onScroll = this.onScroll.bind(this);
this.setSelectedImage = this.setSelectedImage.bind(this);
this.subscribe(this.$scope.domainObject);
@ -80,10 +80,10 @@ define(
var metadata = this.openmct
.telemetry
.getMetadata(this.domainObject);
var timeKey = this.openmct.time.timeSystem().key;
this.timeKey = this.openmct.time.timeSystem().key;
this.timeFormat = this.openmct
.telemetry
.getValueFormatter(metadata.value(timeKey));
.getValueFormatter(metadata.value(this.timeKey));
this.imageFormat = this.openmct
.telemetry
.getValueFormatter(metadata.valuesForHints(['image'])[0]);
@ -161,7 +161,7 @@ define(
/**
* Updates displayable values to match those of the most
* recently recieved datum.
* recently received datum.
* @param {object} [datum] the datum
* @private
*/
@ -170,7 +170,6 @@ define(
this.nextDatum = datum;
return;
}
this.time = this.timeFormat.format(datum);
this.imageUrl = this.imageFormat.format(datum);
@ -185,8 +184,7 @@ define(
ImageryController.prototype.updateHistory = function (datum) {
if (this.$scope.imageHistory.length === 0 ||
!_.isEqual(this.$scope.imageHistory.slice(-1)[0], datum)) {
var index = _.sortedIndex(this.$scope.imageHistory, datum, 'utc');
var index = _.sortedIndex(this.$scope.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
this.$scope.imageHistory.splice(index, 0, datum);
return true;
}
@ -196,8 +194,12 @@ define(
ImageryController.prototype.onScroll = function (event) {
this.$window.requestAnimationFrame(function () {
var thumbnailWrapperHeight = this.scrollable[0].offsetHeight;
var thumbnailWrapperWidth = this.scrollable[0].offsetWidth;
if (this.scrollable[0].scrollLeft <
(this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - 20) {
(this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - (thumbnailWrapperWidth) ||
this.scrollable[0].scrollTop <
(this.scrollable[0].scrollHeight - this.scrollable[0].clientHeight) - (thumbnailWrapperHeight)) {
this.autoScroll = false;
} else {
this.autoScroll = true;
@ -205,12 +207,16 @@ define(
}.bind(this));
};
ImageryController.prototype.scrollToRight = function () {
/**
* Force history imagery div to scroll to bottom.
*/
ImageryController.prototype.scrollToBottom = function () {
if (this.autoScroll) {
this.scrollable[0].scrollLeft = this.scrollable[0].scrollWidth;
this.scrollable[0].scrollTop = this.scrollable[0].scrollHeight;
}
};
/**
* Get the time portion (hours, minutes, seconds) of the
* timestamp associated with the incoming image telemetry
@ -243,16 +249,38 @@ define(
* @returns {boolean} the current state
*/
ImageryController.prototype.paused = function (state) {
if (arguments.length > 0 && state !== this.isPaused) {
this.isPaused = state;
if (this.nextDatum) {
this.updateValues(this.nextDatum);
delete this.nextDatum;
}
if (arguments.length > 0 && state !== this.isPaused) {
this.unselectAllImages();
this.isPaused = state;
if (this.nextDatum) {
this.updateValues(this.nextDatum);
delete this.nextDatum;
}
return this.isPaused;
};
this.autoScroll = true;
}
return this.isPaused;
};
/**
* Set the selected image on the state for the large imagery div to use.
* @param {object} [image] the image object to get url from.
*/
ImageryController.prototype.setSelectedImage = function (image) {
this.imageUrl = this.getImageUrl(image);
this.time = this.getTime(image);
this.paused(true);
this.unselectAllImages();
image.selected = true;
};
/**
* Loop through the history imagery data to set all images to unselected.
*/
ImageryController.prototype.unselectAllImages = function () {
for (var i = 0; i < this.$scope.imageHistory.length; i++) {
this.$scope.imageHistory[i].selected = false;
}
};
return ImageryController;
}
);

View File

@ -226,6 +226,28 @@ define(
expect(controller.updateHistory(mockDatum)).toBe(false);
expect(controller.updateHistory(mockDatum)).toBe(false);
});
describe("user clicks on imagery thumbnail", function () {
var mockDatum = { utc: 1434600258123, url: 'some/url', selected: false};
it("pauses and adds selected class to imagery thumbnail", function () {
controller.setSelectedImage(mockDatum);
expect(controller.paused()).toBeTruthy();
expect(mockDatum.selected).toBeTruthy();
});
it("unselects previously selected image", function () {
$scope.imageHistory = [{ utc: 1434600258123, url: 'some/url', selected: true}];
controller.unselectAllImages();
expect($scope.imageHistory[0].selected).toBeFalsy();
});
it("updates larger image url and time", function () {
controller.setSelectedImage(mockDatum);
expect(controller.getImageUrl()).toEqual(controller.getImageUrl(mockDatum));
expect(controller.getTime()).toEqual(controller.timeFormat.format(mockDatum.utc));
});
});
});
it("initially shows an empty string for date/time", function () {