Turning the Graph Function Into an Object in JavaScript, Part 1

Sometimes it is simple enough to build an object from the ground up in a slow, methodical, organized fashion. By contrast, one may also choose to hack something together to get it to work, play with it, and then refine it. In the particular case of the graphing widget I threw together last week I am clearly taking the latter tack. This is a problem I have solved before but for novel problems it’s often a good idea to work through various trials and prototypes, object-oriented or not. It’s also good to write out the code you want to be able to generate automatically, or at least some examples of it. This ensures that you aren’t trying to debug the resultant code at the same time you’re trying to figure out how to generate it.

Those observations aside, creating a graph on a web page–at least the way I’ve done it–relies on the HTML5 canvas object. There are a couple of ways to proceed that I’ll discuss today. The graph object must be associated with a canvas, but the canvas object itself can be created either as part of the original HTML for a page, which can them be referred to by the graph object, or created as part of the graph object’s constructor and added to an existing page. In either case it is important to remember that the native dimensions of the canvas itself have to be specified at the time of its creation and insertion into the page. Applying style properties that attempt to modify the dimensions of the canvas after it is created and added to the page have unexpected effects, which I’ll describe.

The normal way to define a canvas element in a page is by using the following HTML statement like that shown below. An id must be included so the object can be uniquely referenced, and the dimensions need to be specified as the object is created. If dimensions are not specified the canvas assumes default dimensions of 300 pixels wide and 150 pixels high (in browsers that support the canvas element).

If you want to create the canvas on the fly in JavaScript you must specify its dimensions before you add it to the page as follows:

This uses the object constructor approach, which allows for creation of multiple such objects. It is a means of defining a type rather than a specific, instantiated object.

In this case I’ve provided the constructor with a width, a height, and an id value (expressed as a string). When the constructor is called it looks for an element having the provided id. If the id is found and the located element is, in fact, a canvas, then the graph object assumes its width and height. If the id is found and the located element is not a canvas than the constructor can raise an error of some sort. If no element with the specified id is found then a canvas element is created and added to the page using the document.body.appendChild() function. This is the only case in which the width and height parameters are actually used.

After that the canvas can be referenced and modified as usual, as shown in the example.

I noted above that the dimensions of the canvas element must be set when the object is created and added onto or inserted into the page. If you do not manipulate the dimensions further with CSS commands then any drawing commands will map 1-to-1 by pixel as expected. If you do apply CSS styling to change the width and height of an existing canvas it will change the size of the element on the page, but it will treat the pixels inside the canvas boundaries as if they still had the original dimensions. The interior objects will simply be scaled so they occupy the same relative proportion and location of the interior space. This will also affect the thickness of any lines or other objects drawn with the object.

That said, changing the dimensions of a canvas by directly modifying its width and height properties in JavaScript appears not to have the same effect. If you specify new dimensions then the graphing space in the canvas will have the same dimensions on a 1-to-1 pixel basis. I don’t know why you’d want to modify a created canvas object in that way, but if you do, now you know it’ll work. In short, CSS bad, JavaScript good–in this limited case.

Note that this process could be expanded to include the ability to handle inserting the newly created graph element into the middle of a page using the insertBefore() function. It could be expanded again to make the append and insert operations apply to any level of element and not just the document as a whole. On the other hand, at some point, given that we’ve created the ability to attach to an existing canvas element (and safely modify its dimensions), we might leave it to external code to arbitrarily place the new canvas and then attach to that in the simplest way. The possibilities, of course, are endless.

This entry was posted in Software and tagged , , . Bookmark the permalink.

Leave a Reply