diff -r 3a5423828487 -r dfdefb4dae2c integration/js/streamgraph.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/integration/js/streamgraph.js Mon Oct 15 14:19:51 2012 +0200 @@ -0,0 +1,132 @@ +function streamgraph($selector, $slider) { + + /* Constants */ + + var VMARGIN = 3, + YEARSHEIGHT = 20, + STARTTIME = new Date(2007,6,1), + ENDTIME = new Date(), + CURVE = .3, + COLORS = [ "#943a23", "#fbee97", "#cfbb95", "#da9761", "#ba5036" ], + SELECTEDCOLOR = "#c51810"; + + /* Generating random data */ + + var data = [], + clustercount = 12, + slicecount = 20, + maxdata = 10, + randpart = 4, + dampfactor = .333; + for (var i = 0; i < clustercount; i++) { + var line = [], + peaktime = Math.floor(Math.random() * slicecount); + for (var j = 0; j < slicecount; j++) { + var point = Math.min(maxdata, Math.max(0, (Math.random() - .5) * randpart + Math.max(0, maxdata * (1 - dampfactor * Math.abs(j - peaktime))))); + line.push(point); + } + data.push(line); + } + + /* Calculating scales and positions */ + + var width = $selector.width(), + height = $selector.height(), + transp = _.zip.apply( _, data ), + cumulative = _(transp).map(function(column) { + var total = 0; + return _(column).map(function(point) { + return total += point; + }); + }), + sums = _(cumulative).map(function(column) { + return _(column).last(); + }) + maxcol = _(sums).max(), + streamheight = height - YEARSHEIGHT, + yscale = (streamheight - 2 * VMARGIN) / maxcol, + centery = streamheight / 2, + xscale = width / (transp.length - 1), + txscale = width / (ENDTIME - STARTTIME), + coords = _(data).map(function(line, lineindex) { + return _(line).map(function(point, colindex) { + var lowercumul = lineindex ? cumulative[colindex][lineindex - 1] : 0, + uppercumul = cumulative[colindex][lineindex]; + return { + data: point, + x: xscale * colindex, + lowery: centery + yscale * ( ( sums[colindex] / 2 ) - lowercumul ), + uppery: centery + yscale * ( ( sums[colindex] / 2 ) - uppercumul ), + } + }); + }), + paths = _(coords).map(function(line) { + var lowerline = _(line).reduce(function(path, point, colindex) { + var res = path; + if (colindex) { + res += "," + (point.x - CURVE * xscale) + "," + point.lowery + "," + point.x + "," + point.lowery; + } else { + res += "M" + point.x + "," + point.lowery; + } + if (colindex < line.length - 1) { + res += "C" + (point.x + CURVE * xscale) + "," + point.lowery; + } + return res; + }, ""); + var upperline = _(line).reduceRight(function(path, point, colindex) { + var res = path; + if (colindex < line.length - 1) { + res += "," + (point.x + CURVE * xscale) + "," + point.uppery + "," + point.x + "," + point.uppery; + } else { + res += "L" + point.x + "," + point.uppery; + } + if (colindex) { + res += "C" + (point.x - CURVE * xscale) + "," + point.uppery; + } + return res; + }, ""); + return lowerline + upperline; + }); + + /* Drawing streamgraph*/ + + var paper = new Raphael($selector[0]); + + _(paths).each(function(path, index) { + var color = COLORS[index % COLORS.length], + path = paper.path(path); + path.attr({ + stroke: "none", + fill: color + }).mouseover(function() { + path.attr({ + fill: SELECTEDCOLOR + }); + }).mouseout(function() { + path.attr({ + fill: color + }) + }); + }); + + /* Drawing years */ + + paper.path("M0," + (height - YEARSHEIGHT) + "," + width + "," + (height - YEARSHEIGHT)) + var lastyear = ENDTIME.getFullYear(); + for (var i = STARTTIME.getFullYear(); i <= lastyear; i++) { + var x = txscale * (new Date(i,0,1) - STARTTIME); + paper.path("M" + x + ",0," + x + "," + height); + var x = txscale * (new Date(i,6,1) - STARTTIME); + paper.text(x, height - .5 * YEARSHEIGHT, i) + .attr({ + "text-anchor": "middle", + "font-family": "Times New Roman, serif", + "font-size": "14px" + }); + } + +} + +$(function() { + streamgraph($(".streamgraph"), $("#slider-range")); +})