diff options
Diffstat (limited to 'test/when')
| -rw-r--r-- | test/when/demo-print.css | 13 | ||||
| -rw-r--r-- | test/when/demo.css | 21 | ||||
| -rw-r--r-- | test/when/index.html | 36 | ||||
| -rw-r--r-- | test/when/raphael-utils.js | 33 | ||||
| -rw-r--r-- | test/when/when.js | 187 |
5 files changed, 290 insertions, 0 deletions
diff --git a/test/when/demo-print.css b/test/when/demo-print.css new file mode 100644 index 0000000..c9a3035 --- /dev/null +++ b/test/when/demo-print.css @@ -0,0 +1,13 @@ +body { + background: #fff; + color: #000; + font: 100.1% "Lucida Grande", Lucida, Verdana, sans-serif; +} +#graph { + height: 480px; + left: 50%; + margin: 0 0 0 -320px; + position: absolute; + top: 0; + width: 640px; +} diff --git a/test/when/demo.css b/test/when/demo.css new file mode 100644 index 0000000..ccb1882 --- /dev/null +++ b/test/when/demo.css @@ -0,0 +1,21 @@ +body { + background: #333; + color: #fff; + font: 300 100.1% "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif; +} +#graph { + height: 480px; + left: 50%; + margin: -240px 0 0 -320px; + position: absolute; + top: 50%; + width: 640px; +} +#menus { + height: 480px; + left: 50%; + margin: -240px 0 0 -320px; + position: absolute; + top: 50%; + width: 640px; +} diff --git a/test/when/index.html b/test/when/index.html new file mode 100644 index 0000000..4010062 --- /dev/null +++ b/test/when/index.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>WHEN</title> + <script src="../raphael-min.js"></script> + <script src="raphael-utils.js"></script> + <script src="when.js"></script> + <style type="text/css" media="screen"> + body { + background: #333; + color: #fff; + font: 300 100.1% "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif; + } + #graph { + left: 50%; + position: absolute; + top: 50%; + height: 250px; + margin: -125px 0 0 -400px; + width: 800px; + } + #menus { + left: 50%; + position: absolute; + top: 50%; + margin: 125px 0 0 -400px; + width: 800px; + } + </style> + </head> + <body> + <div id="graph"></div> + <div id="menus"></div> + </body> +</html>
\ No newline at end of file diff --git a/test/when/raphael-utils.js b/test/when/raphael-utils.js new file mode 100644 index 0000000..626713e --- /dev/null +++ b/test/when/raphael-utils.js @@ -0,0 +1,33 @@ +Raphael.fn.drawGrid = function (x, y, w, h, wv, hv, color) { + color = color || "#000"; + var path = ["M", Math.round(x) + .5, Math.round(y) + .5, "L", Math.round(x + w) + .5, Math.round(y) + .5, Math.round(x + w) + .5, Math.round(y + h) + .5, Math.round(x) + .5, Math.round(y + h) + .5, Math.round(x) + .5, Math.round(y) + .5], + rowHeight = h / hv, + columnWidth = w / wv; + for (var i = 1; i < hv; i++) { + path = path.concat(["M", Math.round(x) + .5, Math.round(y + i * rowHeight) + .5, "H", Math.round(x + w) + .5]); + } + for (i = 1; i < wv; i++) { + path = path.concat(["M", Math.round(x + i * columnWidth) + .5, Math.round(y) + .5, "V", Math.round(y + h) + .5]); + } + return this.path(path.join(",")).attr({stroke: color}); +}; + +function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) { + var l1 = (p2x - p1x) / 2, + l2 = (p3x - p2x) / 2, + a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)), + b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y)); + a = p1y < p2y ? Math.PI - a : a; + b = p3y < p2y ? Math.PI - b : b; + var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2, + dx1 = l1 * Math.sin(alpha + a), + dy1 = l1 * Math.cos(alpha + a), + dx2 = l2 * Math.sin(alpha + b), + dy2 = l2 * Math.cos(alpha + b); + return { + x1: p2x - dx1, + y1: p2y + dy1, + x2: p2x + dx2, + y2: p2y + dy2 + }; +}
\ No newline at end of file diff --git a/test/when/when.js b/test/when/when.js new file mode 100644 index 0000000..4e0e6be --- /dev/null +++ b/test/when/when.js @@ -0,0 +1,187 @@ +/* +Tim Redfern Jan 2012 tim@eclectronics.org + +Animated graphing - Edmund Rice School Ties + +see analytics.js example + +http://net.tutsplus.com/tutorials/javascript-ajax/an-introduction-to-the-raphael-js-library/ + +aim for today: have a few items that can be chosen + +1) switch items - multiple lines view .. x amount of lines + 'other' +2) animate between views +3) rollover points +4) label axes +*/ + +var data,raphael,classOfRange,birthplaces,colleges,locations,fields; + +var graphData; + +var maxPaths; + +window.onload = function() { + loadData(); + createMenu(); + //alert(document.getElementById("holder").offsetWidth+","+document.getElementById("holder").offsetHeight); + //seems predictable, gives same result in chrome, firefox, mobile safari + var graph=document.getElementById('graph'); + raphael = new Raphael(graph, graph.offsetWidth, graph.offsetHeight); + drawGraph(); +} + +function graphableData(name) { + //organises a range of data to graph against a variable value + this.name=name; + this.data={}; + this.max=0; + this.addElement = function(element,value) { + if (element in this.data) { + if (value in this.data[element]) this.data[element][value]++; + else this.data[element][value]=1; + } + else { + this.data[element]={}; + this.data[element][value]=1 + } + if (this.data[element][value]>this.max) this.max=this.data[element][value]; + } + this.getElement = function(element) { + if (element in this.data) return data[element]; //returns an associative array + } + this.summary = function() { + var s= ""+name+": "+Object.keys(this.data).length+" elements, max "+this.max+"\n"; + var k=Object.keys(this.data); + //s+=k+":"; + for (i in k) { + s+=k[i]+":"; + var l=Object.keys(this.data[k[i]]); + for (j in l) s+=l[j]+"="+this.data[k[i]][l[j]]+","; + s+="\n"; + } + return s+"\n"; + } + +} + +function loadData() { + maxPaths=8; + //replace with json loader + fields=["Class size","Location","Birthplace","College","Career"]; + fieldNames=["classSize","location","birthplace","college","career"]; + //basic { name:"Joe", surname:"Murphy",school:"Dublin",classOf:"86",location:"Ireland",email:"joem20156@gmail.com"}, + //extended { name:"Joe", surname:"Murphy",school:"Dublin",classOf:"86",location:"Ireland",email:"joem20156@gmail.com",birthplace:"Ireland",college:"UCD",career:"construction",sports:["soccer","hurling"],nickname:"Virgil"}, + data = [ + { school:"Dublin",classOf:"86",location:"Ireland",birthplace:"Ireland",college:"UCD",career:"construction",sports:["soccer","hurling"],nickname:"Virgil"}, + { school:"Dublin",classOf:"87",location:"Ireland",birthplace:"Ireland",college:"NUIG",career:"law",sports:["soccer","gaelic"],nickname:"Con"}, + { school:"Dublin",classOf:"86",location:"Ireland",birthplace:"Ireland",college:"TCD",career:"teaching",sports:["gaelic","hurling"],nickname:"Morty"}, + { school:"Dublin",classOf:"88",location:"USA",birthplace:"UK",college:"UL",career:"army",sports:["soccer"],nickname:"Mick"}, + { school:"Dublin",classOf:"87",location:"Ireland",birthplace:"Ireland",college:"UCD",career:"law",sports:["soccer","gaelic"],nickname:"Johnjoe"}, + { school:"Dublin",classOf:"86",location:"UK",birthplace:"Ireland",college:"TCD",career:"teaching",sports:["handball","hurling"],nickname:"Mossy"}, + { school:"Dublin",classOf:"89",location:"USA",birthplace:"UK",college:"UL",career:"army",sports:["soccer"],nickname:"Mick"}, + { school:"Dublin",classOf:"90",location:"Ireland",birthplace:"Ireland",college:"UCD",career:"law",sports:["soccer","gaelic"],nickname:"Johnjoe"}, + { school:"Dublin",classOf:"88",location:"Ireland",birthplace:"Ireland",college:"UCC",career:"teaching",sports:["handball","hurling"],nickname:"Mossy"}, + ]; + //analyse data to populate menus etc, this may be loaded direct from corresponding server data + classOfRange={}; + classOfRange.start=3000; + classOfRange.end=0; + birthplaces={}; + colleges={}; + locations={}; + for (var i in data) { + var year = parseInt(data[i].classOf); + classOfRange.start=Math.min(classOfRange.start,year); + classOfRange.end=Math.max(classOfRange.end,year); + if (data[i].birthplace in birthplaces) birthplaces[data[i].birthplace]++; + else birthplaces[data[i].birthplace]=1; + if (data[i].college in colleges) colleges[data[i].college]++; + else colleges[data[i].college]=1; + if (data[i].location in locations) locations[data[i].location]++; + else locations[data[i].location]=1; + } + + var numYears=(classOfRange.end-classOfRange.start); + + //prepare all data for graphing + graphData={}; + for (i in fields) graphData[fields[i]]=new graphableData(fields[i]); + for (var i in data) { + var yearField + for (j in fields) { + if (fields[j]=="Class size") { + graphData[fields[j]].addElement("Class size",parseInt(data[i].classOf)); + } + else graphData[fields[j]].addElement(data[i][fieldNames[j]],parseInt(data[i].classOf)); + } + } + + ///* test + var message="from "+classOfRange.start+" to "+classOfRange.end+"\n"; + for (var i in graphData) message+=graphData[i].summary(); + alert(message); + //*/ +} + +function drawGraph() { + var color = "hsl(" + [.6, .5, .5] + ")"; + var numYears=(classOfRange.end-classOfRange.start); + var gutterX=10, + gutterY=16; + //draw grid + var gridX=(raphael.width-(gutterX*2))/numYears; + var gridY=(raphael.height-(gutterY*2)); + raphael.drawGrid(gutterX, gutterY, raphael.width-(gutterX*2), raphael.height -(gutterY*2), numYears, 10, "#000"); + //label axis + var txt = {font: '12px Helvetica, Arial', fill: "#fff"}; + for (var i=0;i<=numYears;i++) raphael.text(gutterX+(i*gridX),raphael.height-gutterY+8,classOfRange.start+i).attr(txt).toBack(); + //construct graph + var graph = raphael.path().attr({stroke: color, "stroke-width": 4, "stroke-linejoin": "round"}), + bgGraph = raphael.path().attr({stroke: "none", opacity: .3, fill: color}); + //default graph is 'Class size' + //find largest class + var classSize=[]; + for (var i=0;i<=numYears;i++) classSize[i]=0; + for (var i in data) { + classSize[parseInt(data[i].classOf)-classOfRange.start]++; + } + var classMax=0; + for (var i in classSize) classMax=Math.max(classMax,classSize[i]); + var path,bgPath; + var stepY=(gridY/classMax); + for (var i=0;i<=numYears;i++) { + var x=gutterX+(i*gridX), + y=raphael.height-gutterY-(stepY*classSize[i]); + if (!i) { + path=["M",x,y,"C",x,y]; + bgPath=["M", gutterX , raphael.height - gutterY, "L", x, y, "C", x, y]; + } + if (i&&i<numYears-1) { + var Y0 = Math.round(raphael.height - gutterY - (stepY*classSize[i-1])), + X0 = Math.round(gutterX + (gridX * (i - .5))), + Y2 = Math.round(raphael.height - gutterY - (stepY*classSize[i+1])), + X2 = Math.round(gutterX + (gridX * (i + 1.5))); + var a = getAnchors(X0, Y0, x, y, X2, Y2); + path = path.concat([a.x1, a.y1, x, y, a.x2, a.y2]); + bgPath = bgPath.concat([a.x1, a.y1, x, y, a.x2, a.y2]); + } + } + path = path.concat([x, y, x, y]); + bgPath = bgPath.concat([x, y, x, y, "L", x, raphael.height - gutterY, "z"]); + graph.attr({path: path}); + bgGraph.attr({path: bgPath}); +} + +function createMenu() { + var menu="<select id='select' onchange='doGraph(this.selectedIndex)'>\n"; + for (i in fields) menu+="<option>"+fields[i]+"</option>/n"; + menu+="</select>\n"; + document.getElementById("menus").innerHTML=menu; +} + +function doGraph(which){ + //draw 1 or multiple graphs. animate between items + //maximum number of graphs + alert(fields[which]); +} |
