Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

HTML
<div id="scrollcontainer" style="overflow:scroll; height:500px">

<canvas id="canvas">

Your browser does not support the HTML5 canvas tag.

</canvas>

</div>


<input type="button" value="Add Next Element" onclick="addNextElement();">

<input type="button" value="Add All Elements" onclick="addAllElements();">

<input type="button" value="Reset Drawing" onclick="reset();">


<table>

<tr><td>Observation Point in Time:</td><td id="observationPoint"><td></tr>

<tr><td>Elements That Start at the Observation Point:</td><td id="elementsStart"><td></tr>

<tr><td>Passed Time Units in Window:</td><td id="actualWindowWidth"><td></tr>

<tr><td>Elements in Window:</td><td id="elementsInWindow"><td></tr>

<tr><td>Count:</td><td id="count"><td></tr>

<tr><td>Sum:</td><td id="sum"><td></tr>

<tr><td>Avg:</td><td id="avg"><td></tr>

</table>




<table>

<tr>

<td>Window Width:</td><td><input id="window_width" value="10" /></td>

</tr>

<tr>

<td>Window Advance:</td><td><input id="window_advance" value="1" /></td>

</tr>

</table>


















<h2>Elements queue:</h2> 

<p>Samples: <select id="samples" size="1">

    <option value="1" selected="selected">Sample 1</option>

    <option value="2">Sample 2</option>

    <option value="3">Random</option>

</select> <input type="button" value="Set Sample Elements" onclick="setSample();"></p>

<pre>timestamp,display value[, other values]</pre>

<textarea id="elements" style="width: 300px; height: 150px;"></textarea>

<div id="infobox"></div>




<script>




var elements = [];

var

setInfoText canvas = document.getElementById('canvas');
var ctxfunction(infotext) {

	var infobox = document.getElementById('canvas').getContext('2d');
ctx.font"infobox");

	infobox.innerHTML = "20px Arial";
ctx.textAlign = 'left';
ctx.fillText("Push button below to add elements.", 50, 100);



setInfoText<p>" + infotext + "</p>" + infobox.innerHTML;

}




firstElement = function() {

	return elements[0];

}




lastElement = function(infotext) {

	var infobox = document.getElementById("infobox");

	infobox.innerHTML = "<p>" + infotext + "</p>" + infobox.innerHTML;

}




firstElement = function(return elements[elements.length-1];

}




startTsOfElement = function(element) {

	return elementsparseInt(element.split(",")[0]);

}




lastElementendTsOfElement = function(element) {

	return elements[elements.length-1];

}




startTsOfElement = function(element) {

	return parseInt(element.split(",")[0]);

}




endTsOfElement = function(element) {

var window_width = parseInt(document.getElementById("window_width").value);

	var window_widthadvance = parseInt(document.getElementById("window_widthadvance").value);

	var window_advance = parseInt(document.getElementById("window_advance").value);

	return Math.floorreturn Math.floor(startTsOfElement(element)/window_advance) * window_advance + window_width;

}




valueOfElement = function(element) {

	return element.split(",")[1];

}




posXOfElement = function(element) {

	return (startTsOfElement(element) - startTsOfElement(firstElement()))*50+25;

}




posYOfElement = function(element) {

	return 10;

}




posXStartOfValidity = function(element) {

	return posXOfElement(element);

}




posYStartOfValidity = function(element) {

	var idx = elements.indexOf(element);

	return 50 + (idx*20);

}







posXEndOfValidity = function(element) {

	return (endTsOfElement(element) - startTsOfElement(firstElement()))*50+25;

}




posYEndOfValidity = function(element) {

	return posYStartOfValidity(element);

}




setCanvasSize = function() {

	var canvas = document.getElementById('canvas');

	canvas.width = posXEndOfValidity(lastElement()) + 100;

	canvas.height = posYEndOfValidity(lastElement()) + 50;

}




