site logo

Bar graph with help of <div>

Basic principle of drawing this type of graph is simple. Prepare helping picture bar.png and container div. Inside of the container helping picture is drawn. The container is declared as CSS position: relative. Thus inside of the container can be used CSS position: absolute  and by setting coordinates lefttopwidth  and height  the size and position of helping picture can be set according to actual needs. For vertical graph width,  and left  coordinates are constant and height  and top  coordinates are changed to render desired picture. Coordinates are indicated to upper left corner of each container. Practical usage of this graph type you can see in applications Raw Materials Stock, or Power Supply.

 

In the left you see simplified graph example from application Production Reports. I use this example for explanation of bar graph drawing principles. Subsequently I bring in extended example of the same bar graph and try to describe some other possibilities. Graph and code sample follow.


<style type="text/css">
.card {width: 240px; height: 165px; position: relative;}
.cont {position: relative; width: 14px; height: 165px; float: left;}
.bar  {position: absolute; width: 13px; left: 0;}
</style>

<body>

<div class="card">
...
<div class="cont">
<img class="bar" style="top: 85px; height: 75px;" src="bar.png" />
</div>
...
</div>

</body>

CSS class .card  is used for definition of graph area. Classes .cont  and .bar  are used for each column in graph. Class .cont  is container for single column. Content of container is visual element with class .bar.  Important are position declarations: container's position: relative; enables using position: absolute; inside of this element.

The width of cont  is one pixel larger, than the width of bar  and so columns of graph are separated by one pixel space. Columns of graph are set side by side thanks to property float: left;  of container. Only constant coordinates of visual element bar  are declared in CSS section, the rest of coordinates are declared as in line style (each bar has different height and top).

HTML section of code reserves drawing area for graph by the help of <div class="card">  and draws one (sample) column of graph <div class="cont"> ....  Visual element img has assigned its variable coordinates top  and height  as in line style. These variable coordinates (in red color) are calculated by server according to actual data.

 
product
date
plan

We extend simple graph now. We add background to graph, we add another graphic element (mark of production plan) and we expand graph by some DHTML functions. If you have JavaScript on, try to move mouse over graph and try to click on graph. You could see numerical values of each bar below graph and linking to report print in very primitive way.


<style type="text/css">
/* bar graph and mark */
.card {width: 240px; height: 165px; position: relative;}
.back {position: absolute; width:240px; height: 180px;
       top: 0; left: 0; z-index: 0;
}
.cont {position: relative; width: 14px; height: 165px; float: left;}
.bar  {position: absolute; width: 13px; left: 0; z-index: 1;}
.mark {position: absolute; width:  9px; height: 9px; left:2px; z-index:2;}

/* dynamic legend below graph */
div.L, div.C, div.R {
 font: normal 100 11px Arial, SansSerif, Verdana;
 background: transparent; color: #666; border: 0; padding: 0;
 position: absolute; top: 162px; height: 16px; width: 55px;
}
div.L {left:  10px; text-align: left;}
div.C {left:  92px; text-align: right;}
div.R {left: 172px; text-align: right;}
</style>

<script type="text/javascript">
function Show(st, dt, pt) {
  document.getElementById("st").innerHTML = st;
  document.getElementById("dt").innerHTML = dt;
  document.getElementById("pt").innerHTML = pt;
}
function Print(dt) {
  alert("report print simulation for day " + dt);
}
</script>

<body>

<div class="card" onmouseout="Show('product','date','plan')">
<img class="back" src="card.png" />
<div class="cont" style="width: 7px;"> </div>
...
<div class="cont"
 onmouseover="Show('A19fn','1.4.','112,0%')"
 onclick="Print('1.4.2006')">
<img class="bar"  style="top: 85px; height: 75px;" src="bar.png" />
<img class="mark" style="top: 90px;" src="mark.png" />
</div>
...
<div class="L" id="st">product</div>
<div class="C" id="dt">date</div>
<div class="R" id="pt">plan</div>
</div>

</body>

Original CSS section is extended by a few new classes. Class .back  is for graph pseudo background. It would be possible to merge .back  and .card  into one class and add definition of background, but usually backgroud is not printed. Class .mark  is added for production plan marking. Classes .L, .C, .R  are used for legend display below graph. They could be defined as id, but only one graph on page is allowed then.

In JavaScript section you see function Show  for dynamic display of values in legend below graph. Function Print  links user to report page (date is passed as queryString). In this page report is simulated by alert.

HTML code. First 3 lines of code define area for drawing, calling function for reset legend text, background picture and left margin of graph setting with help of div element. Example of one graph column is in listing on following 6 lines. Each graph bar is inside single container (<div class="cont" ...). Parameters of this container are JavaScript functions for mouse event processing. Next 2 lines display visual elements bar  and mark. Last part of HTML code are 3 elements div  for legend display.

Black parts of code are constant, reds parts insert server according to calculation based on current values of data and differentiate for each graph column. Do not forget to test graphic range so that position top  is not negative and height  of bar does not exceed the height of container. Use DOCTYPE  declaration to switch browser IE to the standard XHTML mode.

Dynamic functions onMouseOver  and onClick  in container cont  have a bit different behaviour in particular browsers. No problems are in standard browsers, functions are activated in any position of mouse over container. In IE6 these functions apply only above container content, here only above graph bar. Ordinary user does not note of this, because he covers mouse over bar graph of course .

IE problem is in background picture. There are several possible way to solve the problem. You can add another absolutely positioned transparent.gif  into container and draw bar over that (used on the most right column of graph). You can merge background picture as mentioned above. Or you can draw complete graph by help of old good tables (see last article).

updated 11.11.2006