Created
December 23, 2010 00:33
-
-
Save jfsiii/752371 to your computer and use it in GitHub Desktop.
The code for http://jsno.de./flot/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'), | |
app = module.exports = express.createServer(); | |
app | |
// Configuration | |
.configure(function () { | |
app.set('views', __dirname + '/views'); | |
app.set('view engine', 'jade'); | |
app.use(express.bodyDecoder()); | |
app.use(express.methodOverride()); | |
app.use(app.router); | |
app.use(express.staticProvider(__dirname + '/public')); | |
preloadFlot(); | |
}) | |
.configure('development', function () { | |
app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); | |
}) | |
.configure('production', function () { | |
app.use(express.errorHandler()); | |
}) | |
// Routes | |
.get('/', renderHomePage) | |
.get('/flot', renderFlotImage) | |
; | |
// Only listen on $ node app.js | |
if (!module.parent) { | |
app.listen(12914); | |
console.log("Express server listening on port %d", app.address().port) | |
} | |
/* FIXME */ | |
function preloadFlot() | |
{ | |
var document = require("jsdom").jsdom(), | |
window = document.createWindow(), | |
flot_location = 'http://jsno.de/javascripts/jquery.flot.svn.js', | |
text_location = 'http://jsno.de/javascripts/jquery.flot.text.js', | |
loadScript = function ( location, callback ) | |
{ | |
var script = document.createElement("script"); | |
script.src = location; | |
if (callback) script.onload = callback; | |
document.head.appendChild(script); | |
return script; | |
}; | |
window.Canvas = require('canvas'); | |
global.jQuery = require('jquery').create(window), | |
loadScript(flot_location, function () { loadScript(text_location); }); | |
} | |
/* eo FIXME*/ | |
function renderHomePage( req, res ) | |
{ | |
res.render('index', { | |
locals: { | |
title: 'JSNo.de' | |
} | |
}); | |
} | |
function renderFlotImage( req, res ) | |
{ | |
var params = require('url').parse(req.url, true), | |
examples = [ | |
{data: example1Data(), options: example1Options() }, | |
{data: example2Data(), options: example2Options() }, | |
{data: example3Data(), options: example3Options() } | |
], | |
index = /*params.query.example % (examples.length-1) || */ random(0, examples.length-1), | |
example = examples[index], | |
placeholder = jQuery(''), // empty jQuery object | |
plot = jQuery.plot(placeholder, example.data, example.options), | |
node_canvas = plot.getCanvas(), | |
node_canvas_plus_datestamp = datestampCanvas( node_canvas ), | |
image = node_canvas_plus_datestamp.toBuffer(); | |
res.writeHead(200, {'Content-Type': 'image/png'}); | |
res.write(image, 'binary'); | |
function extend( obj, extObj ) | |
{ | |
if (arguments.length > 2) { | |
for (var a = 1; a < arguments.length; a++) extend(obj, arguments[a]); | |
} else { | |
for (var i in extObj) obj[i] = extObj[i]; | |
} | |
return obj; | |
}; | |
function random( min, max ) | |
{ | |
min = min || 0; | |
max = max || 1; | |
var secs = (new Date()).getTime(); | |
var rand = min + Math.round( Math.random( secs ) * (max - min) ); | |
return rand; | |
} | |
function example1Data() | |
{ | |
var i, d1 = [], d2 = [], d3 = []; | |
for (i = 10; --i;) d1.push([i, parseInt(Math.random() * 30)]); | |
for (i = 10; --i;) d2.push([i, parseInt(Math.random() * 30)]); | |
for (i = 10; --i;) d3.push([i, parseInt(Math.random() * 30)]); | |
return [ | |
{label: "one", data: d1, lines: { show: false, fill: true, steps: false }, bars: { show: true, barWidth: 0.6 } }, | |
{label: "two", data: d2, lines: { show: false, fill: true, steps: false }, bars: { show: true, barWidth: 0.6 } }, | |
{label: "three", data: d3, lines: { show: false, fill: true, steps: false }, bars: { show: true, barWidth: 0.6 } } | |
]; | |
} | |
function example1Options() | |
{ | |
return { | |
width: 600, height: 300, | |
xaxis: { labelWidth: 50, labelHeight: 20 }, | |
yaxis: { labelWidth: 50, labelHeight: 20 }, | |
grid: { | |
backgroundColor: "#eee", | |
canvasText: {show: true, font: "sans 9px"}, | |
clickable: false, hoverable: false | |
} | |
}; | |
} | |
function example2Data() | |
{ | |
var d1 = [], d3 = [], d4 = [], d5 = [], d6 = []; | |
var d2 = [[0, 3], [4, 8], [8, 5], [9, 13]]; | |
var i, l = 14; | |
for (i = 0; i < l; i += 0.5) d1.push([i, Math.sin( random(i, l) )]); | |
for (i = 0; i < l; i += 0.5) d3.push([i, Math.cos( random(i, l) )]); | |
for (i = 0; i < l; i += 0.1) d4.push([i, Math.sqrt( random(i, i * 10) )]); | |
for (i = 0; i < l; i += 0.5) d5.push([i, Math.sqrt( random(i, l) )]); | |
for (i = 0; i < l; i += 0.5 + Math.random()) d6.push([i, Math.sqrt(2*i + Math.sin(i) + 5)]); | |
return [ | |
{ data: d1, label: "one", lines: { show: true, fill: true } }, | |
{ data: d2, label: "two", bars: { show: true } }, | |
{ data: d3, label: "three", points: { show: true } }, | |
{ data: d4, label: "four", lines: { show: true } }, | |
{ data: d5, label: "five", lines: { show: true }, points: { show: true } }, | |
{ data: d6, label: "six", lines: { show: true, steps: true } } | |
]; | |
} | |
function example2Options() | |
{ | |
return { | |
width: 600, height: 300, | |
xaxis: { labelWidth: 50, labelHeight: 20 }, | |
yaxis: { labelWidth: 50, labelHeight: 20 }, | |
grid: { | |
backgroundColor: "#eee", | |
canvasText: {show: true, font: "sans 9px"}, | |
legend: { | |
position: "sw", | |
backgroundColor: "#de4", | |
backgroundOpacity: 0.35 | |
} | |
} | |
}; | |
} | |
function example3Data() | |
{ | |
var i, PI2 = Math.PI*2, d1 = [], d2 = [], d3 = []; | |
for (i = 0; i < PI2; i += 0.25) d1.push([i, Math.sin(i)]); | |
for (i = 0; i < PI2; i += 0.25) d2.push([i, Math.cos(i)]); | |
for (i = 0; i < PI2; i += 0.1) d3.push([i, Math.tan(i)]); | |
return [ | |
{ label: "sin(x)", data: d1 }, | |
{ label: "cos(x)", data: d2 }, | |
{ label: "tan(x)", data: d3 } | |
]; | |
} | |
function example3Options() | |
{ | |
return { | |
width: 600, height: 300, | |
series: { lines: { show: true }, points: { show: true } }, | |
xaxis: { | |
labelWidth: 50, labelHeight: 20, | |
ticks: [ | |
0, | |
[Math.PI/2, "Pi/2"], | |
[Math.PI, "Pi"], | |
[Math.PI * 3/2, "3*Pi/2"], | |
[Math.PI * 2, "2*Pi"] | |
] | |
}, | |
yaxis: { | |
ticks: 10, min: -2, max: 2, | |
labelWidth: 50, labelHeight: 20 | |
}, | |
grid: { | |
backgroundColor: "#eee", | |
canvasText: {show: true, font: "sans 9px"} | |
} | |
}; | |
} | |
} | |
function datestampCanvas(canvas) | |
{ | |
var ctx = canvas.getContext('2d'); | |
var date = new Date(); | |
var utc_string = date.toUTCString(); | |
ctx.globalAlpha = 1; | |
ctx.font = "bold 30px sans-serif"; | |
ctx.translate(20, -40); | |
ctx.lineWidth = 1; | |
ctx.strokeStyle = '#aaa'; | |
ctx.strokeText(utc_string, 50, 100); | |
ctx.strokeText(date.getTime()+' epoch ms', 100, 150) | |
return canvas; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment