Create an Animated 3D Bar Chart/Graph

Create an Animated 3D Bar Chart/Graph

Tutorial Details
  • Program: jQuery, HTML, CSS
  • Version (if applicable): 1.4.2+
  • Difficulty: Intermediate
  • Estimated Completion Time: 1 - 1.5 Hours

The Truematter team was recently tasked with creating a fun, sexy web app that presents numerical data in an engaging way. After putting our heads together, we came up with a bar chart that responds interactively to user input without, heaven forbid, reloading any pages. We’re very pleased to be able to share that with the coding community. There are some CSS tricks involved, a dose of jQuery, and some graphic magic, but when we’re done with this tutorial, we’ll have a beautifully interactive chart that you can customize to your heart’s content.


Prepping the Graphics

The graphic elements and the way those elements are chopped up and compiled is what really gives this chart some wow-factor.  There are only three graphic elements needed for this project, but, since we’re essentially creating an illusion using CSS and images, those graphics need to be crafted with precision.

The chart itself is composed of three separate PNGs stacked on top of each other using CSS, two of which are stationary (the front and back “glassy” chart casing pieces), and one of which is animated using jQuery (the green bar piece in the middle).

These are the graphical elements that make up the final presentation.

Graphic Element 1: Back of the Chart

This is the back panel graphic used in the 3D animated graph.

The background piece is comprised of the bottom of the chart (which we only see when the bar is empty at 0%), the back left and back right panels. On this bottommost layer, we include all of the faces of the graph casing that need to become “covered” when the graph is full or partially full. This is the layer that really gives the 3D illusion some depth.


Graphic Element 2: The Bar Graph

The is the middle layer and bar graph of the 3D animated jQuery tutorial

The animated center portion of this graph is simple to create. We suggest using very basic 3D extrude functions in Illustrator, or you can also just draw a three-panel shape in Photoshop and call it a day.  Color your graph very brightly, oversaturating it as much as possible. Why? Because in the final chart, it will be shown beneath a semi-transparent casing, so the color will be muted by the layer that covers it.

It’s super important that the top and bottom edges of this piece remain transparent, so be sure to save it as a PNG.

Also just as important: make this piece exactly the same height as the graph casing pieces. In our pictures here, the middle layer looks shorter than the casing – when you create your central piece, make the central bar exactly as tall as the casing. If you make it too short, your graph will never be able to fill up to 100% properly. If you make it too tall, the graph can shoot out of the casing container when it’s animated.


Graphic Element 3: The Top Casing

The top casing to complete the 3D animated graph/chart using jQuery and CSS

Here’s where we get to the real visual trickery, which happens along the bottom edge of this third and final piece. While the top left and right edges retain transparency, the bottom left and right edges should be filled in solid with the same color as the background the graph will be sitting on.

For example, if your website background is black, the bottom two edges of this piece need to be filled in with solid black. In our example above, the site background is white, so we’ve filled in the bottom edges with white. This solid-color area effectively hides any overspill from the middle bar-chart piece (graphic element 2). Without this piece and its opaque bottom edge, we lose the 3D effect entirely. Here’s the graph without it:

Image illustrating no correctly producing graphics for the 3D animated graph/chart using jQuery and CSS

The HTML

Okay! We’ve got all of our graphic pieces complete and we’re ready to jump right into the code. The HTML itself is pretty straightforward. You’re looking at a few basic form select fields and a few divs for the bar graph.

First, let’s look at the complete code, then we’ll take it piece by piece (no pun intended!). Note that the bar graph div elements are included within the form tag.

<noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>

<form id="form1" action="#" onsubmit="return false;">
<!-- container for the form elements -->
<div id="formcontainer">
How much money do you want to contribute to savings each month?
<select id="savings" onchange="calculate();">
	<option selected="selected" value="0">- select an amount -</option>
	<option value="100">100 dollars</option>
	<option value="200">200 dollars</option>
	<option value="300">300 dollars</option>
	<option value="400">400 dollars</option>
	<option value="500">500 dollars</option>
	<option value="1000">1000 dollars</option>
	<option value="2000">2000 dollars</option>
	<option value="3000">3000 dollars</option>
	<option value="4000">4000 dollars</option>
	<option value="5000">5000 dollars</option>
</select>

