Created
March 23, 2012 14:32
-
-
Save mathieuancelin/2171195 to your computer and use it in GitHub Desktop.
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
package controllers | |
import play.api._ | |
import play.api.mvc._ | |
import play.api.libs._ | |
import play.api.libs.iteratee._ | |
import play.api.libs.concurrent.Promise | |
import java.util.concurrent.TimeUnit | |
import scala.concurrent.stm._ | |
object Application extends Controller { | |
def index() = Action { | |
Ok( views.html.index() ) | |
} | |
def monitoringSource() = Action { | |
SimpleResult( | |
header = ResponseHeader( | |
OK, | |
Map( | |
CONTENT_LENGTH -> "-1", | |
CONTENT_TYPE -> "text/event-stream" | |
) | |
), | |
monitoring &> toEventSource | |
) | |
} | |
val toEventSource = Enumeratee.map[String] { msg => "data: " + msg + "\n\n" } | |
val monitoring = Enumerator.fromCallback{ () => | |
Promise.timeout( | |
Some( ((Math.random * 200) + 1).toInt + | |
":" + ((Math.random * 200) + 1).toInt + | |
":" + ((Math.random * 200) + 1).toInt + | |
":" + ((Math.random * 200) + 1).toInt), 1000, TimeUnit.MILLISECONDS ) | |
} | |
} |
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
@() | |
@main("SSE Monitoring") { | |
<h1>Monitoring</h1> | |
<div id="text"></div> | |
<div id="zone"> | |
<canvas id="drawing" style="border: 1px solid; background: #303030;"></canvas> | |
</div> | |
<script type="text/javascript"> | |
var charts = new Array( { | |
fromX: 10, fromY: 10, val: 0, | |
current: 0, doMove: 0, previous: -1 | |
}, { | |
fromX: 70, fromY: 10, val: 0, | |
current: 0, doMove: 0, previous: -1 | |
}, { | |
fromX: 130, fromY: 10, val: 0, | |
current: 0, doMove: 0, previous: -1 | |
}, { | |
fromX: 190, fromY: 10, val: 0, | |
current: 0, doMove: 0, previous: -1 | |
} ) | |
var canvas | |
var context | |
window.requestAnimFrame = (function(){ | |
return window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function(callback, element){ | |
window.setTimeout(callback, 1000 / 60); | |
}; | |
})(); | |
function openSSEConnection() { | |
var pushSource = new EventSource( '@routes.Application.monitoringSource()' ) | |
pushSource.onopen = function(e) { | |
console.log("[INFO] Monitoring event source opened !") | |
} | |
pushSource.onerror = function(e) { | |
if (pushSource.readyState == EventSource.CLOSED) { | |
console.log("[INFO] Monitoring event source closed !") | |
} else { | |
console.log("[ERROR] Monitoring event source error : %s", e) | |
} | |
charts.forEach(function(element, index, array) { | |
element.val = 0 | |
}) | |
context.fillStyle = "rgb(255,0,0)" | |
context.fillRect(245, 10, 10, 10) | |
$( '#text' ).html( "Error !!!" ) | |
} | |
pushSource.onmessage = function ( event ) { | |
var vals = event.data.split(":") | |
vals.forEach(function(element, index, array) { | |
charts[index].val = element * 1 | |
}) | |
//$( '#text' ).html( charts[0].val + " : " + charts[1].val + ":" + charts[2].val + ":" + charts[3].val ) | |
} | |
} | |
$( document ).ready( function () { | |
var canvas = document.getElementById('drawing'); | |
init(canvas, charts); | |
context.lineWidth = 1 | |
context.lineCap = 'square' | |
context.font = "7pt Calibri"; | |
charts.forEach(function(element, index, array) { | |
drawGrads(array, index) | |
}) | |
animate() | |
setTimeout(openSSEConnection, 200) | |
}) | |
/** | |
* Draw animation | |
**/ | |
function draw() { | |
charts.forEach(function(element, index, array) { | |
drawBar(array, index) | |
}) | |
} | |
function drawGrads(arr, index) { | |
var fromX = arr[index].fromX | |
var fromY = arr[index].fromY | |
// legend | |
context.fillStyle = "rgb(96,96,96)" | |
context.fillText("200", fromX + 34, fromY + 3) | |
context.fillText("150", fromX + 34, fromY + 53) | |
context.fillText("100", fromX + 34, fromY + 103) | |
context.fillText("50", fromX + 34, fromY + 153) | |
context.fillText("0", fromX + 34, fromY + 193) | |
} | |
function drawBar(arr, index) { | |
// if value didn't move then do nothing | |
if (arr[index].previous == arr[index].val) { | |
return | |
} | |
var fromX = arr[index].fromX | |
var fromY = arr[index].fromY | |
context.clearRect(fromX - 3, fromY - 3, 35, 210) | |
// bar background | |
context.fillStyle = "rgb(64,64,64)"; | |
context.fillRect (fromX - 2, fromY - 2, 34, 202); | |
// around bar | |
context.strokeStyle = "rgb(96,96,96)" | |
context.beginPath(); | |
context.moveTo(fromX,fromY); | |
context.lineTo(fromX + 30,fromY); | |
context.lineTo(fromX +30,fromY + 200); | |
context.lineTo(fromX,fromY + 200); | |
context.lineTo(fromX,fromY); | |
// legend bars | |
context.moveTo(fromX,fromY +50); | |
context.lineTo(fromX +30,fromY+50); | |
context.moveTo(fromX,fromY + 100); | |
context.lineTo(fromX +30,fromY + 100); | |
context.moveTo(fromX,fromY+150); | |
context.lineTo(fromX +30,fromY+150); | |
context.closePath(); | |
context.stroke(); | |
// bar | |
context.fillStyle = "00CCFF"; | |
arr[index].current = arr[index].current + arr[index].doMove | |
context.fillRect (fromX, fromY + (200 - arr[index].current), 30, 198 - (200 - arr[index].current)) | |
// compute next move | |
if (arr[index].current > arr[index].val) { | |
arr[index].doMove = calcInc( arr[index].current, arr[index].val ) | |
} | |
if (arr[index].current < arr[index].val) { | |
arr[index].doMove = calcInc( arr[index].current, arr[index].val ) | |
} | |
if (arr[index].current == arr[index].val) { | |
arr[index].doMove = 0 | |
arr[index].previous = arr[index].val | |
} | |
} | |
/** Speed for bars to get a natural movement **/ | |
var SPEEDY = 3 | |
var SLOWY = 1 | |
/** | |
* Return the right increment for bar so they accelerate | |
* and decelerate at start and stop between 2 values | |
**/ | |
function calcInc(current, val) { | |
if (current < val) { | |
if (val - current < 20) { | |
return SLOWY | |
} else { | |
return SPEEDY | |
} | |
} | |
if (current > val) { | |
if (current - val < 20) { | |
return -SLOWY | |
} else { | |
return -SPEEDY | |
} | |
} | |
} | |
/** | |
* Init the canvas size | |
**/ | |
function init(canvas, chart) { | |
canvas.width = (chart.length * 60) + 20; | |
canvas.height = 220; | |
context = canvas.getContext( '2d' ) | |
} | |
/** | |
* Callback function for animation drawing | |
**/ | |
function animate() { | |
requestAnimFrame( animate ) | |
draw() | |
} | |
</script> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment