self.onInit = function () { volume = 0; fluidLevel = 0; self.ctx.$container.append("
"); }; self.onResize = function () { self.draw(); }; //function for scaling a canvas function fitToContainer(canvas) { canvas.style.width = "100%"; canvas.style.height = "100%"; canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight; } self.onDataUpdated = function () { self.ctx.detectChanges(); //setup variables self.volume = 0; self.fluidLevel = 0; for (let i = 0; i < self.ctx.defaultSubscription.data.length; i++) { if (self.ctx.defaultSubscription.data[i].dataKey.name === self.ctx.settings.vessels[0].volumeKey) { self.volume = typeof self.ctx.defaultSubscription.data[i].data[0] !== "undefined" ? self.ctx.defaultSubscription.data[i].data[0][1] : 0; } else if (self.ctx.defaultSubscription.data[i].dataKey.name === self.ctx.settings.vessels[0].fluidLevelKey) { self.fluidLevel = typeof self.ctx.defaultSubscription.data[i].data[0] !== "undefined" ? self.ctx.defaultSubscription.data[i].data[0][1] : 0; } } self.maxHeight = typeof self.ctx.settings.maxHeight !== "undefined" ? self.ctx.settings.maxHeight : 10; self.fluidLevelPercent = self.fluidLevel / self.maxHeight; //draw a new canvas self.draw(); }; self.drawTank = function (ctx, compartmentWidth, compartmentHeight) { ctx.moveTo(compartmentWidth * 0.05, compartmentHeight * 0.05); ctx.lineTo(compartmentWidth * 0.05, compartmentHeight * 0.95); ctx.ellipse(compartmentWidth / 2, compartmentHeight * 0.95, compartmentWidth / 2 - compartmentWidth * 0.05, compartmentHeight * 0.025, 0, Math.PI, 0, true); ctx.lineTo(compartmentWidth * 0.95, compartmentHeight * 0.05); ctx.ellipse(compartmentWidth / 2, compartmentHeight * 0.05, compartmentWidth / 2 - compartmentWidth * 0.05, compartmentHeight * 0.025, 0, 0, 2 * Math.PI); }; self.drawPond = function (ctx, compartmentWidth, compartmentHeight) { ctx.moveTo(compartmentWidth * 0.05, compartmentHeight * 0.1); ctx.lineTo(compartmentWidth * 0.15, compartmentHeight * 0.95); ctx.lineTo(compartmentWidth * 0.85, compartmentHeight * 0.95); ctx.lineTo(compartmentWidth * 0.95, compartmentHeight * 0.1); }; self.drawVessels = function (ctx, canvas, numVessels, cols, rows) { if (numVessels <= cols * rows) { //vessel ctx.beginPath(); for (let i = 1; i <= numVessels; i++) { for (let j = 0; j < self.ctx.defaultSubscription.data.length; j++) { //console.log(self.ctx.settings.vessels[i - 1].volumeKey); //console.log(self.ctx.settings.vessels[i - 1].fluidLevelKey); if (self.ctx.defaultSubscription.data[j].dataKey.name === self.ctx.settings.vessels[i - 1].volumeKey) { self.volume = typeof self.ctx.defaultSubscription.data[j].data[0] !== "undefined" ? self.ctx.defaultSubscription.data[j].data[0][1] : 0; } else if (self.ctx.defaultSubscription.data[j].dataKey.name === self.ctx.settings.vessels[i - 1].fluidLevelKey) { self.fluidLevel = typeof self.ctx.defaultSubscription.data[j].data[0] !== "undefined" ? self.ctx.defaultSubscription.data[j].data[0][1] : 0; } //console.log(self.volume); //console.log(self.fluidLevel); } self.maxHeight = typeof self.ctx.settings.vessels[i - 1].maxHeight !== "undefined" ? self.ctx.settings.vessels[i - 1].maxHeight : 10; self.fluidLevelPercent = self.fluidLevel / self.maxHeight; var vesselType = typeof self.ctx.settings.vessels[i - 1].vesselType !== "undefined" ? self.ctx.settings.vessels[i - 1].vesselType : "Tank"; var fluidColor = typeof self.ctx.settings.vessels[i - 1].fluidColor !== "undefined" ? self.ctx.settings.vessels[i - 1].fluidColor : "Water"; var compartmentWidth = canvas.width / cols; var compartmentHeight = canvas.height / rows; //gradient used as water const grad = ctx.createLinearGradient(0, compartmentHeight * 0.05, 0, compartmentHeight * 0.95); switch (fluidColor) { case "Water": grad.addColorStop(0, "rgba(70,220,210,0.75)"); grad.addColorStop(0.4, "rgba(0,120,240,0.75)"); break; case "Produced Water": grad.addColorStop(0, "rgba(170, 100, 30,1)"); grad.addColorStop(0.4, "rgba(85, 50, 15,1"); break; case "Oil": grad.addColorStop(0, "rgba(100,100,100,0.75)"); grad.addColorStop(0.3, "rgba(25,25,25, 0.85"); break; default: grad.addColorStop(0, fluidColor); break; } grad.addColorStop(1, "rgba(0,0,0, 0.8)"); //draw the vessel switch (vesselType) { case "Pond": self.drawPond(ctx, compartmentWidth, compartmentHeight); break; case "Tank": self.drawTank(ctx, compartmentWidth, compartmentHeight); break; } //draw ctx.stroke(); ctx.save(); //setup clip area of container ctx.clip(); ctx.save(); //set fill style for water to gradient ctx.fillStyle = grad; //move grid for animation if (self.fluidLevelPercent > 1) { ctx.translate(0, compartmentHeight - (compartmentHeight * 0.95 - compartmentHeight * 0.05) * 1 - compartmentHeight * 0.1); } else { ctx.translate(0, compartmentHeight - (compartmentHeight * 0.95 - compartmentHeight * 0.05) * self.fluidLevelPercent - compartmentHeight * 0.1); } ctx.fillRect(0, compartmentHeight * 0.05, compartmentWidth, compartmentHeight * 0.95); ctx.restore(); ctx.restore(); self.drawTicks(ctx, compartmentWidth, compartmentHeight); self.drawText(ctx, compartmentWidth, compartmentHeight); if (i % cols === 0) { ctx.translate(-(cols - 1) * compartmentWidth, compartmentHeight); } else { ctx.translate(compartmentWidth, 0); } } } else { console.error("Not enough space for Vessels"); } }; self.drawText = function (ctx, compartmentWidth, compartmentHeight) { fl = typeof self.fluidLevel === "number" ? self.fluidLevel.toFixed(2) : "0.00"; vl = typeof self.volume === "number" ? self.volume.toFixed(2) : "0.00"; ctx.textAlign = "center"; ctx.fillStyle = "rgba(0,0,0,1)"; var padding = Math.max(Math.sqrt(compartmentWidth), Math.sqrt(compartmentHeight)); ctx.fillText(`${(self.fluidLevelPercent * 100).toFixed(2)} % ${fl} Ft ${vl} BBLs`, compartmentWidth / 2, compartmentHeight * 0.05); //ctx.fillText(`${fl} Ft`, compartmentWidth / 4 - padding, compartmentHeight / 2 + padding); //ctx.fillText(`${vl} BBLs`, compartmentWidth / 4 - padding, compartmentHeight / 2 + 2 * padding); }; self.drawTicks = function (ctx, compartmentWidth, compartmentHeight, guageAlignment) { ctx.fillStyle = "rgba(0,0,0,1)"; ctx.textBaseline = "middle"; var widthOffset; switch (guageAlignment) { case "center": widthOffset = compartmentWidth * 0.5; break; case "left": widthOffset = compartmentWidth * 0.05; break; case "right": widthOffset = compartmentWidth * 0.95; break; default: widthOffset = compartmentWidth * 0.5; } var heightOffset = compartmentHeight * 0.1; var heightRange = compartmentHeight * 0.85; var numTicks = Math.min(Math.round(compartmentHeight / 40), 10); ctx.moveTo(widthOffset, compartmentHeight - compartmentHeight*0.05); ctx.lineTo(widthOffset, heightOffset); for (let i = 0; i < numTicks; i++) { if (i % 2) { ctx.moveTo(widthOffset - ctx.lineWidth / 2, heightOffset + (i * heightRange) / numTicks); ctx.lineTo(widthOffset + 10 + ctx.lineWidth / 2, heightOffset + (i * heightRange) / numTicks); ctx.textAlign = "left"; ctx.fillText((self.maxHeight * ((numTicks - i) / numTicks)).toFixed(2), widthOffset + 15, heightOffset + (i * heightRange) / numTicks); } else { ctx.moveTo(widthOffset + ctx.lineWidth / 2, heightOffset + (i * heightRange) / numTicks); ctx.lineTo(widthOffset - (10 + ctx.lineWidth / 2), heightOffset + (i * heightRange) / numTicks); ctx.textAlign = "right"; ctx.fillText((self.maxHeight * ((numTicks - i) / numTicks)).toFixed(2), widthOffset - 15, heightOffset + (i * heightRange) / numTicks); } } ctx.stroke(); }; self.draw = function () { //self.fluidLevel = typeof self.ctx.defaultSubscription.data[0].data[0] !== "undefined" ? self.ctx.defaultSubscription.data[0].data[0][1] : 0; var numVessels = typeof self.ctx.settings.vessels !== "undefined" ? self.ctx.settings.vessels.length : 1; var vesselType = typeof self.ctx.settings.vessels[0].vesselType !== "undefined" ? self.ctx.settings.vessels[0].vesselType : "Tank"; var fluidColor = typeof self.ctx.settings.vessels[0].color !== "undefined" ? self.ctx.settings.vessels[0].color : "Water"; var numCols = typeof self.ctx.settings.numCols !== "undefined" ? self.ctx.settings.numCols : 1; var numRows = typeof self.ctx.settings.numRows !== "undefined" ? self.ctx.settings.numRows : 1; const canvas = document.getElementById("vessel" + self.ctx.defaultSubscription.id); if (canvas.getContext) { const ctx = canvas.getContext("2d"); fitToContainer(canvas); //clear frame ctx.clearRect(0, 0, canvas.width, canvas.height); //line style ctx.lineWidth = Math.max((canvas.width * 0.005) / numCols, (canvas.height * 0.005) / numRows); ctx.lineJoin = "round"; ctx.strokeStyle = "black"; //text style ctx.font = `${Math.min(Math.sqrt(canvas.width / numCols), Math.sqrt(canvas.height / numRows))}px Times New Roman`; self.drawVessels(ctx, canvas, numVessels, numCols, numRows); } }; self.onDestroy = function () {};