Features

Features > Design Features > CSS

Somewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web. Oftentimes the solutions you see implemented are clunky, for example, manually creating multiple frames of various data points and uploading them by hand. These methods scale poorly and […]

Somewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web. Oftentimes the solutions you see implemented are clunky, for example, manually creating multiple frames of various data points and uploading them by hand. These methods scale poorly and try even the most patient.

Traditionally the task of combatting the challenge has fallen to Flash. To be sure, it is a fine choice. I am not here to rail against Flash and contend that absolutely all things on the web should be done with HTML, CSS, and JavaScript. Flash is tailor-made for creating dynamic web experiences. However, using Flash in some cases might be the technological equivalent of hitting a fly with a sledgehammer.

By using a standardized set of web technologies, it is possible to produce interesting data visualizations that degrade gracefully in the face of browser inferiority. Through careful semantic crafting of our XHTML containers, clever use of CSS, and a splash JavaScript, we can build data visualizations that enhance our message and communicate better to our users. As a frame for this technique, I have created a fake site for a university fundraising event. The data visualization we’re going to be working with here is a temperature gauge that will display progress towards a monetary goal. Go ahead and take a sneak peek at the final result.

Building the XHTML

As with most techniques, the foundational XHTML is the most important piece, enabling us to progressively enhance the visual presentation. The structure of our XHTML will be in three parts:

  1. The container of the data visualization
  2. The progress indicator to be animated
  3. A textual representation of the data

The structure for this is alarmingly simple, so I won’t drag it out over multiple steps for you.


50%

It may seem as though we have an extra div element here. In many other CSS articles, authors go to great lengths to reduce the number of div elements needed to construct a page, oftentimes relying on readily-available block-level elements. While this methodology has great merit, I will always use an extra div instead of using a p when it comes to the visual composition of a key page element. More often than not my work is handed off to a different design/content team and I have no idea if they are going to realize the p tag has a purpose beyond simple content formatting. Using an extra div here protects the integrity of the visual structure moving forward.

Jiggering the CSS

The visualization component will be handled through a clever combination of background images and property manipulation. When I first started developing this technique my instinct was to use absolute positioning to slide the inner element in and out as necessary, essentially “filling” the container with the inner element and hiding the unnecessary parts.

This method worked fine when I was only working with simple blocks. As soon as I started working with non-square shapes it fell completely flat. The points between 0 and 100 never lined up correctly. Searching for a new solution, I struck on the idea to align the inner element with the edge of its parent and alter its width/height depending upon the value being displayed. By doing so we gradually reveal the background image of the inner element, allowing it to line up perfectly with the background element of its parent.

What we will do is create two images. The first image will represent the empty state of our visualization and the second will be the completely full state. The empty state will be applied as the background of the gauge element and the full state as the background of the progress indicator element. Technically speaking, I’m only going to create one image with both states in it. For more information on why I’ve chosen to do this, you can refer to CSS Sprites: Image Slicing’s Kiss of Death, an excellent article by David Shea. You can view the image here.

The CSS for the container is as follows:


.gauge{
	width: 77px;
	height: 442px;
	position:relative;
	background: #333 url(gauge.gif) top left no-repeat;
}

The CSS here is pretty trivial, but do notice that we specify a hex color value in the background property. This hex color increases the technique’s accessibility and will provide a solid reference color to those who have disabled images.

For the inner element:


.gauge .current-value {
	position:absolute;
	left: 0px;
	bottom: 0px;
	height: 50%;
	text-align:center;
	width: 100%;
	background: red url(gauge.gif) bottom right no-repeat;
}

Because this animation is vertical I have positioned the inner element at the bottom of the container and positioned the background element at the bottom of the inner element. This technique works just fine as a horizontal animation as well, with the primary difference being where the internal element is anchored to its parent. As before, we specify a color in the event that images are disabled in the user’s browser.

From here, the only property we care about is height. In our example it is set to 50%. The entire visualization hinges on this value being accurate. You may be tempted to scrape the value from the XHTML p element with JavaScript and set the height from there, but that alienates your users with JavaScript disabled. Therefore, your options are to set this dynamically with a backend script or update it by hand. Either way is exponentially favorable to creating 100 distinct images for the intermittent states.

