Background Prerequisites Advantages Limitations
Description / User's Manual Examples Revision History Copyright Notice, Conditions & Disclaimer

JS Graphing Utility by Christian Lange

Good-looking bar graphs in WEB-pages made easy and flexible!

Notice: The bargraph shown above is NOT a bit-mapped image file! It's a HTML table structure generated by the JS Graphing Utility based upon data included in this document as hidden text!

The background

It has puzzled me and annoyed me for a long time why it should be such a big problem to include graphs onto WEB pages. Especially if you want to visualize all sorts of data which changes over time.

As one approach you have to generate your graphs manually with a spreadsheet program, or in a Unix environment with Gnuplot or the like. Then you must somehow produce a GIF or other bit-mapped image file, which then again can be included on a WEB page. This easily becomes such a big task, that it end up being difficult to keep graphs updated even once per day, if that is desirable. Therefore I have been looking for something which made it possible to produce graphs in general for WEB-pages, which are somehow updated automatically.

OK, I happily admit this: The latest version of Gnuplot offers the possibility of generating graph output directly in GIF format, which makes publishing on a WEB page much easier. But still Gnuplot lacks the possibility of producing filled out bars.

When checking it out, I found a simple piece of JavaScript code which showed some simple bar graphs, but it wasn't so flexible and didn't supply the kind of control with the layout of the graphs, which I had in mind at that time. One thing I also disliked, was the usage of colored GIF's for colorizing the bars, which - how small they ever were - made it difficult to implement usage of more and/ or other colors for bars. Before checking the net for possible solutions, I had got an idea about making a JavaScript application, which could be used to generate bar graphs from simple ASCII text data. Much like the text data supplied to GNUplot and the bar graphs which can be made with Excel, or other spreadsheet programs.

I have also seen a simple implementation in Java, but when I tried to put it into use, it looked as if the graphs should not be too sophisticated before it took a loooong time to produce the display. Well - I thought that it maybe were because I were (still am) a novice when it comes to Java - but why on earth should it be necessary to be a multi-lingual programming and/or application expert to include even fairly simple bar graphics on a WEB-page?

I'm sure there must be several commercial software products which can be used. But again, this involves: a) Finding the right product to the right price, which can do what I want it to do. b) Installing it, and learning how to use it.

The commercial solutions I found while checking, were software for special tasks like watching network traffic and things like that, and didn't seem to offer you the possibility of supplying your own data for whatever you wanted to show.


Well, at this point I decided to try how a simple bar graph could be build up in a HTML table, using no GIF's at all, and with a more sophisticated layout than the JavaScript example I had found surfing on the net.

My idea was, that basically all you should need to know for using my JavaScript utility were how to use HTML tags and attributes - and then maybe how to feed HTML tags and attributes to my utility.

To make a long story short, one line of code lead to the next - and they eventually ended up being the JS Graphing Utility, which is presented here.

Prerequisites

The advantages of the JS Graphing Utility are:

  1. A minimum of bitmapped graphics is involved during design and download. That is unless you choose to use images as background for one or more of the title text areas, the whole graph area, the plot area, or maybe even for one or more of the dataseries legends. (The intention was that everything should be in plain text, but in order to produce thin lines on high resolution screens (more than 800 x 600 pixels), I reluctantly had to use a single (transparent) GIF containing a single pixel/dot!)
  2. You don't have to worry about designing a new table structure for every new graph you decide to show. Hopefully that has already been taken care of.
  3. You can quickly produce the first version of a new graph just by supplying the data (as ASCII text in the correct order and format) and let the JS Graphing Utility use the default layout. Afterwards you can then make the adjustments to the layout, that you wish.
  4. You are free to use any HTML color value for both texts and backgrounds and also dataseries legends (i.e. bars).
  5. You can control the face, size and style of fonts, almost as easy as with ordinary HTML text.
  6. You can just as easily control the alignment of text within the various title text and legend areas.
  7. You can easily control the size of the plotarea and of the various text areas (although it often is probably better to let the browser handle this - that is except for the plotarea).
  8. You can be fairly certain that your graphs display equally well (and fast) in both Netscape and MS Internet Explorer browsers.

