| By Christian Schneider | Article Rating: |
|
| August 31, 2001 12:00 AM EDT | Reads: |
8,834 |
This article describes how to use Scalable Vector Graphics (SVG), the amazing new graphic format, with CFML to create dynamic charts and diagrams. SVG is the W3C standard format for scalable graphics based on XML (see www.W3C.org). Yes, that's right, graphics based on XML; for example, see the following code:
<svg width="250" height="300">
<circle cx="120" cy="120" r="50"
style="fill:red; fill-opacity:
0.7"/>
<circle cx="80" cy="40" r="30"
style="fill:blue; fill-opacity:
0.5"/>
</svg>
This SVG snippet renders a vector graphic 250x300 pixels holding both a red-filled circle with a radius of 50 pixels at the coordinates 120, 120, and an opacity level of 0.7, and a smaller blue circle. Save this snippet as test.svg and embed it in an HTML page using the following code:
<h3>This is my HTML page holding
the SVG</h3>
<embed src="test.svg" type="image/svg+xml"
name="mySvgTest"
width="250" height ="300"></embed>
How will we be able to see this image when opening the HTML page in a browser? Since SVG is a W3C standard, the major browsers will incorporate this format sooner or later into their future releases. Of course, you don't have to wait that long if you install an SVG viewer plug-in that's capable of rendering SVG graphics in your browser now, until this native browser support is available. Some plug-ins for the most common browsers (Internet Explorer and Netscape) are available that comply to W3C's SVG format, including one from Adobe (www.adobe.com/svg).
What Benefits Do We Gain Using SVG?
As SVG is a vector format, it renders on the screen, prints with a high quality and sharpness, and its file size is small compared to other formats such as GIF or JPG. The usage of vectors also makes it "zoomable" on the client without quality loss (just right-click an SVG image, or use CTRL and SHIFT-CTRL to control the zoom with your mouse). The following is a list of some of SVG's coolest features:
- Shapes: You can use a lot of basic shapes such as lines, circles, ellipses, rectangles, and polygons, as well as easily define and use your own shapes.
- Colors: A full color palette that allows you to easily define smooth gradients and transitions in all shapes and directions. You can even use opacity levels to define any grade of transparency for all shapes and texts.
- Images: You can embed the usual raster-format images (like GIF) inside the SVG if you need to.
- Text: You can add text that's fully stylable and transformable, but still keeps text that's searchable and easily changeable. There's a full palette of fonts and you can even use your own fonts in an SVG image.
- Styling: You can use Cascading Style Sheets (CSS) to add lots of styles to your shapes and objects.
- Filters: You can also define custom filters and apply them as a style. Filters include 3D-effect filters and spotlights.
- Animation and interaction: All properties of an SVG element - as well as all CSS styles applied to such an element - are easily animated based on a time frame and events (e.g., "mouseOver" or "click"). This can produce flying animations, morphing shapes, scaling and rotating shapes, and hiding/showing objects with just a few simple tags.
- Paths: You can define any kind of path and bézier curves within an SVG image on which text and other SVG elements can easily be rendered.
- Linking: All SVG elements can be linked to URLs using the <a> tag within SVG. This even works with different frame targets.
- Scripting: All properties and the XML-DOM tree are scriptable using JavaScript or ECMAScript from within the SVG's source or even from within the embedded HTML page's source (using Internet Explorer) and vice versa. This means you can handle an event fired within an SVG image in the embedded page or trigger some changes in the SVG based on an event raised in that page.
- XML: This is the biggest feature since the whole format is just a plain XML document. No proprietary binary formats, just XML allowing you to dynamically generate the SVG's source on the server-side, making it suitable for on-the-fly database-driven charts, for example. And for those folks still wishing these files were a compressed binary, you can optionally compress SVG files with gzip to get the smallest file sizes.
To provide you with a working example of using SVG with CFML, I've developed a custom tag (<cf_bubbleChart>) that renders a bubble chart, similar to the chart in MS Excel; this kind of chart has a value for the x-axis, the y-axis, and the radius of each bubble, which enables you to present three data rows in one chart. See Figure 1 for a screenshot of this custom tag in action (note that you must install the SVG viewer plug-in since current browsers don't yet implement SVG natively).
What is the main concept behind this charting custom tag? It's dual-mode since it consists of the custom tag outputting the <embed> tag to embed the SVG data, and a second part that actually creates the SVG data dynamically. This is achieved by the custom tag entering a URL as the <embed> tag's source attribute, which points to a "loader" file for the custom tag. This "loader" file then invokes the custom tag again to generate the dynamic SVG data stream.
When invoking the charting tag <cf_bubbleChart> within a page, the "loader" file places all attributes into the SESSION scope (<cflock>ed of course!), so the invocation of the tag in "SVG generation mode" from the aforementioned "loader" file still knows all parameters to generate the appropriate SVG data. Using the session scope here is quite straightforward since all attributes provided at the invocation of the custom tag are still available when generating the SVG data stream on the server.
I've decided to place the data into the session scope keyed by a random Universally Unique ID (UUID) to allow multiple instances of the charting tag within one page (hence within one session), without the instances overwriting each other. Using a UUID as the key (which is handed over as a URL parameter in the <embed> tag's source) prevents all invocations of the charting tag in one page from being rendered the same while they have different attributes.
A More Detailed Look
Now let's look at this charting component. The working example consists of four files: Application.cfm, index.cfm, bubbleChartLoader.cfm, and bubbleChart.cfm. (All files are available for download from CFDJ's Web site at www.sys-con.com/coldfusion/sourcec.cfm.) I'll also publish the files to Macromedia's Tag Gallery.
Application.cfm
This file creates a normal session environment for this example using <cfapplication>.
index.cfm
This is our sample file showing how to use the custom tag <cf_bubbleChart>. It sets up a few random bubble values to show in the bubble chart.
bubbleChartLoader.cfm
This file is the aforementioned "loader" file for the custom tag <cf_bubbleChart>, which simply takes a UUID as a URL parameter and calls <cf_bubbleChart> with that UUID.
bubbleChart.cfm
This file is the custom tag <cf_bubbleChart>. When I'm discussing SVG later on I recommend you look at some examples and the specification provided at www. W3C.org and www.adobe.com/svg. This information is important when this custom tag generates the SVG code, since explaining SVG in detail is unfortunately out of this article's scope.
The custom tag first checks if a UUID was passed as an attribute. If so, it loads all attributes from the session scope (where they were stored before) using that UUID, otherwise it expects all attributes directly. After setting the <cfparam>s for the default values of some attributes, the tag decides (by checking if the UUID was provided or not) if it should first create the HTML <embed> tag to embed the SVG chart or the SVG data stream requested from within the <embed> tag. When the first mode is the case, that is, writing the <embed> tag to embed the SVG, <cf_bubbleChart> stores all parameters into the session using a random UUID, which is appended to the URL. This URL of the <embed> tag's source is pointing to the aforementioned "loader" file that calls <cf_bubbleChart>, which loads all attributes from the session scope and generates the SVG data stream.
Generating the SVG data stream is quite easy since SVG is plain XML. After the <?xml version="1.0" standalone="no"?> directive, the DTD must be referenced using the following snippet:
<!DOCTYPE svg PUBLIC "-
//W3C//DTD SVG 20001102//EN"
"http://www.w3.org/TR/2000/CR-
SVG-20001102/DTD/svg-
20001102.dtd">
Following this is the <svg> tag, which describes the actual SVG. Since it's plain XML you can simply use <cfoutput>, <cfloop>, and all other CFML tags (even <cfquery>) to make things dynamic. After a few calculations on how to draw and scale the elements and the x and y axis for the dynamic values, this article's custom tag first draws the chart area, followed by the axis titles and the grid, and finally the bubbles as animated circles. Animation in SVG is easy since it has the genius <animate> tag that allows us to define what properties should become animated (here the radius making the bubbles "fly in" toward the user). From a styling aspect, SVG is also simple to handle since all styles are applied using CSS, which can also be easily manipulated from within CFML.
As I mentioned before, look at the SVG specification and the tutorials (see the aforementioned links) to see what's possible with this open standard from the W3C. Unfortunately, until the major browsers support this standard natively with XHTML, we're forced to use the viewer plug-in, but its installation is simple and smooth so it won't be a problem for most users. And psst..., I've heard rumors that the next release of Acrobat Reader (which many Internet users have, since it allows them to view PDF files) will automatically include the SVG viewer plug-in. So we can even start using SVG before the browsers support it natively.
By the Way
To gain even greater control of displaying alternatives when the viewer plug-in is not available in the client's browser, use the HTML <object> tag to embed the SVG. This lets you specify alternative HTML code to show (in Internet Explorer at least) when the plug-in isn't available. The <embed> tag though works in all browsers! Adobe has prepared a JavaScript for doing browser-independent checking for that plug-in (see www.adobe.com/svg).
There's a lot of work going on around the SVG W3C standard, including the plug-in work from Adobe and others, a Java SDK being developed at Sun, and toolboxes and converters being developed by different companies, including a visual SVG editor (like PaintShop Pro) from Jasc (www.jasc.com). The smartest tool I've seen there is the "Batik" open-source project from Apache (http://xml.apache.org/batik), which includes a Java-based Rasterizer for converting SVG on-the-fly to GIF or JPG images. This can be used for those browsers that don't have the viewer plug-in installed yet, so they receive an image of the SVG instead.
By using the CFML tag <cfobject> to invoke the Java Rasterizer object on the server-side, you can easily serve dynamically generated images to the browser. The coolest thing is that you have to code the graphic only one time for both view types: either serve the SVG stream directly to the browser (having the plug-in available) or use <cfobject> with the Rasterizer to dynamically convert this SVG stream into an image and serve it using <cfcontent>. The HTML <img> tag for doing this would look like <img src="mySvg2-ImageGenerator.cfm?-someparams=somevalues"> where mySvg2-Image-Generator.cfm uses <cfobject> to access the Rasterizer.
Published August 31, 2001 Reads 8,834
Copyright © 2001 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Christian Schneider
Christian Schneider is an Allaire Certified ColdFusion and Web site developer. He has over four years of intensive experience developing CF-based intranet applications for banks and logistic corporations.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe Fiddles with its Web Apps
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF























