HTML5 Game - Chart Bar Chart

Creating a bar chart

The following code creates a configurable Bar Chart.

It takes in an array of data elements and creates a bar chart.

Demo

ResultView the demo in separate window

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

Related Topics