From 978a4190a60fa75b28415ad84fa7c0860177cf79 Mon Sep 17 00:00:00 2001 From: Diogo Cordeiro Date: Fri, 7 Sep 2018 18:20:45 +0100 Subject: [PATCH] First commit --- chart.js | 155 ++++++++++++++++++++++++++++++++++++++++++++ equation-plotter.js | 153 +++++++++++++++++++++++++++++++++++++++++++ index.html | 28 ++++++++ 3 files changed, 336 insertions(+) create mode 100644 chart.js create mode 100644 equation-plotter.js create mode 100644 index.html diff --git a/chart.js b/chart.js new file mode 100644 index 0000000..ca0bf50 --- /dev/null +++ b/chart.js @@ -0,0 +1,155 @@ +// SLA Data +var sla = null; +const request = async () => { + const response = await fetch('sla'); + const json = await response.json(); + sla = json[0]; + console.log("sla data: "); + console.log(sla); +} +request(); + +const chartColors = [ + (a=1) => `rgba( 54, 162, 235, ${a})`, + (a=1) => `rgba( 75, 192, 192, ${a})`, + (a=1) => `rgba(201, 203, 207, ${a})`, + (a=1) => `rgba(255, 159, 64, ${a})`, + (a=1) => `rgba(153, 102, 255, ${a})`, + (a=1) => `rgba(255, 99, 132, ${a})`, + (a=1) => `rgba(255, 205, 86, ${a})` +] + +fetch('top.csv') // Open log +.then(response => response.text()) // Read it +.then(data => data.split('\n').map(x => x.split(','))) // Split in lines and split lines in columns +.then(data => { + const n = 100 // Number of dots + + const headers = data[0].slice(1) // Remove the first header column (timestamp) + // Remove headers line and the empty last one and grab the first 100 + data = data.slice(1, -1).slice(-n) + + // Time will be shown in seconds then we divide it by 1000 + // before building the X axis + const start = Math.round(data[0][0]/1000) + const xAxis = data.map(row => Math.round(row[0]/1000) - start) + + // We will create a chart for each header: + const charts = headers.map((header, index) => { + const canvas = document.getElementById('chart-'+header) + if (!canvas) return null + const color = chartColors[index % chartColors.length] + + const options = { + type: 'line', + responsive: true, + data: { + labels: xAxis, + datasets: [{ + label: header, + data: data.map(row => row[index+1]), // Y axis + backgroundColor: color(0.5), + borderColor: color(), + borderWidth: 1, + pointRadius: 2 // Size of the dots + }] + }, + options: { + legend: { + display: false + }, + scales: { + xAxes: [{ + ticks: { + autoSkip: true, + maxTicksLimit: 15, + }, + scaleLabel: { + display: true, + labelString: 'seconds' + } + }], + yAxes: [{ + ticks: { + autoSkip: true, + maxTicksLimit: 8 + }, + scaleLabel: { + display: true, + labelString: header + } + }] + }, + animation: { + onComplete: function(animation) { + plot_lines(animation) + } + } + } + } + // If we have more than 200 dots then we deactivate lines and animations + // to avoid slowing or crashing the dashboard + if (n > 199) { + options.options.elements = { + line: { + tension: 0 + } + }, + options.options.animation = { + duration: 0 + }, + options.options.hover = { + animationDuration: 0 + }, + options.options.responsiveAnimationDuration = 0 + } + + return new Chart(canvas.getContext('2d'), options) + }) + var charts_loaded = true; + return charts +}) +.then(charts => { + console.log('done', charts) +}) +.catch(error => { + console.error('An error ocurred:', error) +}) + +function plot_lines (animation) { + var execTime_line = new Graph({ + canvasId: 'chart-execTime (ms)', + minX: -10, + minY: -10, + maxX: 10, + maxY: 10, + unitsPerTick: 1 + }); + execTime_line.drawEquation(function(x) { + return sla.maxExecTime; + }, 'green', 1); + + var accuracy_line = new Graph({ + canvasId: 'chart-Accuracy (%)', + minX: -10, + minY: -10, + maxX: 10, + maxY: 10, + unitsPerTick: 1 + }); + accuracy_line.drawEquation(function(x) { + return sla.minAccuracy; + }, 'green', 1); + + var cost_line = new Graph({ + canvasId: 'chart-cost', + minX: -10, + minY: -10, + maxX: 10, + maxY: 10, + unitsPerTick: 1 + }); + cost_line.drawEquation(function(x) { + return sla.maxCost; + }, 'green', 1); +} diff --git a/equation-plotter.js b/equation-plotter.js new file mode 100644 index 0000000..4a6b1bb --- /dev/null +++ b/equation-plotter.js @@ -0,0 +1,153 @@ +// Source: https://www.html5canvastutorials.com/labs/html5-canvas-graphing-an-equation/ + +function Graph(config) { + // user defined properties + this.canvas = document.getElementById(config.canvasId); + this.minX = config.minX; + this.minY = config.minY; + this.maxX = config.maxX; + this.maxY = config.maxY; + this.unitsPerTick = config.unitsPerTick; + + // constants + this.axisColor = '#aaa'; + this.font = '8pt Calibri'; + this.tickSize = 20; + + // relationships + this.context = this.canvas.getContext('2d'); + this.rangeX = this.maxX - this.minX; + this.rangeY = this.maxY - this.minY; + this.unitX = this.canvas.width / this.rangeX; + this.unitY = this.canvas.height / this.rangeY; + this.centerY = Math.round(Math.abs(this.minY / this.rangeY) * this.canvas.height); + this.centerX = Math.round(Math.abs(this.minX / this.rangeX) * this.canvas.width); + this.iteration = (this.maxX - this.minX) / 1000; + this.scaleX = this.canvas.width / this.rangeX; + this.scaleY = this.canvas.height / this.rangeY; + + /*/ draw x and y axis + this.drawXAxis(); + this.drawYAxis();*/ +} + +Graph.prototype.drawXAxis = function() { + var context = this.context; + context.save(); + context.beginPath(); + context.moveTo(0, this.centerY); + context.lineTo(this.canvas.width, this.centerY); + context.strokeStyle = this.axisColor; + context.lineWidth = 2; + context.stroke(); + + // draw tick marks + var xPosIncrement = this.unitsPerTick * this.unitX; + var xPos, unit; + context.font = this.font; + context.textAlign = 'center'; + context.textBaseline = 'top'; + + // draw left tick marks + xPos = this.centerX - xPosIncrement; + unit = -1 * this.unitsPerTick; + while (xPos > 0) { + context.moveTo(xPos, this.centerY - this.tickSize / 2); + context.lineTo(xPos, this.centerY + this.tickSize / 2); + context.stroke(); + context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3); + unit -= this.unitsPerTick; + xPos = Math.round(xPos - xPosIncrement); + } + + // draw right tick marks + xPos = this.centerX + xPosIncrement; + unit = this.unitsPerTick; + while (xPos < this.canvas.width) { + context.moveTo(xPos, this.centerY - this.tickSize / 2); + context.lineTo(xPos, this.centerY + this.tickSize / 2); + context.stroke(); + context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3); + unit += this.unitsPerTick; + xPos = Math.round(xPos + xPosIncrement); + } + context.restore(); +}; + +Graph.prototype.drawYAxis = function() { + var context = this.context; + context.save(); + context.beginPath(); + context.moveTo(this.centerX, 0); + context.lineTo(this.centerX, this.canvas.height); + context.strokeStyle = this.axisColor; + context.lineWidth = 2; + context.stroke(); + + // draw tick marks + var yPosIncrement = this.unitsPerTick * this.unitY; + var yPos, unit; + context.font = this.font; + context.textAlign = 'right'; + context.textBaseline = 'middle'; + + // draw top tick marks + yPos = this.centerY - yPosIncrement; + unit = this.unitsPerTick; + while (yPos > 0) { + context.moveTo(this.centerX - this.tickSize / 2, yPos); + context.lineTo(this.centerX + this.tickSize / 2, yPos); + context.stroke(); + context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos); + unit += this.unitsPerTick; + yPos = Math.round(yPos - yPosIncrement); + } + + // draw bottom tick marks + yPos = this.centerY + yPosIncrement; + unit = -1 * this.unitsPerTick; + while (yPos < this.canvas.height) { + context.moveTo(this.centerX - this.tickSize / 2, yPos); + context.lineTo(this.centerX + this.tickSize / 2, yPos); + context.stroke(); + context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos); + unit -= this.unitsPerTick; + yPos = Math.round(yPos + yPosIncrement); + } + context.restore(); +}; + +Graph.prototype.drawEquation = function(equation, color, thickness) { + var context = this.context; + context.save(); + context.save(); + this.transformContext(); + + context.beginPath(); + context.moveTo(this.minX, equation(this.minX)); + + for (var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) { + context.lineTo(x, equation(x)); + } + + context.restore(); + context.lineJoin = 'round'; + context.lineWidth = thickness; + context.strokeStyle = color; + context.stroke(); + context.restore(); +}; + +Graph.prototype.transformContext = function() { + var context = this.context; + + // move context to center of canvas + this.context.translate(this.centerX, this.centerY); + + /* + * stretch grid to fit the canvas window, and + * invert the y scale so that that increments + * as you move upwards + */ + context.scale(this.scaleX, -this.scaleY); +}; diff --git a/index.html b/index.html new file mode 100644 index 0000000..8922acf --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ + + + +
+ + + + + + +
+ + + + +