What is your monthly income?
<select id="income" onchange="calculate();">
	<option selected="selected" value="0">- select an amount -</option>
	<option value="1000">1000 dollars</option>
	<option value="2000">2000 dollars</option>
	<option value="3000">3000 dollars</option>
	<option value="4000">4000 dollars</option>
	<option value="5000">5000 dollars</option>
</select>
</div>

<div id="grapharea">
<h4>Percentage of Monthly Salary Saved</h4>
<div id="p25">25%</div>
<div id="p50">50%</div>
<div id="p75">75%</div>
<div id="p100">100%</div>
<div id="graphcontainer">
	<img id="graphbackground" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphbackground.png" alt="" width="262" height="430" />
	<img id="graphbar" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphbar.png" alt="" width="262" height="430" />
	<img id="graphforeground" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphforeground.png" alt="" width="262" height="430" />
</div>
</div>
</form>

The Breakdown

Since this chart depends on javascript, we first check to make sure it’s enabled in the browser:

		<noscript><h3>You must enable JavaScript to view this demo!</h3></noscript>
		

Now we begin the form. For the purposes of this demo, we’ve used two simple dropdowns, but you could just as easily modify this code to use text fields, radio buttons, or any other type of input. The select onchange attribute is given the function “calculate();”, which we’ll cover in the jQuery section below.

		<div id="formcontainer">
			How much money do you want to contribute to savings each month?
			<select id="savings" onchange="calculate();"> 
				<option selected="selected" value="0">- select an amount -</option> 
				<option value="100">100 dollars</option> 
				<option value="200">200 dollars</option> 
				<option value="300">300 dollars</option> 
				<option value="400">400 dollars</option> 
				<option value="500">500 dollars</option> 
				<option value="1000">1000 dollars</option> 
				<option value="2000">2000 dollars</option> 
				<option value="3000">3000 dollars</option> 
				<option value="4000">4000 dollars</option> 
				<option value="5000">5000 dollars</option> 
			</select>

			What is your monthly income?
			<select id="income" onchange="calculate();"> 
				<option selected="selected" value="0">- select an amount -</option> 
				<option value="1000">1000 dollars</option> 
				<option value="2000">2000 dollars</option> 
				<option value="3000">3000 dollars</option> 
				<option value="4000">4000 dollars</option> 
				<option value="5000">5000 dollars</option> 
			</select>

		</div>
		

And finally, included within the form tag, the graphic elements:

		<div id="grapharea">
			<h4>Percentage of Monthly Salary Saved</h4>
			<div id="p25">25%</div>
			<div id="p50">50%</div>
			<div id="p75">75%</div>
			<div id="p100">100%</div>
			<div id="graphcontainer">
				<img id="graphbackground" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphbackground.png" alt="" width="262" height="430" /> 
				<img id="graphbar" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphbar.png" alt="" width="262" height="430" /> 
				<img id="graphforeground" src="http://d2o0t5hpnwv4c1.cloudfront.net/2032_animatedBarGraph/images/graphforeground.png" alt="" width="262" height="430" />
			</div>
		</div>
		

The CSS

		#formcontainer { float: left; }
		#grapharea { position: relative; float: left; margin-left: 4em; }
		#graphcontainer {
			position: relative;
			width: 262px;
			height: 430px;
			overflow: hidden;
		}
		#graphbackground, #graphforeground { position: absolute; }
		#graphbar { position: absolute; top: 430px; }

		.graphlabel { position: absolute; left: 270px; }
		#p25 { top: 365px; }
		#p50 { top: 278px; }
		#p75 { top: 191px; }
		#p100 { top: 105px; }
		

Probably the most crucial thing that should catch your eye here is the #graphbar div. Notice that our #graphbar div starts out at 430px – the total height of the bar chart. This height declaration is the number that is manipulated via jQuery to make the graph animate. If you have created your own graphic elements which are taller or shorter than 430px, you’ll need to adjust that number to match your own graphics.

Likewise, you’ll also need to adjust the px of #p25, #p50, #p75, and #p100. These top declarations set the position of the 25%, 50%, 75% and 100% markers on the right side of the graph.

Also, take a close look at the #graphcontainer styles:

		#graphcontainer {
			position: relative;
			width: 262px;
			height: 430px;
			overflow: hidden;
		}
		

