Creating an Animated Vertical Bar Chart
<!DOCTYPE html> <html> <head> <style> #graph {/*from w w w . ja v a 2 s . c o m*/ border: 1px solid #03F; } </style> <script> let canvas; let context; // Chart settings let chartMargin; let chartAxisSpace; let chartWidth; let chartHeight; // bar variables let numBars = 0; // total number of bars let barMargin = 20; // margin between bars let barWidth = 0; // bar width let maxValue = 0; // maximum data value for the bars // number of y-axis labels let numYLabels; // bar animation variables let idxStep; let numSteps; let growSpeed; // Chart JSON sample data let chartData = { 'bars': [{ 'title': 'Year 1', 'value': '7' }, { 'title': 'Year 2', 'value': '12' }, { 'title': 'Year 3', 'value': '20' }, { 'title': 'Year 4', 'value': '33' }, { 'title': 'Year 5', 'value': '55' }, { 'title': 'Year 6', 'value': '93' }, { 'title': 'Year 7', 'value': '156' } ] } function initGraph() { canvas = document.getElementById('graph'); context = canvas.getContext('2d'); initSettings(); // initialize the chart settings drawAxis(); // draw the chart axis and labels growBars(); // animate the bars into the chart } function initSettings() { chartMargin = 20; chartAxisSpace = 50; chartHeight = canvas.height - chartAxisSpace - 2 * chartMargin; chartWidth = canvas.width - chartAxisSpace - 2 * chartMargin; numYLabels = 8; numBars = chartData.bars.length; for (let i = 0; i < numBars; i++) { if (chartData.bars[i].value > maxValue) { maxValue = parseInt(chartData.bars[i].value); } } barWidth = (chartWidth / numBars) - barMargin; idxStep = 0; numSteps = 100; growSpeed = 6; } function drawAxis() { context.lineWidth = 2; context.moveTo(chartMargin + chartAxisSpace, chartHeight + chartMargin); context.lineTo(chartMargin + chartAxisSpace, chartMargin); context.stroke(); context.moveTo(chartMargin + chartAxisSpace, chartMargin + chartHeight); context.lineTo(chartMargin + chartAxisSpace + chartWidth, chartMargin + chartHeight); context.stroke(); context.lineWidth = 1; let markerAmount = parseInt(maxValue / numYLabels); context.textAlign = 'right'; context.fillStyle = '#000'; for (let i = 0; i <= numYLabels; i++) { markerLabel = i * markerAmount; markerXPos = chartMargin + chartAxisSpace - 5; markerYPos = chartMargin + (chartHeight - ((i * markerAmount * chartHeight) / maxValue)); context.fillText(markerLabel, markerXPos, markerYPos, chartAxisSpace); } context.textAlign = 'center'; for (let i = 0; i < numBars; i++) { markerXPos = chartMargin + chartAxisSpace + barMargin + (i * (barWidth + barMargin)) + (.5 * barWidth); markerYPos = chartMargin + chartHeight + 10; context.fillText(chartData.bars[i].title, markerXPos, markerYPos, barWidth); } context.save(); context.translate(chartMargin + 10, chartHeight / 2); context.rotate(Math.PI * -90 / 180); context.fillText('Sales (in 000s)', 0, 0); context.restore(); context.fillText('Year Out', chartMargin + chartAxisSpace + (chartWidth / 2), chartMargin + chartHeight + 40); } function growBars() { let barStartX = 0; let barStartY = 0; let barHeight = 0; let barValue = 0; for (let i = 0; i < numBars; i++) { barValue = parseInt(chartData.bars[i].value); barHeight = (barValue * chartHeight / maxValue) / numSteps * idxStep; barStartX = chartMargin + chartAxisSpace + (i * (barWidth + barMargin)) + barMargin; barStartY = chartMargin + (chartHeight - barHeight); drawBar(barStartX, barStartY, barWidth, barHeight); } if (idxStep < numSteps) { idxStep++; setTimeout('growBars() ', growSpeed); } } function drawBar(barX, barY, barW, barH) { context.fillStyle = '#00c '; context.fillRect(barX, barY, barW, barH); context.shadowOffsetX = 3; context.shadowOffsetY = -3; context.shadowBlur = 3; context.shadowColor = 'rgba(200, 200, 200, .3) '; context.strokeStyle = '#000 '; context.lineWidth = 1; context.strokeRect(barX, barY, barW, barH); } window.addEventListener('load', initGraph, false); </script> </head> <body> <h1>Growing Bar Chart</h1> <canvas id="graph" width="600" height="400"> This browser does not support the canvas element. </canvas> </body> </html>