Skip to content

Instantly share code, notes, and snippets.

@tarkatronic
Created December 9, 2009 16:59
Show Gist options
  • Save tarkatronic/252601 to your computer and use it in GitHub Desktop.
Save tarkatronic/252601 to your computer and use it in GitHub Desktop.
A mashup of the analytics demo and linechart plugin for gRaphael
<html>
<head>
<script type="text/javascript" src="raphael-1.2.5.js"></script>
<script type="text/javascript" src="raphael.path.methods.js"></script>
<script type="text/javascript" src="raphael.primitives.js"></script>
<script type="text/javascript" src="g.raphael-0.4.js"></script>
<script type="text/javascript" src="g.analytics.js"></script>
<script type="text/javascript">
$(function () {
$("#data").css({
position: "absolute",
left: "-9999em",
top: "-9999em"
});
});
window.onload = function () {
// Grab the data
var labels = [],
data = [];
$("#data th").each(function () {
labels.push($(this).html());
});
$("#data td").each(function () {
data.push($(this).html());
});
r = Raphael("holder",846,350);
var count_font = {font: '12px Fontin-Sans,Arial',fill:'#fff'},
label_font = {font: '11px Fontin-Sans,Arial',fill:'#fff'},
frame = r.rect(10,10,150,50,5).attr({fill:'#000',stroke:'none',opacity:.6}).hide(),
framedot = r.circle(25,25,7).hide().attr({stroke:'#fff','stroke-width':1}),
counter = r.text(32,25,'Loading...').attr(count_font).hide(),
label = r.text(32,47,'Loading...').attr(label_font).hide(),
is_label_visible = false,
timers = [],
chart = r.g.analytics(0,0,846,350,data,labels).hoverColumn(function(){
for(var i=0,ii=timers.length;i<ii;i++) clearTimeout(timers[i]);
var newx = (this.x + 7.5);
if(newx+frame.attr('width')>846) newx -= (frame.attr('width')+15);
frame.show().toFront().animate({x:newx},200*is_label_visible);
framedot.attr({fill:this.symbols.items[0].attr('fill')}).show().toFront().animate({cx:(newx+15)},200*is_label_visible);
counter.attr({text:this.values[0]+' registrations'}).show().toFront().animate({x:(newx+82)},200*is_label_visible);
label.attr({text:this.label}).show().toFront().animate({x:(newx+72)},200*is_label_visible);
this.symbols.attr('r',7);
is_label_visible = true;
r.safari();
},
function(){
this.symbols.attr('r',5);
timers.push(setTimeout(function(){
frame.hide();
framedot.hide();
counter.hide();
label.hide();
is_label_visible = false;
r.safari();
}, 50));
});
};
</script>
</head>
<body>
<table id="data">
<tr><th>11-10</th><td>43</td></tr>
<tr><th>11-11</th><td>38</td></tr>
<tr><th>11-12</th><td>23</td></tr>
<tr><th>11-13</th><td>20</td></tr>
<tr><th>11-14</th><td>19</td></tr>
<tr><th>11-15</th><td>16</td></tr>
<tr><th>11-16</th><td>11</td></tr>
<tr><th>11-17</th><td>14</td></tr>
<tr><th>11-18</th><td>7</td></tr>
<tr><th>11-19</th><td>5</td></tr>
<tr><th>11-20</th><td>4</td></tr>
<tr><th>11-21</th><td>11</td></tr>
<tr><th>11-22</th><td>138</td></tr>
<tr><th>11-23</th><td>59</td></tr>
<tr><th>11-24</th><td>32</td></tr>
<tr><th>11-25</th><td>122</td></tr>
<tr><th>11-26</th><td>80</td></tr>
<tr><th>11-27</th><td>53</td></tr>
<tr><th>11-28</th><td>27</td></tr>
<tr><th>11-29</th><td>24</td></tr>
<tr><th>11-30</th><td>14</td></tr>
<tr><th>12-01</th><td>19</td></tr>
<tr><th>12-02</th><td>22</td></tr>
<tr><th>12-03</th><td>15</td></tr>
<tr><th>12-04</th><td>12</td></tr>
<tr><th>12-05</th><td>10</td></tr>
<tr><th>12-07</th><td>0</td></tr>
<tr><th>12-08</th><td>0</td></tr>
<tr><th>12-09</th><td>0</td></tr>
</table>
<div id="holder"></div>
</body>
</html>
Math.average=function(){var l=arguments.length,t=0;for(var i=0;i<l;i++){t+=arguments[i];}return (t/l);}
Raphael.fn.g.analytics = function(x, y, width, height, valuesy, labels, opts) {
opts = opts || {};
if(!this.raphael.is(valuesy[0], "array")) {
valuesy = [valuesy];
}
var all_y = Array.prototype.concat.apply([], valuesy),
max_y = Math.max.apply(Math, all_y),
gutter_t = opts.topgutter || 23,
gutter_r = opts.rightgutter || 15,
gutter_b = opts.bottomgutter || 40,
gutter_l = opts.leftgutter || 40,
ysteps = opts.ysteps || 10,
colors = opts.colors || Raphael.fn.g.colors,
gridcolor = opts.gridcolor || '#333',
labelfont = opts.labelfont || {font:'12px Fontin-Sans, Arial',fill:'#fff'},
valuefont = opts.valuefont || {font:'10px Fontin-Sans, Arial',fill:'#000'},
columns = this.set(),
dots = this.set(),
exported = this.set();
if(!opts.maintain_order) valuesy.sort(function(a,b){return Math.average.apply(Math,b)-Math.average.apply(Math,a);});
var max_x = 0;
for(var i=0;i<valuesy.length;i++){j=valuesy[i].length;if(j>max_x)max_x=j;}
max_x-=1; // Keep this 0-based
var x_step = (width-gutter_l-gutter_r)/max_x;
var y_step = (height-gutter_t-gutter_b)/max_y; // Distance between each y value
var y_height = (height-gutter_t-gutter_b)/ysteps;
this.drawGrid(gutter_l,gutter_t,(width-gutter_l-gutter_r),(height-gutter_t-gutter_b),max_x,ysteps,gridcolor);
for(var i=0;i<=ysteps;i++){this.text(Math.round(gutter_l/2),Math.round(height-gutter_b-(i*y_height)),Math.round(i*(max_y/ysteps))).attr(valuefont).toBack()}
for(var i=0;i<valuesy.length;i++){
cur_line = valuesy[i];
var path = this.path().attr({stroke:colors[i],'stroke-width':4,'stroke-linejoin':'round'}),
bg = this.path().attr({stroke:'none',opacity:.3,fill:colors[i]}).moveTo(gutter_l,(height-gutter_b));
for(var j=0;j<=max_x;j++){
var x = Math.round(gutter_l + (x_step * j));
var y = Math.round((height - gutter_b) - (y_step * cur_line[j]));
var dot = this.circle(x,y,5).attr({fill:colors[i],stroke:'#000'});
dots.push(dot);
// Begin/extend the main path (the line between points)
path[j==0?"moveTo":"cplineTo"](x,y,10); // Not sure what the 10 signifies? Perhaps the curve radius?
bg[j==0?"lineTo":"cplineTo"](x,y,10);
j > columns.length - 1 ? (columns.push(rect = this.rect(x-(x_step/2),gutter_t,x_step,(height-gutter_t-gutter_b)).attr({stroke:'none',fill:'#fff',opacity:0}))) : rect=columns[j];
i==0 && this.text(x-6,height-16,labels[j]).attr(labelfont).toBack().rotate(-60,true) && (rect.label = labels[j]);
rect.x = x;
!rect.y ? rect.y = [y] : rect.y.push(y);
!rect.values ? rect.values = [cur_line[j]] : rect.values.push(cur_line[j]);
//!rect.symbols ? rect.symbols = [dot] : rect.symbols.push(dot);
if(!rect.symbols) rect.symbols = this.set();
rect.symbols.push(dot);
}
bg.lineTo((width-gutter_r),(height-gutter_b)).andClose();
}
exported.dots = dots;
exported.columns = columns;
exported.hoverColumn = function(fin,fout){columns && columns.mouseover(fin).mouseout(fout);return this;}
exported.hover = function(fin,fout){dots && dots.mouseover(fin).mouseout(fout);return this;}
return exported;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment