alcatel/static/js/streamgraph.js
changeset 27 8ca7f2cea729
child 37 3848e1813a30
equal deleted inserted replaced
26:94f586daa623 27:8ca7f2cea729
       
     1 function Streamgraph($selector) {
       
     2     
       
     3     /* Constants */
       
     4    
       
     5     var VMARGIN = 3,
       
     6         YEARSHEIGHT = 20,
       
     7         STARTTIME = new Date(2007,6,1),
       
     8         ENDTIME = new Date(),
       
     9         CURVE = .25,
       
    10         DATEPADDING = 10,
       
    11         COLORS = [ "#943a23", "#fbee97", "#cfbb95", "#da9761", "#ba5036" ],
       
    12         SELECTEDCOLOR = "#c51810"; 
       
    13     
       
    14     /* Generating random data */
       
    15     
       
    16     var data = [],
       
    17         clustercount = 12,
       
    18         slicecount = 20,
       
    19         maxdata = 10,
       
    20         randpart = 4,
       
    21         dampfactor = .333;
       
    22     for (var i = 0; i < clustercount; i++) {
       
    23         var line = [],
       
    24             peaktime = Math.floor(Math.random() * slicecount);
       
    25         for (var j = 0; j < slicecount; j++) {
       
    26             var point = Math.min(maxdata, Math.max(0, (Math.random() - .5) * randpart + Math.max(0, maxdata * (1 - dampfactor * Math.abs(j - peaktime)))));
       
    27             line.push(point);
       
    28         }
       
    29         data.push(line);
       
    30     }
       
    31     
       
    32     /* Calculating scales and positions */
       
    33     
       
    34     var width = $selector.width(),
       
    35         height = $selector.height(),
       
    36         transp = _.zip.apply( _, data ),
       
    37         cumulative = _(transp).map(function(column) {
       
    38             var total = 0;
       
    39             return _(column).map(function(point) {
       
    40                 return total += point;
       
    41             });
       
    42         }),
       
    43         sums = _(cumulative).map(function(column) {
       
    44             return _(column).last();
       
    45         })
       
    46         maxcol = _(sums).max(),
       
    47         streamheight = height - YEARSHEIGHT,
       
    48         yscale = (streamheight - 2 * VMARGIN) / maxcol,
       
    49         centery = streamheight / 2,
       
    50         xscale = width / (transp.length - 1),
       
    51         txscale = width / (ENDTIME - STARTTIME),
       
    52         coords = _(data).map(function(line, lineindex) {
       
    53             return {
       
    54                 points : _(line).map(function(point, colindex) {
       
    55                     var lowercumul = lineindex ? cumulative[colindex][lineindex - 1] : 0,
       
    56                         uppercumul = cumulative[colindex][lineindex];
       
    57                     return {
       
    58                         data: point,
       
    59                         x: xscale * colindex,
       
    60                         lowery: centery + yscale * ( ( sums[colindex] / 2 ) - lowercumul ),
       
    61                         uppery: centery + yscale * ( ( sums[colindex] / 2 ) - uppercumul ),
       
    62                     }
       
    63                 })
       
    64             }
       
    65         }),
       
    66         _(coords).each(function(line) {
       
    67             var lowerline = _(line.points).reduce(function(path, point, colindex) {
       
    68                 var res = path;
       
    69                 if (colindex) {
       
    70                     res += "," + (point.x - CURVE * xscale) + "," + point.lowery + "," + point.x + "," + point.lowery;
       
    71                 } else {
       
    72                     res += "M" + point.x + "," + point.lowery;
       
    73                 }
       
    74                 if (colindex < line.points.length - 1) {
       
    75                     res += "C" + (point.x + CURVE * xscale) + "," + point.lowery;
       
    76                 }
       
    77                 return res;
       
    78             }, "");
       
    79             var upperline = _(line.points).reduceRight(function(path, point, colindex) {
       
    80                 var res = path;
       
    81                 if (colindex < line.points.length - 1) {
       
    82                     res += "," + (point.x + CURVE * xscale) + "," + point.uppery + "," + point.x + "," + point.uppery;
       
    83                 } else {
       
    84                     res += "L" + point.x + "," + point.uppery;
       
    85                 }
       
    86                 if (colindex) {
       
    87                     res += "C" + (point.x - CURVE * xscale) + "," + point.uppery;
       
    88                 }
       
    89                 return res;
       
    90             }, "");
       
    91             line.path = lowerline + upperline;
       
    92         });
       
    93     
       
    94     /* Drawing streamgraph*/
       
    95    
       
    96     var paper = new Raphael($selector[0]);
       
    97     
       
    98     _(coords).each(function(line, index) {
       
    99         line.color = COLORS[index % COLORS.length];
       
   100         line.surface = paper.path(line.path);
       
   101         line.surface.attr({
       
   102             stroke: "none",
       
   103             fill: line.color
       
   104         });
       
   105     });
       
   106     
       
   107     /* Drawing years */
       
   108    
       
   109     paper.path("M0," + (height - YEARSHEIGHT) + "," + width + "," + (height - YEARSHEIGHT))
       
   110     var lastyear = ENDTIME.getFullYear();
       
   111     for (var i = STARTTIME.getFullYear(); i <= lastyear; i++) {
       
   112         var x = txscale * (new Date(i,0,1) - STARTTIME);
       
   113         paper.path("M" + x + ",0," + x + "," + height);
       
   114         var x = txscale * (new Date(i,6,1) - STARTTIME);
       
   115         paper.text(x, height - .5 * YEARSHEIGHT, i)
       
   116             .attr({
       
   117                 "text-anchor": "middle",
       
   118                 "font-family": "Times New Roman, serif",
       
   119                 "font-size": "14px"
       
   120             });
       
   121     }
       
   122     
       
   123     /* Drawing range window */
       
   124     
       
   125     var carregauche = paper.rect(width,-1,width,(2+height)),
       
   126         carredroite = paper.rect(-width,-1,width,(2+height)),
       
   127         attrcarres = {
       
   128             fill: "#333333",
       
   129             "fill-opacity": .5,
       
   130             stroke: SELECTEDCOLOR
       
   131         };
       
   132     carregauche.attr(attrcarres);
       
   133     carredroite.attr(attrcarres);
       
   134     
       
   135     var rangerect = paper.rect(0, (height - YEARSHEIGHT), width, YEARSHEIGHT);
       
   136     rangerect.attr({
       
   137         fill: SELECTEDCOLOR,
       
   138         stroke: "none"
       
   139     });
       
   140     
       
   141     function datetext(date) {
       
   142         var d = new Date(date),
       
   143             m = 1+d.getMonth(),
       
   144             y = d.getFullYear();
       
   145         return ((m < 10 ? "0" : "") + m + "/" + y);
       
   146     }
       
   147     
       
   148     var startdate = paper.text(DATEPADDING, height - .5 * YEARSHEIGHT, datetext(STARTTIME));
       
   149     startdate.attr({
       
   150         fill: "#ffffff",
       
   151         "text-anchor": "start"
       
   152     });
       
   153     var enddate = paper.text(width - DATEPADDING, height - .5 * YEARSHEIGHT, datetext(ENDTIME));
       
   154     enddate.attr({
       
   155         fill: "#ffffff",
       
   156         "text-anchor": "end"
       
   157     });
       
   158     
       
   159     /* Redrawing time slices for rollover effect */
       
   160    
       
   161     _(coords).each(function(line, index) {
       
   162         line.mousesurface = paper.path(line.path);
       
   163         console.log(line.mousesurface);
       
   164         line.mousesurface.attr({
       
   165             stroke: "none",
       
   166             fill: line.color,
       
   167             opacity: .01
       
   168         }).mouseover(function() {
       
   169             line.surface.attr({
       
   170                 fill: SELECTEDCOLOR
       
   171             })
       
   172         }).mouseout(function() {
       
   173             line.surface.attr({
       
   174                 fill: line.color
       
   175             })
       
   176         });
       
   177     });
       
   178     
       
   179     /* Returning a handler for slide value change */
       
   180     
       
   181     this.slidevalues = function(left, right) {
       
   182         left = left || 0;
       
   183         right = right || width;
       
   184         carregauche.attr({x: left - width});
       
   185         carredroite.attr({x: right});
       
   186         startdate.attr({
       
   187             x: DATEPADDING + left,
       
   188             text: datetext(STARTTIME.valueOf() + left / txscale)
       
   189         });
       
   190         enddate.attr({
       
   191             x: right - DATEPADDING,
       
   192             text: datetext(STARTTIME.valueOf() + right / txscale)
       
   193         });
       
   194         rangerect.attr({
       
   195             x: left,
       
   196             width: right - left
       
   197         });
       
   198     }
       
   199 
       
   200 }
       
   201 
       
   202 $(function() {
       
   203     window.streamgraph = new Streamgraph($(".streamgraph"));
       
   204     streamgraph.slidevalues.apply(streamgraph,$("#slider-range").dragslider("values"));
       
   205 })