Pure CSS/HTML Line Charts
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(valueArray, labels, width, height, DOMID, showDataPoints) {
var DOMID = DOMID || 'chart_div',
showDataPoints = showDataPoints || false,
buffer = '<div class="ceLineChart" style="height: ' + height + 'px;width: ' + width + 'px;">',
max = Math.max.apply(0, valueArray),
boxwidth = 1,
prevb = 0,
size = valueArray.length,
len = Math.ceil(width / (size - 1)),
totalWidth = 0;
//-- Draw Chart
newA = new Array();
for (var x = 0; x < size; x++)
newA[x] = Math.floor((height * valueArray[x]) / max);
var start, end, slope, b, m;
for (var x = 0; x < size - 1; x++) {
start = newA[x];
end = newA[x + 1];
slope = (start - end) / len;
for (var i = 0; i < len - 1; i++) {
b = Math.floor(start - (i * slope) - (0.05 * height)); //<- top padding 0.05 = 5%
b = (b < 0) ? 0 : b; //keep height above 0
m = height - b;
//console.log(slope);
if (b == prevb) {
boxwidth++; //if value is same, grow width
} else {
buffer += '<div class="ceLineChartBar" style="height: ' + b +
'px;margin-top: ' + m + '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: ' + b + 'px;margin-top: ' + m + 'px;width: ' + boxwidth + 'px;"></div>';
//-- Done Drawing
//-- Draw Points
for (var i = 0; i < size; i++) {
var left = (i * 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 i = 0; i < size; i++) {
var left = Math.floor((i * len) - (labels[1].length * 3.5));
//Move 1st/last labels inward
if (i === 0) left = 0;
else if (i == size - 1) left -= 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 i = 1; i <= Math.floor(height / 50); i++) {
var bottom = Math.floor(((height - 10) / 4) * i);
var value = Math.floor((bottom * max) / height);
if ((bottom + 18) > height) bottom = 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 i = 0; i < size; i++)
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 { position: relative; overflow: hidden; }
.ceLineChartBar { border-top: 3px solid #9bcf87; float: left; background: #e3eedd; opacity: 0.8; }
.ceLineChartBar:hover { background: #bedfab; }
.ceLabel { padding: 2px 5px 2px 5px; font-size: 12px; text-align: center;
position: absolute; border-radius: 4px; background: white; color: #6d6d6d; }
.ceDataPoint { position: absolute; border-radius: 5px; background: white; padding: 2px; }
Example Usage
Example 1)
ceLineChart( [255,435,354,436], ['A','B','C','D'], 450, 145, 'chart1', true);
Example 2)
ceLineChart( [5,4,23,4,5,2,4], ['A','B','C','D','E','F'], 610, 200, 'chart2', true);
Example 3)
ceLineChart( [92,55,74,49], ['A','B','C','D'], 610, 145, 'chart3');