timeline/js/timeline.js
changeset 97 0444ad28e6ba
parent 96 7d1c2c21d891
child 98 abead2de6332
equal deleted inserted replaced
96:7d1c2c21d891 97:0444ad28e6ba
    30             } else {
    30             } else {
    31                 _object[_k] = _v;
    31                 _object[_k] = _v;
    32             }
    32             }
    33         }
    33         }
    34     });
    34     });
    35 }
    35 };
    36 
    36 
    37 Tlns.Utils.dateFormat = function(_date, _template) {
    37 Tlns.Utils.dateFormat = function(_date, _template) {
    38     if (typeof _date !== "object") {
    38     if (typeof _date !== "object") {
    39         _date = new Date(parseInt(_date));
    39         _date = new Date(parseInt(_date));
    40     }
    40     }
    51         dayOfMonth: _date.getDate(),
    51         dayOfMonth: _date.getDate(),
    52         "0dayOfMonth": Tlns.Utils.zeroPad(_date.getDate()),
    52         "0dayOfMonth": Tlns.Utils.zeroPad(_date.getDate()),
    53         monthNumber: 1+_date.getMonth(),
    53         monthNumber: 1+_date.getMonth(),
    54         "0monthNumber": Tlns.Utils.zeroPad(1+_date.getMonth()),
    54         "0monthNumber": Tlns.Utils.zeroPad(1+_date.getMonth()),
    55         monthName: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"][_date.getMonth()],
    55         monthName: ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"][_date.getMonth()],
    56         shortMonthName: ["jan","fev","mar","avr","mai","jun","jul","aou","sep","oct","nov","dec"][_date.getMonth()],
    56         shortMonthName: ["jan.","fev.","mar.","avr.","mai","jun.","jul.","aou.","sep.","oct.","nov.","dec."][_date.getMonth()],
    57         year: _date.getFullYear()
    57         year: _date.getFullYear()
    58     }
    58     }
    59     return Mustache.to_html(_template, _params);
    59     return Mustache.to_html(_template, _params);
    60 }
    60 };
    61 
    61 
    62 Tlns.Utils.guid = function() {
    62 Tlns.Utils.guid = function() {
    63     return 'xxxx-xxxx-xxxx-xxxx'.replace(/x/g,function() {
    63     return 'xxxx-xxxx-xxxx-xxxx'.replace(/x/g,function() {
    64         return Math.floor(Math.random()*16).toString(16);
    64         return Math.floor(Math.random()*16).toString(16);
    65     });
    65     });
    66 }
    66 };
    67 
    67 
    68 Tlns.Utils.timeFieldProcess = function(_val) {
    68 Tlns.Utils.timeFieldProcess = function(_val) {
    69     var _h = 0,
    69     var _h = 0,
    70         _m = 0,
    70         _m = 0,
    71         _matches = _val.match(/(\d+)/g);
    71         _matches = _val.match(/(\d+)/g);
    78     return {
    78     return {
    79         hours: _h,
    79         hours: _h,
    80         minutes: _m,
    80         minutes: _m,
    81         text: Tlns.Utils.zeroPad(_h) + ':' + Tlns.Utils.zeroPad(_m)
    81         text: Tlns.Utils.zeroPad(_h) + ':' + Tlns.Utils.zeroPad(_m)
    82     }
    82     }
    83 }
    83 };
    84 
    84 
    85 Tlns.Utils.dateFieldProcess = function(_val) {
    85 Tlns.Utils.dateFieldProcess = function(_val) {
    86     var _now = new Date(),
    86     var _now = new Date(),
    87         _y = _now.getFullYear(),
    87         _y = _now.getFullYear(),
    88         _m = 1 + _now.getMonth(),
    88         _m = 1 + _now.getMonth(),
   105         year: _y,
   105         year: _y,
   106         month: _m,
   106         month: _m,
   107         date: _d,
   107         date: _d,
   108         text: Tlns.Utils.zeroPad(_d) + '/' + Tlns.Utils.zeroPad(_m) + '/' + _y
   108         text: Tlns.Utils.zeroPad(_d) + '/' + Tlns.Utils.zeroPad(_m) + '/' + _y
   109     }
   109     }
   110 }
   110 };
   111 
   111 
   112 /* Defaults */
   112 /* Defaults */
   113 
   113 
   114 Tlns.Defaults.Timeline = {
   114 Tlns.Defaults.Timeline = {
   115     email: "",
   115     email: "",
   116     token: "",
   116     token: "",
   117     container : "timeline",
   117     container : "timeline",
   118     width : 780,
   118     width : 790,
   119     height : 225,
   119     height : 225,
   120     min_width : 400,
   120     min_width : 400,
   121     min_height : 100,
   121     min_height : 100,
   122     main_width : 726,
   122     main_width : 726,
   123     linelabels : [
   123     linelabels : [
   213             show: true
   213             show: true
   214         }
   214         }
   215     },
   215     },
   216     maxtime: false,
   216     maxtime: false,
   217     url_base: ""
   217     url_base: ""
   218 }
   218 };
   219 
   219 
   220 for (var _i = 0; _i < Tlns.Defaults.Timeline.timescales.length; _i++) {
   220 for (var _i = 0; _i < Tlns.Defaults.Timeline.timescales.length; _i++) {
   221     Tlns.Defaults.Timeline.timescales[_i].level = _i;
   221     Tlns.Defaults.Timeline.timescales[_i].level = _i;
   222 }
   222 }
   223 
   223 
   224 /* Templates */
   224 /* Templates */
   225 
   225 
   226 Tlns.Templates.Timeline = '<div class="Tl-Main"><div class="Tl-Grid"></div><div class="Tl-TopBar"></div>'
   226 Tlns.Templates.Timeline = '<div class="Tl-Main"><div class="Tl-Grid"></div><div class="Tl-TopBar"></div>'
   227     + '<div class="Tl-BottomPart"><ul class="Tl-UniversLabels"></ul>'
   227     + '<div class="Tl-BottomPart"><div class="Tl-AnotherGroup"><ul class="Tl-UniversLabels"></ul>'
   228     + '<div class="Tl-MainPart"><div class="Tl-Occurrences"></div>'
   228     + '<div class="Tl-MainPart"><div class="Tl-Occurrences"></div>'
   229     + '</div>'
   229     + '</div></div><div class="Tl-Slider-Container"><a class="Tl-Slider-Zoom-In" href="#"></a><div class="Tl-Slider"></div><a class="Tl-Slider-Zoom-Out" href="#"></a></div>'
   230     + '<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></div></div></div></div>'
   230     + '<div class="Tl-Overlay-Container"><div class="Tl-Overlay-Box"><div class="Tl-Overlay"><div class="Tl-Overlay-Main"></div></div></div></div></div></div>'
   231     + '<div class="Tl-Details"></div>'
   231     + '<div class="Tl-Details"></div>';
   232     
   232     
   233 Tlns.Templates.Univers = '<div class="Tl-UniversText">{{title}}</div>';
   233 Tlns.Templates.Univers = '<div class="Tl-UniversText">{{title}}</div>';
   234 
   234 
   235 Tlns.Templates.Occurrence =
   235 Tlns.Templates.Occurrence =
   236     '{{#occurrences}}<div class="Tl-Occurrence Tl-OccOnGrid Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{y}}px;">'
   236     '{{#occurrences}}<div class="Tl-Occurrence Tl-OccOnGrid Tl-Occ{{type}}{{#editing}} Tl-Editing{{/editing}}" occurrence-id="{{id}}" style="left: {{x}}px; top: {{y}}px;">'
   258         height : this.height + "px"
   258         height : this.height + "px"
   259     });
   259     });
   260     this.top_height = this.$.find('.Tl-TopBar').outerHeight();
   260     this.top_height = this.$.find('.Tl-TopBar').outerHeight();
   261     this.main_height = this.height - this.top_height;
   261     this.main_height = this.height - this.top_height;
   262     //this.main_height = this.height - 27;
   262     //this.main_height = this.height - 27;
       
   263     var labelsWidth = this.$.find('.Tl-UniversLabels').width();
       
   264     this.main_width = this.width - labelsWidth - this.$.find('.Tl-Slider-Container').width();
   263     this.$.find('.Tl-BottomPart').css("height", this.main_height + "px");
   265     this.$.find('.Tl-BottomPart').css("height", this.main_height + "px");
   264     this.$.find('.Tl-MainPart, .Tl-Grid').css("width", this.main_width + "px");
   266     this.$.find('.Tl-MainPart').css("width", this.main_width + "px");
       
   267     this.$.find('.Tl-Grid').css({
       
   268         "left": labelsWidth + "px",
       
   269         "width": this.main_width + "px"
       
   270     });
   265     this.$.find('.Tl-Overlay-Container').css("left", (this.$.find('.Tl-BottomPart').outerWidth() - this.main_width) + "px");
   271     this.$.find('.Tl-Overlay-Container').css("left", (this.$.find('.Tl-BottomPart').outerWidth() - this.main_width) + "px");
   266     
   272     this.$slider = this.$.find('.Tl-Slider');
   267     var _o = this.$.find('.Tl-MainPart').offset();
   273     
       
   274     var $mainpart = this.$.find('.Tl-MainPart'),
       
   275         _o = $mainpart.offset();
   268     this.dragging_bounds = {
   276     this.dragging_bounds = {
   269         left: _o.left,
   277         left: _o.left,
   270         top: _o.top,
   278         top: _o.top,
   271         right: _o.left + this.$.find('.Tl-MainPart').outerWidth(),
   279         right: _o.left + $mainpart.outerWidth(),
   272         bottom: _o.top + this.$.find('.Tl-MainPart').outerHeight(),
   280         bottom: _o.top + $mainpart.outerHeight(),
   273     };
   281     };
   274     this.$.find('.Tl-UniversLabels').css({
       
   275         width: this.width - this.main_width
       
   276     });
       
   277     
   282     
   278     var _this = this;
   283     var _this = this;
   279     
   284     
   280     this.throttledDrawGrid = _.throttle(function() {
   285     this.throttledDrawGrid = _.throttle(function() {
   281         _this.drawGrid();
   286         _this.drawGrid();
   282     }, 150);
   287     }, 150);
   283     
   288     
   284     this.setLevel(this.level);
   289     var $scrollgroup = this.$.find('.Tl-AnotherGroup');
   285      
   290      
   286     this.$.find('.Tl-MainPart').mousedown(function(_event) {
   291     $scrollgroup.mousedown(function(_event) {
   287         _this.onMouseDown(_event);
   292         _this.onMouseDown(_event);
   288         return false;
   293         return false;
   289     });
   294     });
   290     
   295     
   291     this.$.find('.Tl-MainPart').mousemove(function(_event) {
   296     $scrollgroup.mousemove(function(_event) {
   292         _this.onMouseMove(_event);
   297         _this.onMouseMove(_event);
   293         return false;
   298         return false;
   294     });
   299     });
   295     
   300     
   296     this.$.find('.Tl-MainPart').mouseup(function(_event) {
   301     $scrollgroup.mouseup(function(_event) {
   297         _this.onMouseUp(_event);
   302         _this.onMouseUp(_event);
   298         return false;
   303         return false;
   299     });
   304     });
   300     
   305     
   301     this.$.find('.Tl-MainPart').mousewheel(function(_event, _delta) {
   306     $scrollgroup.mousewheel(function(_event, _delta) {
   302         var _newLevel = Math.max(0,Math.min(_this.timescales.length-1, (_delta < 0 ? -1 : 1) + parseInt(_this.level)));
   307         var _newLevel = Math.max(0,Math.min(_this.timescales.length-1, (_delta < 0 ? -1 : 1) + parseInt(_this.level)));
   303         if (_newLevel != _this.level) {
   308         if (_newLevel != _this.level) {
   304             _this.hideTooltip();
   309             _this.hideTooltip();
   305             var _deltaX = _event.pageX - _this.dragging_bounds.left,
   310             var _deltaX = _event.pageX - _this.dragging_bounds.left,
   306                 _tAtMouse = _this.timeFromMouse(_event.pageX),
   311                 _tAtMouse = _this.timeFromMouse(_event.pageX),
   317         $(this).show();
   322         $(this).show();
   318     }).mouseout(function(_event) {
   323     }).mouseout(function(_event) {
   319         $(this).hide();
   324         $(this).hide();
   320     });
   325     });
   321     
   326     
       
   327     this.$slider.slider({
       
   328         orientation: "vertical",
       
   329         min: 0,
       
   330         max: this.timescales.length - 1,
       
   331         value: this.level,
       
   332         slide: function(e, ui) {
       
   333             _this.setLevel(ui.value);
       
   334         }
       
   335     });
       
   336     this.$.find('.Tl-Slider-Container').mousewheel(function(_event, _delta) {
       
   337         var _newLevel = Math.max(0,Math.min(_this.timescales.length-1, (_delta < 0 ? -1 : 1) + parseInt(_this.level)));
       
   338         if (_newLevel != _this.level) {
       
   339             _this.hideTooltip();
       
   340             _this.setLevel(_newLevel);
       
   341         }
       
   342         return false;
       
   343     });
       
   344     
       
   345     $(".Tl-Slider-Zoom-In").click(function() {
       
   346         _this.setLevel(Math.min(_this.timescales.length-1,parseInt(_this.level)+1));
       
   347         return false;
       
   348     });
       
   349     $(".Tl-Slider-Zoom-Out").click(function() {
       
   350         _this.setLevel(Math.max(0,parseInt(_this.level)-1));
       
   351         return false;
       
   352     });
       
   353     
       
   354     this.setLevel(this.level);
   322        
   355        
   323     this.onUniversLoaded(this.linelabels);
   356     this.onUniversLoaded(this.linelabels);
   324     
   357     
   325 }
   358 };
   326 
   359 
   327 Tlns.Classes.Timeline.prototype.onMouseDown = function(_event) {
   360 Tlns.Classes.Timeline.prototype.onMouseDown = function(_event) {
   328     this.mouse_down = true;
   361     this.mouse_down = true;
   329     this.is_dragging = false;
   362     this.is_dragging = false;
   330     this.start_pos = {
   363     this.start_pos = {
   333     };
   366     };
   334     if (typeof this.dragging_type === "undefined") {
   367     if (typeof this.dragging_type === "undefined") {
   335         this.time_at_start = this.central_time;
   368         this.time_at_start = this.central_time;
   336         this.dragging_type = "timeline";
   369         this.dragging_type = "timeline";
   337     }
   370     }
   338 }
   371 };
   339 
   372 
   340 Tlns.Classes.Timeline.prototype.onMouseUp = function(_event) {
   373 Tlns.Classes.Timeline.prototype.onMouseUp = function(_event) {
   341     this.mouse_down = false;
   374     this.mouse_down = false;
   342     this.is_dragging = false;
   375     this.is_dragging = false;
   343     this.dragging_type = undefined;
   376     this.dragging_type = undefined;
   344 }
   377 };
   345 
   378 
   346 Tlns.Classes.Timeline.prototype.timeFromX = function(_x) {
   379 Tlns.Classes.Timeline.prototype.timeFromX = function(_x) {
   347     return this.start_time + _x / this.current_scale;
   380     return this.start_time + _x / this.current_scale;
   348 }
   381 };
   349 
   382 
   350 Tlns.Classes.Timeline.prototype.timeFromMouse = function(_pageX) {
   383 Tlns.Classes.Timeline.prototype.timeFromMouse = function(_pageX) {
   351     return this.timeFromX(_pageX - this.dragging_bounds.left);
   384     return this.timeFromX(_pageX - this.dragging_bounds.left);
   352 }
   385 };
   353 
   386 
   354 Tlns.Classes.Timeline.prototype.universFromY = function(_y) {
   387 Tlns.Classes.Timeline.prototype.universFromY = function(_y) {
   355     return Math.max(0,Math.min(this.univers.length, Math.floor(_y / this.univers_height)))
   388     return Math.max(0,Math.min(this.univers.length, Math.floor(_y / this.univers_height)));
   356 }
   389 };
   357 
   390 
   358 Tlns.Classes.Timeline.prototype.universFromMouse = function(_pageY) {
   391 Tlns.Classes.Timeline.prototype.universFromMouse = function(_pageY) {
   359     return this.universFromY(_pageY - this.dragging_bounds.top);
   392     return this.universFromY(_pageY - this.dragging_bounds.top);
   360 }
   393 };
   361 
   394 
   362 Tlns.Classes.Timeline.prototype.onMouseMove = function(_event) {
   395 Tlns.Classes.Timeline.prototype.onMouseMove = function(_event) {
   363     if (this.mouse_down && !this.is_dragging) {
   396     if (this.mouse_down && !this.is_dragging) {
   364         var _dx = this.start_pos.x - _event.pageX,
   397         var _dx = this.start_pos.x - _event.pageX,
   365             _dy = this.start_pos.y - _event.pageY,
   398             _dy = this.start_pos.y - _event.pageY,
   374             case "timeline":
   407             case "timeline":
   375                 this.setTime(this.time_at_start + Math.floor(( this.start_pos.x - _event.pageX ) / this.current_scale));
   408                 this.setTime(this.time_at_start + Math.floor(( this.start_pos.x - _event.pageX ) / this.current_scale));
   376             break;
   409             break;
   377         }
   410         }
   378     }
   411     }
   379 }
   412 };
   380 
   413 
   381 Tlns.Classes.Timeline.prototype.onUniversLoaded = function(_data) {
   414 Tlns.Classes.Timeline.prototype.onUniversLoaded = function(_data) {
   382     this.univers = [];
   415     this.univers = [];
   383     if(_data.length) {
   416     if(_data.length) {
   384         this.univers_height = Math.floor(this.main_height / _data.length);
   417         this.univers_height = Math.floor(this.main_height / _data.length);
   386     for(var _i = 0; _i < _data.length; _i++) {
   419     for(var _i = 0; _i < _data.length; _i++) {
   387         this.univers.push(new Tlns.Classes.Univers(_data[_i], this, _i));
   420         this.univers.push(new Tlns.Classes.Univers(_data[_i], this, _i));
   388     }
   421     }
   389     
   422     
   390     this.loadOccurrences();
   423     this.loadOccurrences();
   391 }
   424 };
   392 
   425 
   393 Tlns.Classes.Timeline.prototype.offsetTime = function(_timeOffset) {
   426 Tlns.Classes.Timeline.prototype.offsetTime = function(_timeOffset) {
   394     this.setTime(this.central_time + _timeOffset);
   427     this.setTime(this.central_time + _timeOffset);
   395 }
   428 };
   396 
   429 
   397 Tlns.Classes.Timeline.prototype.setTime = function(_centralTime) {
   430 Tlns.Classes.Timeline.prototype.setTime = function(_centralTime) {
   398     this.sync_now = false;
   431     this.sync_now = false;
   399     this.central_time = this.maxtime ? Math.min(_centralTime, this.maxtime) : _centralTime;
   432     this.central_time = this.maxtime ? Math.min(_centralTime, this.maxtime) : _centralTime;
   400     this.changeSpan();
   433     this.changeSpan();
   401 }
   434 };
   402 
   435 
   403 Tlns.Classes.Timeline.prototype.setLevel = function(_level) {
   436 Tlns.Classes.Timeline.prototype.setLevel = function(_level) {
   404     if (_level >= 0 && _level < this.timescales.length) {
   437     if (_level >= 0 && _level < this.timescales.length) {
   405         this.level = _level;
   438         this.level = _level;
       
   439         this.$slider.slider("value", _level);
   406         this.changeSpan();
   440         this.changeSpan();
   407     }
   441     }
   408 }
   442 };
   409 
   443 
   410 Tlns.Classes.Timeline.prototype.changeSpan = function() {
   444 Tlns.Classes.Timeline.prototype.changeSpan = function() {
   411     var _now = new Date().valueOf();
   445     var _now = new Date().valueOf();
   412     if (this.sync_now) {
   446     if (this.sync_now) {
   413         this.central_time = _now;
   447         this.central_time = _now;
   415     var _timescale = this.timescales[this.level];
   449     var _timescale = this.timescales[this.level];
   416     this.current_scale = this.main_width / (_timescale.span);
   450     this.current_scale = this.main_width / (_timescale.span);
   417     this.start_time = this.central_time - (_timescale.span / 2);
   451     this.start_time = this.central_time - (_timescale.span / 2);
   418     this.end_time = this.central_time + (_timescale.span / 2);
   452     this.end_time = this.central_time + (_timescale.span / 2);
   419     this.throttledDrawGrid();
   453     this.throttledDrawGrid();
   420 }
   454 };
   421 
   455 
   422 Tlns.Classes.Timeline.prototype.drawGrid = function() {
   456 Tlns.Classes.Timeline.prototype.drawGrid = function() {
   423     var _now = new Date().valueOf(),
   457     var _now = new Date().valueOf(),
   424         _timescale = this.timescales[this.level],
   458         _timescale = this.timescales[this.level],
   425         _offset = new Date().getTimezoneOffset() * 60000,
   459         _offset = new Date().getTimezoneOffset() * 60000,
   426         _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   460         _grid_width = Math.floor(_timescale.grid_interval * this.current_scale),
   427         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   461         _roundstart = Math.floor((this.start_time - _offset) / _timescale.grid_interval) * _timescale.grid_interval + _offset,
   428         _html = '';
   462         _html = '';
   429     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   463     for (var _t = _roundstart; _t < this.end_time; _t += _timescale.grid_interval) {
   430         var _x = this.current_scale * (_t - this.start_time);
   464         var _x = this.current_scale * (_t - this.start_time),
       
   465             isMajor = !((_t - _offset)%(24*60*60*1000));
   431         if (_x > 0) {
   466         if (_x > 0) {
   432             _html += '<div class="Tl-Grid-Column" style="width:' + _grid_width + 'px; left: ' + _x + 'px">'
   467             _html += '<div class="Tl-Grid-Column' + (isMajor ? ' Tl-Grid-Major':'') + '" style="width:' + _grid_width + 'px; left: ' + _x + 'px">'
   433             + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
   468             + '<div class="Tl-Grid-Label">' + Tlns.Utils.dateFormat(_t, _timescale.grid_date_format) + '</div></div>';
   434         }
   469         }
   435     }
   470     }
   436     if (this.start_time <= _now && this.end_time >= _now) {
   471     if (this.start_time <= _now && this.end_time >= _now) {
   437         _html += '<div class="Tl-Grid-Now" style="left: ' + this.current_scale * (_now - this.start_time) + 'px"></div>'
   472         _html += '<div class="Tl-Grid-Now" style="left: ' + this.current_scale * (_now - this.start_time) + 'px"></div>';
       
   473     }
       
   474     if (this.editing_occurrence && this.editing_occurrence.date <= this.end_time && this.editing_occurrence.date >= this.start_time) {
       
   475         _html += '<div class="Tl-Grid-Editing" style="left: ' + this.editing_occurrence.x + 'px"></div>';
   438     }
   476     }
   439     this.$.find('.Tl-Grid').html(_html);
   477     this.$.find('.Tl-Grid').html(_html);
   440     this.drawOccurrences();
   478     this.drawOccurrences();
   441 }
   479 };
   442 
   480 
   443 Tlns.Classes.Timeline.prototype.loadOccurrences = function() {
   481 Tlns.Classes.Timeline.prototype.loadOccurrences = function() {
   444     var _this = this;
   482     var _this = this;
   445     $.getJSON(this.api_endpoint, {
   483     $.getJSON(this.api_endpoint, {
   446         method: this.api_method,
   484         method: this.api_method,
   449     }, function(_data) {
   487     }, function(_data) {
   450         console.log(_data);
   488         console.log(_data);
   451         _this.onOccurrencesLoaded(_data);
   489         _this.onOccurrencesLoaded(_data);
   452     });
   490     });
   453     
   491     
   454 }
   492 };
   455 
   493 
   456 Tlns.Classes.Timeline.prototype.onOccurrencesLoaded = function(_data) {
   494 Tlns.Classes.Timeline.prototype.onOccurrencesLoaded = function(_data) {
   457     for (var _i = 0; _i < _data.data.length; _i++) {
   495     for (var _i = 0; _i < _data.data.length; _i++) {
   458         this.createOrUpdateOccurrence(_data.data[_i]);
   496         this.createOrUpdateOccurrence(_data.data[_i]);
   459     }
   497     }
   460     if (!this.mouse_down) {
   498     if (!this.mouse_down) {
   461         this.drawOccurrences();
   499         this.drawOccurrences();
   462     }
   500     }
   463 }
   501 };
   464 
   502 
   465 Tlns.Classes.Timeline.prototype.deleteOccurrence = function(_id) {
   503 Tlns.Classes.Timeline.prototype.deleteOccurrence = function(_id) {
   466     this.occurrences = _(this.occurrences).reject(function(_occ) {
   504     this.occurrences = _(this.occurrences).reject(function(_occ) {
   467         return _occ.id == _id;
   505         return _occ.id == _id;
   468     });
   506     });
   469 }
   507 };
   470 
   508 
   471 Tlns.Classes.Timeline.prototype.getOccurrence = function(_id) {
   509 Tlns.Classes.Timeline.prototype.getOccurrence = function(_id) {
   472     return _(this.occurrences).find(function(_occ) {
   510     return _(this.occurrences).find(function(_occ) {
   473         return _occ.id == _id;
   511         return _occ.id == _id;
   474     });
   512     });
   475 }
   513 };
   476 
   514 
   477 Tlns.Classes.Timeline.prototype.createOrUpdateOccurrence = function(_data) {
   515 Tlns.Classes.Timeline.prototype.createOrUpdateOccurrence = function(_data) {
   478     var _id = _data.id,
   516     var _id = _data.id,
   479         _occurrence = this.getOccurrence(_id),
   517         _occurrence = this.getOccurrence(_id),
   480         typeinfo = this.class_info[_data.__CLASS__];
   518         typeinfo = this.class_info[_data.__CLASS__];
   484             this.occurrences.push(_occurrence);
   522             this.occurrences.push(_occurrence);
   485         }
   523         }
   486         _occurrence.update(_data);
   524         _occurrence.update(_data);
   487     }
   525     }
   488     return _occurrence;
   526     return _occurrence;
   489 }
   527 };
   490 
   528 
   491 Tlns.Classes.Timeline.prototype.showTooltip = function(_x, _y, _html) {
   529 Tlns.Classes.Timeline.prototype.showTooltip = function(_x, _y, _html) {
   492     this.$.find('.Tl-Overlay-Box')
   530     this.$.find('.Tl-Overlay-Box')
   493         .show()
   531         .show()
   494         .css({
   532         .css({
   495             left: _x + "px",
   533             left: _x + "px",
   496             top: _y + "px"
   534             top: _y + "px"
   497         });
   535         });
   498     this.$.find('.Tl-Overlay-Main').html(_html);
   536     this.$.find('.Tl-Overlay-Main').html(_html);
   499     
   537     
   500 }
   538 };
   501 
   539 
   502 Tlns.Classes.Timeline.prototype.hideTooltip = function() {
   540 Tlns.Classes.Timeline.prototype.hideTooltip = function() {
   503     this.$.find('.Tl-Overlay-Box').hide();
   541     this.$.find('.Tl-Overlay-Box').hide();
   504 }
   542 };
   505 
   543 
   506 Tlns.Classes.Timeline.prototype.drawOccurrences = function() {
   544 Tlns.Classes.Timeline.prototype.drawOccurrences = function() {
   507     var _this = this;
   545     var _this = this;
   508     _(this.occurrences).each(function(_occ) {
   546     _(this.occurrences).each(function(_occ) {
   509         _occ.x = _this.current_scale * (_occ.date - _this.start_time);
   547         _occ.x = _this.current_scale * (_occ.date - _this.start_time);
   562             _id = _el.attr("occurrence-id");
   600             _id = _el.attr("occurrence-id");
   563         if (typeof _id !== "undefined") {
   601         if (typeof _id !== "undefined") {
   564             var _occurrence = _this.getOccurrence(_id);
   602             var _occurrence = _this.getOccurrence(_id);
   565             if (!_this.is_dragging) {
   603             if (!_this.is_dragging) {
   566                 var _html = Mustache.to_html(Tlns.Templates.OccurrenceTooltip, _occurrence);
   604                 var _html = Mustache.to_html(Tlns.Templates.OccurrenceTooltip, _occurrence);
   567                 _this.showTooltip(_occurrence.x + 19, _occurrence.y + 20, _html);
   605                 _this.showTooltip(_occurrence.x, _occurrence.y, _html);
   568             }
   606             }
   569         }
   607         }
   570     }).mouseout(function() {
   608     }).mouseout(function() {
   571         var _el = $(this),
   609         var _el = $(this),
   572             _id = _el.attr("occurrence-id");
   610             _id = _el.attr("occurrence-id");
   574             var _occurrence = _this.getOccurrence(_id);
   612             var _occurrence = _this.getOccurrence(_id);
   575             _this.hideTooltip();
   613             _this.hideTooltip();
   576         }
   614         }
   577     });
   615     });
   578     
   616     
   579 }
   617 };
   580 
   618 
   581 Tlns.Classes.Timeline.prototype.getUnivers = function(_id) {
   619 Tlns.Classes.Timeline.prototype.getUnivers = function(_id) {
   582     return _(this.univers).find(function(_univ) {
   620     return _(this.univers).find(function(_univ) {
   583         return (_univ.id == _id);
   621         return (_univ.id == _id);
   584     });
   622     });
   585 }
   623 };
   586 
   624 
   587 /*
   625 /*
   588  * Univers
   626  * Univers
   589  */
   627  */
   590 
   628 
   600     
   638     
   601     _timeline.$.find('.Tl-UniversLabels').append(this.$label);
   639     _timeline.$.find('.Tl-UniversLabels').append(this.$label);
   602     
   640     
   603     var txtdiv = this.$label.find(".Tl-UniversText");
   641     var txtdiv = this.$label.find(".Tl-UniversText");
   604     txtdiv.css("margin-top", Math.floor((_timeline.univers_height - txtdiv.height()) / 2));
   642     txtdiv.css("margin-top", Math.floor((_timeline.univers_height - txtdiv.height()) / 2));
   605 }
   643 };
   606 
   644 
   607 /*
   645 /*
   608  * Occurrence
   646  * Occurrence
   609  */
   647  */
   610 
   648 
   611 Tlns.Classes.Occurrence = function(_timeline) {
   649 Tlns.Classes.Occurrence = function(_timeline) {
   612     this.timeline = _timeline;
   650     this.timeline = _timeline;
   613 }
   651 };
   614 
   652 
   615 Tlns.Classes.Occurrence.prototype.update = function(_data) {
   653 Tlns.Classes.Occurrence.prototype.update = function(_data) {
   616     this.original_data = _data;
   654     this.original_data = _data;
   617     this.id = _data.id;
   655     this.id = _data.id;
   618     this.date = new Date(1000 * (_data.dateFirstPublication || _data.dateCreate) || Date.now);
   656     this.date = new Date(1000 * (_data.dateFirstPublication || _data.dateCreate) || Date.now);
   620     this.title = _data.title;
   658     this.title = _data.title;
   621     this.type = _data.__CLASS__;
   659     this.type = _data.__CLASS__;
   622     this.importance = _data.importance;
   660     this.importance = _data.importance;
   623     var typeinfo = this.timeline.class_info[_data.__CLASS__];
   661     var typeinfo = this.timeline.class_info[_data.__CLASS__];
   624     this.univers_id = typeinfo.univers_id;
   662     this.univers_id = typeinfo.univers_id;
   625     if (_data.contentHasMedias && _data.contentHasMedias.length) {
   663     var media = _(_data.contentHasMedias).find(function(m) {
   626         this.image = _data.contentHasMedias[0].media.carre.replace(/carre\/[\d]+\/[\d]+/,'carre/32/32');
   664         return !!m.media.carre;
   627         this.detail_image = _data.contentHasMedias[0].media.carre.replace(/carre\/[\d]+\/[\d]+/,'carre/135/135');
   665     });
       
   666     if (media) {
       
   667         this.image = media.media.carre.replace(/carre\/[\d]+\/[\d]+/,'carre/32/32');
       
   668         this.detail_image = media.media.carre.replace(/carre\/[\d]+\/[\d]+/,'carre/135/135');
   628     }
   669     }
   629     if (typeinfo.picto) {
   670     if (typeinfo.picto) {
   630         this.image = this.timeline.picto_url + typeinfo.picto;
   671         this.image = this.timeline.picto_url + typeinfo.picto;
   631     }
   672     }
   632     this.univers = this.timeline.univers[this.univers_id];
   673     this.univers = this.timeline.univers[this.univers_id];
   637     var _tmp = $('<p>').html(_data.resume || "");
   678     var _tmp = $('<p>').html(_data.resume || "");
   638     var trimmedDesc = _tmp.text().trim().replace(/(\n|\r|\r\n)/mg,' ');
   679     var trimmedDesc = _tmp.text().trim().replace(/(\n|\r|\r\n)/mg,' ');
   639     this.description = trimmedDesc.replace(/(^.{60,80})[\s].+$/m,'$1&hellip;');
   680     this.description = trimmedDesc.replace(/(^.{60,80})[\s].+$/m,'$1&hellip;');
   640     this.detail_description = trimmedDesc.replace(/(^.{360,380})[\s].+$/m,'$1&hellip;');
   681     this.detail_description = trimmedDesc.replace(/(^.{360,380})[\s].+$/m,'$1&hellip;');
   641     this.url = this.timeline.url_base + _data.url;
   682     this.url = this.timeline.url_base + _data.url;
   642 }
   683 };
   643 
       
   644 Tlns.Classes.Occurrence.prototype.addDependency = function(_id) {
       
   645     if (_(this.dependsOn).indexOf(_id) == -1) {
       
   646         this.dependsOn.push(_id);
       
   647     }
       
   648 }
       
   649 
       
   650 Tlns.Classes.Occurrence.prototype.removeDependency = function(_id) {
       
   651     this.dependsOn = _(this.dependsOn).reject(function(_n) {
       
   652         return _n == _id;
       
   653     });
       
   654 }
       
   655 
   684 
   656 Tlns.Classes.Occurrence.prototype.toString = function() {
   685 Tlns.Classes.Occurrence.prototype.toString = function() {
   657     return "Occurrence " + this.type + ': "' + this.title + '"';
   686     return "Occurrence " + this.type + ': "' + this.title + '"';
   658 }
   687 };