HTML5 Game - Creating an Animated Vertical Bar Chart

Description

Creating an Animated Vertical Bar Chart

Demo

ResultView the demo in separate window

<!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>

Related Topic