In my previous posts (Part 1 and Part Two), I talked about how a chart can be embedded in Flash Forms. While it isn't exactly straight forward, it isn't too difficult either.
For my last example, I'm going to show how to pass data to your chart so you can change it on the fly. Let's start with the chart data file, test3.cfm:
<cfparam name="url.type" default="bar">
<cfif not listFind("bar,line,pie", url.type)>
<cfset url.type = "bar">
</cfif>
<cfchart name="chartData">
<cfchartseries type="#url.type#">
<cfchartdata item="apples" value="#randRange(1,100)#">
<cfchartdata item="oranges" value="#randRange(1,100)#">
<cfchartdata item="pears" value="#randRange(1,100)#">
<cfchartdata item="jedis" value="#randRange(1,100)#">
<cfchartdata item="pies" value="#randRange(1,100)#">
</cfchartseries>
</cfchart>
<cfcontent type="application/x-shockwave-flash" variable="#chartData#">
The only thing new here, compared to the earlier files, is the use of URL.type. I do some simple validation on the variable, and use it to define the chart type. Now let's look at the front end:
<cfselect name="type">
<option value="bar" selected>Bar</option>
<option value="line">Line</option>
<option value="pie">Pie</option>
</cfselect>
<cftextarea name="chartArea" height="300"></cftextarea>
<cfinput type="button" name="submit" value="Test Flash"
onClick = "_root.chartArea.html=true;_root.chartArea.htmlText
='<img src=""test3.cfm?type=
'+type.getItemAt(type.selectedIndex).data+'&bar=.swf""/>'+' '">
</cfform>
In this version, I've added a drop down with the valid chart types. Note how in the onClick for my button, I now pass the value of the selected item to my chart generator. You can see an example of this here. This is a pretty trivial example, but a lot more could be done. You could use radio/checkbox items to select which values should appear on the chart. You could vary the styles of the chart on the fly.
Please forgive the ugly formatting of the code above.
Archived Comments
It would even be cooler if the chart was part of cfform, one could write code such onClick="chart.style='bar'" or onChange="chart.style = this.selectedItem.label", or you could bind datagrid rows to the chart, or the style attribute to your comboBox selectedItem ;)
I think MM wants to push us CF developers towards Flex via the small door ;))
Very nice Ray! Very helpful.
Ray,
Check out this post on Asfusion.com regarding flash remoting and flash forms that can be used to update the chart via a CFC and then the form can reload it for asynchronous results.
http://www.asfusion.com/blo...
Ray:
I was hoping you could help me out with something. I'm revisiting the topic of cfcharts interacting with cfforms and came up with the following code. Essentially what I'm trying to do is create a popup chart triggered from the cfform. The code works excellent the first time I trigger the alert, but any subsequent clicks of the button screw up the chart formatting. Do you have any idea why this may be happening? Here is my code:
<cfsavecontent variable="popupGraph">
var msg = '<img src="test3.cfm?bar=.swf" height="300" width="400">'+' '
var alertSettings:Object = {title:'Warning', message: msg, width:500, height:400, headerHeight:27 }
errorpopup = mx.managers.PopUpManager.createPopUp(this, FormErrorException, true, alertSettings);
errorpopup.centerPopUp(this);
</cfsavecontent>
<cfform name="test" format="flash" width="500" height="500">
<cfselect name="type">
<option value="bar" selected>Bar</option>
<option value="line">Line</option>
<option value="pie">Pie</option>
</cfselect>
<cftextarea name="chartArea" height="300"></cftextarea>
<cfinput type="button" name="Popup_chart" value="Popup Chart" onclick="#popupGraph#">
<cfinput type="button" name="submit" value="Test Flash"
onClick="_root.chartArea.html=true;_root.chartArea.htmlText
='<img src=""test3.cfm?type='+type.getItemAt(type.selectedIndex).data+'&bar=.swf""/>'+' ';">
</cfform>
Thanks,
Todd Sharp
is this another one of those deals where if you have the developer version of coldfusion you're gonna have problems? When I cut and paste the code into a new coldfusion page created by dreamweaver it crashes firefox. if I clear out all the html header stuff it's a little better but it still kills firefox.
Great article Ray. I have been trying to adapt this to my purpose and I wonder if anyone has any feedback. I need to setup the test3.cfm file to return a .png or .jpg file instead of a flash file. Is this possible? I am trying to make a dynamic image-viewer app using flash forms. I am using Alagad's image.cfc to read the .png file into a variable and trying to use cfcontent with mime type of image/png or image/gif, and the flash form just sits there mocking me! =) Here is a snip of the code I am trying to use, is this even possible or am I beating my head against a brick wall?
File: test3.cfm (the viewing file is exactly like the one above)
<!--- Create instance of image component --->
<CFOBJECT component="Image" name="myImage" />
<CFSET myImage = CreateObject("Component", "Image") />
<CFSET myImage.readImage("\\merovingian\c$\inetpub\wwwroot\imaging\7.png") />
<cfcontent type="application/x-shockwave-flash" variable="#myImage.writeToBrowser("png")#">
Justice:
Have you ever seen this?
http://www.asfusion.com/blo...
P.S. I think you can only do jpg's with what I just posted.... :(
whoaaaa, I did not know you could only do .jpg!
On a happier note, as soon as I changed the myImage.writeToBrowser("png") to .jpg, and boom, it shows just find in flash!! <does a happy dance>
Perhaps it is possible to design my image viewer in flash!
If I get it done and rolling, I will post a demo here =)
Flash 8 can load GIF and PNG as well (with their transparencies).
Thanks Philippe!
I am digging around to find a way to 'update' data inside a flash form from outside of that form. ie, I have 2 side-by-side div's, on the left is a plain jane html form, and the right pane is my flash form. I am going to try and get the form on the left to pass parameters into the flash app on the right, to dynamically update a data grid on the top of the form. Does anyone know a tutorial / example code for doing this? Thanks a ton for your help so far guys!
I have a cms that i created using flash forms, and is password protected. I can't get the chart cfm to load in my app, i think because of the password protection. If I test your example outside my application, it works fine.
any ideas on how to get past the authentication?
Russ,
If you are using application variables to maintain session state, I would think that as long as your flash form generator template is inside your application it would work fine. Is it in a seperate folder of your site, perhaps you just need to add a <cfapplication> tag to the top?
Justice, I was thinking the same thing, and then I remembered how my testing server wasn't holding the sessions, every time I open a page it makes me log in, even if I have a page open already. So I uploaded it to the production server and it works fine. Now I have to figure out why my dev server isn't keeping the session.
check the settings in the cfadmin console, make sure that the caching settings are set correctly, and the same as your production server. Maybe see if one is setup to use jsessions and the other is not?
Also see if the caching locations are the same, maybe one is caching to a database?
I have been trying this in an application I'm doing.
All worked well (or so I thought)
If the client browser has browser cashe setting to automatic then the new cfchart is never loaded.
You keep getting the old swf from the broswer cache !!
I have tried the usual meta headers (pragma) to stop cache with no luck. I also seen Andrew Muller's example of this with Flash and he used the following to load the swf
var salesChart = "salesChart.swf";
chart_mc.loadMovie(salesChart.noCache());
Now I know we can't use loadmovie in flash forms, but is there a way to stop this from caching ??
I also came across a google result about just passing the cfcontent variable back through the cfc, but I can't find it again.
I assume this could be done by passing the binary data type back, but have been unable to get it to work.
Ken
Ken:
<hack>
If you pass a unique variable in the url to get your chart, you'll get a new chart everytime (rather than a cached version). I use a technique like this:
createVar.as
------------
// create variable dateNow containing the current date
// this is placed in an include to
// get around the "new" restriction
var dateNow = new Date();
.cfm page
---------
<!--- Actionscript function to get the chart --->
function genChart(){
#include "createVar.as"
_root.chartArea.htmlText='<img src="myPage.cfm?variable1=' someActionscriptvariable +'&uniqueID='+dateNow+'&bar=.swf"/>'+' ';
}
</hack>
I'm sure there is a better way, but in this method you guarantee that a unique variable is passed in the URL.
Thanks for the info Todd
I thought I had actually tried this, seems I did not as it now works correctly.
I did not use the date tho, I did
var ranNumber = Math.random();
_root.chartArea.htmlText='<img src="myPage.cfm?variable1=' someActionscriptvariable +'&uniqueID='+ranNumber+'&bar=.swf"/>'+' ';
Ken
I'm trying to pass a cfgrid selected id value to create a cfchart / flash. When row is selected in cfgrid, the textarea for chart displays to the right with the button you use, but this is not working for me. Here's the group that displays to right when row is selected. I added your test chart data to the _gains.cfm file but not getting anywhere. This code is embedded in cfform in which cfgrid displays
<cfformgroup type="horizontal" visible="{crrtgrid.selectedItem != undefined}" enabled="Yes" >
<cfinput type="hidden" name="id" bind="{crrtgrid.selectedItem.ZIPCRRT}">
<cftextarea name="chartArea" height="300"></cftextarea>
<cfformgroup type="vertical" v enabled="Yes">
<cfinput type="button" name="submit" value="Test Flash"
onClick = "_root.chartArea.html=true;_root.chartArea.htmlText
='<img src=""_gains.cfm?crrt=
'+crrtgrid.selectedItem.ZIPCRRT+'&bar=.swf""/>'+' '">
</cfformgroup >
</cfformgroup>
</cfformgroup>
I'm having a problems getting this to work behind SSL - any workarounds or advice?
Appreciated