Limitations:

  1. It is not (yet) possible to have negative values in the data to be visualized. Only positive data values or the value zero are permitted.
  2. X-values (shown along the X-axis) is not yet being treated as numerical values, but are taken as pure text, even though they might be numerical. I.e. no scaling along the X-axis are made based upon the values of X from the input data. Only the number of X-values supplied affect scaling along the X-axis.
  3. Since all text are "real" text and not graphics, all text (Titles and Tick Labels) are shown horizontally.
  4. Long titles, legend texts, or values (used for tick-labels along the axises) or specifying large fonts, might pull the plot area out so that the bars and tick labels doesn't align correctly, or so that tick marks and other thin lines becomes more than one pixel wide as they are supposed to be.
  5. The plot area MUST have an absolute size specified in pixels (dots). The default size is "close to" a height of 200 pixels, and width of 400 pixels. ("Close to" because the default size is adjusted, so that all bars are displayed with the same width.) The plot area of the bargraph shown at the top of this page is 150 x 300 pixels. Specifying a size of the plot area, will cause this size to be exactly as specified (unless pulled out of scale by long texts, etc.), which might cause small variations in the width of the bars.
  6. Graphs can only be shown as 2D (two dimensional). Graphs in 3D can not be produced with this utility.
  7. There might be other limitations, which I haven't noticed or thought of yet. No guaranties are given!
Here you can find a detailed description of how the JS Graphing Utility is used. (You could call it an "User's Manual".)

Examples

The following examples are most of the graphs I use, when checking new versions of the JS Graphing Utility. You might be able to learn some usefull tricks here (or get utterly confused??;-).

Uptime Example #1: Stacked bars and enlarged plotarea

Uptime Example #2: Bars side-by-side and default size of plotarea

Uptime Example #3: Default layout

Disk Usage BarGraph Example: Skipping X-tick labels

Active Example #1 & #2: With skip factor, with (#1) and without (#2) X-margin, and number of values which doesn't match modulus of (skip factor + 1)

Main Example Rotated: Vertical X-axis

Time Spend Example: Vertical X-axis ~ Horizontal bars. Large table

Uptime Example #1R: Vertical X-axis, Stacked bars and enlarged plotarea

Uptime Example #2R: Vertical X-axis, Bars side-by-side, No "X-margin"

Uptime Example #3R: Vertical X-axis, otherwise default layout

Disk Usage BarGraph Example, Vertical X-axis: Skipping X-tick labels

Time Spend Example #2: Vertical X-axis ~ Horizontal bars. Huge table of data (89 X-values, each with 2 to 8 dataseries

Data Distribution Example: Same data table as the previous "Time Spend Example #2", but the 4 other dataseries are shown

Active Example #1R & #2R: Vertical X-axis with skip factor, with (#1) and without (#2) X-margin, and number of values which doesn't match modulus of (skip factor + 1)

Revision History

Version Date Comments
ß1.32 2000-10-21 "ALT=" text on graphic lines for debugging purposes,
cosmetic changes,
and minor bug-fixes.
Using clGrWr v.1.27 and clGrSets v.1.3
ß1.31 2000-02-05 New object properties introduced in order to save simple text used in "ALT=" text for bars:
  • dataseries.dv: data value array
  • dataseries.label: legend text
  • xaxis.lv: label (X-) value
