Alison asks:
Do you have any code for cycling through multiple cfcharts? Basically, I need to see one chart at a time, that changes every few seconds. Any help would be awesome and much appreciated!
I didn't have anything like that handy, but I figured it would be trivial in jQuery. I also assumed that there were probably a few hundred plugins that would do this already, but wanted to see if I could write this myself. Here is what I came up with. Feel free to tear it to bits with suggestions!
First, let's assume you have a block that contains the items you want to cycle through:
<div id="slideshow">
<p>First para</p>
<p>
Second para
</p>
<p>
Third para
</p>
</div>
In this example, I want each paragraph to act like a slide. My code is going to assume that all of the children of the main block are also block level elements.
Ok, so given our HTML, here is the jQuery code I came up with:
<script>
var currentPosition = -1
var blocks
var lastBlock
$(document).ready(function() {
blocks = $("#slideshow").children()
if(blocks.length) {
$(blocks).each(function() {
//hide them
$(this).hide()
})
window.setInterval("showNext()", 2000)
}
})
function showNext() {
currentPosition++
if(currentPosition == blocks.length) currentPosition = 0
if(lastBlock) $(lastBlock).fadeOut('normal',function() {$(blocks[currentPosition]).fadeIn() })
else $(blocks[currentPosition]).fadeIn()
lastBlock = blocks[currentPosition]
}
</script>
Reading from the top to bottom, I begin with a few global variables that I'll be using throughout the rest of the script. My document.ready block takes care of defining blocks as the children of my div. If I actually have children then I immediately hide them. (If this were for a real site I'd use some CSS to ensure they were hidden initially. Without that you're going to get a 'flash' of content before the script runs.) Next I setup an interval to run showNext.
The showNext function simply increments currentPosition, determines if it needs to hide a previous item and then shows the next one. Pretty simple. You can see this in action here: http://www.coldfusionjedi.com/demos/jan132010/test4a.cfm
Ok, so now let's take it a step further and actually add the charts in. The first thing I noticed is that when the code cycled through the entire set and returned to the beginning, I got the imfamous 'image has expired' issue. That was easy enough to fix by switching to PNG charts, but the quality took a nosedive. You could tweak this a bit - but honestly, I'd just either live with it or try one of the many other charting alternatives there are out there. I also took the opportunity to fix the initial pause. Now my code runs the first slide immediately and then begins the interval. Here is the entire sample with hard coded charts:
<!---
<cfchart format="flash" xaxistitle="Department" yaxistitle="Salary" title="2002">
<cfchartseries type="bar">
<cfchartdata item="Sales" value="90000">
<cfchartdata item="IT" value="20000">
<cfchartdata item="Marketing" value="110000">
</cfchartseries>
</cfchart>
--->
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
var currentPosition = -1
var blocks
var lastBlock
$(document).ready(function() {
blocks = $("#slideshow").children()
if(blocks.length) {
$(blocks).each(function() {
//hide them
$(this).hide()
})
showNext()
window.setInterval("showNext()", 4000)
}
})
function showNext() {
currentPosition++
if(currentPosition == blocks.length) currentPosition = 0
if(lastBlock) $(lastBlock).fadeOut('normal',function() {$(blocks[currentPosition]).fadeIn() })
else $(blocks[currentPosition]).fadeIn()
lastBlock = blocks[currentPosition]
}
</script>
</head>
<body>
<h2>Testing</h2>
<div id="slideshow">
<p>
<cfchart format="png" xaxistitle="Department" yaxistitle="Salary" title="2002" chartheight="400" chartwidth="400">
<cfchartseries type="bar">
<cfchartdata item="Sales" value="90000">
<cfchartdata item="IT" value="20000">
<cfchartdata item="Marketing" value="110000">
</cfchartseries>
</cfchart>
</p>
<p>
<cfchart format="png" xaxistitle="Department" yaxistitle="Salary" title="2003" chartheight="400" chartwidth="400">
<cfchartseries type="bar">
<cfchartdata item="Sales" value="99000">
<cfchartdata item="IT" value="24000">
<cfchartdata item="Marketing" value="120000">
</cfchartseries>
</cfchart>
</p>
<p>
<cfchart format="jpg" xaxistitle="Department" yaxistitle="Salary" title="2004" chartheight="400" chartwidth="400">
<cfchartseries type="bar">
<cfchartdata item="Sales" value="88000">
<cfchartdata item="IT" value="32000">
<cfchartdata item="Marketing" value="100000">
</cfchartseries>
</cfchart>
</p>
</div>
</body>
</html>
You can see this running here: http://www.coldfusionjedi.com/demos/jan132010/test4b.cfm
p.s. I recently got a wishlist item (Dragon America) with a note asking me to contact the person. However, their name was obscured on the packing slip. From time to time I get gifts from my wish list and I can't find a way to contact the person. So if your in that group, accept my apology and thanks!
Archived Comments
Google has a visualization api that will do that. I've got an example of using cf at home that I can post later if anyone is interested.
Google Visualization API
http://code.google.com/apis...
I reviewed Google Charts for... CFUNITED last year I think. It was a great service, but a royal pain in the ass. I hated how you had to encode data in such a complex manner.
You know - I take it back. A super quick glance seems to show some pretty nice new stuff there, and _simpler_ stuff at that.
@Ray
I really dig this. I'm going to use your nifty slide show technique for an upcoming project (I'll probably throw a pause button and some forward and back controls in but you get the gist). Very cool and easy to understand example - thanks!
Would you (or other readers) like it if I followed this up with an example that included controls?
Do you even have to ask? Yes. I have a request that I will send you via email.
I'd probably have added a class to each 'slide' and just done:
$(".slide-container").hide();
instead of looping over each child like you did.
How 'bout an example that takes each chart and makes each of them a PowerPoint slide with the new PowerPoint ability in CF9 and then calls the SlideSix API and publishes the PowerPoint to SlideSix. Just sayin', that'd rock.... :P
Also - in your demo - the first <p> isn't shown right away. Might do something like $('.slide-container:first).show() before calling the setInterval. Or $('.slide-container).not(':first').hide(); (untested)...
Todd, the issue with the first P not being shown is fixed in the second example. I specifically call out how.
@Scott P - I would love to see your cf and google visualization example. Thanks.
Check out the jQuery Cycle Plugin. It is perfect for what you are trying to do and has the ability to add next/prev/pause/resume controls, tabbed navigation, multiple transitions, etc.
http://malsup.com/jquery/cy...
Ray, can you direct me to any material about improving the quality of the charts in JPG or PNG format? I have some projects for which using the cfcharts is required, can't use other products. The relatively poor quality of the JPG/PNG is a problem. Thanks in advance!
I think you are out of luck. None of the arguments to cfchart allow you to tweak the quality.
Michael, I know you stated you can't use other products, but check out ChartDirector. Very customizable and my client preferred the higher quality graphs.
http://www.advsofteng.com/p...