Putting a position:relative;declaration on this outer wrapper lets us use absolute positioning on the three divs within #graphcontainer, so we can stack them on top of each other using CSS offsets. Setting a height and a width are also vital here – the height and width of this div should perfectly match the height and width of graphic elements 1 and 3. And overflow: hidden; hides the animated graphic, element 2, when it extends outside the bounds of the wrapping div.


The Code

Ah, now for the jQuery! It ties all pieces together and adds in the animation. A quick review of the full jQuery:

		<script>
		 function calculate() { 	
			var ZEROPOS = 355; 	
			var salary = $("#income").val(); 	
			var savings = $("#savings").val(); 	
			var percent = savings / salary; 	

			if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)
			{
				if (parseInt(savings) > parseInt(salary))
					alert("You cannot save more than you earn - please change your selections accordingly.");
				else	
				{
					val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
					$("#graphbar").animate({ top: val + "px" }, 1500);
				}
			}
		}
		</script>
		

The Final Breakdown

First, create a constant to use in the calculations. ZEROPOS is the pixel value of where the central graphic element (graphic 2, the movable piece) should be positioned to represent 0%.

var ZEROPOS = 355;

Next, find the values selected by the user using the select boxes – salary and savings. Then calculate the percentage value – percent.

		var salary = $("#income").val();
		var savings = $("#savings").val();
		var percent = savings / salary;
		

The next step is a validation check to make sure the user has actually selected values from both select boxes. If they have, we continue with the script. Otherwise, we do nothing.

if (parseInt(savings) >  0 &amp;&amp; parseInt(salary) > 0)

If the user has entered the appropriate values, we then make sure that they have selected a salary that is higher than the amount they want to contribute to savings. If they have, we continue with the script. Otherwise we prompt the user to change their selections.

		if (parseInt(savings) > parseInt(salary))
		alert("You cannot save more than you earn - please change your selections accordingly.");
		

Now we are finally to the meat of the script – calculating the position to which we will move the graph bar and then firing off the jQuery animate functionality to make it happen.

		val = (percent == 0) ? ZEROPOS : ZEROPOS - (percent * ZEROPOS);
		$("#graphbar").animate({ top: val + "px" }, 1500);
		

So, in calculating the value for the graph bar position – val –  first determine if the percentage is zero. If so, set value equal to the ZEROPOS constant. Otherwise, calculate the new bar position by subtracting the percentage value multiplied by the zero position value from the zero position value. This formula is used because we are animating the bar from the zero position at the bottom of the chart up towards the top.

Once the pixel value is calculated, we know where we’re heading, so simply call the animate method in jQuery on the graphbar object passing in the new CSS value for the top position with an animation rate of 1500 (the speed of the animation in milliseconds). Then jQuery does the magic for us and moves the bar within the chart accordingly. Violà!

