Line charts shows the data trends.
The following code create a configurable Line Chart class.
It takes in an array of data elements and plots each point while connecting the points with line segments.
<!DOCTYPE HTML> <html> <head> <script> class LineChart{/*from w w w . j a v a 2 s .c o m*/ constructor(config){//from www. ja va2s . c om this.canvas = document.getElementById(config.canvasId); this.minX = config.minX; this.minY = config.minY; this.maxX = config.maxX; this.maxY = config.maxY; this.unitsPerTickX = config.unitsPerTickX; this.unitsPerTickY = config.unitsPerTickY; this.padding = 10; this.tickSize = 10; this.axisColor = "#555"; this.pointRadius = 5; this.font = "12pt Calibri"; this.fontHeight = 12; // relationships this.context = this.canvas.getContext("2d"); this.rangeX = this.maxX - this.minY; this.rangeY = this.maxY - this.minY; this.numXTicks = Math.round(this.rangeX / this.unitsPerTickX); this.numYTicks = Math.round(this.rangeY / this.unitsPerTickY); this.x = this.getLongestValueWidth() + this.padding * 2; this.y = this.padding * 2; this.width = this.canvas.width - this.x - this.padding * 2; this.height = this.canvas.height - this.y - this.padding - this.fontHeight; this.scaleX = this.width / this.rangeX; this.scaleY = this.height / this.rangeY; // draw x y axis and tick marks this.drawXAxis(); this.drawYAxis(); } getLongestValueWidth(){ this.context.font = this.font; let longestValueWidth = 0; for (let n = 0; n <= this.numYTicks; n++) { let value = this.maxY - (n * this.unitsPerTickY); longestValueWidth = Math.max(longestValueWidth, this.context.measureText(value).width); } return longestValueWidth; } drawXAxis(){ let context = this.context; context.save(); context.beginPath(); context.moveTo(this.x, this.y + this.height); context.lineTo(this.x + this.width, this.y + this.height); context.strokeStyle = this.axisColor; context.lineWidth = 2; context.stroke(); // draw tick marks for (let n = 0; n < this.numXTicks; n++) { context.beginPath(); context.moveTo((n + 1) * this.width / this.numXTicks + this.x, this.y + this.height); context.lineTo((n + 1) * this.width / this.numXTicks + this.x, this.y + this.height - this.tickSize); context.stroke(); } // draw labels context.font = this.font; context.fillStyle = "black"; context.textAlign = "center"; context.textBaseline = "middle"; for (let n = 0; n < this.numXTicks; n++) { let label = Math.round((n + 1) * this.maxX / this.numXTicks); context.save(); context.translate((n + 1) * this.width / this.numXTicks + this.x, this.y + this.height + this.padding); context.fillText(label, 0, 0); context.restore(); } context.restore(); } drawYAxis(){ let context = this.context; context.save(); context.save(); context.beginPath(); context.moveTo(this.x, this.y); context.lineTo(this.x, this.y + this.height); context.strokeStyle = this.axisColor; context.lineWidth = 2; context.stroke(); context.restore(); // draw tick marks for (let n = 0; n < this.numYTicks; n++) { context.beginPath(); context.moveTo(this.x, n * this.height / this.numYTicks + this.y); context.lineTo(this.x + this.tickSize, n * this.height / this.numYTicks + this.y); context.stroke(); } // draw values context.font = this.font; context.fillStyle = "black"; context.textAlign = "right"; context.textBaseline = "middle"; for (let n = 0; n < this.numYTicks; n++) { let value = Math.round(this.maxY - n * this.maxY / this.numYTicks); context.save(); context.translate(this.x - this.padding, n * this.height / this.numYTicks + this.y); context.fillText(value, 0, 0); context.restore(); } context.restore(); } drawLine(data, color, width){ let context = this.context; context.save(); this.transformContext(); context.lineWidth = width; context.strokeStyle = color; context.fillStyle = color; context.beginPath(); context.moveTo(data[0].x * this.scaleX, data[0].y * this.scaleY); for (let n = 0; n < data.length; n++) { let point = data[n]; // draw segment context.lineTo(point.x * this.scaleX, point.y * this.scaleY); context.stroke(); context.closePath(); context.beginPath(); context.arc(point.x * this.scaleX, point.y * this.scaleY, this.pointRadius, 0, 2 * Math.PI, false); context.fill(); context.closePath(); // position for next segment context.beginPath(); context.moveTo(point.x * this.scaleX, point.y * this.scaleY); } context.restore(); } transformContext(){ let context = this.context; // move context to center of canvas this.context.translate(this.x, this.y + this.height); // invert the y scale so that that increments // as you move upwards context.scale(1, -1); } } window.onload = function(){ let myLineChart = new LineChart({ canvasId: "myCanvas", minX: 0, minY: 0, maxX: 140, maxY: 100, unitsPerTickX: 10, unitsPerTickY: 10 }); let data = [{ x: 10, y: 80 }, { x: 20, y: 10 }, { x: 40, y: 30 }, { x: 60, y: 80 }, { x: 80, y: 100 }, { x: 100, y: 5 }, { x: 120, y: 5 }, { x: 140, y: 100 }]; myLineChart.drawLine(data, "blue", 3); data = [{ x: 20, y: 15 }, { x: 40, y: 50 }, { x: 60, y: 35 }, { x: 80, y: 10 }, { x: 100, y: 100 }, { x: 120, y: 20 }, { x: 140, y: 35 }]; myLineChart.drawLine(data, "red", 3); }; </script> </head> <body> <canvas id="myCanvas" width="600" height="300" style="border:1px solid black;"> </canvas> </body> </html>