Size of bars set by setting width and height of (transparent) gif instead of setting width and height of table cell.
Data values for X and Y included as "ALT=" text with gif image for bars.
Using clGrWr v.1.26 and clGrSets v.1.3
ß1.30 2000-02-04 Also using 1x1_tr.gif instead of  , when the data (Y-axis) value is zero. With very thin bars on high resolution displays, the table cells for zero data values became wider than the table cells for non-zero data values because a BLANK character took up more space than one pixel even with FONT SIZE of "1pt".
Using clGrWr v.1.25 and clGrSets v.1.3
ß1.29 2000-01-31 Bug fix: Using X-skip factor, vertical X-axis, no X-margin, and a single dataseries didn't work.
Using clGrWr v.1.24 and clGrSets v.1.3
ß1.28 2000-01-30 Bug fix: Using X-skip factor and vertical X-axis didn't work, if the number of X -values wasn't a whole multiple of (X-skip factor + 1).
Improvement: Decrease the smallest shown Y-tick value, so that the smallest Y data value always produces a bar.
Using clGrWr v.1.23 and clGrSets v.1.3
ß1.27 2000-01-24 Global variable CLGRAPHHOME implemented in order to facilitate the location of documents using the JS Graphing Utility in other directories than where the Javascript and other files used for generating graphs are located.
If all (y-)values to be shown are zero, then the Y-axis by default will show 0 as minimum value and 1 as maximum value.
Using clGrWr v.1.22 and clGrSets v.1.3
ß1.26 1999-06-20 Bugfixes and improvements required when Implemented "LegendColumns" and "LegendRows" specifications, in order to facilitate control with the geometry of the table used for the display of the legends.
PREVIOUSLY USED "Legend..." NAMEs OF SPECIFICATIONS CONCERNING THE LEGEND TEXTS, MUST BE RENAMED TO "LegendTitles...".
Using clGrWr v.1.21
ß1.24 1999-06-16 Bugfixes and improvements required when omitting dataseries and when values are missing for some X-values.
FIRST DATASERIES IS NOW SHOWN AT THE BOTTOM OF STACKED BARS - previously the first dataseries was shown at the top.
Minimum value to be shown on the Y-axis is now correctly calculated for stacked bars - and when one or more dataseries is not shown.
Only dataseries shown are now consideret when auto-scaling Y-axis.
Uses clGrWr 1.19.
ß1.23 1999-06-08 clGrWr 1.18: Cosmetic changes & attempts to optimize JavaScript code - not very succesfull :-(
clGrWr 1.17: Improvements and bugfixes for graphs with vertical axis.
Instead of showing legends in a table with a single row (which tended to pull out the horizontal dimension of the plot area), legends are now shown in table with one column.
ß1.22 1999-05-31 Removed 'delete(chart);' - caused javascript error 'chart is permanent' in Netscape 4.03.
Commented out 'Please wait for Netscape to show the page ...' message since operation with Netscape is not that slow anymore.
ß1.21 1999-05-29 Merged tables inside tables for Legend, Axis Titles, and Plot area into the main Chart table.
This improved Netscape performance on most platforms dramatically.
ß1.20 1999-05-24 Implementation of vertical X-axis.
ß1.19 1999-05-07 Bugfix: warning was undefined after succesfull browser check.
ß1.18 1999-05-07 Updated the initial browser check, since this utility doesn't work with Netscape 3.04!
ß1.17 1999-05-03 Removed handling of layer for "Wait" message. It caused document not to be redisplayed when the window was resized (and a onResize="history.go(0)" made printing from Netscape impossible!).
ß1.16 1999-05-02 Changes to make XaxisSkip work.
ß1.15 1999-05-01 Also works with Netscape 4.03 on Windows NT.
ß1.14 1999-04-28 Removed assignment from within "while (...)" and changed "return;" into "return null".
Netscape prior to 4.5 didn't like the "while (...)" construction, nor "return;" when a function sometimes return a value.
ß1.13 1999-04-24 Added a 'Wait' message in the window.status field when the writing of a graph is finished and set a timer to clear window.status 500 msecs later.
Added code to hide document.layer['wait'] if it exist 500 msecs after the writing of a graph is finished. (The document.layer['wait'] should contain a message about the document being loaded and be included in the top of the document.) This has been done because Netscape seems often to fail showing the messages written to the window.status field.
ß1.12 1999-04-23 Bugfix in message-build for old Netscape browsers.
ß1.11 1999-04-21 Two digits in revision level minor. Unused code for displaying progress in separate window.
ß1.10 1999-04-13 Using 1x1_tr.gif to get thin lines, instead of  . The later didn't work well with NT & Unix browsers (Netscape at least).
ß1.9 1999-04-11 First version on the net.

Copyright Notice, Conditions & Disclaimer

Copyright (c) 1999, 2000 Axel Christian Lange. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. This code must not be sold nor included in or with commercial products by anybody else than Axel Christian Lange.
  2. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  3. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS JAVASCRIPT CODE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXEL CHRISTIAN LANGE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Latest update, this page: February 7. 2000