|  |  | @ -13,81 +13,360 @@ | 
			
		
	
		
			
				
					|  |  |  |         <div id="wrapper"> | 
			
		
	
		
			
				
					|  |  |  |             <div id="content"> | 
			
		
	
		
			
				
					|  |  |  |                 <h3>{#TOTAL_POWER}</h3> | 
			
		
	
		
			
				
					|  |  |  |                 <div> | 
			
		
	
		
			
				
					|  |  |  |                 {#LAST} <span id="pwrNumValues"></span> {#VALUES} | 
			
		
	
		
			
				
					|  |  |  |                 <div class="chartDivContainer"> | 
			
		
	
		
			
				
					|  |  |  |                     <div class="chartDiv" id="pwrChart">  </div> | 
			
		
	
		
			
				
					|  |  |  |                     <p> | 
			
		
	
		
			
				
					|  |  |  |                         {#MAX_DAY}: <span id="pwrMaxDay"></span> W. {#LAST_VALUE}: <span id="pwrLast"></span> W.<br /> | 
			
		
	
		
			
				
					|  |  |  |                         {#MAXIMUM}: <span id="pwrMax"></span> W. {#UPDATED} <span id="pwrRefresh"></span> {#SECONDS} | 
			
		
	
		
			
				
					|  |  |  |                         {#LAST_VALUE}: <span id="pwrLast"></span> W.<br /> | 
			
		
	
		
			
				
					|  |  |  |                         {#MAXIMUM}: <span id="pwrMax"></span> W. | 
			
		
	
		
			
				
					|  |  |  |                         {#UPDATED} <span id="pwrRefresh"></span> {#SECONDS} | 
			
		
	
		
			
				
					|  |  |  |                     </p> | 
			
		
	
		
			
				
					|  |  |  |                 </div> | 
			
		
	
		
			
				
					|  |  |  |                 <h3>{#TOTAL_POWER_DAY}</h3> | 
			
		
	
		
			
				
					|  |  |  |                 <div class="chartDivContainer"> | 
			
		
	
		
			
				
					|  |  |  |                     <div class="chartDiv" id="pwrDayChart"> </div> | 
			
		
	
		
			
				
					|  |  |  |                     <p> | 
			
		
	
		
			
				
					|  |  |  |                         {#MAX_DAY}: <span id="pwrDayMaxDay"></span> W. <br /> | 
			
		
	
		
			
				
					|  |  |  |                         {#UPDATED} <span id="pwrDayRefresh"></span> {#SECONDS} | 
			
		
	
		
			
				
					|  |  |  |                     </p> | 
			
		
	
		
			
				
					|  |  |  |                 </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 <!-- | 
			
		
	
		
			
				
					|  |  |  |                 <h3>{#TOTAL_YIELD_PER_DAY}</h3> | 
			
		
	
		
			
				
					|  |  |  |                 <div class="chartDivContainer"> | 
			
		
	
		
			
				
					|  |  |  |                     <div class="chartDiv" id="ydChart"> </div> | 
			
		
	
		
			
				
					|  |  |  |                     <p> | 
			
		
	
		
			
				
					|  |  |  |                         {#MAXIMUM}: <span id="ydMax"></span> Wh<br /> | 
			
		
	
		
			
				
					|  |  |  |                     </p> | 
			
		
	
		
			
				
					|  |  |  |                 </div> | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 <h4 style="margin-bottom:0px;">Insert data into Yield per day history</h4> | 
			
		
	
		
			
				
					|  |  |  |                 <fieldset style="padding: 1px;"> | 
			
		
	
		
			
				
					|  |  |  |                     <legend class="des" style="margin-top: 0px;">Insert data (*.json) i.e. from a saved "/api/yieldDayHistory" call | 
			
		
	
		
			
				
					|  |  |  |                     </legend> | 
			
		
	
		
			
				
					|  |  |  |                     <form id="form" method="POST" action="/api/addYDHist" enctype="multipart/form-data" | 
			
		
	
		
			
				
					|  |  |  |                         accept-charset="utf-8"> | 
			
		
	
		
			
				
					|  |  |  |                         <input type="button" class="btn my-4" style="padding: 3px;margin: 3px;" value="Insert" onclick="submit()"> | 
			
		
	
		
			
				
					|  |  |  |                         <input type="file" name="insert" style="width: 80%;"> | 
			
		
	
		
			
				
					|  |  |  |                     </form> | 
			
		
	
		
			
				
					|  |  |  |                 </fieldset> | 
			
		
	
		
			
				
					|  |  |  |                 --> | 
			
		
	
		
			
				
					|  |  |  |             </div> | 
			
		
	
		
			
				
					|  |  |  |         </div> | 
			
		
	
		
			
				
					|  |  |  |         {#HTML_FOOTER} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         <script type="text/javascript"> | 
			
		
	
		
			
				
					|  |  |  |             const svgns = "http://www.w3.org/2000/svg"; | 
			
		
	
		
			
				
					|  |  |  |             var pwrExeOnce = true; | 
			
		
	
		
			
				
					|  |  |  |             var ydExeOnce = true; | 
			
		
	
		
			
				
					|  |  |  |             // make a simple rectangle | 
			
		
	
		
			
				
					|  |  |  |             var mRefresh = 60; | 
			
		
	
		
			
				
					|  |  |  |             var mLastValue = 0; | 
			
		
	
		
			
				
					|  |  |  |             const mChartHeight = 250; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             function parseHistory(obj, namePrefix, execOnce) { | 
			
		
	
		
			
				
					|  |  |  |                 mRefresh = obj.refresh | 
			
		
	
		
			
				
					|  |  |  |                 var data = Object.assign({}, obj.value) | 
			
		
	
		
			
				
					|  |  |  |                 numDataPts = Object.keys(data).length | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (true == execOnce) { | 
			
		
	
		
			
				
					|  |  |  |                     let s = document.createElementNS(svgns, "svg"); | 
			
		
	
		
			
				
					|  |  |  |                     s.setAttribute("class", "chart"); | 
			
		
	
		
			
				
					|  |  |  |                     s.setAttribute("width", (numDataPts + 2) * 2); | 
			
		
	
		
			
				
					|  |  |  |                     s.setAttribute("height", mChartHeight); | 
			
		
	
		
			
				
					|  |  |  |                     s.setAttribute("role", "img"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     let g = document.createElementNS(svgns, "g"); | 
			
		
	
		
			
				
					|  |  |  |                     s.appendChild(g); | 
			
		
	
		
			
				
					|  |  |  |                     for (var i = 0; i < numDataPts; i++) { | 
			
		
	
		
			
				
					|  |  |  |                         val = data[i]; | 
			
		
	
		
			
				
					|  |  |  |                         let rect = document.createElementNS(svgns, "rect"); | 
			
		
	
		
			
				
					|  |  |  |                         rect.setAttribute("id", namePrefix+"Rect" + i); | 
			
		
	
		
			
				
					|  |  |  |                         rect.setAttribute("x", i * 2); | 
			
		
	
		
			
				
					|  |  |  |                         rect.setAttribute("width", 2); | 
			
		
	
		
			
				
					|  |  |  |                         g.appendChild(rect); | 
			
		
	
		
			
				
					|  |  |  | 				var powerHistObj = null; | 
			
		
	
		
			
				
					|  |  |  | 				var powerHistDayObj = null; | 
			
		
	
		
			
				
					|  |  |  | 				var ydHistObj = null; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 				Number.prototype.pad = function (size) { | 
			
		
	
		
			
				
					|  |  |  | 					var s = String(this); | 
			
		
	
		
			
				
					|  |  |  | 					while (s.length < (size || 2)) { s = "0" + s; } | 
			
		
	
		
			
				
					|  |  |  | 					return s; | 
			
		
	
		
			
				
					|  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 				class powChart { | 
			
		
	
		
			
				
					|  |  |  | 					static objcnt = 0;  // to give each object elemets a unique name prefix | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 					constructor(namePrefix) { | 
			
		
	
		
			
				
					|  |  |  | 						// configurable vars | 
			
		
	
		
			
				
					|  |  |  | 						this.mChartHight = 250; | 
			
		
	
		
			
				
					|  |  |  | 						this.datapoints = 256; | 
			
		
	
		
			
				
					|  |  |  | 						this.xGridDist = 50; | 
			
		
	
		
			
				
					|  |  |  | 						this.yGridDist = 100; | 
			
		
	
		
			
				
					|  |  |  | 						// info vars | 
			
		
	
		
			
				
					|  |  |  | 						this.maxValue = 0; | 
			
		
	
		
			
				
					|  |  |  | 						this.mLastValue = 0; | 
			
		
	
		
			
				
					|  |  |  | 						// intern vars | 
			
		
	
		
			
				
					|  |  |  | 						this.svg = null; | 
			
		
	
		
			
				
					|  |  |  | 						this.refreshIntervall = 30;	// seconds | 
			
		
	
		
			
				
					|  |  |  | 						this.lastValueTs = 0;		// Timestmp of last value | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						++this.objcnt; | 
			
		
	
		
			
				
					|  |  |  | 						if (namePrefix === undefined) | 
			
		
	
		
			
				
					|  |  |  | 							this.namePrefix = "powChart" + this.objcnt; | 
			
		
	
		
			
				
					|  |  |  | 						else | 
			
		
	
		
			
				
					|  |  |  | 							this.namePrefix = namePrefix; | 
			
		
	
		
			
				
					|  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 					init(numDatapoints) { | 
			
		
	
		
			
				
					|  |  |  | 						this.datapoints = numDatapoints; | 
			
		
	
		
			
				
					|  |  |  | 						// generate svg | 
			
		
	
		
			
				
					|  |  |  |                         const svgns = "http://www.w3.org/2000/svg"; | 
			
		
	
		
			
				
					|  |  |  | 						this.svg = document.createElementNS(svgns, "svg"); | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.setAttribute("class", "container"); | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.setAttribute("id", this.namePrefix + "_svg"); | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.setAttribute("width", String(this.datapoints * 2 + 50)); | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.setAttribute("height", String(this.mChartHight + 20)); | 
			
		
	
		
			
				
					|  |  |  | 						// Gradient Line | 
			
		
	
		
			
				
					|  |  |  | 						let defLgLine = document.createElementNS(svgns, "defs"); | 
			
		
	
		
			
				
					|  |  |  | 						{ | 
			
		
	
		
			
				
					|  |  |  | 							let lg = document.createElementNS(svgns, "linearGradient") | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("id", "verlVertLine"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("x1", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("y1", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("x2", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("y2", "100%"); | 
			
		
	
		
			
				
					|  |  |  | 							let s1 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s1.setAttribute("offset", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							s1.setAttribute("stop-color", "blue"); | 
			
		
	
		
			
				
					|  |  |  | 							let s2 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s2.setAttribute("offset", "80%"); | 
			
		
	
		
			
				
					|  |  |  | 							s2.setAttribute("stop-color", "#5050FF"); | 
			
		
	
		
			
				
					|  |  |  | 							let s3 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s3.setAttribute("offset", "100%"); | 
			
		
	
		
			
				
					|  |  |  | 							s3.setAttribute("stop-color", "gray"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s1); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s2); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s3); | 
			
		
	
		
			
				
					|  |  |  | 							defLgLine.appendChild(lg); | 
			
		
	
		
			
				
					|  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.appendChild(defLgLine); | 
			
		
	
		
			
				
					|  |  |  | 						// Gradient Fill | 
			
		
	
		
			
				
					|  |  |  | 						let defLg = document.createElementNS(svgns, "defs"); | 
			
		
	
		
			
				
					|  |  |  | 						{ | 
			
		
	
		
			
				
					|  |  |  | 							let lg = document.createElementNS(svgns, "linearGradient") | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("id", "verlVertFill"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("x1", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("y1", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("x2", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.setAttribute("y2", "100%"); | 
			
		
	
		
			
				
					|  |  |  | 							let s1 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s1.setAttribute("offset", "0%"); | 
			
		
	
		
			
				
					|  |  |  | 							s1.setAttribute("stop-color", "#A0A0FF"); | 
			
		
	
		
			
				
					|  |  |  | 							let s2 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s2.setAttribute("offset", "50%"); | 
			
		
	
		
			
				
					|  |  |  | 							s2.setAttribute("stop-color", "#C0C0FF"); | 
			
		
	
		
			
				
					|  |  |  | 							let s3 = document.createElementNS(svgns, "stop") | 
			
		
	
		
			
				
					|  |  |  | 							s3.setAttribute("offset", "100%"); | 
			
		
	
		
			
				
					|  |  |  | 							s3.setAttribute("stop-color", "#E0E0F0"); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s1); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s2); | 
			
		
	
		
			
				
					|  |  |  | 							lg.appendChild(s3); | 
			
		
	
		
			
				
					|  |  |  | 							defLgLine.appendChild(lg); | 
			
		
	
		
			
				
					|  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.appendChild(defLg); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						let chartFrame = document.createElementNS(svgns, "rect"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("id", this.namePrefix + "_chartFrame"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("class", "chartFrame"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("x", "0"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("y", "0"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("width", String(this.datapoints * 2)); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("height", String(this.mChartHight)); | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.appendChild(chartFrame); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						// Group chart content | 
			
		
	
		
			
				
					|  |  |  | 						let chartContent = document.createElementNS(svgns, "g"); | 
			
		
	
		
			
				
					|  |  |  | 						chartContent.setAttribute("id", this.namePrefix + "_svgChartContent"); | 
			
		
	
		
			
				
					|  |  |  | 						chartFrame.setAttribute("transform", "translate(29, 5)"); | 
			
		
	
		
			
				
					|  |  |  | 						chartContent.setAttribute("transform", "translate(30, 5)"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						// Graph values in a polyline | 
			
		
	
		
			
				
					|  |  |  | 						let poly = document.createElementNS(svgns, "polyline"); | 
			
		
	
		
			
				
					|  |  |  | 						poly.setAttribute("id", this.namePrefix + "Poly"); | 
			
		
	
		
			
				
					|  |  |  | 						poly.setAttribute("stroke", "url(#verlVertLine)"); | 
			
		
	
		
			
				
					|  |  |  | 						poly.setAttribute("fill", "none"); | 
			
		
	
		
			
				
					|  |  |  | 						chartContent.appendChild(poly); | 
			
		
	
		
			
				
					|  |  |  |                         // hidden polyline for fill | 
			
		
	
		
			
				
					|  |  |  |                         let polyFill = document.createElementNS(svgns, "polyline"); | 
			
		
	
		
			
				
					|  |  |  |                         polyFill.setAttribute("id", this.namePrefix + "PolyFill"); | 
			
		
	
		
			
				
					|  |  |  |                         polyFill.setAttribute("stroke", "none"); | 
			
		
	
		
			
				
					|  |  |  |                         polyFill.setAttribute("fill", "url(#verlVertFill)"); | 
			
		
	
		
			
				
					|  |  |  |                         chartContent.appendChild(polyFill); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						// X-grid lines | 
			
		
	
		
			
				
					|  |  |  | 						let numXGridLines = (this.mChartHight / this.xGridDist); | 
			
		
	
		
			
				
					|  |  |  | 						for (let i = 0; i < numXGridLines; i++) { | 
			
		
	
		
			
				
					|  |  |  | 							let line = document.createElementNS(svgns, "line"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("id", this.namePrefix + "XGrid" + i); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("x1", String(0)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("x2", String(this.datapoints * 2)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("y1", String(this.mChartHight - (i + 1) * this.xGridDist)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("y2", String(this.mChartHight - (i + 1) * this.xGridDist)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke-width", "1"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke-dasharray", "1,1"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke", "#A0A0A0"); | 
			
		
	
		
			
				
					|  |  |  | 							chartContent.appendChild(line); | 
			
		
	
		
			
				
					|  |  |  | 							let text = document.createElementNS(svgns, "text"); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("id", this.namePrefix + "XGridText" + i); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("x", "0"); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("y", String(this.mChartHight + 10 - (i + 1) * this.xGridDist)); | 
			
		
	
		
			
				
					|  |  |  | 							text.innerHTML = (i + 1) * this.xGridDist; | 
			
		
	
		
			
				
					|  |  |  | 							this.svg.appendChild(text); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  | 						// Y-grid lines | 
			
		
	
		
			
				
					|  |  |  | 						let numYGridLines = (this.datapoints / this.yGridDist) * 2; | 
			
		
	
		
			
				
					|  |  |  | 						for (let i = numYGridLines; i > 0; i--) { | 
			
		
	
		
			
				
					|  |  |  | 							let line = document.createElementNS(svgns, "line"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("id", this.namePrefix + "YGrid" + i); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("x1", String((i) * this.yGridDist) - 1); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("x2", String((i) * this.yGridDist) - 1); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("y1", String(0)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("y2", String(this.mChartHight)); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke-width", "1"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke-dasharray", "1,3"); | 
			
		
	
		
			
				
					|  |  |  | 							line.setAttribute("stroke", "#A0A0A0"); | 
			
		
	
		
			
				
					|  |  |  | 							chartContent.appendChild(line); | 
			
		
	
		
			
				
					|  |  |  | 							let text = document.createElementNS(svgns, "text"); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("id", this.namePrefix + "YGridText" + i); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("x", String((i) * this.yGridDist + 15)); | 
			
		
	
		
			
				
					|  |  |  | 							text.setAttribute("y", String(this.mChartHight + 17)); | 
			
		
	
		
			
				
					|  |  |  | 							text.innerHTML = ""; | 
			
		
	
		
			
				
					|  |  |  | 							this.svg.appendChild(text); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  | 						// | 
			
		
	
		
			
				
					|  |  |  | 						this.svg.appendChild(chartContent); | 
			
		
	
		
			
				
					|  |  |  | 					}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 					getContainer() { return this.svg; }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 					setXScale(refreshIntervall, lastValueTs) { | 
			
		
	
		
			
				
					|  |  |  | 						this.refreshIntervall = refreshIntervall; | 
			
		
	
		
			
				
					|  |  |  | 						this.lastValueTs = lastValueTs; | 
			
		
	
		
			
				
					|  |  |  | 					} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 					update(values, maxVal) { | 
			
		
	
		
			
				
					|  |  |  | 						if (maxVal === undefined) { | 
			
		
	
		
			
				
					|  |  |  | 							this.maxValue = 0; | 
			
		
	
		
			
				
					|  |  |  | 							for (let val in values) | 
			
		
	
		
			
				
					|  |  |  | 								if (val > this.maxValue) this.maxValue = val; | 
			
		
	
		
			
				
					|  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  | 						else | 
			
		
	
		
			
				
					|  |  |  | 							this.maxValue = maxVal; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         // normalize data to chart | 
			
		
	
		
			
				
					|  |  |  | 						let divider = this.maxValue / this.mChartHight; | 
			
		
	
		
			
				
					|  |  |  |                         if (divider == 0) | 
			
		
	
		
			
				
					|  |  |  |                             divider = 1; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         let firstValPos = -1;  // position of first value >0 W | 
			
		
	
		
			
				
					|  |  |  | 						let lastValPos = -1;   // position of last value >0 W | 
			
		
	
		
			
				
					|  |  |  | 						let points = ""; | 
			
		
	
		
			
				
					|  |  |  |                         for (let i = 0; i < this.datapoints; i++) { | 
			
		
	
		
			
				
					|  |  |  |                             let val = values[i]; | 
			
		
	
		
			
				
					|  |  |  |                             if (val > 0) { | 
			
		
	
		
			
				
					|  |  |  |                                 this.mLastValue = val; | 
			
		
	
		
			
				
					|  |  |  |                                 lastValPos = i; | 
			
		
	
		
			
				
					|  |  |  |                                 if (firstValPos < 0) | 
			
		
	
		
			
				
					|  |  |  |                                     firstValPos = i; | 
			
		
	
		
			
				
					|  |  |  |                                 val = val / divider; | 
			
		
	
		
			
				
					|  |  |  |                                 points += ' ' + String(i * 2) + ',' + String(this.mChartHight - val); | 
			
		
	
		
			
				
					|  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  | 						let poly = document.getElementById(this.namePrefix + "Poly"); | 
			
		
	
		
			
				
					|  |  |  | 						poly.setAttribute("points", points); | 
			
		
	
		
			
				
					|  |  |  |                         // "close" polyFill-line down to the x-axis | 
			
		
	
		
			
				
					|  |  |  |                         points += ' ' + +String(lastValPos  * 2) + ',' + String(this.mChartHight); | 
			
		
	
		
			
				
					|  |  |  |                         points += ' ' + +String(firstValPos * 2) + ',' + String(this.mChartHight); | 
			
		
	
		
			
				
					|  |  |  |                         let polyFill = document.getElementById(this.namePrefix + "PolyFill"); | 
			
		
	
		
			
				
					|  |  |  |                         polyFill.setAttribute("points", points); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						// X-Grid lines | 
			
		
	
		
			
				
					|  |  |  | 						let numXGridLines = (this.mChartHight / this.xGridDist); | 
			
		
	
		
			
				
					|  |  |  | 						let dist = (this.maxValue / numXGridLines); | 
			
		
	
		
			
				
					|  |  |  | 						for (let i = 0; i < numXGridLines; i++) { | 
			
		
	
		
			
				
					|  |  |  | 							let tex = document.getElementById(this.namePrefix + "XGridText" + i); | 
			
		
	
		
			
				
					|  |  |  | 							tex.innerHTML = ((i + 1) * dist).toFixed(0); | 
			
		
	
		
			
				
					|  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 						// Y-Grid lines | 
			
		
	
		
			
				
					|  |  |  | 						if (isNaN(this.lastValueTs) || this.lastValueTs == 0) | 
			
		
	
		
			
				
					|  |  |  | 							this.lastValueTs = Date.now(); | 
			
		
	
		
			
				
					|  |  |  | 						let date = new Date(this.lastValueTs); | 
			
		
	
		
			
				
					|  |  |  | 						let numYGridLines = (this.datapoints / this.yGridDist) * 2; | 
			
		
	
		
			
				
					|  |  |  | 						for (let i = numYGridLines; i > 0; i--) { | 
			
		
	
		
			
				
					|  |  |  | 							let tex = document.getElementById(this.namePrefix + "YGridText" + i); | 
			
		
	
		
			
				
					|  |  |  | 							if (this.refreshIntervall > 8600) // Display date | 
			
		
	
		
			
				
					|  |  |  | 								tex.innerHTML = date.getDate() + "." + (date.getMonth() + 1).pad(2); | 
			
		
	
		
			
				
					|  |  |  | 							else 							// Display time | 
			
		
	
		
			
				
					|  |  |  | 								tex.innerHTML = date.getHours() + ":" + date.getMinutes().pad(2); | 
			
		
	
		
			
				
					|  |  |  | 							date = new Date(date.getTime() - (this.refreshIntervall * (this.yGridDist / 2) * 1000)); | 
			
		
	
		
			
				
					|  |  |  | 						} | 
			
		
	
		
			
				
					|  |  |  | 					}; | 
			
		
	
		
			
				
					|  |  |  | 				}// class powChart | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             function parsePowerHistory(obj){ | 
			
		
	
		
			
				
					|  |  |  |                 if (null != obj) { | 
			
		
	
		
			
				
					|  |  |  |                     let refresh = obj.refresh | 
			
		
	
		
			
				
					|  |  |  |                     let maximum = obj.max; | 
			
		
	
		
			
				
					|  |  |  |                     let addNextChart=false; | 
			
		
	
		
			
				
					|  |  |  |                     if (powerHistObj == null) { | 
			
		
	
		
			
				
					|  |  |  |                         powerHistObj = new powChart("ph"); | 
			
		
	
		
			
				
					|  |  |  |                         powerHistObj.init(obj.value.length); | 
			
		
	
		
			
				
					|  |  |  |                         document.getElementById("pwrChart").appendChild(powerHistObj.getContainer()); | 
			
		
	
		
			
				
					|  |  |  |                         // Regular update: | 
			
		
	
		
			
				
					|  |  |  |                         window.setInterval("getAjax('/api/powerHistory', parsePowerHistory)", refresh * 1000); | 
			
		
	
		
			
				
					|  |  |  |                         // one after the other | 
			
		
	
		
			
				
					|  |  |  |                         addNextChart=true; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById(namePrefix+"Chart").appendChild(s); | 
			
		
	
		
			
				
					|  |  |  |                     powerHistObj.setXScale(refresh, obj.lastValueTs * 1000); | 
			
		
	
		
			
				
					|  |  |  |                     powerHistObj.update(obj.value, maximum); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrLast").innerHTML = powerHistObj.mLastValue; | 
			
		
	
		
			
				
					|  |  |  |                     //document.getElementById("pwrMaxDay").innerHTML = obj.maxDay; | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrMax").innerHTML = maximum; | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrRefresh").innerHTML = refresh; | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrNumValues").innerHTML = obj.value.length; | 
			
		
	
		
			
				
					|  |  |  |                     if (addNextChart) | 
			
		
	
		
			
				
					|  |  |  |                         setTimeout(() => { getAjax("/api/powerHistoryDay", parsePowerHistoryDay); }, 50); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             function parsePowerHistoryDay(obj) { | 
			
		
	
		
			
				
					|  |  |  |                 if (null != obj) { | 
			
		
	
		
			
				
					|  |  |  |                     let refresh = obj.refresh | 
			
		
	
		
			
				
					|  |  |  |                     if (refresh<30) | 
			
		
	
		
			
				
					|  |  |  |                         refresh = 30; | 
			
		
	
		
			
				
					|  |  |  |                     let maximum = obj.max; | 
			
		
	
		
			
				
					|  |  |  |                     let addNextChart = false; | 
			
		
	
		
			
				
					|  |  |  |                     if (powerHistDayObj == null) { | 
			
		
	
		
			
				
					|  |  |  |                         powerHistDayObj = new powChart("phDay"); | 
			
		
	
		
			
				
					|  |  |  |                         powerHistDayObj.init(obj.value.length); | 
			
		
	
		
			
				
					|  |  |  |                         document.getElementById("pwrDayChart").appendChild(powerHistDayObj.getContainer()); | 
			
		
	
		
			
				
					|  |  |  |                         // Regular update: | 
			
		
	
		
			
				
					|  |  |  |                         window.setInterval("getAjax('/api/powerHistoryDay', parsePowerHistoryDay)", refresh * 1000); | 
			
		
	
		
			
				
					|  |  |  |                         // one after the other | 
			
		
	
		
			
				
					|  |  |  |                         addNextChart = false; // if true: add YieldDayHistory | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     powerHistDayObj.setXScale(refresh, obj.lastValueTs * 1000); | 
			
		
	
		
			
				
					|  |  |  |                     powerHistDayObj.update(obj.value, maximum); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 // normalize data to chart | 
			
		
	
		
			
				
					|  |  |  |                 let divider = obj.max / mChartHeight; | 
			
		
	
		
			
				
					|  |  |  |                 if (divider == 0) | 
			
		
	
		
			
				
					|  |  |  |                     divider = 1; | 
			
		
	
		
			
				
					|  |  |  |                 for (var i = 0; i < numDataPts; i++) { | 
			
		
	
		
			
				
					|  |  |  |                     val = data[i]; | 
			
		
	
		
			
				
					|  |  |  |                     if (val > 0) | 
			
		
	
		
			
				
					|  |  |  |                         mLastValue = val | 
			
		
	
		
			
				
					|  |  |  |                     val = val / divider | 
			
		
	
		
			
				
					|  |  |  |                     rect = document.getElementById(namePrefix+"Rect" + i); | 
			
		
	
		
			
				
					|  |  |  |                     rect.setAttribute("height", val); | 
			
		
	
		
			
				
					|  |  |  |                     rect.setAttribute("y", mChartHeight - val); | 
			
		
	
		
			
				
					|  |  |  |                     //document.getElementById("pwrDayLast").innerHTML = powerHistDayObj.mLastValue; | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrDayMaxDay").innerHTML = obj.maxDay; | 
			
		
	
		
			
				
					|  |  |  |                     //document.getElementById("pwrDayMax").innerHTML = maximum; | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrDayRefresh").innerHTML = refresh; | 
			
		
	
		
			
				
					|  |  |  |                     if (addNextChart) | 
			
		
	
		
			
				
					|  |  |  |                         setTimeout(() => { getAjax("/api/yieldDayHistory", parseYieldDayHistory); }, 50); | 
			
		
	
		
			
				
					|  |  |  |                     else | 
			
		
	
		
			
				
					|  |  |  |                         parseNav(obj.generic); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 document.getElementById(namePrefix + "Max").innerHTML = obj.max; | 
			
		
	
		
			
				
					|  |  |  |                 if (mRefresh < 5) | 
			
		
	
		
			
				
					|  |  |  |                     mRefresh = 5; | 
			
		
	
		
			
				
					|  |  |  |                 document.getElementById(namePrefix + "Refresh").innerHTML = mRefresh; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             function parsePowerHistory(obj){ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             function parseYieldDayHistory(obj) { | 
			
		
	
		
			
				
					|  |  |  |                 if (null != obj) { | 
			
		
	
		
			
				
					|  |  |  |                     parseNav(obj.generic); | 
			
		
	
		
			
				
					|  |  |  |                     parseESP(obj.generic); | 
			
		
	
		
			
				
					|  |  |  |                     parseHistory(obj,"pwr", pwrExeOnce) | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrLast").innerHTML = mLastValue | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("pwrMaxDay").innerHTML = obj.maxDay | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 if (pwrExeOnce) { | 
			
		
	
		
			
				
					|  |  |  |                     pwrExeOnce = false; | 
			
		
	
		
			
				
					|  |  |  |                     window.setInterval("getAjax('/api/powerHistory', parsePowerHistory)", mRefresh * 1000); | 
			
		
	
		
			
				
					|  |  |  |                     let refresh = obj.refresh | 
			
		
	
		
			
				
					|  |  |  |                     let maximum = obj.max; | 
			
		
	
		
			
				
					|  |  |  |                     let addNextChart = false; | 
			
		
	
		
			
				
					|  |  |  |                 	if (ydHistObj == null) { | 
			
		
	
		
			
				
					|  |  |  |                         ydHistObj = new powChart("yd"); | 
			
		
	
		
			
				
					|  |  |  |                         ydHistObj.init(obj.value.length); | 
			
		
	
		
			
				
					|  |  |  |                         document.getElementById("ydChart").appendChild(ydHistObj.getContainer()); | 
			
		
	
		
			
				
					|  |  |  |                         // Regular update: | 
			
		
	
		
			
				
					|  |  |  |                         window.setInterval("getAjax('/api/yieldDayHistory', parseYieldDayHistory)", refresh * 500); | 
			
		
	
		
			
				
					|  |  |  |                         addNextChart = true; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     ydHistObj.setXScale(refresh, obj.lastValueTs * 1000); | 
			
		
	
		
			
				
					|  |  |  |                     ydHistObj.update(obj.value, maximum); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     document.getElementById("ydMax").innerHTML = maximum; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |