The following code creates a configurable Bar Chart.
It takes in an array of data elements and creates a bar chart.
<!DOCTYPE HTML> <html> <head> <script> class BarChart {// w w w .j av a2s . co m constructor(config) { this.canvas = document.getElementById(config.canvasId); this.data = config.data; this.color = config.color; this.barWidth = config.barWidth; this.gridLineIncrement = config.gridLineIncrement; this.maxValue = config.maxValue - Math.floor(config.maxValue % this.gridLineIncrement); this.minValue = config.minValue; // constants this.font = "12pt Calibri"; this.axisColor = "#555"; this.gridColor = "#aaa"; this.padding = 10; // relationships this.context = this.canvas.getContext("2d"); this.range = this.maxValue - this.minValue; this.numGridLines = this.numGridLines = Math.round(this.range / this.gridLineIncrement); this.longestValueWidth = this.getLongestValueWidth(); this.x = this.padding + this.longestValueWidth; this.y = this.padding * 2; this.width = this.canvas.width - (this.longestValueWidth + this.padding * 2); this.height = this.canvas.height - (this.getLabelAreaHeight() + this.padding * 4); // draw bar chart this.drawGridlines(); this.drawYAxis(); this.drawXAxis(); this.drawBars(); this.drawYVAlues(); this.drawXLabels(); } getLabelAreaHeight() { this.context.font = this.font; let maxLabelWidth = 0; for (let n = 0; n < this.data.length; n++) { let label = this.data[n].label; maxLabelWidth = Math.max(maxLabelWidth, this.context.measureText(label).width); } /* * return y component of the labelWidth which * is at a 45 degree angle: * * a^2 + b^2 = c^2 * a = b * c = labelWidth * a = height component of right triangle */ return Math.round(maxLabelWidth / Math.sqrt(2)); } getLongestValueWidth() { this.context.font = this.font; let longestValueWidth = 0; for (let n = 0; n <= this.numGridLines; n++) { let value = this.maxValue - (n * this.gridLineIncrement); longestValueWidth = Math.max(longestValueWidth, this.context.measureText(value).width); } return longestValueWidth; } drawXLabels() { let context = this.context; context.save(); let data = this.data; let barSpacing = this.width / data.length; for (let n = 0; n < data.length; n++) { let label = data[n].label; context.save(); context.translate(this.x + ((n + 1 / 2) * barSpacing), this.y + this.height + 10); context.rotate(-1 * Math.PI / 4); // rotate 45 degrees context.font = this.font; context.fillStyle = "black"; context.textAlign = "right"; context.textBaseline = "middle"; context.fillText(label, 0, 0); context.restore(); } context.restore(); } drawYVAlues() { let context = this.context; context.save(); context.font = this.font; context.fillStyle = "black"; context.textAlign = "right"; context.textBaseline = "middle"; for (let n = 0; n <= this.numGridLines; n++) { let value = this.maxValue - (n * this.gridLineIncrement); let thisY = (n * this.height / this.numGridLines) + this.y; context.fillText(value, this.x - 5, thisY); } context.restore(); } drawBars() { let context = this.context; context.save(); let data = this.data; let barSpacing = this.width / data.length; let unitHeight = this.height / this.range; for (let n = 0; n < data.length; n++) { let bar = data[n]; let barHeight = (data[n].value - this.minValue) * unitHeight; if (barHeight > 0) { context.save(); context.translate(Math.round(this.x + ((n + 1 / 2) * barSpacing)), Math.round(this.y + this.height)); context.scale(1, -1); context.beginPath(); context.rect(-this.barWidth / 2, 0, this.barWidth, barHeight); context.fillStyle = this.color; context.fill(); context.restore(); } } context.restore(); } drawGridlines() { let context = this.context; context.save(); context.strokeStyle = this.gridColor; context.lineWidth = 2; // draw y axis grid lines for (let n = 0; n < this.numGridLines; n++) { let y = (n * this.height / this.numGridLines) + this.y; context.beginPath(); context.moveTo(this.x, y); context.lineTo(this.x + this.width, y); context.stroke(); } context.restore(); } 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(); context.restore(); } drawYAxis = function() { let context = this.context; context.save(); context.beginPath(); context.moveTo(this.x, this.y); context.lineTo(this.x, this.height + this.y); context.strokeStyle = this.axisColor; context.lineWidth = 2; context.stroke(); context.restore(); } } window.onload = function() { let data = [{ label: "Java", value: 12 }, { label: "SQL", value: 18 }, { label: "Oracle", value: 28 }, { label: "Javascript", value: 22 }, { label: "HTML", value: 42 }]; new BarChart({ canvasId: "myCanvas", data: data, color: "blue", barWidth: 20, minValue: -10, maxValue: 45, gridLineIncrement: 2 }); }; </script> </head> <body> <canvas id="myCanvas" width="600" height="300" style="border:1px solid black;"> </canvas> </body> </html>