drawGrid = function(ctx, observationPoint) {

	var timevalue = parseInt(startTsOfElement(firstElement()));

	ctx.font = "15px Arial";

	ctx.textAlign = 'left';

  	ctx.textBaseline = 'middle';

	ctx.fillText("Application Time t", 3, posYEndOfValidity(lastElement())+10);




	for(i = 0; i <= posXEndOfValidity(lastElement()) + 50; i = i + 50) {

		if(timevalue == observationPoint) {

			ctx.fillStyle = "rgba(0, 0, 255, 0.5)";

			

			ctx.rect(i, 0, 50, posYEndOfValidity(lastElement()) + 50);

			ctx.fill();

			ctx.fillStyle = 'blue';

		} else {

			ctx.fillStyle = 'black';

		}

		

		

		

		ctx.lineWidth=0.5;

		

		ctx.beginPath();

		ctx.moveTo(i,0);

		ctx.lineTo(i,posYEndOfValidity(lastElement()) + 50);

		ctx.stroke();

		

		ctx.font = "20px Arial";

		ctx.textAlign = 'center';

	  	ctx.textBaseline = 'middle';

		ctx.fillText(timevalue, i+25, posYEndOfValidity(lastElement()) + 40);

		timevalue = timevalue + 1;

	}

	

	ctx.beginPath();

	ctx.moveTo(0,posYEndOfValidity(lastElement()) + 20);

	ctx.lineTo(i,posYEndOfValidity(lastElement()) + 20);

	ctx.stroke();

}




isInWindow = function(element, observationPoint) {

	return parseInt(startTsOfElement(element)) <= observationPoint && parseInt(endTsOfElement(element)) > observationPoint;

}




elementsInWindow = function(observationPoint) {

	var elementsInWindow = [];

	for(i = 0; i < elements.length; ++i) {

		if(isInWindow(elements[i], observationPoint)) {

			elementsInWindow.push(elements[i]);

		}

	}

	return elementsInWindow;

}




drawElements = function(ctx, observationPoint) {

	for(i = 0; i < elements.length; ++i) {

		if(isInWindow(elements[i], observationPoint)) {

			ctx.fillStyle = 'blue';

			ctx.strokeStyle = '#0000ff';

			ctx.lineWidth=3;

			ctx.font = "bold 20px Arial";

		} else {

			ctx.fillStyle = 'black';

			ctx.strokeStyle = '#000000';

			ctx.lineWidth=1;

			ctx.font = "20px Arial";

		}

		

		

		

		if(i > 0 && startTsOfElement(elements[i]) == startTsOfElement(elements[i-1])) {

			if(i > 1 && startTsOfElement(elements[i]) == startTsOfElement(elements[i-2])) {

				// "+" has been printed already

			} else {

				ctx.textAlign = 'right';

			  	ctx.textBaseline = 'middle';

				ctx.fillText("+", posXOfElement(elements[i])+25, posYOfElement(elements[i]));

			}

		} else {

			ctx.textAlign = 'center';

		  	ctx.textBaseline = 'middle';

			ctx.fillText(valueOfElement(elements[i]), posXOfElement(elements[i]), posYOfElement(elements[i]));

		}

		

		ctx.beginPath();

		ctx.moveTo(posXStartOfValidity(elements[i]), posYStartOfValidity(elements[i]));

		ctx.lineTo(posXEndOfValidity(elements[i]), posYEndOfValidity(elements[i]));

		ctx.stroke();

		

		ctx.beginPath(); 

		ctx.arc(posXStartOfValidity(elements[i]), posYStartOfValidity(elements[i]), 5, 0, Math.PI*2, true);  

		ctx.closePath();

		ctx.fill();

		

		ctx.beginPath(); 

		ctx.arc(posXEndOfValidity(elements[i]), posYEndOfValidity(elements[i]), 5, 0, Math.PI*2, true);  

		ctx.closePath();

		ctx.fillStyle = 'white';

		ctx.fill();

		ctx.stroke();

	}

	ctx.fillStyle = 'black';

	ctx.strokeStyle = '#000000';

	ctx.lineWidth=1;

}




elementsStartAt = function(observationPoint) {

	var e = [];

	for(i = 0; i < elements.length; ++i) {

		if(startTsOfElement(elements[i]) == observationPoint) {

			e.push(elements[i]);

		}

	}

	return e;

}




setInfoData = function(observationPoint) {

	document.getElementById("observationPoint").innerHTML = observationPoint;

	document.getElementById("elementsStart").innerHTML = "[" + elementsStartAt(observationPoint).join("]; [") + "]";

	var allElementsInWindow = elementsInWindow(observationPoint);

	document.getElementById("elementsInWindow").innerHTML = "[" + allElementsInWindow.join("]; [") + "]";

	document.getElementById("count").innerHTML = allElementsInWindow.length;

	var sum = 0;

	for(i = 0; i < allElementsInWindow.length; ++i) {

		sum = sum + parseInt(valueOfElement(allElementsInWindow[i]));

	}

	document.getElementById("avg").innerHTML = sum / allElementsInWindow.length;

	document.getElementById("sum").innerHTML = sum;

}




