integration/js/streamgraph.js
changeset 8 dfdefb4dae2c
child 9 86ddd934464a
equal deleted inserted replaced
7:3a5423828487 8:dfdefb4dae2c
       
     1 function streamgraph($selector, $slider) {
       
     2     
       
     3     /* Constants */
       
     4    
       
     5     var VMARGIN = 3,
       
     6         YEARSHEIGHT = 20,
       
     7         STARTTIME = new Date(2007,6,1),
       
     8         ENDTIME = new Date(),
       
     9         CURVE = .3,
       
    10         COLORS = [ "#943a23", "#fbee97", "#cfbb95", "#da9761", "#ba5036" ],
       
    11         SELECTEDCOLOR = "#c51810"; 
       
    12     
       
    13     /* Generating random data */
       
    14     
       
    15     var data = [],
       
    16         clustercount = 12,
       
    17         slicecount = 20,
       
    18         maxdata = 10,
       
    19         randpart = 4,
       
    20         dampfactor = .333;
       
    21     for (var i = 0; i < clustercount; i++) {
       
    22         var line = [],
       
    23             peaktime = Math.floor(Math.random() * slicecount);
       
    24         for (var j = 0; j < slicecount; j++) {
       
    25             var point = Math.min(maxdata, Math.max(0, (Math.random() - .5) * randpart + Math.max(0, maxdata * (1 - dampfactor * Math.abs(j - peaktime)))));
       
    26             line.push(point);
       
    27         }
       
    28         data.push(line);
       
    29     }
       
    30     
       
    31     /* Calculating scales and positions */
       
    32     
       
    33     var width = $selector.width(),
       
    34         height = $selector.height(),
       
    35         transp = _.zip.apply( _, data ),
       
    36         cumulative = _(transp).map(function(column) {
       
    37             var total = 0;
       
    38             return _(column).map(function(point) {
       
    39                 return total += point;
       
    40             });
       
    41         }),
       
    42         sums = _(cumulative).map(function(column) {
       
    43             return _(column).last();
       
    44         })
       
    45         maxcol = _(sums).max(),
       
    46         streamheight = height - YEARSHEIGHT,
       
    47         yscale = (streamheight - 2 * VMARGIN) / maxcol,
       
    48         centery = streamheight / 2,
       
    49         xscale = width / (transp.length - 1),
       
    50         txscale = width / (ENDTIME - STARTTIME),
       
    51         coords = _(data).map(function(line, lineindex) {
       
    52             return _(line).map(function(point, colindex) {
       
    53                 var lowercumul = lineindex ? cumulative[colindex][lineindex - 1] : 0,
       
    54                     uppercumul = cumulative[colindex][lineindex];
       
    55                 return {
       
    56                     data: point,
       
    57                     x: xscale * colindex,
       
    58                     lowery: centery + yscale * ( ( sums[colindex] / 2 ) - lowercumul ),
       
    59                     uppery: centery + yscale * ( ( sums[colindex] / 2 ) - uppercumul ),
       
    60                 }
       
    61             });
       
    62         }),
       
    63         paths = _(coords).map(function(line) {
       
    64             var lowerline = _(line).reduce(function(path, point, colindex) {
       
    65                 var res = path;
       
    66                 if (colindex) {
       
    67                     res += "," + (point.x - CURVE * xscale) + "," + point.lowery + "," + point.x + "," + point.lowery;
       
    68                 } else {
       
    69                     res += "M" + point.x + "," + point.lowery;
       
    70                 }
       
    71                 if (colindex < line.length - 1) {
       
    72                     res += "C" + (point.x + CURVE * xscale) + "," + point.lowery;
       
    73                 }
       
    74                 return res;
       
    75             }, "");
       
    76             var upperline = _(line).reduceRight(function(path, point, colindex) {
       
    77                 var res = path;
       
    78                 if (colindex < line.length - 1) {
       
    79                     res += "," + (point.x + CURVE * xscale) + "," + point.uppery + "," + point.x + "," + point.uppery;
       
    80                 } else {
       
    81                     res += "L" + point.x + "," + point.uppery;
       
    82                 }
       
    83                 if (colindex) {
       
    84                     res += "C" + (point.x - CURVE * xscale) + "," + point.uppery;
       
    85                 }
       
    86                 return res;
       
    87             }, "");
       
    88             return lowerline + upperline;
       
    89         });
       
    90     
       
    91     /* Drawing streamgraph*/
       
    92    
       
    93     var paper = new Raphael($selector[0]);
       
    94     
       
    95     _(paths).each(function(path, index) {
       
    96         var color = COLORS[index % COLORS.length],
       
    97             path = paper.path(path);
       
    98         path.attr({
       
    99             stroke: "none",
       
   100             fill: color
       
   101         }).mouseover(function() {
       
   102             path.attr({
       
   103                 fill: SELECTEDCOLOR
       
   104             });
       
   105         }).mouseout(function() {
       
   106             path.attr({
       
   107                 fill: color
       
   108             })
       
   109         });
       
   110     });
       
   111     
       
   112     /* Drawing years */
       
   113    
       
   114     paper.path("M0," + (height - YEARSHEIGHT) + "," + width + "," + (height - YEARSHEIGHT))
       
   115     var lastyear = ENDTIME.getFullYear();
       
   116     for (var i = STARTTIME.getFullYear(); i <= lastyear; i++) {
       
   117         var x = txscale * (new Date(i,0,1) - STARTTIME);
       
   118         paper.path("M" + x + ",0," + x + "," + height);
       
   119         var x = txscale * (new Date(i,6,1) - STARTTIME);
       
   120         paper.text(x, height - .5 * YEARSHEIGHT, i)
       
   121             .attr({
       
   122                 "text-anchor": "middle",
       
   123                 "font-family": "Times New Roman, serif",
       
   124                 "font-size": "14px"
       
   125             });
       
   126     }
       
   127 
       
   128 }
       
   129 
       
   130 $(function() {
       
   131     streamgraph($(".streamgraph"), $("#slider-range"));
       
   132 })