I found it necessary to go back and automate the definition and display of blocks of values associated with different elements in a simulation. I’ve based it on a global canvas and will rewrite everything else accordingly. This will make updating the status of a simulation a lot simpler. One thing I may still add is a line or some other type of visual connection between the block of values and the element to which it refers. I note that each one of these things can take up a fair amount of space, so in the long run they should mostly be used for debugging or detailed monitoring.
Here’s the requisite code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
var globalWidth; var globalHeight; var canvas = document.getElementById("bcanimation"); if (canvas) { //element already exists if (canvas.nodeName == "CANVAS") { globalWidth = canvas.width; globalHeight = canvas.height; } else { //element is *not* a canvas alert("Error: Element you've linked to is *not* a canvas."); } } else { //element does not already exist and must be created canvas = document.createElement("canvas"); canvas.id = "bcanimation" canvas.height = 250; canvas.width = 380; globalWidth = canvas.width; globalHeight = canvas.height; document.body.appendChild(canvas); } canvas.style.border = "2px solid lime"; canvas.style.margin = "5px auto"; var globalCTX = canvas.getContext("2d"); //*************************************************************************************** //*** display variables //*************************************************************************************** function clearCanvas(color) { globalCTX.fillStyle = color; globalCTX.fillRect(0,0,globalWidth,globalHeight); }; //clearCanvas function displayValue(value,label,format,places) { //assumes alignment and color/fillStyle are set before calling this.value = value; this.label = label + ":"; this.format = format; this.places = places; globalCTX.font = "12px Arial"; this.width = globalCTX.measureText(label).width; this.getWidth = function() { return this.width; } this.drawLabel = function(x,y) { globalCTX.fillText(this.label,x,y); } this.drawValue = function(x,y) { var s; if (this.format == "integer") { s = this.value; } else if (this.format == "numdec") { s = this.value.toFixed(this.places); } else if (this.format == "numwide") { s = this.value.toPrecision(this.places); } else if (this.format == "text") { s = this.value; } else if (this.format == "bool") { if (this.value) { s = "TRUE"; } else { s = "FALSE"; } } globalCTX.fillText(s,x,y); } } //displayValue function displayGroup(label,x,y,vw,lc,vc,bc) { this.label = label; this.xLocation = x; this.yLocation = y; this.valueWidth = vw; this.labelColor = lc; this.valueColor = vc; this.borderColor = bc; this.maxLabelWidth = 0; globalCTX.font = "12px Arial"; this.valueCount = 0; this.valueList = new Array(); this.addValue = function(value,label,format,places) { var v = new displayValue(value,label,format,places); this.valueList.push(v); this.valueCount++; var w = v.getWidth(); if (w > this.maxLabelWidth) { this.maxLabelWidth = w; } } this.drawBasic = function() { this.height = (this.valueCount * 12) + 15; this.width = this.maxLabelWidth + this.valueWidth + 8; globalCTX.strokeStyle = this.borderColor; globalCTX.beginPath; globalCTX.moveTo(this.xLocation+0.5,this.yLocation+0.5); globalCTX.lineTo(this.xLocation+this.width+0.5,this.yLocation+0.5); globalCTX.lineTo(this.xLocation+this.width+0.5,this.yLocation+this.height+0.5); globalCTX.lineTo(this.xLocation+0.5,this.yLocation+this.height+0.5); globalCTX.lineTo(this.xLocation+0.5,this.yLocation+0.5); globalCTX.stroke(); globalCTX.font = "12px Arial"; globalCTX.fillStyle = this.labelColor; globalCTX.textAlign = "center"; globalCTX.fillText(this.label,this.xLocation+(this.width*0.5),this.yLocation+12); globalCTX.textAlign = "right"; for (var i=0; i<this.valueCount; i++) { var l = this.valueList[i].label; var x = this.xLocation+this.maxLabelWidth+5; var y = this.yLocation+(i*12)+24; //globalCTX.fillText(valueList[i].label,this.xLocation+this.maxLabelWidth+3,this.yLocation+(i*12)+12); globalCTX.fillText(l,x,y); } globalCTX.fillStyle = this.valueColor; globalCTX.textAlign = "left"; for (var i=0; i<this.valueCount; i++) { this.valueList[i].drawValue(this.xLocation+this.maxLabelWidth+8,this.yLocation+(i*12)+24); } } } //displayGroup //we've defined the mechanisms, now let's use them var fred = 4; var barney = Math.PI; var wilma = "Wilma"; var betty = true; var pebbles = 247.94837747587382040906; var bambam = 747; var testGroup = new displayGroup("Test Group",20,20,100,"#00BBFF","#FF0000","#FFFF00"); testGroup.addValue(fred,"Fred","integer"); testGroup.addValue(barney,"Barney","numdec",4); testGroup.addValue(wilma,"Wilma","text"); testGroup.addValue(betty,"Betty","bool"); testGroup.addValue(pebbles,"Pebbles","numdec",8); testGroup.addValue(bambam,"Bam Bam","numwide",5); clearCanvas("#000000"); testGroup.drawBasic(); |
The output looks like this: