Skip to content

Instantly share code, notes, and snippets.

@foeken
Created January 11, 2011 10:47
Show Gist options
  • Save foeken/774287 to your computer and use it in GitHub Desktop.
Save foeken/774287 to your computer and use it in GitHub Desktop.
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)]);
}
return null; //this.path(path.join(",")).attr({stroke: color});
};
$(function () {
$("#data").css({
position: "absolute",
left: "-9999em",
top: "-9999em"
});
});
window.drawGraph = function () {
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
};
}
// Grab the data
var labels = [],
data = [];
$("#data tfoot th").each(function () {
labels.push($(this).html());
});
$("#data tbody td").each(function () {
data.push($(this).html());
});
$("#holder").remove();
$("body").append('<div id="holder"></div>')
// Draw
var width = 800,
height = 250,
leftgutter = 30,
bottomgutter = 20,
topgutter = 20,
colorhue = .6 || Math.random(),
color = "hsb(" + [colorhue, .5, 1] + ")",
color2 = "hsb(" + [.2, .5, 1] + ")",
white = "hsb(" + [colorhue, .5, 1.5] + ")",
r = Raphael("holder", width, height),
txt = {font: '12px Helvetica, Arial', fill: "#fff"},
txt1 = {font: '10px Helvetica, Arial', fill: "#fff"},
txt2 = {font: '12px Helvetica, Arial', fill: "#000"},
X = (width - leftgutter) / labels.length,
max = Math.max.apply(Math, data),
min = Math.min.apply(Math, data),
Y = (height - bottomgutter - topgutter) / (max-min);
y_axis_offset = Y*(min);
bottomgutter = bottomgutter - y_axis_offset;
r.drawGrid(leftgutter + X * .5 + .5, topgutter + .5, width - leftgutter - X, height - topgutter, 10, 10, "#333",a);
a = r.path(["M",291,21,"V", height-bottomgutter].join(',')).attr({stroke:color2,"stroke-width": 4});
var path = r.path().attr({stroke: color, "stroke-width": 4, "stroke-linejoin": "round"}),
//path2 = r.path().attr({stroke: color2, "stroke-width": 4, "stroke-linejoin": "round"}),
bgp = r.path().attr({stroke: "none", opacity: .3, fill: color}),
label = r.set(),
is_label_visible = false,
leave_timer,
blanket = r.set();
label.push(r.text(60, 12, "24 hits").attr(txt));
label.push(r.text(60, 27, "22 September 2008").attr(txt1).attr({fill: color}));
label.hide();
var frame = r.popup(100, 100, label, "right").attr({fill: "#000", stroke: "#666", "stroke-width": 2, "fill-opacity": .7}).hide();
var p, bgpp;
var dots = [];
for (var i = 0, ii = labels.length; i < ii; i++) {
var y = Math.round(height - bottomgutter - Y * data[i]),
x = Math.round(leftgutter + X * (i + .5)),
t = r.text(x, height - 6 + y_axis_offset, labels[i]).attr(txt)//.toBack();
if (!i) {
p = ["M", x, y, "C", x, y];
bgpp = ["M", leftgutter + X * .5, height - bottomgutter, "L", x, y, "C", x, y];
}
if (i && i < ii - 1) {
var Y0 = Math.round(height - bottomgutter - Y * data[i - 1]),
X0 = Math.round(leftgutter + X * (i - .5)),
Y2 = Math.round(height - bottomgutter - Y * data[i + 1]),
X2 = Math.round(leftgutter + X * (i + 1.5));
var a = getAnchors(X0, Y0, x, y, X2, Y2);
p = p.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
bgpp = bgpp.concat([a.x1, a.y1, x, y, a.x2, a.y2]);
}
var dot = r.circle(x, y, 4).attr({fill: "#000", stroke: color, "stroke-width": 2});
dots.push(dot);
blanket.push(r.rect(leftgutter + X * i, 0, X, height).attr({stroke: "none", fill: "#fff", opacity: 0}));
var rect = blanket[blanket.length - 1];
(function (x, y, data, lbl, dot) {
var timer, i = 0;
rect.hover(function () {
clearTimeout(leave_timer);
var side = "right";
if (x + frame.getBBox().width > width) {
side = "left";
}
var ppp = r.popup(x, y, label, side, 1);
frame.show().stop().animate({path: ppp.path}, 200 * is_label_visible);
label[0].attr({text: data + " hit" + (data == 1 ? "" : "s")}).show().stop().animateWith(frame, {translation: [ppp.dx, ppp.dy]}, 200 * is_label_visible);
label[1].attr({text: lbl + " September 2008"}).show().stop().animateWith(frame, {translation: [ppp.dx, ppp.dy]}, 200 * is_label_visible);
dot.attr("r", 6);
is_label_visible = true;
}, function () {
dot.attr("r", 4);
leave_timer = setTimeout(function () {
frame.hide();
label[0].hide();
label[1].hide();
is_label_visible = false;
}, 1);
});
})(x, y, data[i], labels[i], dot);
}
p = p.concat([x, y, x, y]);
bgpp = bgpp.concat([x, y, x, y, "L", x, height - bottomgutter, "z"]);
path.attr({path: p});
r.path(["M",leftgutter + X * .5 + .5,height+y_axis_offset-20,"H",width-leftgutter+X]).attr({ stroke: white, "stroke-width": 1 })
p2 = path.getSubpath(0,460)
r.path(p2).attr({stroke: color2, "stroke-width": 4});
for (var i=0; i < dots.length; i++) {
dots[i].toFront();
}
bgp.attr({path: bgpp});
frame.toFront();
label[0].toFront();
label[1].toFront();
blanket.toFront();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment