Tuesday, January 22, 2008

Who knew you could create CFCHART Maps with ColdFusion 8

Ever since reading Raymond Camden's entry on creating gauge charts with ColdFusion 8, I have had charts on the brain. I continued to experiment with the webcharts utility and discovered yet another neat webcharts tool. One that can be used to create map charts like this:

The tool is called Map Editor and it allows you to edit SHP or CSHP files and save them as a webcharts3d .MAP file. You can then use the .MAP file with the webcharts utility to create your chart. You can launch the Map Editor from the command line.

C:\ColdFusion8\lib>  java -jar wc50.jar --mapedit

Now I did not have any .SHP files lying around, so I downloaded one from esri.com. Then I opened up the file in Map Editor and modified the xml to add a few country names.

After saving the file with a .MAP extension, I opened up the webcharts utility and selected a map chart. Now initially the chart preview was blank, because ColdFusion 8's jar does not ship with any .MAP files. But after changing the source to point to my new .MAP file the preview appeared.

Then I saved my project as a WCP file, ran my test code and it produced a great looking map chart. Pretty cool stuff!

09/03/2009: Just like the "url" element of cfchart, you can display another url when one of the chart elements is clicked. Simply use the webcharts utility to set the action attribute to the desired cfm page. You can use pseudo variables like $(value) to pass information about the selected element as url parameters. Example action:


Test Code

Aside from minor changes for the chart type, the code is entirely borrowed from Raymond Camden's entry on gauge charts . (His example was good, so why re-invent the wheel ;) Anyway, all credit and thanks for the code go to him.

<!--- Get base server url --->
<cfif len(CGI.HTTPS)>
<cfset baseURL = "https://"& CGI.HTTP_HOST &"/">
<cfset baseURL = "http://"& CGI.HTTP_HOST &"/">

<!--- Extract chart style from the WCP file --->
<cfset wcp = XMLParse( ExpandPath("./testMap.wcp") )>
<cfset chartStyle = ToString(wcp.project.style.map)>

<!--- Create sample chart data --->
<cfsavecontent variable="chartModel"><?xml version="1.0" encoding="UTF-8"?>
<map name="Europe">
<item name="Country" popup="$(name)">
<item name="United Kingdom" backColor="#ECC362"/>
<item name="Spain" backColor="#F1D372"/>
<item name="Portugal" backColor="#C7BE7B"/>
<item name="France" backColor="#989A74"/>
<item name="Item" backColor="#D17610"/>

<!--- Initialize chart settings --->
oMyWebChart = createObject("Java","com.gp.api.jsp.MxServerComponent");
oMyApp = getPageContext().getServletContext();
oSvr = oMyWebChart.getDefaultInstance(oMyApp);
oMyChart2 = oSvr.newImageSpec();
oMyChart2.width = 500;
oMyChart2.height= 570;
oMyChart2.type = "png";
oMyChart2.style = "#chartStyle#";
oMyChart2.model = "#chartModel#";

<!--- Create html tag set --->
<cfsavecontent variable="chartImgTag">
<cfoutput>#oSvr.getImageTag(oMyChart2, baseURL& "CFIDE/GraphData.cfm?graphCache=wc50&graphID=")#</cfoutput>

<!--- Good old Webcharts loves to add an extra /Images/ to the URL --->
<cfset chartImgTag = replace(chartImgTag, baseURL &"Images/", baseURL, "All")>

<h2>Map Chart</h2>


delroekid@yahoo.com,  September 3, 2008 at 1:07 AM  

nice and helpful. i can use this stuff sooner

Asaf,  May 21, 2009 at 2:08 PM  

I approached this problem in a slightly different manner. Instead of creating my own .MAP files, I downloaded the most updated version of webcharts from their website (which includes the map files) and just pasted the entire folder into the CF8 charting directory. So in terms of my style and model, I just copied them directly out of the webcharts editor (rather than grab them using the .wcp file). At first this produced an error due to the fact that the source attribute in the style (source="maps/Continents/USA.map") ends up resolving to the CF8/runtime/bin directory. Do you know why it's resolving there? Do you know if grabbing the style from .wcp corrects this problem? I guess this is all moot because I'm able to just hardcode the full path of the .MAP file into the style but I'm more curious why it thinks it should be looking in the runtime/bin directory.