Hope you enjoyed this tutorial!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://notes.kloop.kg Said Kaldybaev

    Need to try, thanks!

  • http://www.wimbledon-it.co.uk WimbledonIT

    This looks actually pretty nice. I think I might use that in my next WordPress plugin.

  • http://pressedweb.com Cory

    Just about to go to sleep, but this looks awesome. I can’t wait to overuse the snot out of these. :D

    Thanks guys!

  • Sergey

    Very elegant approach. Thanks for sharing this!
    You inspired me to do this with pure CSS, here is what I’ve got so far (targeted FF & Chrome just for now):
    http://sergeylukin.com/css-3d-bar-graph/

    Adjust the height of #graphbar in Firebug to see it moving;)
    ..it’s a pitty I couldn’t avoid using a background patch too.. but anyways it’s first draft. I will do more polish work later on.

    • http://pressedweb.com Cory

      Looks awesome man! :)

      Considered using radio buttons to avoid the page jump so this can be a small element with tons of content around it?

      • Sergey

        Thanks!:)
        You are right – replaced links with radio buttons, so much better now

    • Chris

      looks great!

  • Nick

    I was just thinking, wouldn’t it be awesome to give the graph a little bounce at the end?

  • Hamid

    Very elegant and very good article,thQ Kendra.

  • http://ooooak.tubler.com aksahy

    that’s really cool . thanks

  • Alchemication

    I hate that IE6 does not support transparency..personally i don’t give a damn but we still need to support the Devil (IE666)….
    Thanks for Post, great stuff…

  • Potado

    It would be more fun if you used THREE.js :D

  • http://www.mekshq.com meks

    Nice tutorial!

    Learn a lot! Thank you!

  • http://www.kendraschaefer.com Kendra Schaefer

    Thanks guys, glad you all like, it’s so cool to see other people using this! And double thanks to Ken at Truematter for the the code that drives the back end. Credits should also go to Molly Oakley, who also worked on the graphics.

  • http://www.persefer.com ozan dikerler

    I think there is a problem with empty state. Bar image is coming down more than needed.

  • http://www.edwardingram.com/ Edward Ingram

    Props!

  • Hithaishi

    Nice article

  • http://www.brushstrokemedia.co.uk Brushstroke Media

    Kendra, Ken, great post, I have been playing with the idea of creating a series of interactive infographics using css and jquery, some of the effects are nightmare to create though. This is certainly going to come in handy.

    • http://www.kendraschaefer.com Kendra

      Would love to see it when you do!

  • David

    If you don’t mind leaving out IE, you could achieve the transparent PNG’s with CSS3 Skew. Off the top of my head, the lines could either be created with or each block a separate div. But I haven’t gone through the whole tutorial, so I’m not sure if there would be any hitches.

    Cheers!

  • http://WebFABRIKA.ba WebFABRIKA

    Looks very interesting … :) Thanks

  • Cyro

    Great tutorial. I just wish I knew how to work with echoed out php variables. I wonder if anyone can help me?

  • Cyro

    Great tutorial. I just wish I knew how to work with echoed out php variables. I wonder if anyone can help me?

  • http://palpaldal.com Nuruzzaman Sheikh

    Very useful tutorial. Thanks a lot for sharing. Surely going to try something with this :)

  • hhe

    Very nice!

  • Sean Lum

    Thank you very much! This was quite helpful!

  • http://www.thewebsweweave.com Jeff

    Kendra & Ken,

    Great tutorial and thanks for sharing with us!

    Please excuse my lack of javascript knowledge, but what would it take to add a comment next to the graph that says something like, “Wow! You can save x.xx% of your salary!”?

    Of course, x.xx would equal the calculated amount.

  • Anudeep

    hi super tutorial can you make this video tutorial

  • http://boletobest.com aaditya

    Now when we has Html5 and css3 can’t we stop using all the math stuff while programming. :)

  • http://italkless.com/ Ngb

    Great work, and it’s stunning.

  • http://haryanvimaza.com aaditya

    very explanative tutorial .. I am trying to make pie charts with the help of this tutorial .

  • http://davidsteenkamp.com David Steenkamp

    This was a great tutorial. I normally suck real bad with Javascript, but this was a nice little easement into it. I wanted to try and enter some text inputs for the numbers, as well as create something that actually displays what the percentage is… so I did. It took me a while (remember, I suck at JS) and I uploaded what I did here if you want to check it out. You should be able to view source to see it all:

    http://davidsteenkamp.com/dev/graph/

    I wanted to take it a step further and make it so that the graph goes back down and disappears when you click on ‘reset’ but didn’t even know where to start. Any ideas? Also, I wanted to have it so that if you entered a different number in either of the boxes after already doing one calculation, the numbers would change by counting…. ie: initially it says “50.98%” – then have that go to 50.97…50.96…50.95 etc… all the way down to whatever the new calculation would be. I found a couple resources online but they seemed a bit over my head.

    Anyways, a great tutorial and I thank you very much for posting it with such great notes!

  • http://squarepackage.com john coyne

    I got this running in appMobi on ipad and iphone as a challengetoself to learn more js and appMobi – thanks for the tutorial!

  • Mark Miller

    This is really great. I’m wondering if someone could help me take it a step further.
    I’d like a set of radio buttons for various project elements, and a graph that fluctuates based on the buttons selected. Imagine nine buttons ranging values in percent (2, 10, 3, 20, 15, 7, 5, 8, 30). Click any two buttons (or more) and the graph resizes to the combined value. Click them all it hits 100.
    I’ve used nice round numbers that add to 100, but I’m really looking to do specific costs that add to a project total, allowing a user to select options and watch the total change.
    Any help tips pointers or suggestions would be greatly appreciated.
    Thanks.

    • Mark Miller

      … and I should have added that I need it to work on an iPad. thanks.