Broad Network


Drawing a Histogram in HTML Canvas

Foreword: In this article I explain how a histogram can be drawn using the HTML canvas.

By: Chrysanthus Date Published: 24 Apr 2016

Introduction

A histogram is a number of vertical rectangular bars joined together, where each bar represents the number of values in a range of values, and the ranges form a large set of continuous values; the longer the bar, the more the number of values in the range. The height of a bar is proportional to the number of values in the range. In this article I explain how a histogram can be drawn using the HTML canvas. No image is involved. The little mathematical skills you need to achieve this is taught to you.

A Histogram Table
The heights of 100 men were measured in centimeters and the result is given in the following table:

Height Range (cm)Number per Range
150 – 1548
155 - 15916
160 - 16443
165 - 16929
170 - 1744


So, the number of men with heights from 150cm to 154cm is 8. The number from 155cm to 159cm is 16. The number from 160 to 164 is 43. The number from 165 to 169 is 29. The number from 170 to 174 is 4. Number-per-range is called Frequency.

The Histogram
You will draw the following histogram, which represents the above table.
Men’s Height Distribution

Canvas Coordinates
Remember, the top-left corner of the canvas has coordinates, (0,0). The coordinates of any point in the canvas is given in general terms as (x,y). x value increases to the right and y value increases downward. The different values for x or y indicates the position of the corresponding pixel. A pixel is the smallest dot on the screen.

Axes
The horizontal axis is the horizontal line on which the bars stand. The vertical axis is the vertical line against which the heights of the bars are measured.

The horizontal axis starts from (30,240) and ends at (260,240). Its y coordinate is 240; this is the y line on which the bars stand. This is the horizontal axis.

The vertical axis starts from (30,240) and ends at (30,40). Its x coordinate is 30; this is the x line against which the heights of the bars are measured. This is the vertical axis.

Drawing a Rectangle
The bars are rectangles. The 2D context method for drawing a rectangle is:

        context.rect(x, y, w, h)

where, x and y are the left-top corner coordinates of the rectangle. w is the width of the rectangle and h is the height of the rectangle.

Horizontal Scale
For simplicity, the ranges have been considered as follows:

150 – 155 instead of 150 – 154
155 – 160 instead of 155 – 159
160 – 165 instead of 160 – 164
165 – 170 instead of 165 – 169
170 – 175 instead of 170 – 174

The range-width or class-width is 5cm for each range. The complete set of values (ranges) is considered to scan from 150cm to 175cm, for simplicity.

The horizontal scale is 5-is-to-20, written as:

    5 : 20

This means that for every 5cm of height, you have 20 pixels interval, measured horizontally, in the canvas.

The width of each bar is 20px, representing 5cm. The first bar starts at an x value of 70 and ends at 90. The second bar starts at an x value of 90 and ends at 110. The third bar starts at an x value of 110 and ends at 130. The fourth bar starts at an x value of 130 and ends at 150. The fifth bar starts at an x value of 150 and ends at 170.

Vertical Scale
The vertical scale is 10-is-to-40, written as:

    10 : 40

This means that for every 10 men, you have 40 pixels interval, measured vertically, in the canvas. That is, for every frequency of 10, you have 40 pixels interval, measured vertically.

So for the first bar whose frequency is 8, the height is given by,

    8/10 x 40 = 32px

This is the height of the bar and not the y coordinate of the top of the bar. To have the y coordinate of the top of the bar, you have to subtract this number from 240, which is the y coordinate of the horizontal axis. 240 – 32 = 208px, giving the y coordinate of the top of the first bar.

For the second bar whose frequency is 16, the height is given by,

    16/10 x 40 = 64px

Subtracting this from 240 you have 176px as the y coordinate of the top of the second bar.

For the third bar whose frequency is 43, the height is given by,

    43/10 x 40 = 172px

Subtracting this from 240 you have 68px as the y coordinate of the top of the third bar.

For the fourth bar whose frequency is 29, the height is given by,

    29/10 x 40 = 116px

Subtracting this from 240 you have 124px as the y coordinate of the top of the fourth bar.

For the fifth bar whose frequency is 4, the height is given by,

    4/10 x 40 = 16px

Subtracting this from 240 you have 224px as the y coordinate of the top of the fifth bar.

Coding
Any canvas code begins with something like:

        cv = document.getElementById('C1');

        cntxt = cv.getContext('2d');

