diff options
| author | Kristian Lyngstol <kristian@bohemians.org> | 2015-04-10 01:39:04 +0200 | 
|---|---|---|
| committer | Kristian Lyngstol <kristian@bohemians.org> | 2015-04-10 01:39:04 +0200 | 
| commit | 59976f1f12b5f8c57d16c622e5f412e49d0c4062 (patch) | |
| tree | 0d254ced2574ec1ca3246b65704b68b1fbfceb9d /web | |
| parent | 9c7c9174b1fe53722e39a2af9f1269186ce604fb (diff) | |
NMS2: Integrate the prototype-map into nms2
Diffstat (limited to 'web')
| -rw-r--r-- | web/nms.gathering.org/nms2/map.html | 14 | ||||
| -rw-r--r-- | web/nms.gathering.org/nms2/map.js | 589 | 
2 files changed, 506 insertions, 97 deletions
| diff --git a/web/nms.gathering.org/nms2/map.html b/web/nms.gathering.org/nms2/map.html index dbede7c..685b014 100644 --- a/web/nms.gathering.org/nms2/map.html +++ b/web/nms.gathering.org/nms2/map.html @@ -44,7 +44,12 @@                                  <li><a href="#temp" onclick="setUpdater(handler_temp)">Temperature map</a></li>                                  <li><a href="#ping" onclick="setUpdater(handler_ping)">Ping map</a></li>                                  <li><a href="#traffic" onclick="setUpdater(handler_traffic)">Traffic map</a></li> +                                <li><a href="#disco" onclick="setUpdater(handler_disco)">DISCO</a></li> +				<li class="divider"> </li>                                  <li><a href="#" onclick="toggleNightMode()" title="Add 'nightMode' anywhere in the url to auto-enable">Toggle Night Mode</a></li> +				<li class="divider"> </li> +				<li><input type="range" id="scaler" name="points" min="0.5" max="3" step="0.01" onchange="scaleChange()" /></li> +				<li><a href="#">Scale: <div id="scaler-text"></div></a></li>                              </ul>                          </li>                      </ul> @@ -65,7 +70,10 @@          <div class="row-fluid">              <div class="span12"> -                <p id="playground"><img src="img/tg15-salkart.png" alt="" id="map" style="filter:invert; z-index: 0;"></p> +<canvas id="myCanvas" width="1920" height="1032" style="cursor: pointer; border:1px solid #000000;" onclick="canvasClick(event)"> +</canvas> + +<div style="display:none;"><img id="source" src="prototype/tg15-salkart-full.png" ></div>              </div>          </div> @@ -86,6 +94,8 @@      <script type="text/javascript">      updatePorts();      updatePing(); +	window.addEventListener('resize',resizeEvent,true); +	document.addEventListener('load',resizeEvent,true);      setInterval(updatePorts,5000);      setInterval(updateInfo,5000);      setInterval(updatePing,1000); @@ -100,6 +110,8 @@              setUpdater(handler_temp);      } else if (/#traffic/.exec(url)) {              setUpdater(handler_traffic); +    } else if (/#disco/.exec(url)) { +            setUpdater(handler_disco);      } else {              setUpdater(handler_ping);      } diff --git a/web/nms.gathering.org/nms2/map.js b/web/nms.gathering.org/nms2/map.js index 8aff190..d7581cc 100644 --- a/web/nms.gathering.org/nms2/map.js +++ b/web/nms.gathering.org/nms2/map.js @@ -12,6 +12,29 @@ var nms = {  	did_update:false // Set to 'true' after we've done some basic updating  }; +var c = document.getElementById("myCanvas"); +var ctx = c.getContext("2d"); +var fontSize = 12; +var fontFace = "Arial Black"; +var nightMode = false; +var nightBlur = {}; +var orig = { +	width:1920, +	height:1032 +	}; + +var canvas = {  +	width:0, +	height:0, +	scale:1 +}; +var margin = { +	x:10, +	y:20, +	text:3 +}; + +  /*   * Handlers. "updater" is run periodically when the handler is active, and   * "init" is run once when it's activated. @@ -41,6 +64,12 @@ var handler_traffic = {  	name:"Uplink traffic map"  }; +var handler_disco = { +	updater:randomizeColors, +	init:discoInit, +	name:"Disco fever" +}; +  function byteCount(bytes) {  	var units = ['', 'K', 'M', 'G', 'T', 'P'];  	i = 0; @@ -52,6 +81,8 @@ function byteCount(bytes) {  }  function toggleNightMode() { +	setNightMode(!nightMode); +	/*  	var bg = "white";  	var filter = "invert(0%)";  	if (!nms.night) { @@ -65,6 +96,7 @@ function toggleNightMode() {  	body.style.background = bg;  	var img = document.getElementById("map");  	img.style.webkitFilter = filter; +	*/  }  /* @@ -176,7 +208,11 @@ function switchInfo(x)  		tr = document.createElement("tr"); td1 = document.createElement("td"); td2 = document.createElement("td");  		td1.innerHTML = "Latency"; -		td2.innerHTML = nms.ping_data["switches"][x]["latency"]; +		if (nms.ping_data && nms.ping_data["switches"] && nms.ping_data["switches"][x]) { +			td2.innerHTML = nms.ping_data["switches"][x]["latency"]; +		} else { +			td2.innerHTML = "N/A"; +		}  		tr.appendChild(td1); tr.appendChild(td2); switchele.appendChild(tr);  		tr = document.createElement("tr"); td1 = document.createElement("td"); td2 = document.createElement("td"); @@ -209,65 +245,6 @@ function switchInfo(x)  }  /* - * Draw/create a specific switch - */ -function createSwitch(sysname, x, y, zorder, width, height) -{ -	var s = document.createElement("div"); -	var map = document.getElementById('map'); -	var top_offset = map.getBoundingClientRect().top; -	var left_offset = map.getBoundingClientRect().left; - -	var onclick = "console.log(\"foo\");"; -	s.style.position = 'absolute'; -	s.style.left = (left_offset + x) + 'px'; -	s.style.top = (top_offset + y) + 'px'; -	s.style.width = width + 'px'; -	s.style.height = height + 'px'; -	s.style.backgroundColor = '#0000ff'; -	s.style.border = '1px solid black'; -	s.style.padding = "0"; -	s.style.zIndex = zorder + 100; -	s.style.cursor = "pointer"; -	s.addEventListener("click", function(){ switchInfo(sysname); }); -	s.title = sysname + " - " + nms.switches_now["switches"][sysname]["management"]["ip"]; -	nms.globalmap[sysname] = s; - -	var span = document.createElement("div"); -	span.className = "switchname"; -	if (width < 1.5 * height) { -		span.className = "switchname rot"; -	} -	span.style.border = "0"; -	span.style.padding = "0"; -	s.appendChild(span); - -	var text = document.createTextNode(sysname); -	span.appendChild(text); - -	s.setAttribute("data-sysname", sysname); - -	document.body.appendChild(s); -} - -/* - * Draw/add switches. - */ -function drawSwitches() -{ -	for (var sysname in nms.switches_now["switches"]) { -		var s = nms.switches_now['switches'][sysname]["placement"]; -		createSwitch(sysname, -		              parseInt(s['x']), -			      parseInt(s['y']), -			      parseInt(s['zorder']), -		              parseInt(s['width']), -		              parseInt(s['height'])); -	} -	nms.drawn = true; -} - -/*   * Update various info elements periodically.   */  function updateInfo() @@ -280,29 +257,6 @@ function updateInfo()  }  /* - * Short hand for setting color on a switch in the map - */ -function colorSwitch(sysname, color) -{ -	if (nms.globalmap[sysname]) { -		nms.globalmap[sysname].style.background = color; -	} -} - -/* - * Reset switch color to "blue". - * Used when changing mode so colors don't linger for switches that are - * not explicitly colored by the update handler. - */ -function resetSwitches() { -	if (nms.switches_now) { -		for (var sw in nms.switches_now["switches"]) { -			colorSwitch(sw,"blue"); -		} -	} -} - -/*   * Update function for uplink map   * Run periodically when uplink map is active.   */ @@ -327,15 +281,15 @@ function uplinkUpdater()  			 }  		}  		if (uplinks == 0) { -			colorSwitch(sw,"blue"); +			setSwitchColor(sw,"blue");  		} else if (uplinks == 1) { -			colorSwitch(sw,"red"); +			setSwitchColor(sw,"red");  		} else if (uplinks == 2) { -			colorSwitch(sw, "yellow"); +			setSwitchColor(sw, "yellow");  		} else if (uplinks == 3) {  -			colorSwitch(sw, "green"); +			setSwitchColor(sw, "green");  		} else if (uplinks > 3) { -			colorSwitch(sw, "white"); +			setSwitchColor(sw, "white");  		}  	}  } @@ -372,15 +326,15 @@ function trafficUpdater()  		}  		var m = 1024 * 1024 / 8;  		if (speed == 0) { -			colorSwitch(sw,"blue"); +			setSwitchColor(sw,"blue");  		} else if (speed > (1000 * m)) { -			colorSwitch(sw,"red"); +			setSwitchColor(sw,"red");  		} else if (speed > (800 * m)) { -			colorSwitch(sw, "yellow"); +			setSwitchColor(sw, "yellow");  		} else if (speed > (5 * m)) {  -			colorSwitch(sw, "green"); +			setSwitchColor(sw, "green");  		} else { -			colorSwitch(sw, "white"); +			setSwitchColor(sw, "white");  		}  	}  } @@ -428,7 +382,7 @@ function tempUpdater()  	for (sw in nms.switches_now["switches"]) {  		var t = nms.switches_now["switches"][sw]["temp"]; -		colorSwitch(sw, temp_color(t)); +		setSwitchColor(sw, temp_color(t));  	}  } @@ -475,7 +429,7 @@ function rgb_from_latency(latency_ms)  function pingUpdater()  {  	for (var sw in nms.ping_data["switches"]) { -		colorSwitch(sw, gradient_from_latency(nms.ping_data["switches"][sw]["latency"])); +		setSwitchColor(sw, gradient_from_latency(nms.ping_data["switches"][sw]["latency"]));  	}  } @@ -504,7 +458,7 @@ function updateMap()  function setUpdater(fo)  {  	nms.updater = undefined; -	resetSwitches(); +	resetColors();  	fo.init();  	nms.updater = fo.updater;  	var foo = document.getElementById("updater_name"); @@ -523,6 +477,7 @@ function setUpdater(fo)  function initialUpdate()  {  	if (nms.ping_data && nms.switches_then && nms.switches_now && nms.updater != undefined && nms.did_update == false ) { +		resizeEvent();  		if (!nms.drawn) {  			drawSwitches();  		} @@ -559,6 +514,7 @@ function updatePorts()  		success: function (data, textStatus, jqXHR) {  			var  switchdata = JSON.parse(data);  			nms.switches_now = switchdata; +			parseIntPlacements();  			initialUpdate();  		}  	}); @@ -628,3 +584,444 @@ function updateSpeed()  	}  	nms.speed = speed_in;  } + +/* + * Draw a linknet with index i. + * + * XXX: Might have to change the index here to match backend + */ +function drawLinknet(i) +{ +	var c1 = nms.switches_now.linknets[i].c1 ? nms.switches_now.linknets[i].c1 : "blue"; +	var c2 = nms.switches_now.linknets[i].c2 ? nms.switches_now.linknets[i].c2 : "blue"; +	if (nms.switches_now.switches[nms.switches_now.linknets[i].sysname1] && nms.switches_now.switches[nms.switches_now.linknets[i].sysname2]) { +		connectSwitches(nms.switches_now.linknets[i].sysname1,nms.switches_now.linknets[i].sysname2, c1, c2); +	} +} + +/* + * Draw all linknets + */ +function drawLinknets() +{ +	if (nms.switches_now && nms.switches_now.linknets) { +	for (var i in nms.switches_now.linknets) { +		drawLinknet(i); +	} +	} +} + +/* + * Change both colors of a linknet. + * + * XXX: Probably have to change this to better match the backend data + */ +function setLinknetColors(i,c1,c2) +{ +	nms.switches_now.linknets[i].c1 = c1; +	nms.switches_now.linknets[i].c2 = c2; +} + +/* + * (Re)draw a switch 'sw'. + * + * Color defaults to 'blue' if it's not set in the data structure. + */ +function drawSwitch(sw) +{ +		var box = nms.switches_now['switches'][sw]['placement']; +		var color = nms.switches_now['switches'][sw]['color']; +		if (color == undefined) { +			color = "blue"; +		} +		ctx.fillStyle = color; +		if (nightMode && nightBlur[sw] != true) { +			ctx.shadowBlur = 10; +			ctx.shadowColor = "#00EE00"; +			nightBlur[sw] = true; +		} else { +			ctx.shadowBlur = 0; +			ctx.shadowColor = "#000000"; +		} +		drawBox(box['x'],box['y'],box['width'],box['height']); +		ctx.shadowBlur = 0; +		if ((box['width'] + 10 )< box['height'] ) +			drawSideways(sw,box['x'],box['y'],box['width'],box['height']); +		else +			drawRegular(sw,box['x'],box['y'],box['width'],box['height']); +} + +/* + * Make sure all placements of switches are parsed as integers so we don't + * have to pollute the code with pasreInt() every time we use it. + */ +function parseIntPlacements() { +	for (var sw in nms.switches_now.switches) { +		nms.switches_now.switches[sw]['placement']['x'] = +			parseInt(nms.switches_now.switches[sw]['placement']['x']); +		nms.switches_now.switches[sw]['placement']['y'] = +			parseInt(nms.switches_now.switches[sw]['placement']['y']); +		nms.switches_now.switches[sw]['placement']['width'] = +			parseInt(nms.switches_now.switches[sw]['placement']['width']); +		nms.switches_now.switches[sw]['placement']['height'] = +			parseInt(nms.switches_now.switches[sw]['placement']['height']); +	} +} + +/* + * Draw all switches + */ +function drawSwitches() +{ +	if (!nms.switches_now || !nms.switches_now.switches) +		return; +	for (var sw in nms.switches_now.switches) { +		drawSwitch(sw); +	} +	nms.drawn = true; +} + +/* + * Draw foreground/scene. + * + * This is used so linknets are drawn before switches. If a switch is all + * that has changed, we just need to re-draw that, but linknets require + * scene-redrawing. + */ +function drawScene() +{ +	ctx.font = Math.round(fontSize * canvas.scale) + "px " + fontFace; +	drawLinknets(); +	drawSwitches(); +} + +/* + * Set the scale factor and (re)draw the scene and background. + * Uses canvas.scale and updates canvas.height and canvas.width. + */ +function setScale() +{ +	c.height = canvas.height =  orig.height * canvas.scale ; +	c.width = canvas.width = orig.width * canvas.scale ; +	drawBG(); +	nightBlur = {}; +	drawScene(); +	document.getElementById("scaler").value = canvas.scale; +	document.getElementById("scaler-text").innerHTML = (parseFloat(canvas.scale)).toPrecision(3); +} + +/* + * Returns true if the coordinates (x,y) is inside the box defined by + * box.{x,y,w.h} (e.g.: placement of a switch). + */ +function isin(box, x, y) +{ +	if ((x >= box.x) && (x <= (box.x + box.width)) && (y >= box.y) && (y <= (box.y + box.height))) { +		return true; +	} +	return false; + +} + +/* + * Return the name of the switch found at coordinates (x,y), or 'undefined' + * if none is found. + */ +function findSwitch(x,y) { +	x = parseInt(parseInt(x) / canvas.scale); +	y = parseInt(parseInt(y) / canvas.scale); + +	for (var v in nms.switches_now.switches) { +		if(isin(nms.switches_now.switches[v]['placement'],x,y)) { +			return v; +		} +	} +	return undefined; +} + +/* + * Set switch color of 'sw' to 'c', then re-draw the switch. + */ +function setSwitchColor(sw, c) +{ +	nms.switches_now.switches[sw]['color'] = c; +	drawSwitch(sw); +} + +/* + * Return a random-ish color (for testing) + */ +function getRandomColor() +{ +	var i = Math.round(Math.random() * 5); +	var colors = [ "white", "red", "pink", "yellow", "orange", "green" ]; +	return colors[i];	 +} + +/* + * Helper functions for the front-end testing. + */ +function hideBorder() +{ +	c.style.border = ""; +} + +function showBorder() +{ +	c.style.border = "1px solid #000000"; +} + +/* + * Event handler for the front-end drag bar to change scale + */ +function scaleChange() +{ +	var scaler = document.getElementById("scaler").value; +	canvas.scale = scaler; +	setScale(); +} + +/* + * Draw a "cross hair" at/around (x,y). + * + * Used for testing. + */ +function crossHair(x,y) +{ +	ctx.fillStyle = "yellow"; +	ctx.fillRect(x,y,-100,10); +	ctx.fillStyle = "red"; +	ctx.fillRect(x,y,100,10); +	ctx.fillStyle = "blue"; +	ctx.fillRect(x,y,10,-100); +	ctx.fillStyle = "green"; +	ctx.fillRect(x,y,10,100); +} + +/* + * Called when a switch is clicked + */ +function switchClick(sw) +{ +	switchInfo(sw); +} + +/* + * Testing-function to randomize colors of linknets and switches + */ +function randomizeColors() +{ +	for (var i in nms.switches_now.linknets) { +		setLinknetColors(i, getRandomColor(), getRandomColor()); +	} +	drawLinknets(); +	for (var sw in nms.switches_now.switches) { +		setSwitchColor(sw, getRandomColor()); +	} +} + +function discoInit() +{ +	setNightMode(true); +	setLegend(1,"blue","0");	 +	setLegend(5,"red", "1"); +	setLegend(4,"yellow","2"); +	setLegend(3,"green", "3"); +	setLegend(2,"white","4"); +} +/* + * Resets the colors of linknets and switches. + * + * Useful when mode changes so we don't re-use colors from previous modes + * due to lack of data or bugs. + */ +function resetColors() +{ +	if (!nms.switches_now) +		return; +	if (nms.switches_now.linknets) { +		for (var i in nms.switches_now.linknets) { +			setLinknetColors(i, "blue","blue"); +		} +		drawLinknets(); +	} +	for (var sw in nms.switches_now.switches) { +		setSwitchColor(sw, "blue"); +	} +} + +/* + * onclick handler for the canvas + */ +function canvasClick(e) +{ +	var sw = findSwitch(e.pageX - e.target.offsetLeft, e.pageY - e.target.offsetTop); +	if (sw != undefined) { +		switchClick(sw); +	} +} + +/* + * Resize event-handler. + * + * Recomputes the scale and applies it. + * + * Has to use c.offset* since we are just scaling the canvas, not + * everything else. + * + */ +function resizeEvent() +{ +	var width = window.innerWidth - c.offsetLeft; +	var height = window.innerHeight - c.offsetTop; +	if (width / (orig.width + margin.x) > height  /  (orig.height + margin.y)) { +		canvas.scale = height / (orig.height + margin.y); +	} else { +		canvas.scale = width / (orig.width + margin.x); +	} +	setScale(); +} + +/* + * Draws the background image (scaled). + */ +function drawBG() +{ +	var image = document.getElementById('source'); +	image.style.webkitFilter = "invert(100%)"; +	ctx.drawImage(image, 0, 0, canvas.width, canvas.height); +	if (nightMode) { +		invertCanvas(); +	} +} + +function setNightMode(toggle) { +	nightMode = toggle; +	var body = document.getElementById("body"); +	body.style.background = toggle ? "black" : "white"; +	body.style.color = toggle ? "#00FF00" : "black"; +	setScale(); +} +/* + * Draw a box (e.g.: switch). + */ +function drawBox(x,y,boxw,boxh) +{ +	var myX = Math.round(x * canvas.scale); +	var myY = Math.round(y * canvas.scale); +	var myX2 = Math.round((boxw) * canvas.scale); +	var myY2 = Math.round((boxh) * canvas.scale); +	ctx.fillRect(myX,myY, myX2, myY2); +	ctx.lineWidth = Math.round(0.5 * canvas.scale); +	if (canvas.scale < 1.0) { +		ctx.lineWidth = 0.5; +	} +	ctx.strokeStyle = "#000000"; +	ctx.strokeRect(myX,myY, myX2, myY2); +} + +/* + * Draw text on a box - sideways! + * + * XXX: This is pretty nasty and should also probably take a box as input. + */ +function drawSideways(text,x,y,w,h) +{ +	ctx.rotate(Math.PI * 3 / 2); +	ctx.fillStyle = "white"; +	ctx.strokeStyle = "black"; +	ctx.lineWidth = Math.round(1 * canvas.scale); +	if (canvas.scale < 0.7) { +		ctx.lineWidth = 0.5; +	} +	ctx.fillText(text, - canvas.scale * (y + h - margin.text),canvas.scale * (x + w - margin.text) ); +	ctx.strokeText(text, - canvas.scale * (y + h - margin.text),canvas.scale * (x + w - margin.text) ); + +	ctx.rotate(Math.PI / 2); +} + +/* + * Draw background inverted (wooo) + * + * XXX: This is broken for chromium on local file system (e.g.: file:///) + * Seems like a chromium bug? + */ +function invertCanvas() { +	var canvas = document.getElementById('myCanvas'); +	var context = canvas.getContext('2d'); +	var canvas2 = document.getElementById('mySecretCanvas'); +	var context2 = canvas.getContext('2d'); + +	var imageObj = document.getElementById('source'); +	context2.drawImage(imageObj, 0, 0, canvas.width, canvas.height); + +	var imageData = context2.getImageData(0, 0, canvas.width, canvas.height); +	var data = imageData.data; + +	for(var i = 0; i < data.length; i += 4) { +		data[i] = 255 - data[i]; +		data[i + 1] = 255 - data[i + 1]; +		data[i + 2] = 255 - data[i + 2]; +	} +	context.putImageData(imageData, 0, 0); +} + +/* + * Draw regular text on a box. + * + * Should take the same format as drawSideways() + * + * XXX: Both should be renamed to have 'text' or something in them + */ +function drawRegular(text,x,y,w,h) { + +	ctx.fillStyle = "white"; +	ctx.strokeStyle = "black"; +	ctx.lineWidth = Math.round(1 * canvas.scale); +	if (canvas.scale < 0.7) { +		ctx.lineWidth = 0.5; +	} +	ctx.fillText(text, (x + margin.text) * canvas.scale, (y + h - margin.text) * canvas.scale); +	ctx.strokeText(text, (x + margin.text) * canvas.scale, (y + h - margin.text) * canvas.scale); +} + +/* + * Draw a line between switch "insw1" and "insw2", using a gradiant going + * from color1 to color2. + * + * XXX: beginPath() and closePath() is needed to avoid re-using the + * gradient/color  + */ +function connectSwitches(insw1, insw2,color1, color2) { +	var sw1 = nms.switches_now.switches[insw1].placement; +	var sw2 = nms.switches_now.switches[insw2].placement; +	if (color1 == undefined) +		color1 = "blue"; +	if (color2 == undefined) +		color2 = "blue"; +	var x0 = Math.round((sw1.x + sw1.width/2) * canvas.scale); +	var y0 = Math.round((sw1.y + sw1.height/2) * canvas.scale); +	var x1 = Math.round((sw2.x + sw2.width/2) * canvas.scale); +	var y1 = Math.round((sw2.y + sw2.height/2) * canvas.scale); +	var gradient = ctx.createLinearGradient(x1,y1,x0,y0); +	gradient.addColorStop(0, color1); +	gradient.addColorStop(1, color2); +	ctx.beginPath(); +	ctx.strokeStyle = gradient; +	ctx.moveTo(x0,y0); +	ctx.lineTo(x1,y1);  +	ctx.lineWidth = Math.round(2 * canvas.scale); +	ctx.closePath(); +	ctx.stroke(); +	ctx.moveTo(0,0); +} + +function debugIt(e) +{ +	console.log("Debug triggered"); +	console.log(e); +} + +window.addEventListener('resize',resizeEvent,true); +document.addEventListener('load',resizeEvent,true); + | 
