Skip to content

Commit

Permalink
[Time Conductor] merged from open1182
Browse files Browse the repository at this point in the history
  • Loading branch information
akhenry committed Sep 30, 2016
1 parent 22da348 commit 5cd0c8a
Show file tree
Hide file tree
Showing 13 changed files with 201 additions and 51 deletions.
32 changes: 32 additions & 0 deletions platform/commonUI/formats/src/UTCTimeFormat.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,38 @@ define([
})[0][0];
}

UTCTimeFormat.prototype.timeUnits = function (timeRange) {
var momentified = moment.duration(timeRange);
return [
["Decades", function (r) {
return r.years() > 15;
}],
["Years", function (r) {
return r.years() > 1;
}],
["Months", function (r) {
return r.years() === 1 || r.months() > 1;
}],
["Days", function (r) {
return r.months() === 1 || r.days() > 1;
}],
["Hours", function (r) {
return r.days() === 1 || r.hours() > 1;
}],
["Minutes", function (r) {
return r.hours() === 1 || r.minutes() > 1;
}],
["Seconds", function (r) {
return r.minutes() === 1 || r.seconds() > 1;
}],
["Milliseconds", function (r) {
return true;
}]
].filter(function (row){
return row[1](momentified);
})[0][0];
};

/**
*
* @param value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ define(
ConductorRepresenter.prototype.destroy = function destroy() {
this.conductor.off("bounds", this.boundsListener);
this.conductor.off("timeSystem", this.timeSystemListener);
this.conductor.off("follow", this.followListener);
};

return ConductorRepresenter;
Expand Down
12 changes: 11 additions & 1 deletion platform/features/conductor-v2/conductor/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,17 @@ define([
"$window",
"timeConductor",
"timeConductorViewService",
"timeSystems[]"
"timeSystems[]",
"formatService"
]
},
{
"key": "ConductorAxisController",
"implementation": ConductorAxisController,
"depends": [
"timeConductor",
"formatService",
"timeConductorViewService"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,13 @@
.l-time-conductor-zoom-w {
@include justify-content(flex-end);
.time-conductor-zoom {
display: none; // TEMP per request from Andrew 8/1/16
//display: none; // TEMP per request from Andrew 8/1/16
height: $r3H;
min-width: 100px;
width: 20%;
}
.time-conductor-zoom-current-range {
display: none; // TEMP per request from Andrew 8/1/16
//display: none; // TEMP per request from Andrew 8/1/16
color: $colorTick;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,15 @@
</mct-control>
<!-- Zoom control -->
<div class="l-time-conductor-zoom-w grows flex-elem l-flex-row">
<span class="time-conductor-zoom-current-range flex-elem flex-fixed holder"></span>
<input class="time-conductor-zoom flex-elem" type="range" />
<span
class="time-conductor-zoom-current-range flex-elem flex-fixed holder">{{timeUnits}}</span>
<input class="time-conductor-zoom flex-elem" type="range"
ng-model="currentZoom"
ng-mouseUp="tcController.zoomStop(currentZoom)"
ng-change="tcController.zoom(currentZoom)"
min="0.01"
step="0.01"
max="0.99" />
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,20 @@ define([], function () {
throw new Error('Not implemented');
};

/**
/***
*
* @typedef {object} TimeConductorZoom
* @property {number} min The largest time span that the time
* conductor can display in this time system
* @property {number} max The smallest time span that the time
* conductor can display in this time system
*
* @typedef {object} TimeSystemDefault
* @property {TimeConductorDeltas} deltas The deltas to apply by default
* when this time system is active. Applies to real-time modes only
* @property {TimeConductorBounds} bounds The bounds to apply by default
* when this time system is active
* @property {TimeConductorZoom} zoom Default min and max zoom levels
* @returns {TimeSystemDefault[]} At least one set of default values for
* this time system.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ define(
* labelled 'ticks'. It requires 'start' and 'end' integer values to
* be specified as attributes.
*/
function ConductorAxisController(conductor, formatService) {
function ConductorAxisController(conductor, formatService, conductorViewService) {
// Dependencies
this.d3 = d3;
this.formatService = formatService;
this.conductor = conductor;
this.conductorViewService = conductorViewService;

// Runtime properties (set by 'link' function)
this.target = undefined;
Expand All @@ -46,14 +47,22 @@ define(
this.initialized = false;
this.msPerPixel = undefined;

this.setScale = this.setScale.bind(this);
this.changeBounds = this.changeBounds.bind(this);
this.changeTimeSystem = this.changeTimeSystem.bind(this);

this.bounds = conductor.bounds();
this.timeSystem = conductor.timeSystem();

//Bind all class functions to 'this'
Object.keys(ConductorAxisController.prototype).filter(function (key) {
return typeof ConductorAxisController.prototype[key] === 'function';
}).forEach(function (key) {
this[key] = ConductorAxisController.prototype[key].bind(this);
}.bind(this));
}

ConductorAxisController.prototype.destroy = function () {
this.conductor.off('timeSystem', this.changeTimeSystem);
this.conductor.off('bounds', this.setScale);
};

ConductorAxisController.prototype.changeBounds = function (bounds) {
this.bounds = bounds;
if (this.initialized) {
Expand Down Expand Up @@ -129,18 +138,26 @@ define(

if (this.timeSystem !== undefined) {
this.changeTimeSystem(this.timeSystem);
this.setScale(this.bounds);
this.setScale();
}

//Respond to changes in conductor
this.conductor.on("timeSystem", this.changeTimeSystem);
this.conductor.on("bounds", this.changeBounds);

this.scope.$on("$destroy", this.destroy);

this.conductorViewService.on("zoom", this.zoom);
};

ConductorAxisController.prototype.panEnd = function () {
ConductorAxisController.prototype.panStop = function () {
//resync view bounds with time conductor bounds
this.conductor.bounds(this.bounds);
this.scope.$emit("pan-stop");
this.conductorViewService.emit("pan-stop");
};

ConductorAxisController.prototype.zoom = function (bounds) {
this.changeBounds(bounds);
};

ConductorAxisController.prototype.pan = function (delta) {
Expand All @@ -154,7 +171,7 @@ define(
end: end
};
this.setScale();
this.scope.$emit("pan", this.bounds);
this.conductorViewService.emit("pan", this.bounds);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ define([], function () {

template: '<div class="l-axis-holder" ' +
' mct-drag-down="axis.panStart()"' +
' mct-drag-up="axis.panEnd(delta)"' +
' mct-drag-up="axis.panStop(delta)"' +
' mct-drag="axis.pan(delta)"' +
' mct-resize="axis.resize()"></div>'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ define(['./MctConductorAxis'], function (MctConductorAxis) {
d3;

beforeEach(function () {
mockScope = {};
mockScope = jasmine.createSpyObj("scope", [
"$on"
]);

//Add some HTML elements
mockTarget = {
Expand All @@ -49,7 +51,8 @@ define(['./MctConductorAxis'], function (MctConductorAxis) {
mockConductor = jasmine.createSpyObj("conductor", [
"timeSystem",
"bounds",
"on"
"on",
"off"
]);
mockConductor.bounds.andReturn(mockBounds);

Expand Down Expand Up @@ -85,6 +88,13 @@ define(['./MctConductorAxis'], function (MctConductorAxis) {
expect(mockConductor.on).toHaveBeenCalledWith("bounds", directive.setScale);
});

it("on scope destruction, deregisters listeners", function () {
expect(mockScope.$on).toHaveBeenCalledWith("$destroy", directive.destroy);
directive.destroy();
expect(mockConductor.off).toHaveBeenCalledWith("timeSystem", directive.changeTimeSystem);
expect(mockConductor.off).toHaveBeenCalledWith("bounds", directive.setScale);
});

describe("when the time system changes", function () {
var mockTimeSystem;
var mockFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ define(
],
function (TimeConductorValidation) {

function TimeConductorController($scope, $window, timeConductor, conductorViewService, timeSystems) {
function TimeConductorController($scope, $window, timeConductor, conductorViewService, timeSystems, formatService) {

var self = this;

Expand All @@ -43,6 +43,7 @@ define(
this.conductor = timeConductor;
this.modes = conductorViewService.availableModes();
this.validation = new TimeConductorValidation(this.conductor);
this.formatService = formatService;

// Construct the provided time system definitions
this.timeSystems = timeSystems.map(function (timeSystemConstructor) {
Expand All @@ -53,9 +54,6 @@ define(
this.initializeScope();

this.conductor.on('bounds', this.setFormFromBounds);
this.conductor.on('follow', function (follow) {
$scope.followMode = follow;
});
this.conductor.on('timeSystem', this.changeTimeSystem);

// If no mode selected, select fixed as the default
Expand Down Expand Up @@ -100,14 +98,25 @@ define(

// Watch scope for selection of mode or time system by user
this.$scope.$watch('modeModel.selectedKey', this.setMode);
this.$scope.$on('pan', function (e, bounds) {
this.$scope.panning = true;
this.setFormFromBounds(bounds);
}.bind(this));
this.conductorViewService.on('pan', this.pan);

this.conductorViewService.on('pan-stop', this.panStop);

this.$scope.$on('$destroy', this.destroy);
};

TimeConductorController.prototype.destroy = function () {
this.conductor.off('bounds', this.setFormFromBounds);
this.conductor.off('timeSystem', this.changeTimeSystem);
};

this.$scope.$on('pan-stop', function () {
this.$scope.panning = false;
}.bind(this));
TimeConductorController.prototype.pan = function (bounds) {
this.$scope.panning = true;
this.setFormFromBounds(bounds);
};

TimeConductorController.prototype.panStop = function () {
this.$scope.panning = false;
};

/**
Expand All @@ -119,6 +128,10 @@ define(
TimeConductorController.prototype.setFormFromBounds = function (bounds) {
this.$scope.boundsModel.start = bounds.start;
this.$scope.boundsModel.end = bounds.end;

this.$scope.currentZoom = this.toSliderValue(bounds.end - bounds.start);
this.toTimeUnits(bounds.end - bounds.start);

if (!this.pendingUpdate) {
this.pendingUpdate = true;
this.$window.requestAnimationFrame(function () {
Expand Down Expand Up @@ -153,9 +166,12 @@ define(
* @private
*/
TimeConductorController.prototype.setFormFromTimeSystem = function (timeSystem) {
this.$scope.timeSystemModel.selected = timeSystem;
this.$scope.timeSystemModel.format = timeSystem.formats()[0];
this.$scope.timeSystemModel.deltaFormat = timeSystem.deltaFormat();
var timeSystemModel = this.$scope.timeSystemModel;
timeSystemModel.selected = timeSystem;
timeSystemModel.format = timeSystem.formats()[0];
timeSystemModel.deltaFormat = timeSystem.deltaFormat();
timeSystemModel.minZoom = timeSystem.defaults().zoom.min;
timeSystemModel.maxZoom = timeSystem.defaults().zoom.max;
};


Expand Down Expand Up @@ -242,6 +258,41 @@ define(
}
};

TimeConductorController.prototype.toSliderValue = function (timeSpan) {
var timeSystem = this.conductor.timeSystem();
if (timeSystem) {
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
var perc = timeSpan / (zoomDefaults.min - zoomDefaults.max);
return 1 - Math.pow(perc, 1 / 4);
}
};

TimeConductorController.prototype.toTimeSpan = function (sliderValue) {
var center = this.$scope.boundsModel.start +
((this.$scope.boundsModel.end - this.$scope.boundsModel.start) / 2);
var zoomDefaults = this.conductor.timeSystem().defaults().zoom;
var timeSpan = Math.pow((1 - sliderValue), 4) * (zoomDefaults.min - zoomDefaults.max);
return {start: center - timeSpan / 2, end: center + timeSpan / 2};
};

TimeConductorController.prototype.toTimeUnits = function (timeSpan) {
if (this.conductor.timeSystem()) {
var timeFormat = this.formatService.getFormat(this.conductor.timeSystem().formats()[0]);
this.$scope.timeUnits = timeFormat.timeUnits && timeFormat.timeUnits(timeSpan);
}
}

TimeConductorController.prototype.zoom = function(sliderValue) {
var bounds = this.toTimeSpan(sliderValue);
this.setFormFromBounds(bounds);
this.conductorViewService.emit("zoom", bounds);
};

TimeConductorController.prototype.zoomStop = function (sliderValue) {
var bounds = this.toTimeSpan(sliderValue);
this.conductor.bounds(bounds);
};

return TimeConductorController;
}
);
Loading

0 comments on commit 5cd0c8a

Please sign in to comment.