drawWindowBox = function(ctx, observationPoint) {

	var ts;

	var window_width = parseInt(document.getElementById("window_width").value);

	for(i = startTsOfElement(firstElement()) - window_width; i <= observationPoint; ++i) {

		if(isInWindow(i + ",0", observationPoint)) {

			ts = i;

			break;

		}

	}

	ctx.strokeStyle = '#0000ff';

	ctx.lineWidth=3;

	ctx.beginPath(); 

	ctx.rect(posXOfElement(ts + ",0")-25, 0, posXOfElement((ts + window_width ) + ",0")-posXOfElement(ts + ",0"), 20);

	ctx.stroke();

	

	document.getElementById("actualWindowWidth").innerHTML = observationPoint - ts + 1;

}




draw = function(observationPoint) {

	observationPoint = observationPoint || startTsOfElement(lastElement());

	setInfoData(observationPoint);

	var ctx = document.getElementById('canvas').getContext('2d');

	setCanvasSize();

	drawGrid(ctx, observationPoint);

	drawElements(ctx, observationPoint);

	drawWindowBox(ctx, observationPoint);

}




function scrollToLastElement() {

	var div = document.getElementById("scrollcontainer");

	var scrollWidth = Math.max(div.scrollWidth, div.clientWidth);

	div.scrollLeft = scrollWidth - div.clientWidth;

}




addNextElement = function() {

	var nextElements = document.getElementById("elements").value.trim().split("\n");

	if(nextElements.length > 0 && nextElements[nextElements.length-1].trim().length > 0) {

		if(elements.length > 0 && startTsOfElement(lastElement()) > startTsOfElement(nextElements[0])) {

			// reset if the new element is not temporal after the current drawn elements

			reset();

		}

		elements.push(nextElements.shift());

		setInfoText("Element <em>" + elements[elements.length-1] + "</em> added.");

		document.getElementById("elements").value = nextElements.join("\n");

		draw();

		scrollToLastElement();

	} else {

		setInfoText("No next element.");

	}

}




addAllElements = function() {

	var nextElements = document.getElementById("elements").value.trim().split("\n");

	if(nextElements.length > 0 && nextElements[nextElements.length-1].trim().length > 0) {

		if(elements.length > 0 && startTsOfElement(lastElement()) > startTsOfElement(nextElements[0])) {

			// reset if the new elements are not temporal after the current drawn elements

			reset();

		}

		elements = elements.concat(nextElements);

		document.getElementById("elements").value = "";

		setInfoText(nextElements.length + " elements added.");

		draw();

		scrollToLastElement();

	} else {

		setInfoText("No elements.");

	}

}




mousePosToObservationPoint = function(mouseX, mouseY) {

	if(elements.length > 0) {

		return Math.floor(mouseX/50) + parseInt(startTsOfElement(firstElement()));

	} else {

		return 0;

	}

}




canvas = document.getElementById('canvas');

canvas.onmousemove = mousePos;




function mousePos(e) {

    if (e.offsetX) {

        mouseX = e.offsetX;

        mouseY = e.offsetY;

    }

    else if (e.layerX) {

        mouseX = e.layerX;

        mouseY = e.layerY;

    }

    var x = mousePosToObservationPoint(mouseX, mouseY);

    if(x > 0) {

		draw(x);

	}

}




setSample();




var randomTs = 10;




function setSample() {

	var sampleId = document.getElementById("samples").value;

	switch(parseInt(sampleId)) {

		case 1:

			var sample = "59,15\n61,16\n62,17\n62,18\n65,19\n66,20\n68,21\n70,11\n71,56\n72,54\n74,23\n80,34\n81,73\n82,11\n87,24";

			break;

		case 2:

			var e = [];

			for(i = 10; i < 100; ++i) {

				e.push(i + "," + i);

			}

			var sample = e.join("\n");

			break;

		case 3:

			var e = [];

			for(i = 1; i < 20; ++i) {

				randomTs = randomTs + Math.floor((Math.random() * 5) + 1);

				e.push(randomTs + "," + Math.floor((Math.random() * 99) + 1));

			}

			

			var sample = e.join("\n");

			break;

	}

	document.getElementById("elements").value = sample;

}




function reset() {

	elements = [];

	var canvas = document.getElementById('canvas');

	var ctx = document.getElementById('canvas').getContext('2d');

	ctx.clearRect(0, 0, canvas.width, canvas.height);

}

var canvas = document.getElementById('canvas');
canvas.width = 500;
var ctx = document.getElementById('canvas').getContext('2d');
ctx.font = "20px Arial";
ctx.textAlign = 'left';
ctx.fillText("To start the visualization:", 20, 100);
ctx.fillText("Push button below to add elements.", 20, 150);
</script>