timeline/js/timeline.js
changeset 67 5d1ac260d3ee
parent 66 37492d1ce841
child 68 4def147b1604
equal deleted inserted replaced
66:37492d1ce841 67:5d1ac260d3ee
   126 
   126 
   127 Tlns.Templates.Timeline = '<div class="Tl-TopBar"><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-AddButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
   127 Tlns.Templates.Timeline = '<div class="Tl-TopBar"><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-AddButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
   128     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-PreviousButton"></div></div><div class="Tl-TopBar-TimeSpan Tl-TopBar-TextBtn Tl-Border-Right">--/--</div>'
   128     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-PreviousButton"></div></div><div class="Tl-TopBar-TimeSpan Tl-TopBar-TextBtn Tl-Border-Right">--/--</div>'
   129     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-SyncButton"></div></div><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-NextButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
   129     + '<div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-SyncButton"></div></div><div class="Tl-TopBar-Button Tl-Border-Right"><div class="Tl-TopBar-NextButton"></div></div><div class="Tl-TopBar-Spacer Tl-Border-Right"></div>'
   130     + '<div class="Tl-TopBar-Timescales">{{#timescales}}<div class="Tl-TopBar-Button Tl-TopBar-TextBtn Tl-Border-Right" data-level="{{level}}">{{label}}</div>{{/timescales}}</div></div>'
   130     + '<div class="Tl-TopBar-Timescales">{{#timescales}}<div class="Tl-TopBar-Button Tl-TopBar-TextBtn Tl-Border-Right" data-level="{{level}}">{{label}}</div>{{/timescales}}</div></div>'
   131     + '<div class="Tl-BottomPart"><ul class="Tl-UniversLabels"></ul><div class="Tl-MainPart"><div class="Tl-Layer Tl-Grid"></div><div class="Tl-Layer Tl-Occurrences"></div></div>'
   131     + '<div class="Tl-BottomPart"><ul class="Tl-UniversLabels"></ul><div class="Tl-MainPart"><div class="Tl-Layer Tl-Grid"></div><canvas class="Tl-Layer Tl-Canvas"></canvas><div class="Tl-Layer Tl-Occurrences"></div></div>'
   132     + '<div class="Tl-Overlay-Container"><div class="Tl-Overlay-Box"><div class="Tl-Overlay"><div class="Tl-Overlay-Main"></div><div class="Tl-Overlay-Tip"></div></div></div></div></div>';
   132     + '<div class="Tl-Overlay-Container"><div class="Tl-Overlay-Box"><div class="Tl-Overlay"><div class="Tl-Overlay-Main"></div><div class="Tl-Overlay-Tip"></div></div></div></div></div>';
   133 
   133 
   134 Tlns.Templates.Univers = '<span class="Tl-UniversText">{{title}}</span>';
   134 Tlns.Templates.Univers = '<span class="Tl-UniversText">{{title}}</span>';
   135 
   135 
   136 Tlns.Templates.Occurrence = '{{#clusters}}<div class="Tl-Cluster Tl-Occ{{type}}" style="left: {{x}}px; top: {{y}}px;" cluster-contents="{{#occurrences}}{{type}}|{{id}},{{/occurrences}}"><div class="Tl-ClusterCount">{{occurrences.length}}</div></div>{{/clusters}}{{#occurrences}}<div class="Tl-Occurrence Tl-Occ{{type}}" occurrence-type="{{type}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{univers.y}}px;"></div>{{/occurrences}}';
   136 Tlns.Templates.Occurrence = '{{#clusters}}<div class="Tl-Cluster Tl-Occ{{type}}" style="left: {{x}}px; top: {{y}}px;" cluster-contents="{{#occurrences}}{{type}}|{{id}},{{/occurrences}}"><div class="Tl-ClusterCount">{{occurrences.length}}</div></div>{{/clusters}}{{#occurrences}}<div class="Tl-Occurrence Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-type="{{type}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{univers.y}}px;"></div>{{/occurrences}}';
   137 
   137 
   138 /* Classes */
   138 /* Classes */
   139 
   139 
   140 Tlns.Classes.Timeline = function(_options) {
   140 Tlns.Classes.Timeline = function(_options) {
   141 
   141 
   152     this.$.html(Mustache.to_html(Tlns.Templates.Timeline, this));
   152     this.$.html(Mustache.to_html(Tlns.Templates.Timeline, this));
   153     
   153     
   154     this.main_height = this.height - this.$.find('.Tl-TopBar').outerHeight();
   154     this.main_height = this.height - this.$.find('.Tl-TopBar').outerHeight();
   155     this.$.find('.Tl-BottomPart').css("height", this.main_height + "px");
   155     this.$.find('.Tl-BottomPart').css("height", this.main_height + "px");
   156     this.$.find('.Tl-MainPart').css("width", this.main_width + "px");
   156     this.$.find('.Tl-MainPart').css("width", this.main_width + "px");
   157     this.$.find('.Tl-Overlay-Container').css("left", Math.floor(this.$.find('.Tl-BottomPart').outerWidth() - this.main_width / 2) + "px");
   157     this.$.find('.Tl-Overlay-Container').css("left", (this.$.find('.Tl-BottomPart').outerWidth() - this.main_width) + "px");
       
   158     this.$.find('.Tl-Canvas').attr({
       
   159         width: this.main_width,
       
   160         height: this.main_height
       
   161     });
   158     var _o = this.$.find('.Tl-MainPart').offset();
   162     var _o = this.$.find('.Tl-MainPart').offset();
   159     this.dragging_bounds = {
   163     this.dragging_bounds = {
   160         left: _o.left,
   164         left: _o.left,
   161         top: _o.top,
   165         top: _o.top,
   162         right: _o.left + this.$.find('.Tl-MainPart').outerWidth(),
   166         right: _o.left + this.$.find('.Tl-MainPart').outerWidth(),
   202         $(this).show();
   206         $(this).show();
   203     }).mouseout(function(_event) {
   207     }).mouseout(function(_event) {
   204         $(this).hide();
   208         $(this).hide();
   205     })
   209     })
   206     
   210     
   207     this.throttledSetTime = _.throttle(function(_time) {
   211     this.throttledDrawGrid = _.throttle(function() {
   208         _this.setTime(_time)
   212         _this.drawGrid();
   209     }, 150);
   213     }, 150);
   210     
   214     
   211     /* Loading Univers */
   215     /* Loading Univers */
   212     $.getJSON(this.url_univers, function(_data) {
   216     $.getJSON(this.url_univers, function(_data) {
   213         _this.onUniversLoaded(_data);
   217         _this.onUniversLoaded(_data);
   215 }
   219 }
   216 
   220 
   217 Tlns.Classes.Timeline.prototype.onMouseDown = function(_event) {
   221 Tlns.Classes.Timeline.prototype.onMouseDown = function(_event) {
   218     this.mouse_down = true;
   222     this.mouse_down = true;
   219     this.is_dragging = false;
   223     this.is_dragging = false;
   220     this.time_at_start = this.central_time;
       
   221     this.start_pos = {
   224     this.start_pos = {
   222         x: _event.pageX,
   225         x: _event.pageX,
   223         y: _event.pageY
   226         y: _event.pageY
   224     };
   227     };
   225     if (typeof this.dragging_type === "undefined") {
   228     if (typeof this.dragging_type === "undefined") {
       
   229         this.time_at_start = this.central_time;
   226         this.dragging_type = "timeline";
   230         this.dragging_type = "timeline";
   227     }
   231     }
   228 }
   232 }
   229 
   233 
   230 Tlns.Classes.Timeline.prototype.onMouseUp = function(_event) {
   234 Tlns.Classes.Timeline.prototype.onMouseUp = function(_event) {
       
   235     if (this.is_dragging) {
       
   236         switch (this.dragging_type) {
       
   237             case "occurrence":
       
   238                 this.editing_occurrence.editing = false;
       
   239                 this.throttledDrawGrid();
       
   240             break;
       
   241         }
       
   242     }
   231     this.mouse_down = false;
   243     this.mouse_down = false;
   232     this.is_dragging = false;
   244     this.is_dragging = false;
   233     this.dragging_type = undefined;
   245     this.dragging_type = undefined;
   234 }
   246 }
   235 
   247 
   240         if (_event.pageX > this.dragging_bounds.left
   252         if (_event.pageX > this.dragging_bounds.left
   241             && _event.pageX < this.dragging_bounds.right
   253             && _event.pageX < this.dragging_bounds.right
   242             && _event.pageY > this.dragging_bounds.top
   254             && _event.pageY > this.dragging_bounds.top
   243             && _event.pageY < this.dragging_bounds.bottom
   255             && _event.pageY < this.dragging_bounds.bottom
   244         ) {
   256         ) {
   245             var _newTime = Math.floor(this.time_at_start + ( this.start_pos.x - _event.pageX ) / this.current_scale);
   257             var _timeDelta = Math.floor(( this.start_pos.x - _event.pageX ) / this.current_scale);
   246             switch (this.dragging_type) {
   258             switch (this.dragging_type) {
       
   259                 case "occurrence":
       
   260                     this.editing_occurrence.date = this.time_at_start - _timeDelta;
       
   261                     var _u = Math.max(0,Math.min(this.univers.length, Math.floor(this.u_at_start - (this.start_pos.y - _event.pageY) / this.univers_height)));
       
   262                     this.editing_occurrence.univers = this.univers[_u];
       
   263                     this.editing_occurrence.univers_id = this.univers[_u].id;
       
   264                     this.throttledDrawGrid();
       
   265                 break;
   247                 case "timeline":
   266                 case "timeline":
   248                     this.throttledSetTime(_newTime);
   267                     this.setTime(this.time_at_start + _timeDelta);
   249                 break;
   268                 break;
   250             }
   269             }
   251         } else {
   270         } else {
   252             this.onMouseUp(_event);
   271             this.onMouseUp(_event);
   253         }
   272         }
   270 }
   289 }
   271 
   290 
   272 Tlns.Classes.Timeline.prototype.setTime = function(_centralTime) {
   291 Tlns.Classes.Timeline.prototype.setTime = function(_centralTime) {
   273     this.sync_now = false;
   292     this.sync_now = false;
   274     this.central_time = _centralTime;
   293     this.central_time = _centralTime;
   275     this.drawGrid();
   294     this.throttledDrawGrid();
   276 }
   295 }
   277 
   296 
   278 Tlns.Classes.Timeline.prototype.setLevel = function(_level) {
   297 Tlns.Classes.Timeline.prototype.setLevel = function(_level) {
   279     if (_level >= 0 && _level < this.timescales.length) {
   298     if (_level >= 0 && _level < this.timescales.length) {
   280         this.$.find('.Tl-TopBar-Timescales>div').each(function() {
   299         this.$.find('.Tl-TopBar-Timescales>div').each(function() {
   306     var _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   325     var _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   307         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   326         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   308         _html = '';
   327         _html = '';
   309     this.$.find('.Tl-TopBar-TimeSpan').html(Tlns.Utils.dateFormat(this.start_time, _timescale.start_date_format) + ' - ' + Tlns.Utils.dateFormat(this.end_time, _timescale.end_date_format));
   328     this.$.find('.Tl-TopBar-TimeSpan').html(Tlns.Utils.dateFormat(this.start_time, _timescale.start_date_format) + ' - ' + Tlns.Utils.dateFormat(this.end_time, _timescale.end_date_format));
   310     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   329     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   311         _html += '<div class="Tl-Grid-Column" style="width:' + _grid_width + 'px; left: ' + this.current_scale * (_t - this.central_time) + 'px">'
   330         _html += '<div class="Tl-Grid-Column" style="width:' + _grid_width + 'px; left: ' + this.current_scale * (_t - this.start_time) + 'px">'
   312         + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
   331         + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
   313     }
   332     }
   314 /*
   333 /*
   315  
   334  
   316     for (var _t = _roundstart; _t < _tmax; _t += _timescale.grid_interval) {
   335     for (var _t = _roundstart; _t < _tmax; _t += _timescale.grid_interval) {
   317         var _isMajor = !(Math.floor((_t - _offset) / _timescale.grid_interval) % _timescale.major_interval);
   336         var _isMajor = !(Math.floor((_t - _offset) / _timescale.grid_interval) % _timescale.major_interval);
   318         _html += '<div class="Tl-Grid-Column' + ( _isMajor ? ' Tl-Grid-Major' : '' ) + '" style="width:' + _grid_width + 'px; left: ' + _scale * (_t - this.central_time) + 'px">'
   337         _html += '<div class="Tl-Grid-Column' + ( _isMajor ? ' Tl-Grid-Major' : '' ) + '" style="width:' + _grid_width + 'px; left: ' + _scale * (_t - this.start_time) + 'px">'
   319         + ( _isMajor ? '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.date_format) + '</div>' : '' ) + '</div>';
   338         + ( _isMajor ? '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.date_format) + '</div>' : '' ) + '</div>';
   320     }
   339     }
   321 */
   340 */
   322     if (this.start_time <= _now && this.end_time >= _now) {
   341     if (this.start_time <= _now && this.end_time >= _now) {
   323         _html += '<div class="Tl-Grid-Now" style="left: ' + this.current_scale * (_now - this.central_time) + 'px"></div>'
   342         _html += '<div class="Tl-Grid-Now" style="left: ' + this.current_scale * (_now - this.start_time) + 'px"></div>'
   324     }
   343     }
   325     this.$.find('.Tl-Grid').html(_html);
   344     this.$.find('.Tl-Grid').html(_html);
   326     this.drawOccurrences();
   345     this.drawOccurrences();
   327 }
   346 }
   328 
   347 
   383     var _this = this,
   402     var _this = this,
   384         _visible = _(this.occurrences).filter(function(_occ) {
   403         _visible = _(this.occurrences).filter(function(_occ) {
   385         return (_occ.date >= _this.start_time && _occ.date <= _this.end_time && _occ.published);
   404         return (_occ.date >= _this.start_time && _occ.date <= _this.end_time && _occ.published);
   386     });
   405     });
   387     _(_visible).each(function(_occ) {
   406     _(_visible).each(function(_occ) {
   388         _occ.x = _this.current_scale * (_occ.date - _this.central_time);
   407         _occ.x = _this.current_scale * (_occ.date - _this.start_time);
   389         _occ.in_cluster = false;
   408         _occ.in_cluster = false;
   390     });
   409     });
   391     
   410     
   392     var _moved = true;
   411     var _moved = true;
   393     while (_moved) {
   412     while (_moved) {
   439                 break;
   458                 break;
   440             }
   459             }
   441         }
   460         }
   442     });
   461     });
   443     
   462     
       
   463     var _links = [];
       
   464     
       
   465     _(_visible).each(function(_occurrence) {
       
   466         _(_occurrence.dependsOn).each(function(_dependance) {
       
   467             var _parent = _(_visible).find(function(_o) {
       
   468                 return _o.type == "narrative" && _o.id == _dependance;
       
   469             });
       
   470             if (typeof _parent !== "undefined") {
       
   471                 _links.push({
       
   472                     from_x: _occurrence.x,
       
   473                     from_y: _occurrence.univers.y + Math.floor(_this.univers_height / 2),
       
   474                     to_x: _parent.x,
       
   475                     to_y: _parent.univers.y + Math.floor(_this.univers_height / 2)
       
   476                 });
       
   477             }
       
   478         });
       
   479     });
       
   480     
       
   481     var _ctx = this.$.find('.Tl-Canvas')[0].getContext('2d');
       
   482     _ctx.clearRect(0,0,this.main_width, this.main_height);
       
   483     _(_links).each(function(_link) {
       
   484         _ctx.beginPath();
       
   485         _ctx.moveTo(_link.from_x,_link.from_y);
       
   486         _ctx.lineTo(_link.to_x,_link.to_y);
       
   487         _ctx.stroke();
       
   488     })
       
   489     
   444     var _html = Mustache.to_html(Tlns.Templates.Occurrence, {
   490     var _html = Mustache.to_html(Tlns.Templates.Occurrence, {
   445         occurrences:_(_visible).reject(function(_o) {return _o.in_cluster}),
   491         occurrences:_(_visible).reject(function(_o) {return _o.in_cluster}),
   446         clusters: _clusters
   492         clusters: _clusters
   447     });
   493     });
   448     this.$.find('.Tl-Occurrences').html(_html);
   494     this.$.find('.Tl-Occurrences').html(_html);
   449     this.$.find('.Tl-Occurrence').mousedown(function() {
   495     this.$.find('.Tl-Occurrence').mousedown(function() {
   450         _this.dragging_type = "occurrence"
   496         var _el = $(this);
       
   497         _this.editing_occurrence = _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
       
   498         if (typeof _this.editing_occurrence !== "undefined") {
       
   499             _this.dragging_type = "occurrence";
       
   500             _this.time_at_start = _this.editing_occurrence.date;
       
   501             _this.u_at_start = _this.editing_occurrence.univers.index;
       
   502             _this.editing_occurrence.editing = true;
       
   503         }
   451     }).mouseover(function() {
   504     }).mouseover(function() {
   452         var _el = $(this),
   505         var _el = $(this),
   453             _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   506             _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   454         _this.showTooltip(_occurrence.x, _occurrence.univers.y, _occurrence.title);
   507         _this.showTooltip(_occurrence.x, _occurrence.univers.y, _occurrence.title);
   455     }).mouseout(function() {
   508     }).mouseout(function() {