timeline/js/timeline.js
changeset 68 4def147b1604
parent 67 5d1ac260d3ee
child 69 7bb5f89ad242
equal deleted inserted replaced
67:5d1ac260d3ee 68:4def147b1604
   113     level: 0,
   113     level: 0,
   114     central_time: 0,
   114     central_time: 0,
   115     sync_now: true,
   115     sync_now: true,
   116     url_occurrences: '',
   116     url_occurrences: '',
   117     occurrences: [],
   117     occurrences: [],
   118     cluster_spacing: 9
   118     cluster_spacing: 10
   119 }
   119 }
   120 
   120 
   121 for (var _i = 0; _i < Tlns.Defaults.Timeline.timescales.length; _i++) {
   121 for (var _i = 0; _i < Tlns.Defaults.Timeline.timescales.length; _i++) {
   122     Tlns.Defaults.Timeline.timescales[_i].level = _i;
   122     Tlns.Defaults.Timeline.timescales[_i].level = _i;
   123 }
   123 }
   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><canvas class="Tl-Layer Tl-Canvas"></canvas><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-Tip-Top"></div><div class="Tl-Overlay-Main"></div><div class="Tl-Overlay-Tip-Bottom"></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}}{{#editing}} Tl-Editing{{/editing}}" 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="{{contents}}"><div class="Tl-ClusterCount">{{occurrences.length}}</div></div>{{/clusters}}{{#occurrences}}<div class="Tl-Occurrence Tl-OccOnGrid Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-type="{{type}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{y}}px;"></div>{{/occurrences}}{{#open_cluster}}<div class="Tl-ClusterOverlay" style="left: {{x}}px; top: {{y}}px;">{{#occurrences}}<div class="Tl-Occurrence Tl-OccInCluster Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-type="{{type}}" occurrence-id="{{id}}"></div>{{/occurrences}}</div>{{/open_cluster}}';
   137 
   137 
   138 /* Classes */
   138 /* Classes */
   139 
   139 
   140 Tlns.Classes.Timeline = function(_options) {
   140 Tlns.Classes.Timeline = function(_options) {
   141 
   141 
   165         top: _o.top,
   165         top: _o.top,
   166         right: _o.left + this.$.find('.Tl-MainPart').outerWidth(),
   166         right: _o.left + this.$.find('.Tl-MainPart').outerWidth(),
   167         bottom: _o.top + this.$.find('.Tl-MainPart').outerHeight(),
   167         bottom: _o.top + this.$.find('.Tl-MainPart').outerHeight(),
   168     };
   168     };
   169     
   169     
       
   170     var _this = this;
       
   171     
       
   172     this.throttledDrawGrid = _.throttle(function() {
       
   173         _this.drawGrid();
       
   174     }, 150);
       
   175     
   170     this.setLevel(this.level);
   176     this.setLevel(this.level);
   171     
   177     
   172     var _this = this;
       
   173     this.$.find('.Tl-TopBar-Timescales>div').click(function() {
   178     this.$.find('.Tl-TopBar-Timescales>div').click(function() {
   174         _this.setLevel($(this).attr("data-level"));
   179         _this.setLevel($(this).attr("data-level"));
   175     });
   180     });
   176     
   181     
   177     this.$.find('.Tl-TopBar-SyncButton').click(function() {
   182     this.$.find('.Tl-TopBar-SyncButton').click(function() {
   200     this.$.find('.Tl-MainPart').mouseup(function(_event) {
   205     this.$.find('.Tl-MainPart').mouseup(function(_event) {
   201         _this.onMouseUp(_event);
   206         _this.onMouseUp(_event);
   202         return false;
   207         return false;
   203     });
   208     });
   204     
   209     
       
   210     this.$.find('.Tl-MainPart').mousewheel(function(_event, _delta) {
       
   211         var _newLevel = Math.max(0,Math.min(_this.timescales.length-1, (_delta < 0 ? -1 : 1) + parseInt(_this.level)));
       
   212         if (_newLevel != _this.level) {
       
   213             _this.hideTooltip();
       
   214             var _deltaX = _event.pageX - _this.dragging_bounds.left,
       
   215                 _tAtMouse = _this.timeFromMouse(_event.pageX),
       
   216                 _newScale = _this.main_width / (_this.timescales[_newLevel].span),
       
   217                 _newStart = _tAtMouse - _deltaX / _newScale;
       
   218             _this.central_time = _newStart + _this.timescales[_newLevel].span / 2;
       
   219             _this.setLevel(_newLevel);
       
   220         }
       
   221         return false;
       
   222     });
       
   223     
   205     this.$.find('.Tl-Overlay-Box').mouseover(function(_event) {
   224     this.$.find('.Tl-Overlay-Box').mouseover(function(_event) {
   206         $(this).show();
   225         $(this).show();
   207     }).mouseout(function(_event) {
   226     }).mouseout(function(_event) {
   208         $(this).hide();
   227         $(this).hide();
   209     })
   228     });
   210     
       
   211     this.throttledDrawGrid = _.throttle(function() {
       
   212         _this.drawGrid();
       
   213     }, 150);
       
   214     
   229     
   215     /* Loading Univers */
   230     /* Loading Univers */
   216     $.getJSON(this.url_univers, function(_data) {
   231     $.getJSON(this.url_univers, function(_data) {
   217         _this.onUniversLoaded(_data);
   232         _this.onUniversLoaded(_data);
   218     });
   233     });
   243     this.mouse_down = false;
   258     this.mouse_down = false;
   244     this.is_dragging = false;
   259     this.is_dragging = false;
   245     this.dragging_type = undefined;
   260     this.dragging_type = undefined;
   246 }
   261 }
   247 
   262 
       
   263 Tlns.Classes.Timeline.prototype.timeFromX = function(_x) {
       
   264     return Math.max(this.start_time,Math.min(this.end_time, this.start_time + _x / this.current_scale));
       
   265 }
       
   266 
       
   267 Tlns.Classes.Timeline.prototype.timeFromMouse = function(_pageX) {
       
   268     return this.timeFromX(_pageX - this.dragging_bounds.left);
       
   269 }
       
   270 
   248 Tlns.Classes.Timeline.prototype.onMouseMove = function(_event) {
   271 Tlns.Classes.Timeline.prototype.onMouseMove = function(_event) {
   249     if (this.mouse_down) {
   272     if (this.mouse_down) {
   250         this.is_dragging = true;
   273         this.is_dragging = true;
   251         this.$.find('.Tl-Overlay-Box').hide();
   274         this.hideTooltip();
   252         if (_event.pageX > this.dragging_bounds.left
   275         if (_event.pageX > this.dragging_bounds.left
   253             && _event.pageX < this.dragging_bounds.right
   276             && _event.pageX < this.dragging_bounds.right
   254             && _event.pageY > this.dragging_bounds.top
   277             && _event.pageY > this.dragging_bounds.top
   255             && _event.pageY < this.dragging_bounds.bottom
   278             && _event.pageY < this.dragging_bounds.bottom
   256         ) {
   279         ) {
   257             var _timeDelta = Math.floor(( this.start_pos.x - _event.pageX ) / this.current_scale);
       
   258             switch (this.dragging_type) {
   280             switch (this.dragging_type) {
   259                 case "occurrence":
   281                 case "occurrence":
   260                     this.editing_occurrence.date = this.time_at_start - _timeDelta;
   282                     var _d = this.timeFromMouse(_event.pageX);
   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)));
   283                     this.editing_occurrence.date = _d;
       
   284                     var _u = Math.max(0,Math.min(this.univers.length, Math.floor((_event.pageY - this.dragging_bounds.top) / this.univers_height)));
   262                     this.editing_occurrence.univers = this.univers[_u];
   285                     this.editing_occurrence.univers = this.univers[_u];
   263                     this.editing_occurrence.univers_id = this.univers[_u].id;
   286                     this.editing_occurrence.univers_id = this.univers[_u].id;
   264                     this.throttledDrawGrid();
   287                     this.throttledDrawGrid();
   265                 break;
   288                 break;
   266                 case "timeline":
   289                 case "timeline":
   267                     this.setTime(this.time_at_start + _timeDelta);
   290                     this.setTime(this.time_at_start + Math.floor(( this.start_pos.x - _event.pageX ) / this.current_scale));
   268                 break;
   291                 break;
   269             }
   292             }
   270         } else {
   293         } else {
   271             this.onMouseUp(_event);
   294             this.onMouseUp(_event);
   272         }
   295         }
   303             } else {
   326             } else {
   304                 _el.removeClass("active");
   327                 _el.removeClass("active");
   305             }
   328             }
   306         });
   329         });
   307         this.level = _level;
   330         this.level = _level;
   308         this.drawGrid();
   331         this.throttledDrawGrid();
   309     }
   332     }
   310 }
   333 }
   311 
   334 
   312 Tlns.Classes.Timeline.prototype.drawGrid = function() {
   335 Tlns.Classes.Timeline.prototype.drawGrid = function() {
   313     var _now = new Date().valueOf();
   336     var _now = new Date().valueOf();
   325     var _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   348     var _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   326         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   349         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   327         _html = '';
   350         _html = '';
   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));
   351     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));
   329     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   352     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   330         _html += '<div class="Tl-Grid-Column" style="width:' + _grid_width + 'px; left: ' + this.current_scale * (_t - this.start_time) + 'px">'
   353         var _x = this.current_scale * (_t - this.start_time);
   331         + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
   354         if (_x > 0) {
       
   355             _html += '<div class="Tl-Grid-Column" style="width:' + _grid_width + 'px; left: ' + _x + 'px">'
       
   356             + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
       
   357         }
   332     }
   358     }
   333 /*
   359 /*
   334  
   360  
   335     for (var _t = _roundstart; _t < _tmax; _t += _timescale.grid_interval) {
   361     for (var _t = _roundstart; _t < _tmax; _t += _timescale.grid_interval) {
   336         var _isMajor = !(Math.floor((_t - _offset) / _timescale.grid_interval) % _timescale.major_interval);
   362         var _isMajor = !(Math.floor((_t - _offset) / _timescale.grid_interval) % _timescale.major_interval);
   383         this.occurrences.push(_occurrence);
   409         this.occurrences.push(_occurrence);
   384     }
   410     }
   385     _occurrence.update(_type, _data);
   411     _occurrence.update(_type, _data);
   386 }
   412 }
   387 
   413 
   388 Tlns.Classes.Timeline.prototype.showTooltip = function(_x, _y, _html) {
   414 Tlns.Classes.Timeline.prototype.showTooltip = function(_x, _y, _html, _isUp) {
   389     this.$.find('.Tl-Overlay-Box').show()
   415     this.$.find('.Tl-Overlay-Box')
       
   416         .removeClass(_isUp ? 'Tl-Overlay-Down' : 'Tl-Overlay-Up')
       
   417         .addClass(_isUp ? 'Tl-Overlay-Up' : 'Tl-Overlay-Down')
       
   418         .show()
   390         .css({
   419         .css({
   391             left: _x + "px",
   420             left: _x + "px",
   392             top: _y + "px"
   421             top: _y + "px"
   393         });
   422         });
   394     this.$.find('.Tl-Overlay-Main').html(_html);
   423     this.$.find('.Tl-Overlay-Main').html(_html);
   403         _visible = _(this.occurrences).filter(function(_occ) {
   432         _visible = _(this.occurrences).filter(function(_occ) {
   404         return (_occ.date >= _this.start_time && _occ.date <= _this.end_time && _occ.published);
   433         return (_occ.date >= _this.start_time && _occ.date <= _this.end_time && _occ.published);
   405     });
   434     });
   406     _(_visible).each(function(_occ) {
   435     _(_visible).each(function(_occ) {
   407         _occ.x = _this.current_scale * (_occ.date - _this.start_time);
   436         _occ.x = _this.current_scale * (_occ.date - _this.start_time);
       
   437         _occ.y = _occ.univers.y;
   408         _occ.in_cluster = false;
   438         _occ.in_cluster = false;
   409     });
   439     });
   410     
   440     
   411     var _moved = true;
   441     var _moved = true;
   412     while (_moved) {
   442     while (_moved) {
   422                     _visible[_j].x = this.cluster_spacing * Math.round(_visible[_j].x / this.cluster_spacing);
   452                     _visible[_j].x = this.cluster_spacing * Math.round(_visible[_j].x / this.cluster_spacing);
   423                 }
   453                 }
   424             }
   454             }
   425         }
   455         }
   426     }
   456     }
   427     var _clusters = [];
   457     var _clusters = [],
       
   458         _openCluster = false;
   428     for (var _i = 0; _i < _visible.length; _i++) {
   459     for (var _i = 0; _i < _visible.length; _i++) {
   429         for (var _j = 0; _j < _i; _j++) {
   460         for (var _j = 0; _j < _i; _j++) {
   430             if (_visible[_j].univers_id == _visible[_i].univers_id && _visible[_j].x == _visible[_i].x) {
   461             if (_visible[_j].univers_id == _visible[_i].univers_id && _visible[_j].x == _visible[_i].x) {
   431                 _visible[_j].in_cluster = true;
   462                 _visible[_j].in_cluster = true;
   432                 _visible[_i].in_cluster = true;
   463                 _visible[_i].in_cluster = true;
   433                 var _x = _visible[_j].x,
   464                 var _x = _visible[_j].x,
   434                     _y = _visible[_j].univers.y;
   465                     _y = _visible[_j].y;
   435                     _cluster = _(_clusters).find(function(_c) { return _c.x == _x && _c.y == _y });
   466                     _cluster = _(_clusters).find(function(_c) { return _c.x == _x && _c.y == _y });
   436                 if (typeof _cluster === "undefined") {
   467                 if (typeof _cluster === "undefined") {
   437                     _cluster = { x: _x, y: _y, occurrences: [] };
   468                     _cluster = { x: _x, y: _y, occurrences: [] };
   438                     _clusters.push(_cluster);
   469                     _clusters.push(_cluster);
   439                 }
   470                 }
   440                 if ("undefined" === typeof _(_cluster.occurrences).find(function(_o) {
   471                 if ("undefined" === typeof _(_cluster.occurrences).find(function(_o) {
   441                     return _o.type == _visible[_j].type && _o.id == _visible[_j].id;
   472                     return _o.type == _visible[_j].type && _o.id == _visible[_j].id;
   442                 })) {
   473                 })) {
   443                     _cluster.occurrences.push({type: _visible[_j].type, id: _visible[_j].id});
   474                     _cluster.occurrences.push(_visible[_j]);
   444                 }
   475                 }
   445                 if ("undefined" === typeof _(_cluster.occurrences).find(function(_o) {
   476                 if ("undefined" === typeof _(_cluster.occurrences).find(function(_o) {
   446                     return _o.type == _visible[_i].type && _o.id == _visible[_i].id;
   477                     return _o.type == _visible[_i].type && _o.id == _visible[_i].id;
   447                 })) {
   478                 })) {
   448                     _cluster.occurrences.push({type: _visible[_i].type, id: _visible[_i].id});
   479                     _cluster.occurrences.push(_visible[_i]);
   449                 }
   480                 }
   450             }
   481             }
   451         }
   482         }
   452     }
   483     }
   453     _(_clusters).each(function(_cluster) {
   484     _(_clusters).each(function(_cluster) {
   454         _cluster.type = _cluster.occurrences[0].type;
   485         _cluster.type = _cluster.occurrences[0].type;
       
   486         _cluster.contents = _cluster.occurrences.map(function(_o) {
       
   487             return _o.type + ":" + _o.id;
       
   488         }).join("|");
       
   489         if (_cluster.contents == _this.open_cluster) {
       
   490             _openCluster = _cluster;
       
   491         }
   455         for (var _i = 1; _i < _cluster.occurrences.length; _i++) {
   492         for (var _i = 1; _i < _cluster.occurrences.length; _i++) {
   456             if (_cluster.occurrences[_i].type !== _cluster.type) {
   493             if (_cluster.occurrences[_i].type !== _cluster.type) {
   457                 _cluster.type = "both";
   494                 _cluster.type = "both";
   458                 break;
   495                 break;
   459             }
   496             }
   460         }
   497         }
   461     });
   498     });
       
   499     
   462     
   500     
   463     var _links = [];
   501     var _links = [];
   464     
   502     
   465     _(_visible).each(function(_occurrence) {
   503     _(_visible).each(function(_occurrence) {
   466         _(_occurrence.dependsOn).each(function(_dependance) {
   504         _(_occurrence.dependsOn).each(function(_dependance) {
   468                 return _o.type == "narrative" && _o.id == _dependance;
   506                 return _o.type == "narrative" && _o.id == _dependance;
   469             });
   507             });
   470             if (typeof _parent !== "undefined") {
   508             if (typeof _parent !== "undefined") {
   471                 _links.push({
   509                 _links.push({
   472                     from_x: _occurrence.x,
   510                     from_x: _occurrence.x,
   473                     from_y: _occurrence.univers.y + Math.floor(_this.univers_height / 2),
   511                     from_y: _occurrence.y + Math.floor(_this.univers_height / 2),
   474                     to_x: _parent.x,
   512                     to_x: _parent.x,
   475                     to_y: _parent.univers.y + Math.floor(_this.univers_height / 2)
   513                     to_y: _parent.y + Math.floor(_this.univers_height / 2)
   476                 });
   514                 });
   477             }
   515             }
   478         });
   516         });
   479     });
   517     });
   480     
   518     
   485         _ctx.moveTo(_link.from_x,_link.from_y);
   523         _ctx.moveTo(_link.from_x,_link.from_y);
   486         _ctx.lineTo(_link.to_x,_link.to_y);
   524         _ctx.lineTo(_link.to_x,_link.to_y);
   487         _ctx.stroke();
   525         _ctx.stroke();
   488     })
   526     })
   489     
   527     
       
   528     console.log(_openCluster);
       
   529     
   490     var _html = Mustache.to_html(Tlns.Templates.Occurrence, {
   530     var _html = Mustache.to_html(Tlns.Templates.Occurrence, {
   491         occurrences:_(_visible).reject(function(_o) {return _o.in_cluster}),
   531         occurrences:_(_visible).reject(function(_o) {return _o.in_cluster}),
   492         clusters: _clusters
   532         clusters: _clusters,
       
   533         open_cluster: _openCluster
   493     });
   534     });
   494     this.$.find('.Tl-Occurrences').html(_html);
   535     this.$.find('.Tl-Occurrences').html(_html);
       
   536     
       
   537     
       
   538     if (_openCluster) {
       
   539         var _w = this.$.find('.Tl-Occurrence').width(),
       
   540             _ww = _w * _openCluster.occurrences.length;
       
   541         this.$.find('.Tl-ClusterOverlay').css({
       
   542             "margin-left": - Math.floor(_ww/2) + "px",
       
   543             width: _ww
       
   544         });
       
   545         _(_openCluster.occurrences).each(function(_o, _i) {
       
   546             _o.y = _o.y - 20;
       
   547             _o.x = _o.x - (_ww / 2) + ((_i + .5) * _w);
       
   548         });
       
   549     }
       
   550     
   495     this.$.find('.Tl-Occurrence').mousedown(function() {
   551     this.$.find('.Tl-Occurrence').mousedown(function() {
   496         var _el = $(this);
   552         var _el = $(this);
   497         _this.editing_occurrence = _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   553         _this.editing_occurrence = _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   498         if (typeof _this.editing_occurrence !== "undefined") {
   554         if (typeof _this.editing_occurrence !== "undefined") {
   499             _this.dragging_type = "occurrence";
   555             _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;
   556             _this.editing_occurrence.editing = true;
   503         }
   557         }
   504     }).mouseover(function() {
   558     }).mouseover(function(_event) {
   505         var _el = $(this),
   559         var _el = $(this),
   506             _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   560             _occurrence = _this.getOccurrence(_el.attr("occurrence-type"),_el.attr("occurrence-id"));
   507         _this.showTooltip(_occurrence.x, _occurrence.univers.y, _occurrence.title);
   561         _this.showTooltip(_occurrence.x, _occurrence.y, _occurrence.title, (_event.pageY - _this.dragging_bounds.top) > (_this.main_height / 2) );
   508     }).mouseout(function() {
   562     }).mouseout(function() {
   509         _this.hideTooltip();
   563         _this.hideTooltip();
   510     });
   564     });
       
   565     this.$.find('.Tl-Cluster').click(function() {
       
   566         var _el = $(this),
       
   567             _contents = _el.attr("cluster-contents");
       
   568         if (_this.open_cluster == _contents) {
       
   569             _this.open_cluster = false;
       
   570         } else {
       
   571             _this.open_cluster = _contents;
       
   572         }
       
   573         console.log(_this.open_cluster);
       
   574         _this.throttledDrawGrid();
       
   575     })
   511 }
   576 }
   512 
   577 
   513 Tlns.Classes.Timeline.prototype.getUnivers = function(_id) {
   578 Tlns.Classes.Timeline.prototype.getUnivers = function(_id) {
   514     return _(this.univers).find(function(_univ) {
   579     return _(this.univers).find(function(_univ) {
   515         return (_univ.id == _id);
   580         return (_univ.id == _id);