KavaChart ProServe


Using a Java enabled web server, KavaChart can produce Flash, SVG, JPEG, PNG, GIF, or other image output that can be viewed on the thinnest of clients. Tomcat, WebSphere, BEA, ColdFusion MX, Jigsaw, JBoss, and other servers that include Java support can use KavaChart to instantly add dynamically generated images to any web page.

Finally, you can use KavaChart imaging beans to add graphical output to your own servlets or server-side output. The com.ve.kavachart.servlet package includes a collection of imaging beans that can be used by your servlets or JSP output to create dynamic graph images. Each subclass of com.ve.kavachart.servlet.Bean includes support for multiple image types, server-side caching, and definable client-side imagemaps. Bean properties are identical to those used by the com.ve.kavachart.applet collection for rapid prototyping and experimentation.

For complete KavaChart ProServe details, please see The KavaChart ProServe User's Guide


ProServe Overview

KavaChart's built-in server charts are found in the com.ve.kavachart.servlet package, and have a one-to-one correspondence with the standard KavaChart AlaCarte applets found in com.ve.kavachart.applet. While you would use com.ve.kavachart.applet.lineApp to generate line charts at the client via applets, you would use com.ve.kavachart.servlet.lineApp to generate line chart images at the server via servlets. Most KavaChart applets have a parallel servlet bean in the com.ve.kavachart.servlet package.

To increase the compatibility between servlets and applets, KavaChart servlets use exactly the same property/parameter strings (and parameter parsing class) as KavaChart applets. This makes it easy to switch from applet to servlet and back. For example, this is a simple applet definition that creates a bar chart:

<applet code="com.ve.kavachart.applet.barApp" width=300 height=200>
	<param name="dataset0yValues" value="321, 234, 234, 456>
	<param name="xAxisLabels" value="apples, oranges, peaches, pears">
</applet>
The same JSP tag definition looks like this:
<chart:streamed chartType="com.ve.kavachart.servlet.barApp">
	<chart:param name="dataset0yValues" value=321, 234, 234, 456 \>
	<chart:param name="xAxisLabels" value="apples, oranges, peaches, pears" \>
</chart:streamed>
Because server objects run on the server, rather than the client, the chart and image computation expense isn't automatically distributed across many machines. In fact, the server may be called upon to generate many charts simultaneously. To maximize KavaChart's servlet production speed, the com.ve.kavachart.servlet package implements a mechanism to cache images on the server. Once a particular chart definition has passed through the servlet to generate an image file, subsequent requests can simply retrieve the requested image from the server's cache, rather than generate it dynamically.

ProServe deployment varies somewhat from server to server, but for most servers, you can get started by simply placing the "kavachart.war" file into your web applications directory (usually "webapps").  This will create a sample KavaChart installation with JSP chart tag samples and JSP scriptlet samples.

To generate an image, KavaChart employs various classes in Java's AWT package. These classes require certain Java features that may not be available by default on Unix based servers. To access these features in a Java installation of 1.4.0 or greater, you can accomplish this by setting the java property java.awt.headless = true. This can be done by passing the argument "-Djava.awt.headless=true" to your JRE on startup. To use KavaChart with a Unix server and an older version of Java, please consult the Appendixes in The KavaChart ProServe User's Guide.


Installation

KAVACHART.WAR

Generally, you can install KavaChart ProServe by just placing the kavachart.war file into your web applications directory (usually "webapps").  This will create a sample KavaChart application that has JSP examples for both chart tags and scriptlets.  See the taglib documentation for more information about setting up your web.xml file and installing your KavaChart taglib descriptor file.