The last step is to hide the textual value.


.gauge .current-value * {
	display:none;
}

Note: I am not here to get into a debate on the best way to hide text.

This step is optional, you may wish to leave the textual equivalent of your data displayed over the top of the visualization. I have chosen to hide it, but users who come along with CSS disabled will still be able to view the progress of the fundraiser.

At this point, you can stop. You have created a compelling visual representation that is highly reusable and degrades gracefully in the face of antiquated technology, all using skills already at your disposal. Take a look at the example page to see the results. However, if you want to add a finishing touch you can sprinkle in some JavaScript animation.

Working The JavaScript

Now that we have our gauge built, we will add an unobtrusive layer of JavaScript to animate the mercury of our gauge from zero to its current state. Those users who do not have JavaScript enabled will not see this, but those who do will be presented with a nice animation to complete the temperature gauge visualization.The first thing we will do is setup an object literal to contain our gauge animation. This will help us maintain scope and increase portability if we need to extend our JavaScript.

var gauge = {}

We are going to need to keep track of two things: the document node we’re animating and the height at which we will need to stop animating. We don’t know either of these things at the time of creation, so we’ll create variable place holders for now.


var gauge = {
	targetHeight : 0,
	progressMeter : new Object(),
}

My own preference when working with JavaScript object literals is to create an init() method to kick start whatever it is I will be using them for. In this case, init() will need to do three things:

  1. Verify the user’s browser supports the Document Object Model (DOM) specific methods we will be using
  2. Reset the value of the gauge to 0
  3. Animate the gauge to its final value

As such, our init() method will look like:


init : function(){
		if(!document.getElementByID) return false;
		this.resetValue();
		this.animateGauge();
}

The first line checks to see if we can use document.getElementById and aborts if we cannot. This will exclude all browsers that do not support the standard DOM. The next two lines are for methods we have not written yet, which is something we will do now.


resetValue : function(){
		this.progressMeter = document.getElementById("campaign-progress-current");
		this.targetHeight = this.progressMeter.offsetHeight;
		this.progressMeter.style.height = "0px";
	}

This method grabs the node we wish to animate and stores it in the progressMeter variable we set above. It then grabs the current height of the node and saves it as the target height we will be animating to. Finally, it sets the height of the node to 0. Once we have done all of this, we are ready to animate the mercury to its current value.


animateGauge : function(){
		var currHeight = this.progressMeter.offsetHeight;
		if(currHeight == this.targetHeight){}
		else{
			var interval = Math.ceil((this.targetHeight - currHeight) / 10);
			this.progressMeter.style.height = currHeight   interval   "px";
			setTimeout("gauge.animateGauge()",30);
		}
	}

This function is where the magic happens. It first grabs the current height of the node and compares it to the target height and halts the animation if they are equal. If they are not equal, it runs a very simple formula to calculate an animation interval which is appended to the node’s current height. The formula we use creates a very simple illusion of easing, which is more natural to the eye than a simple linear animation. Once it’s done that, it waits 30 milliseconds and calls the animateGuage() again. This process, known as recursion, will repeat until the gauge has reached its target value. Now all we need to do is call the init() function once the window has loaded.


window.onload = function(){
		gauge.init();
	}

Note: I fully acknowledge that this is a very primitive onload function and should not be used in production. However, that debate is long and not appropriate to this article. Because I have used this technique you may notice some initial flickering.

Putting it all together, the final code looks like this:


window.onload = function(){
		gauge.init();
	}

var gauge = {

	targetHeight : 0,
	progressMeter : new Object(),

	init : function(){
		if(!document.getElementById) return false;
		this.resetValue();
		this.animateGauge();
	},

	resetValue : function(){
		this.progressMeter = document.getElementById("campaign-progress-current");
		this.targetHeight = this.progressMeter.offsetHeight;
		this.progressMeter.style.height = "0px";
	},

	animateGauge : function(){
		var currHeight = this.progressMeter.offsetHeight;

		if(currHeight == this.targetHeight){
		}

		else{
			var interval = Math.ceil((this.targetHeight - currHeight) / 10);
			this.progressMeter.style.height = currHeight   interval   "px";
			setTimeout("gauge.animateGauge()",30);
		}
	}
}

