code everywhere
technology, web services and applications

Pure CSS/HTML Line Charts

posted on June 30, 2013, 7:11 pm in html, php, js

Draw a line chart in pure CSS/HTML with this small JavaScript snippet.

There are many ways to build charts for use on the internet, this one uses the idea of integration to build small DIVs under a curve. Altho we use JavaScript to generate the CSS/HTML the line chart itself is built using pure CSS/HTML, once the code has been generated you could copy it into different pages with no need of JavaScript support.

The code is small and has no external dependancies, but is very limited in functionality. If you need something more powerful, Google Charts API might be more suited to your needs. The style of the line chart can be changed using CSS style rules. There are only 5 main parameters.

data array this is the array of data to draw the line chart with.
data labels the data labels are drawn on the bottom of the chart and must match up with the data array.
width the width of the chart
height the height of the chart
target DIV the id of the target where you want to insert the chart

The Code

JavaScript

/* File:    CSS/HTML Line Chart Builder
 * Date:    June 28, 2013
 * License: MIT (http://opensource.org/licenses/MIT)
 * Copyright (C) 2013 by http://codeeverywhere.ca
 */
var ceLineChart = function(valueArraylabelswidthheightDOMIDshowDataPoints) {
    var 
DOMID DOMID || 'chart_div',
        
showDataPoints showDataPoints || false,
        
buffer '<div class="ceLineChart"  style="height: ' height 'px;width: ' width 'px;">',
        
max Math.max.apply(0valueArray),
        
boxwidth 1,
        
prevb 0,
        
size valueArray.length,
        
len Math.ceil(width / (size 1)),
        
totalWidth 0;


    
//-- Draw Chart
    
newA = new Array();
    for (var 
0sizex++)
        
newA[x] = Math.floor((height valueArray[x]) / max);

    var 
startendslopebm;
    for (var 
0size 1x++) {
        
start newA[x];
        
end newA[1];
        
slope = (start end) / len;

        for (var 
0len 1i++) {
            
Math.floor(start - (slope) - (0.05 height)); //<- top padding 0.05 = 5%
            
= (0) ? b//keep height above 0
            
height b;

            
//console.log(slope);

            
if (== prevb) {
                
boxwidth++; //if value is same, grow width
            
} else {
                
buffer += '<div class="ceLineChartBar" style="height: ' +
                    
'px;margin-top: ' 'px;width: ' boxwidth 'px;"></div>'//if value changes, draw block
                
totalWidth += boxwidth;
                
boxwidth 1;
            }
            
prevb b//set previous height to current height
        
}
    }
    
totalWidth += boxwidth;
    
boxwidth += width totalWidth;

    
//sometimes last box too large for width, this fixes that
    
if (boxwidth 0)
        
buffer += '<div data="1" class="ceLineChartBar" style="height: ' 'px;margin-top: ' 'px;width: ' boxwidth 'px;"></div>';
    
//-- Done Drawing


    //-- Draw Points
    
for (var 0sizei++) {
        var 
left = (len) - 15//<-- offset, (-) goes left -- (+) goes right
        
var top height newA[i] + 3//<-- offset, (-) goes up -- (+) goes down

        
if (showDataPoints)
        
//Points with data
            
buffer += '<div class="ceDataPoint" style="left: ' left 'px;top: ' top 'px;">' valueArray[i] + '</div>';
        else
        
//Points without data
            
buffer += '<a href="#" class="ceDataPoint" style="left: ' left 'px;top: ' top 'px;" title="' valueArray[i] + '"></a>';
    }
    
//--


    //-- Draw Bottom Labels (if height > 75px)
    
if (height 75) {
        var 
ceLabels '';
        for (var 
0sizei++) {
            var 
left Math.floor((len) - (labels[1].length 3.5));

            
//Move 1st/last labels inward
            
if (=== 0left 0;
            else if (
== size 1left -= 20;

            
//Add labels to buffer    
            
ceLabels += '<div class="ceLabel" style="left: ' left 'px;bottom:0px;">' labels[i] + '</div>';
        }
    }
    
//--


    //-- Draw Left Labels, 1 label for every 50px in height
    
var ceLeftLabels '';
    for (var 
1<= Math.floor(height 50); i++) {
        var 
bottom Math.floor(((height 10) / 4) * i);
        var 
value Math.floor((bottom max) / height);
        if ((
bottom 18) > heightbottom height 18//Make sure labels dont go higher than height        
        
ceLeftLabels += '<div class="ceLabel" style="bottom: ' bottom 'px;left:0px;">' value '</div>';
    }
    
//--


    //-- Draw Left Labels, level with points on graph
    
if (false) {
        for (var 
0sizei++)
            
ceLeftLabels += '<div class="ceLabel" style="bottom: ' newA[i] + 'px;left:0px;">' valueArray[i] + '</div>';
    }
    
//--

    
buffer += ceLabels;
    
buffer += ceLeftLabels;
    
buffer += '</div>';

    
document.getElementById(DOMID).innerHTML buffer;
};

CSS

.ceLineChart positionrelativeoverflowhidden; }
.
ceLineChartBar border-top3px solid #9bcf87; float: left; background: #e3eedd; opacity: 0.8; }
.ceLineChartBar:hover background#bedfab; }
.ceLabel padding2px 5px 2px 5pxfont-size12pxtext-aligncenter;
    
positionabsoluteborder-radius4pxbackgroundwhitecolor#6d6d6d; }
.ceDataPoint positionabsoluteborder-radius5pxbackgroundwhitepadding2px; }

Example Usage

Example 1)

ceLineChart( [255,435,354,436], ['A','B','C','D'], 450145'chart1'true);

Example 2)

ceLineChart( [5,4,23,4,5,2,4], ['A','B','C','D','E','F'], 610200'chart2'true);

Example 3)

ceLineChart( [92,55,74,49], ['A','B','C','D'], 610145'chart3');

recent posts

< back