/* PicoGraph, graphing library for Javascript, Copyright Vishnu Shankar B, https://github.com/RainingComputers */ colors = [ "#e52b50", "#008000", "#0000ff", "#ff00ff", "#a52a2a", "#00008b", "#008b8b", "#a9a9a9", "#006400", "#bdb76b", "#8b008b", "#556b2f", "#ff8c00", "#9932cc", "#8b0000", "#e9967a", "#9400d3", "#ff00ff", "#ffd700", "#008000", "#4b0082", "#f0e68c", "#add8e6", "#e0ffff", "#90ee90", "#d3d3d3", "#ffb6c1", "#ffffe0", "#800000", "#000080", "#808000", "#ffa500", "#ffc0cb", "#800080", "#800080", "#ff0000", "#c0c0c0", "#ffffff", "#ffff00" ] var byID = function(id) { return document.getElementById(id); }; /* Helper function for creating graphs */ function createGraph(canvasID, labels, unit, labelDivID, intervalSize, maxVal, vlines=false, timestamps=false, scalesteps=5, linecolor="#f0e68c") { /* Create valueIDs for each label */ valueIDs = [] for(var i = 0; i < labels.length; i++) { valueIDs[i] = canvasID + labels[i].replace(" ", "") + "value"; } /* Create graph */ var canvas = byID(canvasID); var graph = new Graph(canvas, labels.length, valueIDs, unit, intervalSize, maxVal, vlines, timestamps, scalesteps); /* Set label colors */ for(var i = 0; i < labels.length; i++) { var colorID = valueIDs[i] + "color"; byID(labelDivID).innerHTML += `
${labels[i]}:
` /*labelcolor = graph.colors[i];*/ byID(colorID).style = "fill:"+linecolor/*labelcolor*/; } return graph; } /* Graph class, plots and updates graphs */ class Graph { constructor(canvas, noLabels, valueIDs, unit, intervalSize, maxVal, vlines, timestamps, scalesteps,linecolor) { /* Get the drawing context */ this.canvas = canvas; var ctx = canvas.getContext("2d"); this.ctx = ctx; /* Set proper height and width */ this.setWidthHeight() /* Initialize class variables */ this.scalesteps = scalesteps this.noLabels = noLabels; this.intervalSize = intervalSize; this.nValuesFloat = this.width/intervalSize this.nValues = Math.round(this.nValuesFloat)+1; this.points = emptyArray(noLabels, this.nValues); this.timestamps_array = emptyArray(1, this.nValues, ""); this.colors = colorArray(noLabels); this.maxVal = maxVal; this.valueIDs = valueIDs; this.unit = unit; this.vlines = vlines; this.timestamps = timestamps; } setWidthHeight() { this.cssScale = window.devicePixelRatio; /* Set canvas height and width */ this.canvas.width = this.canvas.clientWidth*this.cssScale; this.canvas.height = this.canvas.clientHeight*this.cssScale; this.width = this.ctx.canvas.width; this.height = this.ctx.canvas.height; } update(values,max_val,linecolor) /*AVB add maxval*/ { for(var i = 0; i < this.noLabels; i++) { /* Update scale */ this.maxVal = max_val /*AVB added this line*/ if(values[i] > this.maxVal) { this.maxVal = values[i]; } /* Shift new point into points array */ this.points = shiftArrayRowLeft(this.points, i, this.nValues, values[i]); /* Update value */ byID(this.valueIDs[i]).innerHTML = ` ${values[i].toFixed(2)} ${this.unit}`; } /* Log time and add to timestamps_array array */ var d = new Date(); var timestamp_str = d.getHours()+":"+d.getMinutes()+":"+d.getSeconds(); this.timestamps_array = shiftArrayRowLeft(this.timestamps_array, 0, this.nValues, timestamp_str); /* Clear canvas */ this.ctx.clearRect(0, 0, this.width, this.height); /* Set proper height and width */ this.setWidthHeight() /* update interval size */ this.intervalSize = this.width/this.nValuesFloat; /* Set line width */ this.ctx.lineWidth = 2*this.cssScale; /* Set font for canvas */ this.ctx.font = (10*this.cssScale)+"px monospace"; /* Draw vertical scale */ if(this.vlines) { for(var i = this.nValues-1; i >= 0; i--) { /* Calculate line coordinates */ var x = (i+1)*this.intervalSize; /* Draw line */ this.ctx.beginPath(); this.ctx.moveTo(x, 0); this.ctx.lineTo(x, this.height); this.ctx.strokeStyle = "#e3e3e3"; this.ctx.stroke(); } } /* Draw horizontal scale */ var hstep = this.height/this.scalesteps; var sstep = this.maxVal/this.scalesteps; for(var i = 1; i <= this.scalesteps; i++) { var y = this.height-i*hstep var xoffset = this.width-25*this.cssScale; var yoffset = 12*this.cssScale; if (i>1) {this.ctx.fillText(((i-1)*sstep).toFixed(2), xoffset, y+yoffset);} this.ctx.beginPath(); this.ctx.moveTo(0, y); this.ctx.lineTo(this.width, y); this.ctx.strokeStyle = "#e3e3e3"; this.ctx.stroke(); } /* Draw time stamps */ if(this.timestamps) { var xBoundPix = this.ctx.measureText((this.scalesteps*sstep).toFixed(2)).width; var xBound = Math.floor((xBoundPix/this.intervalSize)+1) for(var i = this.nValues-1; i >= xBound; i--) { /* Calculate line coordinates */ var x = (i+1)*this.intervalSize; /* Put time stamps */ var xoffset = this.width-25*this.cssScale; var yoffset = this.ctx.measureText(this.timestamps_array[0][i]).width+4*this.cssScale; this.ctx.rotate(Math.PI/2); this.ctx.fillText(this.timestamps_array[0][i], this.height-yoffset, -x+xoffset); this.ctx.stroke(); this.ctx.rotate(-Math.PI/2); } } /* Draw graph */ for(var i = 0; i < this.noLabels; i++) { for(var j = this.nValues-1; j > 0; j--) { /* Calculate line coordinates */ var xstart = (j+1)*this.intervalSize-50*this.cssScale; var xend = j*this.intervalSize-50*this.cssScale; /*var xend = this.width-25*this.cssScale;*/ var ystart = scaleInvert(this.points[i][j], this.maxVal, this.height); var yend = scaleInvert(this.points[i][j-1], this.maxVal, this.height); /* Draw line */ this.ctx.beginPath(); this.ctx.moveTo(xstart, ystart); this.ctx.lineTo(xend, yend); this.ctx.strokeStyle = linecolor; /*this.colors[i];*/ this.ctx.stroke(); } } } } /* Helper function to take a value value and return y-coordinate for the canvas */ function scaleInvert(value, maxVal, height) { return (1 - value/maxVal) * height; } /* Helper function that shifts the contents of row to left */ function shiftArrayRowLeft(array, row, ncols, newVal) { for(var i = 0; i < ncols-1; i++) { array[row][i] = array[row][i+1]; } array[row][ncols-1] = newVal; return array; } /* Helper function to create an empty */ function emptyArray(nrows, ncols, fill=0) { var arr = []; for(var i = 0; i < nrows; i++) { arr[i] = []; for(var j = 0; j < ncols; j++) { arr[i][j] = fill; } } return arr; } /* Helper function to create array of colors */ function colorArray(len) { var colorArray = []; for(var i = 0; i < len; i++) { colorArray[i] = colors[i%colors.length]; } return colorArray; }