Make Bar Chart from User-Inputted Data
In this tutorial, we will make a bar chart from User-Inputted data.
JavaScript Charts, Graphs, Graphics, Circles, Ellipses, Arcs, Lines, and Polygons
Grab and Drop, Not Drag and Drop
Add Ids and onClicks to Divs
Add Ids and onClicks and Grab and Drop to Divs
Make Anti-alias (Almost) Lines
Make Anti-alias (Almost) Lines Using Bresenham's Line Algorithm
Good JavaScript Circle Algorithm
Good JavaScript Ellipse Algorithm
Good JavaScript Arc Algorithm
Make JavaScript Irregular Polygon
JavaScript Area of Irregular Polygon Algorithm
Make Line Chart from User-Inputted Data
Make Line Chart from CSV Data
Make Line Chart from MySQL Table Data
Make Bar Chart from User-Inputted Data
Make Bar Chart from CSV Data
Make Bar Chart from MySQL Table Data
Make Pie Chart from User-Inputted Data
Make Pie Chart from CSV Data
Make Pie Chart from MySQL Table Data
Data for line charts and bar graphs and pie charts can come from any number of sources. We considered putting together a user input form and the numeric data could be charted and the non-numeric data turned into labels, and we did that below—the script on this page. But we decided to also interface with the two most important database sources needing charting: CSV files and MySQL tables. CSV is a delimited data format that has fields/columns separated by the comma character and records/rows terminated by newlines, and MySQL is the most popular open-source database ever. The first, CSV, can be pulled out of any competant database app, for example: spreadsheets such as Microsoft Excel or databases such as Microsoft Access database or Apache OpenOffice, which is a spreadsheet, database, word processor, plus other stuff (and it's free). MySQL is a server-side relational database, and the tables that we store in this database can be easily created, modified, or just read with server-side computer languages—such as PHP. We'll read a MySQL table here: Make Bar Chart from MySQL table data, and a CSV file here: Make Bar Chart from CSV Data, but on this page we'll stick to User-Inputted data.
In the script, the user will simply type a title and comma-separated data and labels into a form and press the submit button. Excel can make lots better graphs than what we'll do here (but at some point one has to enter data even in Excel). However, if you like programming as much as we do, you'd like to check out how it's done. Besides, what if you've created a PHP poll but do not feel like dealing with the script for making a chart, but you do want a bar chart or line chart or pie chart?
When entering comma-separated labels, remember to type in comma-separated words, like the names of months for example (labels need to be 12 characters or less, so keep this in mind, or you can change the number in the trimit() function). When entering comma-separated data amounts, keep in mind that these must be just plain numbers without decimal points. If your data is .05, .77, 1.07, and .98, simply type 5,77,107,98 with no spaces, dollar signs, quotes, or other things. If you need it to be about money, have this in your chart name, such as Monthly Data in Dollars Collected From Selling Pottery. If you'd like to add a $ filter or decimal point filter so that you can deal with exported Excel data with $ in front of it, that's simple programming we'll leave up to you to add to the PHP program below.
Check out the PHP program below called Make Bar Chart from User-Inputted Data, which you may copy from this page and name as a PHP file called getuserdatatobarchart.php.
In the script, first comes the function validate(), for form validation. We include PHP form validation later. We use the standard regular expression codes, and also utilize the JavaScript search method. So, sendname is the form name and title is the input tag name, and the next two scripts filter data and labels, similarly. Note the focus() method is used if the user uses forbidden characters. What this does is keep the user in the input box until he does it right, by focusing on that box, which means keeping the cursor there. Our JavaScript filter is friendlier than our PHP input filter, since the former lets you edit input box contents on the fly, while the latter reloads the page so you start over—your penalty for having JavaScript turned off! The return true code means input is okay, and return false means it was not. The form onsubmit event runs the validate() function, and return false means the form will not get submitted.
Next comes the bye() and hello() functions. We didn't end up needing the hello() function, but the bye() function we
did. Once the chart is made, we run bye() to display the question Do another? by setting the display property for this question to block. It's a link that prompts you for an answer. At the same time, bye() sets the display property for the user input form to none. We are preventing these forms from being displayed on top of each other, chaotically.
Now, after a bit of CSS styling, we code the aDiv and bDiv DIV styles. bDiv we use for the "labels" labels and aDiv we use for the "data" labels. We'll be adding these labels to the document with DOM methods like createElement() and appendChild(), using innerHTML for inserting the actual text into the DIV. We'll use calculated height and marginLeft properties on the DIVs later. Note that the overflow property is hidden and the background-color is transparent so in case you decide to have longer labels, the text won't slobber all over nearby text.
Next, there's the data input form whose action is the PHP file getuserdatatobarchart.php, which is the name you need to give the PHP file on this page. In other words, once you type in your data, the web page calls itself, reloading but remembering the POSTed title, data, and labels you typed into this user input form.
Next comes the div with the message Do another? Note that its display property, gotten from class='reload', starts out as none—it will stay that way until form submission. This message is link text and clicking the link reloads the page (getuserdatatobarchart.php) and displays the input form again.
Next comes the PHP script. We POST in the title and filter it with regular expressions, using the preg_match() function, which was likely invented to filter input. We do the same with the POSTed data and labels fields, which have comma-separated data, you recall. But we cannot leave them in this form, so we use the explode() function, which returns an array of strings, each of which is a substring of the to-be-processed POSTed string. The array is formed by splitting the POSTed string on boundaries formed by the string delimiter—our commas. These PHP arrays will get converted to JavaScript arrays with JavaScript Object Notation (JSON), a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse. How else will you convert our data from PHP to JavaScript? We employ the max() function to get the biggest value in the data array. Finally we use the strlen() function to check if the POSTed array strings were empty or nearly empty. If so, we show a message and reload the page.
Now come JavaScript Object Notation (JSON) for PHP to JavaScript conversions. We use the json_encode() function to convert the PHP data and labels arrays and $flag flag and $biggest value and the chart title into JavaScript arrays and variables, respectively, for convenient use.
Then we divide the maximum amount value by 350. The 350 is the height of the graph minus 30—which we did because we don't want the top of a bar in the graph to hit the top of the graph. We'll be using a[i]/r to figure out bar heights. The a[] array is where the amounts are stored.
Next we use the Document Object Model (DOM) in two for loops to add labels to the chart bars as well as drawing the bars themselves. We use the createElement() Method to bring a div into existence and the appendChild() Method to get it integrated into the document. The innerHTML property is used to put the labels into the div elements.
Next we put a box around the entire bar chart. Finally, we insert the chart title under the chart and we draw a box around the whole bar chart using a width forced by the width and min-width properties. And we end with the bye() function to undisplay the input form and display the Do another? question link instead.
<html>
<head>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>Make Bar Charts from User-Inputted Data</TITLE>
<meta name="description" content="Make Bar Charts from User-Inputted Data">
<meta name="keywords" content="Make Bar Charts from User-Inputted Data,View User-Inputted Data as Bar Charts,bar chart User-Inputted Data,php,javascript, dhtml, DHTML">
<script language="javascript">
function validate(){
if(document.sendname.title.value.length>0){
var ck_title = /^[a-zA-Z0-9\s\_\,]{2,40}$/;
if (document.sendname.title.value.search(ck_title)==-1)
{alert("Please only enter 2 to 40 letters, numbers, spaces and underlines for Bar Chart Title.");document.sendname.title.focus();return false}}
if(document.sendname.data.value.length>0){
var ck_data = /^[0-9\,]{3,200}$/;
if (document.sendname.data.value.search(ck_data)==-1)
{alert("Please only enter 3 to 200 characters, which should be integer numbers separated by commas for Bar Chart Data.");document.sendname.data.focus();return false}}
if(document.sendname.labels.value.length>0){
var ck_labels = /^[a-zA-Z0-9\s\_\,]{3,200}$/;
if (document.sendname.labels.value.search(ck_labels)==-1)
{alert("Please only enter 3 to 200 characters, which should be letters, numbers, spaces and underlines separated by commas for Bar Chart Labels.");document.sendname.labels.focus();return false}}
return true;}
function bye(){var thediv=document.getElementById('myform');thediv.style.display='none';var b=document.getElementById('b');b.style.display='block';}
function hello(){var thediv=document.getElementById('myform');thediv.style.display='block';var b=document.getElementById('b');b.style.display='none';}
</script>
<STYLE TYPE="text/css">
BODY {margin-left:0; margin-right:0; margin-top:0;text-align:left;}
p, li, td {font:13px Verdana; color:black;text-align:left}
h1 {font:bold 28px Verdana; color:black;text-align:center}
h2 {font:bold 24px Verdana;text-align:center}
h3 {font:bold 15px Verdana;}
input {font:13px Verdana;text-align:left}
#myid {position:absolute;left:10px;top:117px;height:380px;border: solid 1px #000;}
#myform {position:absolute;left:50px;top:20px}
#label {position:absolute;left:400px;top:550px;}
.l {font:bold 13px Verdana;text-align:center}
.reload {position:absolute;left:400px;top:50px;text-align:center;display:none}
.aDiv {
width: 68px;
border: solid 1px #000;
background-color: #e1e1e1;
font-size: 11px;
font-family: verdana;
color: #000;
padding: 5px;
overflow:hidden
}
.bDiv {
width: 68px;
border: none;
background-color: #fff;
font-size: 11px;
font-family: verdana;
color: #000;
padding: 5px;
overflow:hidden
}
</STYLE>
</head>
<body>
<div id='myform'>
<center><h1>Make Bar Charts from User-Inputted Data</h1></center>
<form action='getuserdatatobarchart.php' method='post' name='sendname' onsubmit='return validate()'>
Bar Chart Title: <input type='text' name='title' id='whattable' size='35' maxlength='40' value=''><BR>
Bar Chart Data (comma-separated integers only): <input type='text' name='data' id='whatdata' size='35' maxlength='200' value=''><BR>
Bar Chart Labels (comma-separated letters, numbers, spaces, underscores only): <input type='text' name='labels' id='whatlabels' size='35' maxlength='200' value=''><BR>
<input type='submit' class='l' value='Get bar chart' name='flag'></form></div>
<div id='b' class='reload'><a HREF="getuserdatatobarchart.php">Do another?</a></div>
<?php
$flag=$_POST['flag'];
if (isset($flag)){
$t = $_POST['title'];
if(preg_match('/[^a-zA-Z0-9\\s\\_\\,]/', $t)){echo '<script language="javascript">alert("Enter title using only letters and numbers and spaces and underscores.");window.location="getuserdatatobarchart.php";</script>;';}else
{$d = $_POST['data'];}
if(preg_match('/[^0-9\\,]/', $d)){echo '<script language="javascript">alert("Enter data using only comma-separated integer numbers.");window.location="getuserdatatobarchart.php";</script>;';}else
{$data = explode(',',$d);$biggest=max($data);}
$l = $_POST['labels'];
if(preg_match('/[^a-zA-Z0-9\\s\\_\\,]/', $l)){echo '<script language="javascript">alert("Enter labels using only comma-separated letters and numbers and spaces and underscores.");window.location="getuserdatatobarchart.php";</script>;';}else
{$labels = explode(',',$l);}
if(strlen($d) <3 || strlen($l) <3){
echo '<script language="javascript">alert("Enter both data and labels, using only integer numbers for data and letters and numbers and spaces and underscores for labels.");window.location="getuserdatatobarchart.php";</script>;';}}
?>
<script language="javascript">
var m = <?php echo json_encode($labels); ?>;
var a = <?php echo json_encode($data); ?>;
var b = <?php echo json_encode($biggest); ?>;
var t = <?php echo json_encode($t); ?>;
var f = <?php echo json_encode($flag); ?>;
var r=b/350;
if (a.length > 0 && m.length > 0) {
for (var i=0;i<a.length;i++){
var divTag = document.createElement("div");
divTag.id="a" + i;
divTag.setAttribute("align", "center");
divTag.style.marginLeft = (i*78+20)+"px";
divTag.style.position = "absolute";
divTag.style.bottom = 100+"px";
divTag.style.height = (a[i]/r)+"px";
divTag.className = "aDiv";
divTag.innerHTML = a[i];
document.body.appendChild(divTag);
}
for (var i=0;i<a.length;i++){
var divTag = document.createElement("div");
divTag.id="b" + i;
divTag.setAttribute("align", "center");
divTag.style.marginLeft = (i*78+20)+"px";
divTag.style.position = "absolute";
divTag.style.bottom = 70+"px";
divTag.style.height = 30+"px";
divTag.className = "bDiv";
divTag.innerHTML = m[i];
document.body.appendChild(divTag);
}
document.write("<div id='label'><h1>"+t+"</h1></div><div id='myid' style='min-width:"+(a.length*80)+"px; width:"+(a.length*80)+"px'> </div>");
bye();
}
</script>
</body>
</html>