P.S. My interest is in the USA Map file but I had to do some editing of the .MAP file to get it to load with the older version of webcharts including with CF8. There are arrows in the chart that help label the small cramped states in New England (such as RI) and WebCharts 5.1 throws an error because of these tags. You will need to remove them to get it to work properly.

cfSearching May 25, 2009 at 8:15 AM  


My guess would be that webcharts uses the runtime context to determine the base path. So say you are using the developer version (with the Jrun server), webcharts defaults to C:\ColdFusion8\runtime\bin, because that is where jrun.exe is located.

- Leigh

steve September 3, 2009 at 12:18 PM  


I have successfully gotten the USA map to display popups with data from my SQL db (loops on the item, looks for two letter state abbv in DB and compares it to the item name in the .wcp file), and it works really well. I also got it to change the state colors based on recordcounts. Kinda like the Woot stat charts that shows how many Wooters are Wooting. http://woot.com/stats

I'm banging my head against the desk on my next challenge though. It seems that with other WebCharts types it is possible to add event handlers for onClick per element. Have you seen or maybe developed a way to do this with map charts?

I'd like to have the mouseover popup show a snippet (result.recordcount), which it already does, and then if clicked maybe a window.open call to a page with more details on the data for that state. I've seen this done on the web, but not sure if WebCharts is being used or not. Any thoughts?

cfSearching September 3, 2009 at 3:12 PM  


I do not think you could place it in the pop-up, because how would you click on it?

Try using the usual "action" and "target" attributes in the xml style. Using one of the psuedo variables to pass element properties to the action page.

For example:
<map action="somePage.cfm?elemValue=$(value)" ...>


steve September 3, 2009 at 3:49 PM  


Sorry, I meant clicking the state, not the popup (that would be rather difficult wouldn't it?)

"For example:
map action="somePage.cfm?elemValue=$(value)" ...

I'm not familiar with the action and target attribs you speak of. I tried to search but couldn't find anything. Got a link to some syntax docs?

Anyway, I added the action attribute to my map tag and nothing happened...I think I need to find a way to edit the imagemap tags that the WebCharts spits out, if I could just slip an onClick attrib in there somehow...

cfSearching September 3, 2009 at 4:59 PM  


LOL. That had me scratching my head for a moment ;)

It works fine for me. So I am not sure why it is not working for you. Are you using the webcharts utility to add the "action" property to the wcp file? That is what I used ..


cfSearching September 3, 2009 at 6:33 PM  


I updated the entry to include a screen shot of where you would set the action property in the webcharts utility.


steve September 4, 2009 at 5:26 AM  


I was trying to put the action tag in the cfml where it creates sample chart data. Went into the wc50 editor and BAM! Works like a charm. Now on to experiment with some jQuery to see if I can make the action display a div below the map.

This is one of those 'duh' things that was right in front of my face the whole time, but I couldn't find anywhere in the docs. The maps page in WebCharts3d help is about 3 paragraphs and doesn't mention action anywhere.

Thanks for this post!

Anonymous,  July 14, 2010 at 6:50 AM  

Very nice... problem is I'm getting this an error

Invalid attribute: outline

on this code:

#oSvr.getImageTag(oMyChart2, baseURL& "CFIDE/GraphData.cfm?graphCache=wc50&graphID=")#

cfSearching July 14, 2010 at 1:28 PM  


It sounds like you may have some off code in either your .wcp file or perhaps the .SHP image is not valid. You may want to run your image through the utility first to make sure it is valid. Because if it does not work there, it will not work in CF either.


  © Blogger templates The Professional Template by Ourblogtemplates.com 2008

Header image adapted from atomicjeep