If you're not using JSP, or if you're creating your own servlets, installing KavaChart on your system basically consists of three steps:
  • Place the kcServlet.jar file within your server's CLASSPATH
  • Create a "writeDirectory" on your server's disk for the servlet cache
  • Set the "writeDirectory" property to correctly point to the cache directory
  • CLASSPATH

    The process of putting the ProServe jar file into your CLASSPATH varies across servers, but most servers have one or more of these mechanisms available:
  • a default directory, such as $WebApplicationHome/WEB-INF/lib, that is searched for jar and class files
  • a startup flag, such as -classpath that lets you override defaults to add a new file. Usually, you should use an absolute path, such as "-classpath /usr/local/java/lib/kcServlet.jar"
  • a startup batch file or script that lets you set the CLASSPATH environment variable to include kcServlet.jar
  • writeDirectory

    To use KavaChart ProServe's image cache mechanism, you'll need to set the "writeDirectory" property to point to that cache directory. Servlets and JSPs have an
    application.getRealPath(String)
    method for obtaining the proper name of your cache directory.


    KavaChart ProServe, JSP and taglib

    Java Server Pages (JSP) give you a high level of abstaction to separate content from presentation. JSPs inherit all the multi-platform, multi-threading, object oriented heritage of Java. KavaChart ProServe objects are easy to use from within a JSP.

    The best way to combine KavaChart with your JSP is to use our custom tag library. You can find examples using the tag library in the kavachart.war file as well as a tutorial describing how to use these tags. Here's a sample:

    <chart:streamed dataProviderID="myData" style="myStyle" />
    

    KavaChart tags will help you to separate your presentation and business logic layers, making your JSPs simple and easy to maintain.  They also implement the best optimization logic to make your chart generation as fast as possible.  The chart tag DataProvider class also helps you re-use your existing data sources for chart generation.

    If you still prefer to use scriptlets, though, KavaChart ProServe objects make the task easy.  Here's a simple example JSP  that creates a chart object, generates some data using a Java scriptlet, and generates chart output:

    <%@ page import = "com.ve.kavachart.servlet.barApp" %>
    <jsp:useBean id="chart" class="com.ve.kavachart.servlet.barApp" scope="page"/>

    <html>
    <head>&lttitle>Simple Chart Generation</title></head>
    <body bgcolor="white">
    <font size=4>

    <%
    //add some random data here:
    StringBuffer sb = new StringBuffer();
    double d = Math.random();
    sb.append(d);
    for(int i=0;i&lt5;i++){
    sb.append(",");
    d = Math.random();
    sb.append(d);
    }
    chart.setProperty("dataset0yValues", sb.toString());

    //set a few other properties to make the chart look nice
    chart.setProperty("titleString", "hello, world");
    chart.setProperty("writeDirectory", application.getRealPath("/cache"));
    chart.setProperty("yAxisOptions", "gridOn, minTickOn");
    chart.setProperty("xAxisOptions", "gridOn");
    chart.setProperty("plotAreaColor", "lightGray");
    chart.setProperty("dwellUseXValue", "false");
    chart.setProperty("dwellYString", "value: XX");

    //now attempt to get a background color from a Request parameter:
    String s = request.getParameter("bc");
    if(s!=null){
    chart.setProperty("backgroundColor", s);
    }
    %>
    <p>
    here's the chart:
    <img src=/cache/<%= chart.getFileName() %>>
    <p>
    And here's the same chart with tooltips:
    <%= chart.getLinkMap() %>
    <img src=/cache/<%= chart.getFileName() %> BORDER=0 ISMAP USEMAP=#map0>
    </body>
    </html>

    A few things are worth noting in the sample above. First, the ProServe object is imported and instantiated. Then a set of properties describe the chart, and a list of random numbers is provided as chart data. Finally, the chart is generated when the chart filename is requested. Since we didn't provide a fixed file name, the chart uses a name derived from the chart properties.

    The chart is written into a specified directory, which we know (the code assumes, anyway) is the same as our "application root" plus "cache". The chart is referenced in the outgoing HTML stream so it will be easy to add additional text and graphics. If we wanted to stream the bytes out instead, we'd need to set the "content type" and get the image bytes from our chart.


    Server Object Properties

    Most KavaChart server object properties are shared with applets.  These properties can be found in the General Properties chapter. Other properties are unique to particular chart types: see Chart-specific properties, below. And, still other properties are applicable to server side KavaChart, and do not apply to applets: see the server-only properties in the following table.
    Property value type effect
    chartType String the kind of chart you want to generate. These are all the "App" files in the servlet package, and include all the chart types enumerated in the Individual Charts section of the documentation, such as "barApp", "lineApp", and so on. The default chart type is a horizontal bar chart. If you want to reference a chart that's not in the com.ve.kavachart.servlet package, it must be a subclass of com.ve.kavachart.servlet.Bean, and you must provide the fully qualified name (e.g. "chartType=com.ve.kavachart.contrib.TwinAxisDateLineServlet"). This parameter is for "ChartServlet" only, and doesn't apply to individual server beans.  
    imageType String Output image type. This defaults to a pure Java png encoder. Available imageTypes are j_png (for png images, recommended), svg (for scalable vector graphics), swf or flash (for a flash image), jpeg (using Sun's native JPEG encoder), j_jpeg (using a java jpeg generator), j_bmp (a java .BMP file generator), and gifencoder
    properties string a server-side properties file containing default chart properties. This is a great way to set up a customized look for your chart without constantly passing the same parameters to the servlet. This parameter is only used by ChartServlet, if you are using a Bean subclass then use the loadProperties(String s) method instead. 
    height integer pixel height of generated image 
    width integer pixel width of generated image 
    writeDirectory String KavaChart writes image files into this directory. By default this is set to "public_html/images". Since writeDirectory is "public_html/images" by default, the server will attempt to write images into $SERVER_ROOT/public_html/images/file_name. You can also specify an absolute path, such as /usr/lib/webserver/images for this directory. The write directory must be writable by the servlet engine, and readable by the web server. NOTE: this property is currently disabled in ChartServlet for security reasons. 
    readDirectory String This is the cache directory browsers will use to retrieve images generated by ChartServlet. By default, readDirectory is "images", which means the servlet will return an "img src" tag that points to "images/filename.jpg". See also "writeDirectory". This property isn't used by general ProServe objects, but only by ChartServlet. NOTE: this property is currently disabled in ChartServlet for security reasons. 
    debug String If a KavaChart servlet finds the parameter "debug" it will log messages to the server log about files names, locations, sizes, etc. The value of this parameter is ignored. 
    useCache boolean If "true", the servlets will attempt to use an image in the cache directory matching this servlet's parameters. If "false" the image will be generated each time. Note: if you are reading data by reference (e.g. dataset0yURL) and the data changes from time to time, you should either use this parameter to generate a fresh image, or clear the image cache whenever your data changes. Image caching is enabled by default. If useCache is false and byteStream is true, the bean won't write any output to the server's disk. NOTE: this property is currently disabled in ChartServlet for security reasons. 
    byteStream boolean By default, the servlets write an image to disk, and then send a <IMG SRC=...> message to the response OutputStream. If byteStream is set to "true", however, the servlet will instead set the content-type to the appropriate image type and send a stream of bytes. Note, however, that servlet parameters must still be set to generate a meaningful chart. By combining useCache=false and byteStream=true you can avoid using the server's disk entirely. NOTE: this property is currently disabled in ChartServlet for security reasons. 
    fileName String An image file name for this servlet. By default, the servlets use a Secure Hash Algorithm (SHA) to create a digest of all the parameters in a given servlet definition. This digest is used to create a filename that uniquely identifies a chart defined by a given set of parameters. The servlet's CacheManager looks for the unique SHA filename in the image cache, and sends that image without regenerating it, if the image exists. Any change in the parameters, even the addition of an unused parameter, will create a new file name, and will cause the image to be regenerated. You can override the default image name with this parameter to force the image to be a specified name NOTE: this property is currently disabled in ChartServlet for security reasons. 
    mapName String ToolTips and hyperlinks use client side imagemaps to link strings and URLs to image geometries. These imagemaps must be named. The default name is "map0". This property lets you override the map name.
    toolTips true/false Tells the ChartServlet whether to create a client-side MAP for tool-tip dwell labels.
    hasLinkMap true/false Tells ChartServlet whether to create a client-side MAP for hyperlinks (set using DatasetNLinks). The default value is true
    internalData true/false If "internalData" is set to true, KavaChart beans will look for data from the method getDataset(ChartInterface,int). This method gives you an alternate way of retrieving data that might provide better performance or cleaner code than property lists.
    antialiasOn true/false Turns antialiasing on for the resulting chart image. Antialiasing requires a java 2 environment (jdk 1.2 or above)
    compressOutput true/false This determines whether svg output will be compressed or not. This defaults to true.
    useCacheCleaner true/false Determines whether an instance of CacheCleaner will be created to clean up the cache directory.
    cacheCleanerDirectory String This sets the cache directory to be regulated by CacheCleaner. Note that CacheCleaner cannot tell the difference between chart images and other files so it will delete any files in this directory over the expiration age.
    cacheCleanerInterval integer Determines the sleep interval in minutes for this instance of the CacheCleaner
    cacheCleanerExpirationTime integer Any file in the cache directory over this age in minutes will be automatically deleted by CacheCleaner

    General Properties

    KavaChart applets and ProServe objects share a rich set of properties (used as parameters for the applets).  You will find these properties documented here.  For more information about how to add your own custom charts to the applet and server object frameworks, consult the KavaChart Enterprise Edition User Guide.


    Chart-specific Properties

    Each chart type has its own set of properties in addition to the general chart  property set. You can find links to predefined server object properties here:
  • Area Charts
  • Bar and Column Charts
  • Line Charts
  • Pie Charts
  • Speedo and Polar Charts
  • Combination Charts
  • Finance Charts
  • Twin Axis Charts
  • Bubble Chart
  • HLOC Related Charts
  • Gantt Chart
  • Sector Map Chart
  • Contributed Statistical Charts: Histogram, Box-Whisker, Pareto, Stem-Leaf

  • Running the sample servlet

    KcServlet.jar includes a sample charting servlet that will generate streamed image output. This is useful for verifying the installation for your own servlets. After you've installed the servlet jar and established a directory to write server images and determined what address browsers will use to read those same images, you're ready to run. There are a wide variety of ways to tell a server to run a particular servlet. Since these instructions vary from server to server, we'll focus on general concepts here. Refer to your server documentation for more specific information.

    First, it's important to note that KavaChart servlets are in a Java package. Unlike simple demonstration servlets, KavaChart servlets require a number of interdependent Java classes, and are organized into package groupings. Your servlet engine probably has a "HelloWorld" class that would run from a browser something like this:

    http://server:8080/servlet/HelloWorld
    You would replace "server" with the name of your server machine or with localhost if the server is on your local machine. Similarly, you'd replace "8080" with a different port, if your servlet engine uses another port, and "servlet" might be different on your configuration. If "HelloWorld" were part of a package called "demo", you'd start it from your browser like this:
    http://server:8080/servlet/demo.HelloWorld
    The equivalent command for the sample KavaChart servlet would be similar to this:
    http://server:8080/servlet/com.ve.kavachart.servlet.ChartServlet
    When the server receives this HTTP GET command, it will attempt to find a Java class named ChartServlet.class in the com.ve.kavachart.servlet package located within it's CLASSPATH. Next, it will attempt to create a JPEG image in the directory "public_html/images", since we didn't change the default writeDirectory within our command. The servlet will return something like <IMG SRC="images/abcd123.jpg">. Your browser will then attempt to get this image file with a conventional HTTP transaction.

    We could modify our servlet URL a little bit to write the image to a specific location, and just return the image stream instead of an IMG SRC tag. We'll also add a "debug" parameter to add some information on the server console or log about the image name. Finally, we'll add a parameter to define a bit of data. Here's our modified URL:

    http://server:8080/servlet/com.ve.kavachart.servlet.ChartServlet?byteStream=true&debug=true&writeDirectory=/usr/tmp&dataset0yValues=123,342,123
    You can also refer to your servlet with a registered name. Consult your server documentation for information on how to do this. A registered name can be the same or different than the actual class name. Some servers also permit you to create servlet aliases that will automatically create shortcuts to servlets (and startup properties in some cases).

    Another common technique is to use Server Side Include (SSI) to pre-process HTML output to embed the output of a servlet. Pages that contain servlet definitions usually have a .shtml or .jhtml suffix to notify the server that the page should be filtered for servlet output before being sent to a browser. This is what an SSI definition might look like:

    <servlet code=com.ve.kavachart.servlet.ChartServlet>
    <param name="chartType" value="barApp">
    <param name="dataset0yValues" value="321, 234, 234, 456">
    <param name="xAxisLabels" value="apples, oranges, peaches, pears">
    </servlet>
    ColdFusion servers use the CFSERVLET tag instead of SERVLET, but use the same sort of server-side include syntax. However, if you're a ColdFusion MX user, the tag library is a much cleaner way to implement KavaChart with your data sources. See The KavaChart ProServe User Guide for more information.

    Creating Your Own Charting Servlet

    There are a variety of ways to embed KavaChart images into your servlet environment. While a complete discussion of servlet environments and usage is beyond the scope of this document, we'll build some simple charting servlets that can serve as a basis for all sorts of server side graphics generation.

    In our first approach, we'll use a KavaChart imaging bean to build an image on the server. Ignore the details for the moment, we'll explain how servlets work shortly. Focus instead on the overall approach. Here's the code:

    public class SimpleChartServlet extends HttpServlet {

            protected void doGet(HttpServletRequest request,
                                                    HttpServletResponse response) throws ServletException,
                                                    IOException {

                    ServletOutputStream out = response.getOutputStream();

                    com.ve.kavachart.servlet.Bean chart = new com.ve.kavachart.servlet.barApp();
                    chart.setProperty("imageType", "j_png");
                    chart.setProperty("useCache", "false");
                    chart.setProperty("byteStream", "true");
                    chart.setProperty("xAxisLabels", "Larry, Curly, Moe, Bob, Dave");
                    chart.setProperty("dataset0yValues", "123,432,123,543,345");
                    chart.setProperty("width", (new Integer(WIDTH)).toString());
         
               chart.setProperty("height", (new Integer(HEIGHT)).toString());
                    response.setContentType("image/png");
                    out.write(chart.getImageBytes());
            }
    }

    This code simply creates a charting bean, sets some string pairs as bean properties, and retrieves an image name. Compared with using KavaChart Enterprise Edition's core charting classes, there are several advantages to this approach, as well as some minor disadvantages: First, you don't need to learn the com.ve.kavachart.chart API to use these beans. Simply follow the examples in our applet HTML, or use the applets to experiment with various properties. Second, you can isolate the chart aesthetics into a properties file that is external to your application. Third, you'll have automatic access to a variety of image output types, and a server-side cache management mechanism. Finally, the properties code is completely portable among chart types. It doesn't hurt, for example, to set a pie chart starting angle if you're using a bar chart. It's also worth noting that the KavaChart objects are in use at thousands of installations, and have gone through extensive testing and optimization.

    On the other side of the ledger, the beans are a "black box" image generation engine. If you run into problems, they may be more difficult to solve than if the code is all in your servlet.

    If you plan to build an image generation servlet, you should also look into the KavaChart "DataProvider" interface, which makes your data sources portable across a variety of techniques, and lets you populate a chart with data directly, rather than with property strings. You can read about DataProviders in the KavaChart ProServe User's Guide and in the Tag Library Tutorial


    Imaging Bean API

    Here is a list of public Bean methods that will help you make the most of KavaChart in your servlets, JSPs, and ASPs:

    Method Effect
    Constructor(java.util.Properties) any bean subclass can be instantiated with a java.util.Properties to provide predefined charting properties. The properties available are all those listed for applets and servlets.
    public void generate() Generates an image file or ByteArray based on the current property settings.
    public String getFileName() Retrieves the user specified fileName or the default file name. If the image for this chart has not yet been generated, calls generate().
    public byte[] getImageBytes() Retrieves this image as an array of bytes. Generates the image if required. Retrieves the bytes from image cache if available.
    public String getParameter(String) Retrieves a property, or parameter, if set.
    public Enumeration getParameterNames() Retrieves the current list of available properties.
    public String getProperty(String) see getParameter(String).
    public void setProperty(String, String) Sets a specified property to a specified value. Consult the list of servlet properties, general properties, and chart-specific properties for more information.
    public void setProperties(Properties props) Sets the properties for this charting bean.  It's often more efficient to read your properties one time, and let this object persist in your servlet or application memory, rather than create a new Properties object for each chart.
    public void accumulateProperty(String, String) Some properties take the form "a,b,c,d". For example, the property "dataset0yValues" might look like this: "432,123,432". In a servlet, ASP or JSP, it's often easier to accumulate these properties in a loop that examines a resultset from a database lookup. To create the list for dataset0yValues, you'd call this method three times: accumulateProperty("dataset0yValues", "432"), accumulateProperty("dataset0yValues", "123"), and so on. Consult the list of servlet properties, general properties, and chart-specific properties for more information.
    public String getLinkMap() Retrieves HTML statements for a client-side imagemap that contains tool-tip information for each Datum (based on the dwellLabel properties above) and a set of hyperlinks (based on the datasetNLinks and datasetNTargets properties above). This string contains the geometries for each data item on the chart (pie slice, bar, line vertex, etc.) and may be quite large for complex charts.
    public void loadProperties(String) Loads properties from a specified include file. This file contains a single column of entries with the form "propertyName=value".
    public ChartInterface getChart() Retrieves the internal com.ve.kavachart.chart.Chart object from the charting bean for direct customization in java code.
    public Dataset getDataset(ChartInterface c, int index) Method for you to override to provide one data series in com.ve.kavachart.chart.Dataset form.
    public void setUserImagingCodec(UserImagingCodec codec) Adds a custom class to be used by Bean to produce the output file or bytestream. This can be used to encode charts to postscript files, transparent gif files or other file types not supported by CacheManager. Any custom class should extend com.ve.kavachart.servlet.UserImagingCodec and override either the public byte[] drawChartToOutputStream(ChartInterface), or public byte[] encodeImageBytes(Image) methods. Two such sample classes can be found in the contrib package, they are com.ve.kavachart.contrib.PostScriptEncoder, and com.ve.kavachart.contrib.GifEncoderForKava.

    KavaChart and ASP

    Active Server Pages (ASP) can also be used for generating dynamic content from Microsoft web servers. Unfortunately, Microsoft has chosen to drop support for Java in newer installations of ASP, but if you have a Java-enabled version of IIS, KavaChart ProServe bjects can be installed as COM objects for use with any ASP scripting mechanism, such as VisualBasic, JScript, and so on. Here's how:

    Use the "jar" command to extract the kcServlet.jar file into the appropriate directory:

  • 1) Copy kcServlet.jar to your NT server.
  • 2) Open a command prompt
  • 3) cd to the Web server's Winnt\Java\Trustlib directory.
  • 4) Extract kcServlet with the "jar" command: "jar xvf kcServlet.jar". This will create "com.ve.kavachart. and "com\sun" subdirectories. Note: if you don't have "jar" available, you can obtain it from any JDK, or you can use a zip utility, such as WinZip, to extract the files.

    Now you're ready to create an ASP that uses a KavaChart object. Below is a sample ASP that generates chart output this way:

    <%@ LANGUAGE = JScript %>
    <html dir=ltr> // Create an instance of the BarChart object
    chart = Server.getObject("java:com.ve.kavachart.servlet.barApp.class");


    //Use your instance of the BarChart object

    //write into the server tutorial directory - where this ASP file should go...
    chart.setProperty("writeDirectory", "/winnt/help/iishelp/iis/htm/tutorial");
    //use png output
    chart.setProperty("imageType", "j_png");
    //set a size
    chart.setProperty("width", "500");
    chart.setProperty("height", "300");
    //some values
    chart.setProperty("dataset0yValues", "123,432,123,432,123");
    //some aesthetics
    chart.setProperty("dataset0Color", "green");
    chart.setProperty("backgroundColor", "aabbff");
    chart.setProperty("3D", true);
    chart.setProperty("yAxisOptions", "gridOn");
    chart.setProperty("titleString", "KavaChart is Cool!");
    chart.setProperty("subTitleString", "with a little Java...");
    chart.setProperty("XDepth", "3");
    chart.setProperty("YDepth", "3");
    str = chart.getFileName();
    %>

    <h3></A>The automatically generated filename is <%= str%>.</h3>
    <img src=<%= str%>>



    </FONT>

    </BODY>
    </HTML>

    In this example, we instantiate our COM object by calling Server.getObject, and then set properties that describe what the chart should look like. We could use a link to a database or some other dynamic data mechanism to populate our chart data, but to keep things simple, we just put a static set of numbers into the chart.

    When we call the getFileName method, the chart generates its output data (PNG encoded, per our request) into a file in the specified writeDirectory. Since we didn't specify a file name, the chart object creates one based on this charts unique properties. Subsequent requests for an identical chart will use that file rather than regenerating it.

    Even though our example uses JScript, you're free to use VisualBasic or some other scripting language you're familiar with to populate the chart properties. The high level of abstraction lets you create the chart in the most convenient way possible, while the more difficult charting and image generation code disappears from your code base.

    You'll find both JScript and VBScript examples in the "asp" directory.