That’s it. Take a look at the final example to see this at work. This particular data visualization example is very simple, but it is easily extendable and limited only by your ability to create graphical representations of data. With slightly more complicated JavaScript, you can create very dynamic animations on top of this basic XHTML/CSS. As I stated in the introduction, this technique should probably not be used for large data visualization dashboards or situations requiring extensive animation. However, it is excellent at providing progressive enhancement for situations calling for low-to-moderate levels of data visualization.

digg.com logo Like this article? Digg it!

Fuel is a brand new, affordable conference about powering your business with the web: London June 13

39 Responses to “The Standards Way to Do Dynamic Data”

  1. BillyG says

    Very nice, but quick before they swarm ya:

    script type=”text/javascript”

    btw: guess I got the addition right vs concatenation :-)

  2. share.websitemagazine.com says

    The Standards Way to Do Dynamic Data…

    Somewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web….

  3. Eric Anderson says

    So you have a entire heap of code to implement an animation that I didn’t see the FIRST FOUR TIMES I loaded the page because it has finished before I got around to actually scrolling down to see it. And that is with me searching for some form of animation on the page.

    Sounds to me like a classic case of over-engineering. My first thought when I visit that site (if it was real) would be I’m not going to donate money to this organization if they waste it on BS like this. If you really want the animation save yourself a few hours and just make a animated GIF. This sounds like a much bigger sledgehammer than flash.

  4. Dmitry Baranovskiy says

    Absolutely agree. You probably would be interested to take a look at my attemt to create dynamic data: dynamic pie-chart. Yes, you are not mistaken pie-chart without Flash and with only one image: Pie Chart (JavaScript edition).

  5. Steve Cochrane says

    You really nailed the design and animation here… it’s perfect.

    While I don’t entirely agree with Eric Anderson he raises a good point in that the animation might be running too early. Personally I saw the animation, but it happened while in the “images off” state. The images didn’t finish loading until after the animation was over. Perhaps there should be a two second delay or so before the animation runs? Was this considered?

    This feels like nitpicking though and it’s really nice otherwise, good article…

  6. Logic says

    To be honest it is just an example it is not meant to be the perfect solution only yo prove the concept can be done. Just take it with a heavy grain of salt. Try refreshing the page once all the graphic are loading that should satisfy.

    I plan to take what I learned from this article and implementing it into my current which uses quite a bit of dynamic data.

  7. picture of Sean Madden Sean Madden says

    @Eric: A very passionate response. I’m sorry that you feel this is over-engineered, but you have to build out the HTML and the CSS regardless, so you may as well do it in a way that will allow you to leverage certain techniques and achieve both accessibility and graceful degradation (neither of which you get with animated gifs). That the JavaScript was buggy for you, I apologize. This was not meant to be a production-ready example, merely something to elucidate the concepts.

    @Steve: Yes, there are better methods/times to trigger the animation. I really tried to keep this simple and impose as few “site-specific” JavaScript methods to it and make the principles as clear as possible. Plus, I’ve already been given some crap about it by my developer buddies.

  8. Rene Grassegger says

    Very nice Article. Love the smooth upcoming of the bar.

    Your Post inspired me, and I asked myself, how to show some basic data in a nice simple chart.

    http://grassegger.at/xperimente/charts-daten-semantik-css/

    The next days I put a bit of info on this site, finished it ten minute ago. Your post really makes me think, and I had to work on that for 2 hours in my work. :-)

    Its not even a bit a elegant as you example, but It just about the idea.

    René

  9. Vlad says

    Hi. I was expecting something else from this article. “Doing” dynamic data, as the title promised, encompassed quite a lot for me.
    It’s a good article, reminding those great CSS sprites everyone should be using.
    I want to argue about the need for that animation. Need is what keeps websites simple. You don’t actually need any gauges to fill up in a super-duper animated way. This would apply for charts of any kind, pies, gauges, whatever.

    I think that a compelling design should come first, because people are still reading (and boy are they reading) the web like it’s a mag. I’m reading Vitamin as a magazine, and would really hate crazy animations going on up and about.

    Taking your example as cue, i would choose to finish up the design and typography, than to use any kind of animation. Plus, animation in js tends to be a bit too complicated.

    And if it’s not a content-oriented site, well…i can hear all the users saying “Man, you gotta do Flash, man”. Or else it’s a snazzy web app, in which case as long as you display the ajax loading bubble often enough, they will not care.

  10. Chris says

    Thats pretty cool. I always like find new and different approaches to solving problems. Ironically I’m currently working on something similar and was trying to come up with approaches. Neat stuff.

  11. Brian says

    Generating content by using markup which no browser natively supports… Real standards compliant there… The XHTML may meet the standard according to a spec sheet once written but we’ve already been over this. XHTML will never be reliably supported and implemented with predictable functionality, you are better off using the latest HTML spec. I agree this approach is akin to using a sledgehammer to hang a picture frame.

  12. gordon says

    i think it is hard to display data and make the average person get it. i have a huge problem with data display on my website and your post will help me greatly. thanks

    http://www.cheapgreencar.com

  13. Mike says

    Interesting technique, however, the order your script and graphics load are backwards, I see a big block of red expand and then the temp meter graphic shows up after the animation is done. The code required to handle all this in Flash would be far less weight and graphically superior with a lighter page load, no JavaScript required.

  14. The Standards Way to Do Dynamic Data « News Coctail says

    […] The Standards Way to Do Dynamic Data Filed under: Uncategorized — recar @ 4:40 pm The Standards Way to Do Dynamic Data Somewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web. Oftentimes the solutions you see implemented are clunky, for example, manually creating multiple frames of various data points and uploading them by hand.[technology] [programming] [news] […]

  15. Vlad says

    Yeah, i too noticed that the images load weird.

  16. Future of Online Advertising » Left at Sunrise says

    […] I was reading a pretty nifty article on how to display dynamic data in a standards-compliant way on Think Vitamin when I saw a little note that they are giving out five free passes for their Future of Online Advertising conference in NYC on June 7-8 to the first five readers who email them about the offer. I thought, what the heck? What’s the worst that could happen, I waste a minute or two of my time? You may already see where this is going, so I’ll just go ahead and get to the punchline: I won a free pass to FOOA! […]

  17. links for 2007-05-10 « toonz says

    […] Vitamin Features » The Standards Way to Do Dynamic Data (tags: css javascript xhtml) […]

  18. Urls Sinistras » Blog Archive » del.icio.us entre 07/05/2007 e 10/05/2007 says

    […] Vitamin Features » The Standards Way to Do Dynamic DataSomewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web. […]

  19. Dan says

    I’m all for cool javascript techniques and animations, such as moo.fx or lightbox - but in those cases, they serve as solutions to layout, as opposed to serving as a graphical element. I realize that there could be fine line between the two.

    Aside from the complaints given in the first comments, I’m curious to know if there would be a huge difference in file size as a animated gif or swf compared to javascript, plus the two images, and extra css.

    I don’t think we’ve entered an era yet where we can totally blow off load times because a lot of us are still on dial up.

    Obviously there’s no right or wrong answer, but there are other factors that come into play such as browser compatibility, whether javascript or images are disabled (as you mentioned) or what version of flash the user has installed.

    In the end I usually end up going with a solution that balances a quick load time and compatibility.

  20. Mike Cherim says

    Very nice job. I’m impressed. The data is available with images off, without JavaScript, without CSS support and it looks great. A while back I made a donations thermometer with PHP, and mine meets all of the requirements of accessibility/usability, but your is slicker looking. Nice.

  21. Motorcycle Guy says

    I think it’s supposed to load like that but I don’t really understand the benefit you could do this all in php with the gd or imagemagick even.

  22. Top 6 Programming Diggs in last 30 days - Intelligentedu.com Free Computer Training Blogs says

    […] Here are what I judge to be the Top 6 Digg Programming posts in last 30 days, for providing free training content and tutorials covering web application development.  The Standards Way to Do Dynamic Data Somewhere in between presenting static information graphics and complex, interactive data dashboards there’s a need for a way to visualize moderately dynamic data on the web. Oftentimes the solutions you see implemented are clunky, for example, manually creating multiple frames of various data points and uploading them by hand. More… Top 5 Javascript Frameworks A list of the top 5 javascript frameworks and features. More… The Javascript Programming Language “Excellent presentation and great insight on the history and basics. Douglas rocks, yahoo is real lucky to have him!” More… Learn to Ruby: 74 Quality RoR Resources and Tutorials As is the case with every language, learning Ruby on Rails from scratch can be quite a pain. We’ve compiled a list of the best Rails resources the Web has to offer, covering installation (both manual and automatic, plus web hosts), tutorials (beginner and advanced topics), books, blogs, forums, cheat sheets, code snippets and API documents. More… 8 Defensive Programming Best Practices to Prevent Breaking Your Sites This article describes some software development best practices that have been used to prevent problems that can break Web sites. More… Faster PHP Apps - Profile Your Code with Xdebug Using Xdebug and WinCacheGrind or KCacheGrind to profile PHP script execution. More…Technorati Tags: programming diggs, top programming diggsPopularity: 1% [?] Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. […]

  23. Bob Burbach says

    Great job on the article, thanks for taking the time to put it together!

    I currently have been doing a lot of development for a number of medical research departments the study how to present risk and treatment information to (often aging) patients.

    Using something like this is perfect because visual movement can be a huge help in communicating increased (or decreased) risk. Being able to gracefully degrade and still show the information to those who may not have the newest computers or flash versions means we can use similar techniques much more widely than we otherwise could.

    A great solution for a particular set of needs!

  24. Acronyms says

    Very neat approach.

  25. SeoGenetic Blogs » The Standards Way to Do Dynamic Data says

    […] read more | digg story […]

  26. Best of May/June 2007 says

    […] The Standards Way to Do Dynamic Data Sean Madden cooks up an example of presenting dynamic data graphically using XHTML, CSS and a dash of JavaScript - no Flash required. […]

  27. Presseschau für Webentwickler - Ausgabe Juli 2007 | Dr. Web Weblog says

    […] The Standards Way to Do Dynamic Data Technik zur grafischen Aufbereitung von dynamischen Daten mittels XHTML, CSS und JavaScript - kein Flash ist notwendig. […]

  28. Best of May/June 2007 | Webdesign (css, grafica e altro) says

    […] The Standards Way to Do Dynamic Data Sean Madden cooks up an example of presenting dynamic data graphically using XHTML, CSS and a dash of JavaScript - no Flash required. […]

  29. lost node » Blog Archive » Best of May/June 2007 says

    […] The Standards Way to Do Dynamic Data Sean Madden cooks up an example of presenting dynamic data graphically using XHTML, CSS and a dash of JavaScript - no Flash required. […]

  30. Best of May/June 2007 · Style Grind says

    […] The Standards Way to Do Dynamic Data Sean Madden cooks up an example of presenting dynamic data graphically using XHTML, CSS and a dash of JavaScript - no Flash required. […]

  31. All in a days work… says

    […] A Dynamic Thermometer - The Standards Way to Do Dynamic Data Excellent at providing progressive enhancement for situations calling for low-to-moderate levels of data visualization. […]

  32. Best of May/June 2007 at Design Resources says

    […] The Standards Way to Do Dynamic Data Sean Madden cooks up an example of presenting dynamic data graphically using XHTML, CSS and a dash of JavaScript - no Flash required. […]

  33. küchler blog » Vitamin Features » The Standards Way to Do Dynamic Data says

    […] Vitamin Features » The Standards Way to Do Dynamic Data […]

  34. Orkut » Blog Archive » The Standards Way to Do Dynamic Data says

    […] read more | digg story […]

  35. Goa » Blog Archive » The Standards Way to Do Dynamic Data says

    […] read more | digg story […]

  36. The Standards Way to Do Dynamic Data « Programming News says

    […] read more | digg story […]

  37. boris says

    Look this site

    http://www.ooyes.net

  38. islami sohbet says

    tesekkürler

  39. tech.twomadgeeks.com » The Standards Way To Do Dynamic Data says

    […] Link: Think Vitamin […]

Leave a Reply

Basic HTML (<strong>, <em>, <a>, etc.) is allowed in your comments. Please be respectful and keep your comments on-topic. If we think you're being offensive for no reason, we'll delete your comment.

Comments RSS