Merge pull request #955 from nasa/timeline-zoom-936
[Timeline] Improve zoom behaviors
This commit is contained in:
@@ -32,16 +32,26 @@ define(
|
||||
var zoomLevels = ZOOM_CONFIGURATION.levels || [1000],
|
||||
zoomIndex = Math.floor(zoomLevels.length / 2),
|
||||
tickWidth = ZOOM_CONFIGURATION.width || 200,
|
||||
bounds = { x: 0, width: tickWidth },
|
||||
duration = 86400000; // Default duration in view
|
||||
|
||||
// Round a duration to a larger value, to ensure space for editing
|
||||
function roundDuration(value) {
|
||||
// Ensure there's always an extra day or so
|
||||
var sz = zoomLevels[zoomLevels.length - 1];
|
||||
var tickCount = bounds.width / tickWidth,
|
||||
sz = zoomLevels[zoomLevels.length - 1] * tickCount;
|
||||
value *= 1.25; // Add 25% padding to start
|
||||
return Math.ceil(value / sz) * sz;
|
||||
}
|
||||
|
||||
function toMillis(pixels) {
|
||||
return (pixels / tickWidth) * zoomLevels[zoomIndex];
|
||||
}
|
||||
|
||||
function toPixels(millis) {
|
||||
return tickWidth * millis / zoomLevels[zoomIndex];
|
||||
}
|
||||
|
||||
// Get/set zoom level
|
||||
function setZoomLevel(level) {
|
||||
if (!isNaN(level)) {
|
||||
@@ -53,20 +63,27 @@ define(
|
||||
}
|
||||
}
|
||||
|
||||
// Persist current zoom level
|
||||
function storeZoom() {
|
||||
var isEditMode = $scope.commit &&
|
||||
$scope.domainObject &&
|
||||
$scope.domainObject.hasCapability('editor') &&
|
||||
$scope.domainObject.getCapability('editor').inEditContext();
|
||||
if (isEditMode) {
|
||||
$scope.configuration = $scope.configuration || {};
|
||||
$scope.configuration.zoomLevel = zoomIndex;
|
||||
$scope.commit();
|
||||
function initializeZoomFromTimespan(timespan) {
|
||||
var timelineDuration = timespan.getDuration();
|
||||
zoomIndex = 0;
|
||||
while (toMillis(bounds.width) < timelineDuration &&
|
||||
zoomIndex < zoomLevels.length - 1) {
|
||||
zoomIndex += 1;
|
||||
}
|
||||
bounds.x = toPixels(timespan.getStart());
|
||||
}
|
||||
|
||||
function initializeZoom() {
|
||||
if ($scope.domainObject) {
|
||||
$scope.domainObject.useCapability('timespan')
|
||||
.then(initializeZoomFromTimespan);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch("configuration.zoomLevel", setZoomLevel);
|
||||
$scope.$watch("scroll", function (scroll) {
|
||||
bounds = scroll;
|
||||
});
|
||||
$scope.$watch("domainObject", initializeZoom);
|
||||
|
||||
return {
|
||||
/**
|
||||
@@ -83,27 +100,29 @@ define(
|
||||
zoom: function (amount) {
|
||||
// Update the zoom level if called with an argument
|
||||
if (arguments.length > 0 && !isNaN(amount)) {
|
||||
var center = this.toMillis(bounds.x + bounds.width / 2);
|
||||
setZoomLevel(zoomIndex + amount);
|
||||
storeZoom(zoomIndex);
|
||||
bounds.x = this.toPixels(center) - bounds.width / 2;
|
||||
}
|
||||
return zoomLevels[zoomIndex];
|
||||
},
|
||||
/**
|
||||
* Set the zoom level to fit the bounds of the timeline
|
||||
* being viewed.
|
||||
*/
|
||||
fit: initializeZoom,
|
||||
/**
|
||||
* Get the width, in pixels, of a specific time duration at
|
||||
* the current zoom level.
|
||||
* @returns {number} the number of pixels
|
||||
*/
|
||||
toPixels: function (millis) {
|
||||
return tickWidth * millis / zoomLevels[zoomIndex];
|
||||
},
|
||||
toPixels: toPixels,
|
||||
/**
|
||||
* Get the time duration, in milliseconds, occupied by the
|
||||
* width (specified in pixels) at the current zoom level.
|
||||
* @returns {number} the number of pixels
|
||||
*/
|
||||
toMillis: function (pixels) {
|
||||
return (pixels / tickWidth) * zoomLevels[zoomIndex];
|
||||
},
|
||||
toMillis: toMillis,
|
||||
/**
|
||||
* Get or set the current displayed duration. If used as a
|
||||
* setter, this will typically be rounded up to ensure extra
|
||||
|
||||
Reference in New Issue
Block a user