Changed scale on timeline
authorveltr
Tue, 24 Sep 2013 14:22:36 +0200
changeset 114 19bd54c8bbbd
parent 113 c0d1d15130b3
child 115 52589f846d42
Changed scale on timeline
src/jocondelab/static/jocondelab/js/front-timeline.js
--- a/src/jocondelab/static/jocondelab/js/front-timeline.js	Tue Sep 24 10:45:54 2013 +0200
+++ b/src/jocondelab/static/jocondelab/js/front-timeline.js	Tue Sep 24 14:22:36 2013 +0200
@@ -1,41 +1,93 @@
 $(function() {
     
-    var startYear = -10000,
+    var startYear = -20000,
         endYear = 2012,
-        zoomLevel = 8,
+        gamma = 2,
+        zoomLevel = 4,
         zoomStep = Math.SQRT2,
         minZoomLevel = 1,
-        maxZoomLevel = 256,
+        maxZoomLevel = 64,
         sliderWidth = 3000,
-        baseSpan = (endYear - startYear),
         $slider = $(".timeline-mill-slider"),
         $tlcontainer = $(".timeline-container"),
         canvas = $tlcontainer.find('canvas')[0],
-        lineDistances = [ 1000, 500, 250, 100, 50, 25, 10, 5, 2 ],
-        miniLineDist = 1000,
-        cWidth, cHeight,
-        wSpan, wStart, wEnd, cScale, wLineDist, sScale, mScale,
-        wCenter = endYear - baseSpan / 16,
+        lineDistances = [ 50000, 25000, 10000, 5000, 2500, 1000, 500, 250, 100, 50, 25, 10, 5, 2 ],
+        miniLines = [-20000, -5000, -1000, 0, 500, 1000, 1500, 2000],
+        wCenter = .875,
         itemCount = 12,
         tlCache = [], tlIdCache = [], currentTerm = null,
-        startSlide = startYear, endSlide = endYear, userStartSlide = startSlide, userEndSlide = endSlide;
+        startSlide = startYear, endSlide = endYear, userStartSlide = startSlide, userEndSlide = endSlide,
+        fromYear, toYear;
+    
+    function tToW(t) {
+        //return Math.pow(2 / (2-Math.min(1,Math.max(0,t))) - 1,gamma);
+        return Math.pow(t, gamma);
+    }
+    function wToT(w) {
+        //return 2 - 2/(Math.pow(Math.min(1,Math.max(0,w)),1/gamma)+1);
+        return Math.pow(w, 1/gamma);
+    }
+    function tToYr(t) {
+        return startYear + (endYear - startYear) * t;
+    }
+    function yrToT(yr) {
+        return (yr - startYear)/(endYear - startYear);
+    }
+    function wToYr(w) {
+         return tToYr(wToT(w));
+    }
+    function yrToW(yr) {
+        return tToW(yrToT(yr));
+    }
+    function deltaXToDeltaW(dx) {
+        return dx / (zoomLevel * cWidth);
+    }
+    function deltaWToDeltaX(dw) {
+        return dw * zoomLevel * cWidth;
+    }
+    function wToX(w) {
+        return deltaWToDeltaX(w - wCenter + (.5 / zoomLevel));
+    }
+    function xToW(x) {
+        return deltaXToDeltaW(x) + wCenter - (.5 / zoomLevel);
+    }
+    function wToMini(w) {
+        return cWidth * w;
+    }
+    function miniToW(m) {
+        return m / cWidth;
+    }
+    function wToSlider(w) {
+        return zoomLevel * sliderWidth * (w - wCenter + (.5 / zoomLevel));
+    }
+    function sliderToW(slidepos) {
+        return slidepos / (sliderWidth * zoomLevel) + wCenter - (.5 / zoomLevel);
+    }
+    function yrToMiniX(yr) {
+        return wToMini(yrToW(yr));
+    }
+    function yrToX(yr) {
+        return wToX(yrToW(yr));
+    }
+    function yrToSliderPos(yr) {
+        return wToSlider(yrToW(yr));
+    }
+    function sliderPosToYr(slidepos) {
+        return wToYr(sliderToW(slidepos));
+    }
     
     function boundValue(val) {
-        return Math.max(Math.floor(wStart), Math.min(Math.floor(wEnd), val));
+        return Math.max(Math.floor(fromYear), Math.min(Math.floor(toYear), val));
     }
-    
     function updateCoords() {
         cWidth = $tlcontainer.width();
         cHeight = $tlcontainer.height();
-        wSpan = baseSpan / zoomLevel;
-        wStart = wCenter - wSpan / 2;
-        wEnd = wCenter + wSpan / 2;
-        cScale = cWidth / wSpan;
-        sScale = sliderWidth / wSpan;
-        mScale = cWidth / baseSpan;
         wLineDist = null;
+        fromYear = wToYr(wCenter - .5 / zoomLevel);
+        toYear = wToYr(wCenter + .5 / zoomLevel);
+        var yearAtQuarter = wToYr(wCenter - .25 / zoomLevel);
         for (var i = 0; i < lineDistances.length; i++) {
-            if (lineDistances[i] * cScale < 50) {
+            if (yrToX(yearAtQuarter + lineDistances[i]) - cWidth / 4 < 50) {
                 break;
             }
             wLineDist = lineDistances[i];
@@ -46,22 +98,6 @@
         updateSpans();
     }
     
-    function yrToSliderPos(yr) {
-        return sScale * (yr - wStart);
-    }
-    function sliderPosToYr(x) {
-        return wStart + x / sScale;
-    }
-    function yrToX(yr) {
-        return cScale * (yr - wStart);
-    }
-    function xToYr(x) {
-        return wStart + x / cScale;
-    }
-    function yrToMiniX(yr) {
-        return (yr - startYear)*mScale;
-    }
-    
     var itemTpl = _.template(
         '<li class="timeline-item"><div class="timeline-item-box<%- current ? " timeline-current" : "" %>"'
         + ' data-dbpedia-uri="<%- item.dbpedia_uri %>" style="left: <%- left %>px; width: <%- width %>px;">'
@@ -74,8 +110,8 @@
         
         var ctx = canvas.getContext("2d");
         
-        var xstart = yrToMiniX(wStart),
-            xend = yrToMiniX(wEnd);
+        var xstart = yrToMiniX(fromYear),
+            xend = yrToMiniX(toYear);
         ctx.fillStyle = "#f0f2ff";
         ctx.strokeStyle = "#3090ff";
         ctx.beginPath();
@@ -96,22 +132,23 @@
         ctx.fillRect( 0, 0, cWidth, 30 );
         ctx.font = 'bold 12px Arial,Helvetica';
         ctx.fillStyle = "#333333";
-        for (var y = miniLineDist * Math.ceil(startYear/miniLineDist); y <= endYear; y += miniLineDist ) {
-            var x = yrToMiniX(y);
+        for (var i = 0; i < miniLines.length; i++ ) {
+            var y = miniLines[i],
+                x = yrToMiniX(y);
             ctx.beginPath();
             ctx.moveTo(x,0);
             ctx.lineTo(x,6);
             ctx.moveTo(x,24);
             ctx.lineTo(x,30);
             ctx.stroke();
-            ctx.textAlign = ((y - startYear) < miniLineDist ? "left" : ((endYear - y) < miniLineDist ? "right" : "center") );
+            ctx.textAlign = (i ? (i == miniLines.length - 1 ? "right" : "center") : "left" );
             ctx.fillText(y || 1, x,20);
         }
         ctx.textAlign = 'center';
         ctx.font = 'bold 14px Arial,Helvetica';
         ctx.fillStyle = "#000000";
-        for (var y = wLineDist * Math.ceil(wStart/wLineDist); y <= wEnd; y += wLineDist ) {
-            var x = yrToX(y+1/2),
+        for (var y = wLineDist * Math.ceil(fromYear/wLineDist); y <= toYear; y += wLineDist ) {
+            var x = yrToX(y),
                 isPrimary = !((y/wLineDist) % 2);
             ctx.strokeStyle = (isPrimary ? "#000000": "#999999");
             ctx.beginPath();
@@ -124,10 +161,10 @@
         }
         var html = _(tlCache).chain()
             .filter(function(item) {
-                return (item.end_year >= wStart && item.start_year <= wEnd);
+                return (item.end_year >= fromYear && item.start_year <= toYear);
             }).first(itemCount)
             .sortBy(function(item) {
-                return (item.start_year + item.end_year)
+                return (item.start_year + item.end_year);
             }).map(function(item) {
                 var l = Math.max(0, yrToX(item.start_year)),
                     r = Math.min(cWidth, yrToX(item.end_year + 1));
@@ -142,19 +179,19 @@
         dbpediaBox.bind(".timeline-item-box");
         $(".timeline-item-box").click(function() {
             var $this = $(this);
-            currentTerm = $this.attr("data-dbpedia-uri")
+            currentTerm = $this.attr("data-dbpedia-uri");
             $(".timeline-item-box").removeClass("timeline-current");
             $this.addClass("timeline-current");
             loadSearchResults({ dbpedia_uri: currentTerm });
         });
     }
-    
+  
     function getData() {
         $.getJSON(
             urls.ajax_years,
             {
-                from_year: Math.floor(wStart),
-                to_year: Math.floor(wEnd)
+                from_year: Math.floor(fromYear),
+                to_year: Math.floor(toYear)
             },
             function(data) {
                 _(data).each(function(term) {
@@ -170,7 +207,7 @@
             }
         );
     }
-    
+
     var throttledRedraw = _.throttle(function() {
         updateCoords();
         redrawView();
@@ -190,13 +227,14 @@
     }).mousemove(function(e) {
         if (mousedown) {
             dragging = true;
+            var halfSpan = .5/zoomLevel;
             wCenter = Math.max(
-                startYear + wSpan / 2,
+                halfSpan,
                 Math.min(
-                    endYear - wSpan / 2,
+                    1 - halfSpan,
                     dragmini ?
-                        (wcStart + (e.clientX - xstart) / mScale) :
-                        (wcStart + (xstart - e.clientX) / cScale)
+                        (wcStart + miniToW(e.clientX - xstart)) :
+                        (wcStart + deltaXToDeltaW(xstart - e.clientX))
                     )
                 );
             throttledRedraw();
@@ -204,7 +242,7 @@
             return false;
         }
     }).mousewheel(function(e, d) {
-        var yrMouse = xToYr(e.clientX - $(this).offset().left),
+        var wMouse = xToW(e.clientX - $(this).offset().left),
             scaleRatio = (d > 0 ? zoomStep : 1/zoomStep);
         if (d < 0 && zoomLevel <= minZoomLevel) {
             return;
@@ -213,8 +251,8 @@
             return;
         }
         zoomLevel *= scaleRatio;
-        var newSpan = baseSpan / ( 2 * zoomLevel );
-        wCenter = Math.max(startYear + newSpan, Math.min(endYear - newSpan, yrMouse * (1 - 1 / scaleRatio) + wCenter / scaleRatio ));
+        var halfSpan = .5/zoomLevel;
+        wCenter = Math.max(halfSpan, Math.min(1 - halfSpan, wMouse * (1 - 1 / scaleRatio) + wCenter / scaleRatio ));
         throttledRedraw();
         debouncedGetData();
     });
@@ -232,7 +270,7 @@
         $endSpan.text(endSlide);
     }
     
-    //updateSpans();
+    updateSpans();
     
     $slider.slider({
         range: true,
@@ -249,7 +287,7 @@
     $(".timeline-mill-submit").click(function() {
         loadSearchResults({ from_year: startSlide, to_year: endSlide, show_years: 1 });
     });
-    
+
     throttledRedraw();
     
     getData();