{"id":1056,"date":"2016-10-10T22:45:27","date_gmt":"2016-10-11T03:45:27","guid":{"rendered":"http:\/\/rpchurchill.com\/?p=1056"},"modified":"2017-02-03T14:37:39","modified_gmt":"2017-02-03T19:37:39","slug":"a-simple-discrete-event-simulation-part-22","status":"publish","type":"post","link":"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/10\/10\/a-simple-discrete-event-simulation-part-22\/","title":{"rendered":"A Simple Discrete-Event Simulation: Part 22"},"content":{"rendered":"<p>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&#8217;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.<\/p>\n<p>Here&#8217;s the requisite code.<\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">\r\n    var globalWidth;\r\n    var globalHeight;\r\n    \r\n    var canvas = document.getElementById(\"bcanimation\");\r\n    if (canvas) {\r\n      \/\/element already exists\r\n      if (canvas.nodeName == \"CANVAS\") {\r\n        globalWidth = canvas.width;\r\n        globalHeight = canvas.height;\r\n      } else {\r\n        \/\/element is *not* a canvas\r\n        alert(\"Error: Element you've linked to is *not* a canvas.\");\r\n      }\r\n    } else {\r\n      \/\/element does not already exist and must be created\r\n      canvas = document.createElement(\"canvas\");\r\n      canvas.id = \"bcanimation\"\r\n      canvas.height = 250;\r\n      canvas.width = 380;\r\n      globalWidth = canvas.width;\r\n      globalHeight = canvas.height;\r\n      document.body.appendChild(canvas);\r\n    }  \r\n    canvas.style.border = \"2px solid lime\";\r\n    canvas.style.margin = \"5px auto\";\r\n    var globalCTX = canvas.getContext(\"2d\");\r\n\/\/***************************************************************************************\r\n\/\/*** display variables\r\n\/\/***************************************************************************************\r\n    function clearCanvas(color) {\r\n      globalCTX.fillStyle = color;\r\n      globalCTX.fillRect(0,0,globalWidth,globalHeight);\r\n    };  \/\/clearCanvas\r\n\r\n    function displayValue(value,label,format,places) {\r\n      \/\/assumes alignment and color\/fillStyle are set before calling\r\n      this.value = value;\r\n      this.label = label + \":\";\r\n      this.format = format;\r\n      this.places = places;\r\n      globalCTX.font = \"12px Arial\";\r\n      this.width = globalCTX.measureText(label).width;\r\n      this.getWidth = function() {\r\n        return this.width;\r\n      }\r\n      this.drawLabel = function(x,y) {\r\n        globalCTX.fillText(this.label,x,y);\r\n      }\r\n      this.drawValue = function(x,y) {\r\n        var s;\r\n        if (this.format == \"integer\") {\r\n          s = this.value;\r\n        } else if (this.format == \"numdec\") {\r\n          s = this.value.toFixed(this.places);\r\n        } else if (this.format == \"numwide\") {\r\n          s = this.value.toPrecision(this.places);\r\n        } else if (this.format == \"text\") {\r\n          s = this.value;\r\n        } else if (this.format == \"bool\") {\r\n          if (this.value) {\r\n            s = \"TRUE\";\r\n          } else {\r\n            s = \"FALSE\";\r\n          }\r\n        }\r\n        globalCTX.fillText(s,x,y);\r\n      }\r\n    }  \/\/displayValue\r\n    function displayGroup(label,x,y,vw,lc,vc,bc) {\r\n      this.label = label;\r\n      this.xLocation = x;\r\n      this.yLocation = y;\r\n      this.valueWidth = vw;\r\n      this.labelColor = lc;\r\n      this.valueColor = vc;\r\n      this.borderColor = bc;\r\n      this.maxLabelWidth = 0;\r\n      globalCTX.font = \"12px Arial\";\r\n      this.valueCount = 0;\r\n      this.valueList = new Array();\r\n      this.addValue = function(value,label,format,places) {\r\n        var v = new displayValue(value,label,format,places);\r\n        this.valueList.push(v);\r\n        this.valueCount++;\r\n        var w = v.getWidth();\r\n        if (w > this.maxLabelWidth) {\r\n          this.maxLabelWidth = w;\r\n        }\r\n      }\r\n      this.drawBasic = function() {\r\n        this.height = (this.valueCount * 12) + 15;\r\n        this.width = this.maxLabelWidth + this.valueWidth + 8;\r\n        globalCTX.strokeStyle = this.borderColor;\r\n        globalCTX.beginPath;\r\n        globalCTX.moveTo(this.xLocation+0.5,this.yLocation+0.5);\r\n        globalCTX.lineTo(this.xLocation+this.width+0.5,this.yLocation+0.5);\r\n        globalCTX.lineTo(this.xLocation+this.width+0.5,this.yLocation+this.height+0.5);\r\n        globalCTX.lineTo(this.xLocation+0.5,this.yLocation+this.height+0.5);\r\n        globalCTX.lineTo(this.xLocation+0.5,this.yLocation+0.5);\r\n        globalCTX.stroke();\r\n        globalCTX.font = \"12px Arial\";\r\n        globalCTX.fillStyle = this.labelColor;\r\n        globalCTX.textAlign = \"center\";\r\n        globalCTX.fillText(this.label,this.xLocation+(this.width*0.5),this.yLocation+12);\r\n        globalCTX.textAlign = \"right\";\r\n        for (var i=0; i<this.valueCount; i++) {\r\n          var l = this.valueList[i].label;\r\n          var x = this.xLocation+this.maxLabelWidth+5;\r\n          var y = this.yLocation+(i*12)+24;\r\n          \/\/globalCTX.fillText(valueList[i].label,this.xLocation+this.maxLabelWidth+3,this.yLocation+(i*12)+12);\r\n          globalCTX.fillText(l,x,y);\r\n        }\r\n        globalCTX.fillStyle = this.valueColor;\r\n        globalCTX.textAlign = \"left\";\r\n        for (var i=0; i<this.valueCount; i++) {\r\n          this.valueList[i].drawValue(this.xLocation+this.maxLabelWidth+8,this.yLocation+(i*12)+24);\r\n        }\r\n      }\r\n    }  \/\/displayGroup\r\n\r\n    \/\/we've defined the mechanisms, now let's use them\r\n    var fred = 4;\r\n    var barney = Math.PI;\r\n    var wilma = \"Wilma\";\r\n    var betty = true;\r\n    var pebbles = 247.94837747587382040906;\r\n    var bambam = 747;\r\n    \r\n    var testGroup = new displayGroup(\"Test Group\",20,20,100,\"#00BBFF\",\"#FF0000\",\"#FFFF00\");\r\n    testGroup.addValue(fred,\"Fred\",\"integer\");\r\n    testGroup.addValue(barney,\"Barney\",\"numdec\",4);\r\n    testGroup.addValue(wilma,\"Wilma\",\"text\");\r\n    testGroup.addValue(betty,\"Betty\",\"bool\");\r\n    testGroup.addValue(pebbles,\"Pebbles\",\"numdec\",8);\r\n    testGroup.addValue(bambam,\"Bam Bam\",\"numwide\",5);\r\n    clearCanvas(\"#000000\");\r\n    testGroup.drawBasic();\r\n<\/pre>\n<p>The output looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.rpchurchill.com\/images\/articles\/20161010_displayGroup.png\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;ve based it on a global canvas and will rewrite everything else accordingly. This will make &hellip; <a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/10\/10\/a-simple-discrete-event-simulation-part-22\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[60],"tags":[121,49],"_links":{"self":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1056"}],"collection":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1056"}],"version-history":[{"count":2,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1056\/revisions"}],"predecessor-version":[{"id":1441,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1056\/revisions\/1441"}],"wp:attachment":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}