cv holds the reference of the HTML canvas element. cntxt holds the reference of the two dimensional (2D) context, which draws. The code for the first bar (150 – 155 range) is:

        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(70,208,20,32);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();

The path is begun. The line-width for the outline of the rectangle of the bar is given. The color of the outline of the rectangle is then given as black. After that, the position and size of the rectangle for the bar is defined with, “cntxt.rect(70,208,20,32);”. The color to fill inside the rectangle is chosen as brown. The rectangle is then filled with the brown color. And finally, the outline color of the rectangle is drawn with “cntxt.stroke();”.

The other bars are similarly drawn.

The Complete Code
The complete code is:

<!DOCTYPE HTML>
<html>
<head>
    <title>Illustration</title>
</head>
<body>


    <figure style="width:308px; border:2px solid red; display:inline-block">
        <figcaption><strong>Men’s Height Distribution</strong></figcaption>
        <canvas id="C1" width="300" height="260">
        </canvas>
    </figure>

    <script type="text/ECMAScript">
        cv = document.getElementById('C1');

        cntxt = cv.getContext('2d');

        //the axes
        cntxt.beginPath();
        cntxt.moveTo(30,240);
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.lineTo(260,240);
        cntxt.stroke();

        cntxt.beginPath();
        cntxt.moveTo(30,240);
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.lineTo(30,40);
        cntxt.stroke();

        //150cm - 154cm
        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(70,208,20,32);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();

        //155cm - 159cm
        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(90,176,20,64);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();

        //160cm - 164cm
        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(110,68,20,172);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();

        //165cm - 169cm
        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(130,124,20,116);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();

        //170cm - 174cm
        cntxt.beginPath();
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "black";
        cntxt.rect(150,224,20,16);
        cntxt.fillStyle = "brown";
        cntxt.fill();
        cntxt.stroke();


        //labelling the horizontal axis
        cntxt.fillStyle = "blue";
        cntxt.fillText("150",60,251);
        cntxt.fillText("175",160,251);


        //labelling the vertical axis
        cntxt.fillStyle = "blue";

        cntxt.beginPath();
        cntxt.fillText("10",16,202);
        cntxt.moveTo(28,200);
        cntxt.strokeStyle = "blue";
        cntxt.lineWidth = 1;
        cntxt.lineTo(32,200);
        cntxt.stroke();

        cntxt.fillText("20",16,162);
        cntxt.moveTo(28,160);
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "blue";
        cntxt.lineTo(32,160);
        cntxt.stroke();

        cntxt.fillText("30",16,122);
        cntxt.moveTo(28,120);
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "blue";
        cntxt.lineTo(32,120);
        cntxt.stroke();

        cntxt.fillText("40",16,82);
        cntxt.moveTo(28,80);
        cntxt.lineWidth = 1;
        cntxt.strokeStyle = "blue";
        cntxt.lineTo(32,80);
        cntxt.stroke();

        //the axes names
        cntxt.fillText("Frequency",22,37);
        cntxt.fillText("Height (cm)",238,251);

        //key
        cntxt.fillStyle = "green";
        cntxt.fillText("Class-Width : 5cm", 216,100);

    </script>

</body>
</html>

Proper Ranges
The proper ranges to use for the drawing are:

149.5 – 154.5 instead of 150 – 154
154.5 – 159.5 instead of 155 – 159
159.5 – 164.5 instead of 160 – 164
164.5 – 169.5 instead of 165 – 169
169.5 – 174.5 instead of 170 – 174

The class-width (range-width) remains the same for all the bars.

Chrys

Related Links

Surrounding a Web Page Image with Text
Advantages and Disadvantages of HTML Table for Layout
Layout Without Frames for the Web Page
Designing Iconic Hyperlink for a Web Page
A Suitable RWD Layout for Smartphones and Desktop
Knowing the Resolutions of Visitor Screens with ECMAScript
Enlarge and Reduce HTML Image with ECMAScript
HTML5 Image Gallery and Image Enlargement with ECMAScript
Designing a Video Gallery
Ajax Web Technology Explained
Perl Course
MySQL Course
Using the PurePerl MySQL API
Drawing Bar Chart in HTML Canvas
Drawing Pie Chart in HTML Canvas
HTML Canvas 2D Context
Drawing a Histogram in HTML Canvas
More Related Links
PurePerl MySQL API
Web Development Course
Major in Website Design
Producing a Pure Perl Library

Comments

Become the Writer's Follower
Send the Writer a Message