Created
April 14, 2015 18:58
-
-
Save esshka/6f737235c609459776a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | |
| Zoomator.directive("timeline", [ | |
| "$filter", "$document", "$window", "FactorComputate", function($filter, $document, $window, FactorComputate) { | |
| return { | |
| restrict: "EA", | |
| replace: true, | |
| template: "<div id='timeline' style='height:90px;'><svg style='height:100%;width:100%;'></svg></div>", | |
| scope: { | |
| selectedPeriodBegin: "=", | |
| selectedPeriodEnd: "=", | |
| fullPeriodBegin: "=", | |
| fullPeriodEnd: "=", | |
| iconsPath: "@", | |
| markerDatetime: "=", | |
| markerPosition: "=" | |
| }, | |
| link: function(scope, element) { | |
| /** | |
| * Snap svg plugin | |
| */ | |
| var BottomAxis, Label, Marker, Selector, Timeline, TopAxis, timeline; | |
| Snap.plugin(function(Snap, Element) { | |
| return Element.prototype.moveTo = function(x, y) { | |
| var diffx, diffy; | |
| diffx = this.getBBox().cx - x; | |
| diffy = this.getBBox().cy - y; | |
| return this.attr("transform", this.transform().local + ("" + (this.transform().local ? 'T' : 't') + (-diffx) + "," + (-diffy))); | |
| }; | |
| }); | |
| /** | |
| * timeline main class | |
| */ | |
| Timeline = (function() { | |
| function Timeline() { | |
| this.paper = Snap(angular.element('#timeline').find('svg')[0]); | |
| this.paper.selectAll('*').remove(); | |
| /** | |
| * detect timeline container width and height | |
| */ | |
| this.containerWidth = angular.element("#timeline").width(); | |
| this.containerHeight = angular.element("#timeline").height(); | |
| /** | |
| * initialize timeline components | |
| */ | |
| Snap.load(scope.iconsPath, (function(_this) { | |
| return function(icons) { | |
| _this.svgIcons = icons; | |
| _this.topAxis = new TopAxis(_this); | |
| _this.bottomAxis = new BottomAxis(_this); | |
| _this.selector = new Selector(_this); | |
| scope.markerDatetime = scope.selectedPeriodBegin + (scope.selectedPeriodEnd - scope.selectedPeriodBegin) / 2; | |
| scope.markerPosition = _this.bottomAxis.timestampToXPosition(scope.markerDatetime); | |
| _this.marker = new Marker(_this); | |
| return scope.$emit('timeline:ready'); | |
| }; | |
| })(this)); | |
| } | |
| /** | |
| * public | |
| */ | |
| Timeline.prototype.update = function() { | |
| var newx1, newx2; | |
| if (this.topAxis) { | |
| newx1 = this.topAxis.timestampToXPosition(scope.selectedPeriodBegin); | |
| newx2 = this.topAxis.timestampToXPosition(scope.selectedPeriodEnd); | |
| this.selector.update(newx1, newx2); | |
| this.bottomAxis.updateLabels(); | |
| return scope.$emit('timeline:ready'); | |
| } | |
| }; | |
| return Timeline; | |
| })(); | |
| TopAxis = (function() { | |
| function TopAxis(timeline) { | |
| this.timeline = timeline; | |
| this.paper = this.timeline.paper; | |
| this.duration = scope.fullPeriodEnd - scope.fullPeriodBegin; | |
| this.nodeClass = "t_axis"; | |
| this.strokeWidth = 2; | |
| this.margin = { | |
| left: 25, | |
| right: 25, | |
| top: 20 | |
| }; | |
| this.labels = []; | |
| this.minLabelsSpacing = 4; | |
| this.bigLabelsNumber = 10; | |
| this.length = this.timeline.containerWidth - this.margin.left - this.margin.right; | |
| this.labelsNumber = Math.ceil(this.length / this.minLabelsSpacing); | |
| this.bigLabelsSpacing = Math.ceil(this.labelsNumber / this.bigLabelsNumber); | |
| this.pixelMilliseconds = this.duration / this.length; | |
| this._fillLabels(); | |
| this._draw(); | |
| this._drawSideControls(); | |
| } | |
| TopAxis.prototype._drawSideControls = function() { | |
| var moversGroup; | |
| moversGroup = this.paper.group().attr({ | |
| "class": 'movers' | |
| }); | |
| this.lm = this.timeline.svgIcons.select("#to_left"); | |
| this.paper.append(this.lm); | |
| moversGroup.g(this.lm).attr({ | |
| "class": 'move-left' | |
| }).moveTo(0 + this.lm.getBBox().width / 2, this.margin.top * 3 / 4).click(this._leftShiftPeriod); | |
| this.rm = this.timeline.svgIcons.select("#to_right"); | |
| this.paper.append(this.rm); | |
| return moversGroup.g(this.rm).attr({ | |
| "class": 'move-right' | |
| }).moveTo(this.length - this.rm.getBBox().width / 2 + this.margin.right * 2, this.margin.top * 3 / 4).click(this._rightShiftPeriod); | |
| }; | |
| TopAxis.prototype._leftShiftPeriod = function() { | |
| var duration; | |
| duration = scope.selectedPeriodEnd - scope.selectedPeriodBegin; | |
| if (scope.selectedPeriodBegin - duration > scope.fullPeriodBegin) { | |
| scope.selectedPeriodEnd -= duration; | |
| return scope.selectedPeriodBegin -= duration; | |
| } | |
| }; | |
| TopAxis.prototype._rightShiftPeriod = function() { | |
| var duration; | |
| duration = scope.selectedPeriodEnd - scope.selectedPeriodBegin; | |
| if (scope.selectedPeriodEnd + duration < scope.fullPeriodEnd) { | |
| scope.selectedPeriodEnd += duration; | |
| return scope.selectedPeriodBegin += duration; | |
| } | |
| }; | |
| TopAxis.prototype._fillLabels = function() { | |
| _.times(this.labelsNumber, (function(_this) { | |
| return function(n) { | |
| var label, type, x; | |
| type = (function() { | |
| switch (false) { | |
| case !(n % this.bigLabelsSpacing === 0 && n !== 0 && n !== this.labelsNumber): | |
| return "big"; | |
| case n % 2 !== 0: | |
| return "medium"; | |
| default: | |
| return "small"; | |
| } | |
| }).call(_this); | |
| x = n * _this.minLabelsSpacing + _this.margin.left; | |
| label = new Label(_this, x, type); | |
| if (label !== void 0) { | |
| return _this.labels.push(label); | |
| } | |
| }; | |
| })(this)); | |
| return this.labels = _.compact(this.labels); | |
| }; | |
| TopAxis.prototype._draw = function() { | |
| this.tAxis = this.paper.g(this.paper.line(this.margin.left, this.margin.top, this.timeline.containerWidth - this.margin.right, this.margin.top).attr({ | |
| "class": "" + this.nodeClass | |
| })).attr({ | |
| "class": 'topaxis-group' | |
| }); | |
| return _.each(this.labels, (function(_this) { | |
| return function(l) { | |
| return l.draw(_this.tAxis); | |
| }; | |
| })(this)); | |
| }; | |
| /** | |
| * Public | |
| */ | |
| TopAxis.prototype.xPositionToTimestamp = function(x) { | |
| return scope.fullPeriodBegin + this.pixelMilliseconds * (x - this.margin.left); | |
| }; | |
| TopAxis.prototype.timestampToXPosition = function(ts) { | |
| return this.margin.left + (ts - scope.fullPeriodBegin) / this.pixelMilliseconds; | |
| }; | |
| return TopAxis; | |
| })(); | |
| BottomAxis = (function() { | |
| function BottomAxis(timeline) { | |
| this.timeline = timeline; | |
| this.updateLabels = __bind(this.updateLabels, this); | |
| this.paper = this.timeline.paper; | |
| this.duration = scope.selectedPeriodEnd - scope.selectedPeriodBegin; | |
| this.nodeClass = "b_axis"; | |
| this.strokeWidth = 4; | |
| this.margin = { | |
| top: this.timeline.containerHeight, | |
| left: 0, | |
| right: 0 | |
| }; | |
| this.labels = []; | |
| this.minLabelsSpacing = 4; | |
| this.bigLabelsNumber = 10; | |
| this.length = this.timeline.containerWidth; | |
| this.labelsNumber = Math.ceil(this.length / this.minLabelsSpacing); | |
| this.bigLabelsSpacing = Math.ceil(this.labelsNumber / this.bigLabelsNumber); | |
| this.pixelMilliseconds = this.duration / this.length; | |
| this._fillLabels(); | |
| this._draw(); | |
| } | |
| BottomAxis.prototype._fillLabels = function() { | |
| _.times(this.labelsNumber, (function(_this) { | |
| return function(n) { | |
| var label, type, x; | |
| type = (function() { | |
| switch (false) { | |
| case !(n % this.bigLabelsSpacing === 0 && n !== 0 && n !== this.labelsNumber): | |
| return "big"; | |
| case n % 2 !== 0: | |
| return "medium"; | |
| default: | |
| return "small"; | |
| } | |
| }).call(_this); | |
| x = n * _this.minLabelsSpacing; | |
| label = new Label(_this, x, type); | |
| if (label !== void 0) { | |
| return _this.labels.push(label); | |
| } | |
| }; | |
| })(this)); | |
| return this.labels = _.compact(this.labels); | |
| }; | |
| BottomAxis.prototype._draw = function() { | |
| this.tAxis = this.paper.g(this.paper.line(this.margin.left, this.margin.top, this.timeline.containerWidth - this.margin.right, this.margin.top).attr({ | |
| "class": "" + this.nodeClass | |
| })).attr({ | |
| "class": 'bottomaxis-group' | |
| }); | |
| return _.each(this.labels, (function(_this) { | |
| return function(l) { | |
| return l.draw(_this.tAxis); | |
| }; | |
| })(this)); | |
| }; | |
| BottomAxis.prototype._refreshCoeffs = function() { | |
| this.duration = scope.selectedPeriodEnd - scope.selectedPeriodBegin; | |
| return this.pixelMilliseconds = this.duration / this.length; | |
| }; | |
| /** | |
| * Public | |
| */ | |
| BottomAxis.prototype.xPositionToTimestamp = function(x) { | |
| return scope.selectedPeriodBegin + this.pixelMilliseconds * x; | |
| }; | |
| BottomAxis.prototype.timestampToXPosition = function(ts) { | |
| return (ts - scope.selectedPeriodBegin) / this.pixelMilliseconds; | |
| }; | |
| BottomAxis.prototype.updateLabels = function() { | |
| this._refreshCoeffs(); | |
| return _(this.labels).filter(function(label) { | |
| return label.type === 'big'; | |
| }).each((function(_this) { | |
| return function(label) { | |
| var d, t, ts; | |
| ts = _this.xPositionToTimestamp(label.x); | |
| d = "" + ($filter('date')(ts, 'dd MMMM yyyy')); | |
| t = "" + ($filter('date')(ts, 'HH:MM')); | |
| return label.updateText(d, t); | |
| }; | |
| })(this)); | |
| }; | |
| return BottomAxis; | |
| })(); | |
| Label = (function() { | |
| function Label(axis, x, type) { | |
| this.axis = axis; | |
| this.x = x; | |
| this.type = type; | |
| this.updateText = __bind(this.updateText, this); | |
| this.draw = __bind(this.draw, this); | |
| this.nodeClass = (function() { | |
| switch (false) { | |
| case !(this.axis instanceof TopAxis): | |
| return "t_mark"; | |
| case !(this.axis instanceof BottomAxis): | |
| return "b_mark"; | |
| } | |
| }).call(this); | |
| this.bigLabelClass = (function() { | |
| switch (false) { | |
| case !(this.axis instanceof TopAxis): | |
| return "axis_labels"; | |
| case !(this.axis instanceof BottomAxis): | |
| return "bt_axis_labels"; | |
| } | |
| }).call(this); | |
| this.bigTopLabelTextBottomOffset = 2; | |
| this.bigBottomLabelBottomDateOffset = 12; | |
| this.bigBottomLabelBottomTimeOffset = 2; | |
| this.labelHeight = (function() { | |
| switch (this.type) { | |
| case "big": | |
| return 8; | |
| case "medium": | |
| return 4; | |
| case "small": | |
| return 2; | |
| } | |
| }).call(this); | |
| this.text = this.axis.xPositionToTimestamp(this.x); | |
| } | |
| /** | |
| * public | |
| */ | |
| Label.prototype.draw = function(g) { | |
| if (this.type !== "big") { | |
| return g.add(this.axis.paper.line(this.x, this.axis.margin.top - this.axis.strokeWidth / 2, this.x, this.axis.margin.top - this.labelHeight - this.axis.strokeWidth / 2).attr({ | |
| "class": "" + this.nodeClass + " " + this.type | |
| })); | |
| } else { | |
| this.bigLabelGroup = this.axis.paper.g(this.axis.paper.line(this.x, this.axis.margin.top - this.axis.strokeWidth / 2, this.x, this.axis.margin.top - this.labelHeight - this.axis.strokeWidth / 2).attr({ | |
| "class": "" + this.nodeClass + " " + this.type | |
| })).attr({ | |
| "class": 'big-labels-group' | |
| }); | |
| if (this.axis instanceof TopAxis) { | |
| this.bigLabelGroup.add(this.axis.paper.text(this.x, this.axis.margin.top - this.labelHeight - this.bigTopLabelTextBottomOffset - this.axis.strokeWidth, ["" + ($filter('date')(this.text, 'dd MMMM yyyy'))]).attr({ | |
| "class": "" + this.bigLabelClass, | |
| textAnchor: 'middle' | |
| })); | |
| } else { | |
| this.dateText = this.axis.paper.text(this.x, this.axis.margin.top - this.labelHeight - this.bigBottomLabelBottomDateOffset - this.axis.strokeWidth, ["" + ($filter('date')(this.text, 'dd MMMM yyyy'))]).attr({ | |
| "class": "" + this.bigLabelClass, | |
| textAnchor: 'middle' | |
| }); | |
| this.bigLabelGroup.add(this.dateText); | |
| this.timeText = this.axis.paper.text(this.x, this.axis.margin.top - this.labelHeight - this.bigBottomLabelBottomTimeOffset - this.axis.strokeWidth, ["" + ($filter('date')(this.text, 'HH:MM'))]).attr({ | |
| "class": "" + this.bigLabelClass, | |
| textAnchor: 'middle' | |
| }); | |
| this.bigLabelGroup.add(this.timeText); | |
| } | |
| return g.add(this.bigLabelGroup); | |
| } | |
| }; | |
| Label.prototype.updateText = function(d, t) { | |
| this.dateText.node.textContent = d; | |
| return this.timeText.node.textContent = t; | |
| }; | |
| return Label; | |
| })(); | |
| Selector = (function() { | |
| function Selector(timeline) { | |
| this.timeline = timeline; | |
| this.translateRunner = __bind(this.translateRunner, this); | |
| this.updateMovement = __bind(this.updateMovement, this); | |
| this.saveOrigData = __bind(this.saveOrigData, this); | |
| this.rightRunnerMoveEnd = __bind(this.rightRunnerMoveEnd, this); | |
| this.rightRunnerMoveStart = __bind(this.rightRunnerMoveStart, this); | |
| this.rightRunnerMove = __bind(this.rightRunnerMove, this); | |
| this.leftRunnerMoveEnd = __bind(this.leftRunnerMoveEnd, this); | |
| this.leftRunnerMoveStart = __bind(this.leftRunnerMoveStart, this); | |
| this.leftRunnerMove = __bind(this.leftRunnerMove, this); | |
| this.endMove = __bind(this.endMove, this); | |
| this.startMove = __bind(this.startMove, this); | |
| this.move = __bind(this.move, this); | |
| this.paper = this.timeline.paper; | |
| this.begin = this.timeline.topAxis.timestampToXPosition(scope.selectedPeriodBegin); | |
| this.end = this.timeline.topAxis.timestampToXPosition(scope.selectedPeriodEnd); | |
| this.runnerWidth = 10; | |
| this._draw(); | |
| } | |
| Selector.prototype._draw = function() { | |
| this.line = this.paper.line(this.begin, 20, this.end, 20).attr({ | |
| "class": "range_selector", | |
| stroke: "#76b7e4", | |
| strokeWidth: 10 | |
| }).drag(this.move, this.startMove, this.endMove); | |
| this.tlBorder = this.paper.line(0, this.timeline.containerHeight - 60, this.begin, this.timeline.containerHeight - 60).attr({ | |
| "class": 'tl_border' | |
| }); | |
| this.trBorder = this.paper.line(this.end, this.timeline.containerHeight - 60, this.timeline.containerWidth, this.timeline.containerHeight - 60).attr({ | |
| "class": 'tr_border' | |
| }); | |
| this.paper.g(this.paper.line(0, this.timeline.containerHeight - 60, 0, this.timeline.containerHeight).attr({ | |
| "class": 'r_border' | |
| }), this.paper.line(this.timeline.containerWidth, this.timeline.containerHeight - 60, this.timeline.containerWidth, this.timeline.containerHeight).attr({ | |
| "class": 'l_border' | |
| })); | |
| this.rightRunner = this.timeline.svgIcons.select("#drag_right"); | |
| this.paper.append(this.rightRunner); | |
| this.rightRunner.moveTo(this.end + this.rightRunner.getBBox().width / 2, this.timeline.topAxis.margin.top + 2).drag(this.rightRunnerMove, this.rightRunnerMoveStart, this.rightRunnerMoveEnd); | |
| this.leftRunner = this.timeline.svgIcons.select("#drag_left"); | |
| this.paper.append(this.leftRunner); | |
| this.leftRunner.moveTo(this.begin - this.leftRunner.getBBox().width / 2, this.timeline.topAxis.margin.top + 2).drag(this.leftRunnerMove, this.leftRunnerMoveStart, this.leftRunnerMoveEnd); | |
| return this.controlGroup = this.timeline.topAxis.tAxis.add(this.line, this.leftRunner, this.rightRunner).attr({ | |
| "class": 'control-group' | |
| }); | |
| }; | |
| Selector.prototype.update = function(newx1, newx2) { | |
| this.begin = newx1; | |
| this.end = newx2; | |
| this.leftRunner.moveTo(newx1 - this.leftRunner.getBBox().width / 2, this.leftRunner.getBBox().cy); | |
| this.rightRunner.moveTo(newx2 + this.rightRunner.getBBox().width / 2, this.rightRunner.getBBox().cy); | |
| this.line.attr('x1', newx1); | |
| this.line.attr('x2', newx2); | |
| this.tlBorder.attr('x2', newx1); | |
| return this.trBorder.attr('x1', newx2); | |
| }; | |
| Selector.prototype.move = function(dx) { | |
| return this.updateMovement(this.line, dx); | |
| }; | |
| Selector.prototype.startMove = function(x) { | |
| return this.saveOrigData(); | |
| }; | |
| Selector.prototype.endMove = function(e) { | |
| var ex1, ex2; | |
| ex1 = this.line.attr("x1"); | |
| ex2 = this.line.attr("x2"); | |
| scope.selectedPeriodBegin = this.timeline.topAxis.xPositionToTimestamp(ex1); | |
| return scope.selectedPeriodEnd = this.timeline.topAxis.xPositionToTimestamp(ex2); | |
| }; | |
| Selector.prototype.leftRunnerMove = function(dx) { | |
| return this.updateMovement(this.leftRunner, dx); | |
| }; | |
| Selector.prototype.leftRunnerMoveStart = function(x) { | |
| return this.saveOrigData(); | |
| }; | |
| Selector.prototype.leftRunnerMoveEnd = function(e) { | |
| var ex1; | |
| ex1 = this.line.attr("x1"); | |
| return scope.selectedPeriodBegin = this.timeline.topAxis.xPositionToTimestamp(ex1); | |
| }; | |
| Selector.prototype.rightRunnerMove = function(dx) { | |
| return this.updateMovement(this.rightRunner, dx); | |
| }; | |
| Selector.prototype.rightRunnerMoveStart = function(x) { | |
| return this.saveOrigData(); | |
| }; | |
| Selector.prototype.rightRunnerMoveEnd = function(e) { | |
| var ex2; | |
| ex2 = this.line.attr("x2"); | |
| return scope.selectedPeriodEnd = this.timeline.topAxis.xPositionToTimestamp(ex2); | |
| }; | |
| Selector.prototype.saveOrigData = function() { | |
| this.line.data('ox1', this.line.attr("x1")); | |
| this.line.data('ox2', this.line.attr("x2")); | |
| this.leftRunner.data('origTransform', this.leftRunner.transform().local); | |
| this.rightRunner.data('origTransform', this.rightRunner.transform().local); | |
| this.leftRunner.data("origBBoxCx", this.leftRunner.getBBox().cx); | |
| this.rightRunner.data("origBBoxCx", this.rightRunner.getBBox().cx); | |
| this.leftRunner.data('ibb', this.leftRunner.getBBox()); | |
| return this.rightRunner.data('ibb', this.rightRunner.getBBox()); | |
| }; | |
| Selector.prototype.updateMovement = function(obj, dx) { | |
| var lim1, lim2, newx1, newx2; | |
| if (obj !== this.line) { | |
| this.translateRunner(obj, dx); | |
| } | |
| newx1 = +this.line.data("ox1") + dx; | |
| newx2 = +this.line.data("ox2") + dx; | |
| switch (false) { | |
| case obj !== this.leftRunner: | |
| lim1 = this.timeline.topAxis.margin.left; | |
| lim2 = this.line.attr('x2'); | |
| if (newx1 < lim1) { | |
| this.line.attr('x1', lim1); | |
| return this.tlBorder.attr('x2', lim1); | |
| } else if (newx1 > lim2) { | |
| this.line.attr('x1', lim2); | |
| return this.tlBorder.attr('x2', lim2); | |
| } else { | |
| this.line.attr('x1', newx1); | |
| return this.tlBorder.attr('x2', newx1); | |
| } | |
| break; | |
| case obj !== this.rightRunner: | |
| lim1 = this.line.attr('x1'); | |
| lim2 = this.timeline.containerWidth - this.timeline.topAxis.margin.right; | |
| if (newx2 < lim1) { | |
| this.line.attr('x2', lim1); | |
| return this.trBorder.attr('x1', lim1); | |
| } else if (newx2 > lim2) { | |
| this.line.attr('x2', lim2); | |
| return this.trBorder.attr('x1', lim2); | |
| } else { | |
| this.line.attr('x2', newx2); | |
| return this.trBorder.attr('x1', newx2); | |
| } | |
| break; | |
| case obj !== this.line: | |
| lim1 = 0 + this.timeline.topAxis.margin.left; | |
| lim2 = this.timeline.containerWidth - this.timeline.topAxis.margin.right; | |
| if (newx1 > lim1 && newx2 < lim2) { | |
| newx1 = +this.line.data("ox1") + dx; | |
| newx2 = +this.line.data("ox2") + dx; | |
| this.line.attr('x1', newx1); | |
| this.line.attr('x2', newx2); | |
| this.trBorder.attr('x1', newx2); | |
| this.tlBorder.attr('x2', newx1); | |
| return _.each([this.leftRunner, this.rightRunner], (function(_this) { | |
| return function(ele) { | |
| return _this.translateRunner(ele, dx); | |
| }; | |
| })(this)); | |
| } | |
| } | |
| }; | |
| Selector.prototype.translateRunner = function(ele, dx) { | |
| var cur, lim1, lim2, transformString; | |
| if (ele === this.leftRunner) { | |
| lim1 = this.rightRunner.getBBox().x; | |
| lim2 = this.timeline.topAxis.margin.left; | |
| cur = this.leftRunner.data("ibb").x2 + dx; | |
| if (cur > lim1) { | |
| dx = lim1 - this.leftRunner.data("ibb").x2; | |
| } | |
| if (cur < lim2) { | |
| dx = lim2 - this.leftRunner.data("ibb").x2; | |
| } | |
| } else if (ele === this.rightRunner) { | |
| lim1 = this.leftRunner.getBBox().cx + this.leftRunner.getBBox().width / 2; | |
| lim2 = this.timeline.containerWidth - this.timeline.topAxis.margin.right; | |
| cur = this.rightRunner.data("ibb").x + dx; | |
| if (cur < lim1) { | |
| dx = lim1 - this.rightRunner.data("ibb").x; | |
| } | |
| if (cur > lim2) { | |
| dx = lim2 - this.rightRunner.data("ibb").x; | |
| } | |
| } | |
| transformString = ele.data('origTransform') + ("" + (ele.data('origTransform') ? 'T' : 't') + dx); | |
| return ele.attr('transform', transformString); | |
| }; | |
| return Selector; | |
| })(); | |
| Marker = (function() { | |
| function Marker(timeline) { | |
| this.timeline = timeline; | |
| this._onEndMove = __bind(this._onEndMove, this); | |
| this._onMove = __bind(this._onMove, this); | |
| this.paper = this.timeline.paper; | |
| this.icon = this.timeline.svgIcons.select('#runner'); | |
| this.position = this.timeline.containerWidth / 2 || this.timeline.bottomAxis.timestampToXPosition(scope.markerDatetime); | |
| this.lim1 = 0; | |
| this.lim2 = this.timeline.containerWidth; | |
| this._draw(); | |
| this._bindEvents(); | |
| } | |
| Marker.prototype._draw = function() { | |
| var shiftx; | |
| this.paper.append(this.icon); | |
| shiftx = this.icon.getBBox().height / 2; | |
| return this.icon.moveTo(this.position, this.timeline.containerHeight - shiftx - 2); | |
| }; | |
| Marker.prototype._bindEvents = function() { | |
| return this.icon.drag(this._onMove, this._onStartMove, this._onEndMove); | |
| }; | |
| Marker.prototype._onMove = function(dx) { | |
| var cx; | |
| cx = this.icon.data("startcx"); | |
| if (cx + dx < this.lim1) { | |
| dx = this.lim1 - cx; | |
| } else if (this.icon.data("startcx") + dx > this.lim2) { | |
| dx = this.lim2 - cx; | |
| } | |
| this.icon.attr("transform", this.icon.data('origTransform') + ("" + (this.icon.data('origTransform') ? 'T' : 't') + dx)); | |
| scope.markerDatetime = Math.round(this.timeline.bottomAxis.xPositionToTimestamp(cx + dx)); | |
| scope.markerPosition = Math.round(cx + dx); | |
| return scope.$apply(); | |
| }; | |
| Marker.prototype._onStartMove = function() { | |
| this.data('origTransform', this.transform().local); | |
| return this.data('startcx', this.getBBox().cx); | |
| }; | |
| Marker.prototype._onEndMove = function() { | |
| return console.log("end move"); | |
| }; | |
| return Marker; | |
| })(); | |
| timeline = void 0; | |
| scope.$watchGroup(["fullPeriodBegin", "fullPeriodEnd"], function(newvalues) { | |
| if (newvalues[0] && newvalues[1]) { | |
| return timeline = new Timeline; | |
| } | |
| }); | |
| return scope.$watchGroup(["selectedPeriodBegin", "selectedPeriodEnd"], function(newvalues) { | |
| if (newvalues[0] && newvalues[1]) { | |
| scope.$on("timeline:ready", function() { | |
| return console.log('timeline ready event'); | |
| }); | |
| return timeline.update(); | |
| } | |
| }); | |
| } | |
| }; | |
| } | |
| ]); | |
| }).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment