ChartDirector 6.0 (ColdFusion Edition)

Producing Multiple Charts With One Database Query




In this example, we will demonstrate how to produce multiple charts on the same page, in which the data come from the same database query.

As similar to the last example, the user will select a year from a drop down list box and press OK. The web server will query a database to obtain the necessary data, and return a web page containing two charts about the selected year.

Note: To run this example, you need to set up the sample data source first. Please refer to "Database Sample Code Overview" for details.

[File: cfdemo/dbdemo2.cfm]
<cfscript>

// ChartDirector for ColdFusion API Access Point
cd = CreateObject("java", "ChartDirector.CFChart");

// A utility to allow us to create arrays with data in one line of code
function Array() {
    var result = ArrayNew(1);
    var i = 0;
    for (i = 1; i LTE ArrayLen(arguments); i = i + 1)
        result[i] = arguments[i];
    return result;
}

//
// Create the first chart based on the given data
//
function createChart1(selectedYear, software, hardware, services)
{
    // Declare local variables
    var c = 0;
    var layer = 0;
    var labels = 0;

    // Create a XYChart object of size 600 x 300 pixels, with a light grey (eeeeee) background,
    // black border, 1 pixel 3D border effect and rounded corners.
    c = cd.XYChart(600, 300, "0xeeeeee", "0x000000", 1);
    c.setRoundedFrame();

    // Set the plotarea at (60, 60) and of size 520 x 200 pixels. Set background color to white
    // (ffffff) and border and grid colors to grey (cccccc)
    c.setPlotArea(60, 60, 520, 200, "0xffffff", -1, "0xcccccc", "0xccccccc");

    // Add a title to the chart using 15pt Times Bold Italic font, with a light blue (ccccff)
    // background and with glass lighting effects.
    c.addTitle("Global Revenue for Year " & selectedYear, "Times New Roman Bold Italic", 15
        ).setBackground("0xccccff", "0x000000", cd.glassEffect());

    // Add a legend box at (70, 32) (top of the plotarea) with 9pt Arial Bold font
    c.addLegend(70, 32, False, "Arial Bold", 9).setBackground(cd.Transparent);

    // Add a line chart layer using the supplied data
    layer = c.addLineLayer2();
    layer.addDataSet(software, "0xff0000", "Software").setDataSymbol(cd.CircleShape, 9);
    layer.addDataSet(hardware, "0x00ff00", "Hardware").setDataSymbol(cd.DiamondShape, 11);
    layer.addDataSet(services, "0xffaa00", "Services").setDataSymbol(cd.Cross2Shape(), 11);

    // Set the line width to 3 pixels
    layer.setLineWidth(3);

    // Set the x axis labels. In this example, the labels must be Jan - Dec.
    labels = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov",
        "Dec");
    c.xAxis().setLabels(labels);

    // Set the y axis title
    c.yAxis().setTitle("USD (Millions)");

    // Set axes width to 2 pixels
    c.xAxis().setWidth(2);
    c.yAxis().setWidth(2);

    // Output the chart
    ret = StructNew();
    ret.imageURL = c.makeSession(getPageContext(), "chart1");

    // Include tool tip for the chart
    ret.imageMap = c.getHTMLImageMap("", "",
        "title='{dataSetName} Revenue for {xLabel} = USD {value}M'");
    return ret;
}

//
// Create the second chart based on the given data
//
function createChart2(selectedYear, software, hardware, services)
{
    // Declare local variables
    var c = 0;
    var layer = 0;
    var labels = 0;

    // Create a XYChart object of size 600 x 300 pixels, with a light grey (eeeeee) background,
    // black border, 1 pixel 3D border effect and rounded corners.
    c = cd.XYChart(600, 300, "0xeeeeee", "0x000000", 1);
    c.setRoundedFrame();

    // Set the plotarea at (60, 60) and of size 520 x 200 pixels. Set background color to white
    // (ffffff) and border and grid colors to grey (cccccc)
    c.setPlotArea(60, 60, 520, 200, "0xffffff", -1, "0xcccccc", "0xccccccc");

    // Add a title to the chart using 15pt Times Bold Italic font, with a dark green (006600)
    // background and with glass lighting effects.
    c.addTitle("Global Revenue for Year " & selectedYear, "Times New Roman Bold Italic", 15,
        "0xffffff").setBackground("0x006600", "0x000000", cd.glassEffect(cd.ReducedGlare));

    // Add a legend box at (70, 32) (top of the plotarea) with 9pt Arial Bold font
    c.addLegend(70, 32, False, "Arial Bold", 9).setBackground(cd.Transparent);

    // Add a stacked area chart layer using the supplied data
    layer = c.addAreaLayer2(cd.Stack);
    layer.addDataSet(software, "0x40ff0000", "Software");
    layer.addDataSet(hardware, "0x4000ff00", "Hardware");
    layer.addDataSet(services, "0x40ffaa00", "Services");

    // Set the area border color to the same as the fill color
    layer.setBorderColor(cd.SameAsMainColor);

    // Set the x axis labels. In this example, the labels must be Jan - Dec.
    labels = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov",
        "Dec");
    c.xAxis().setLabels(labels);

    // Set the y axis title
    c.yAxis().setTitle("USD (Millions)");

    // Set axes width to 2 pixels
    c.xAxis().setWidth(2);
    c.yAxis().setWidth(2);

    // Output the chart
    ret = StructNew();
    ret.imageURL = c.makeSession(getPageContext(), "chart2");

    // Include tool tip for the chart
    ret.imageMap = c.getHTMLImageMap("", "",
        "title='{dataSetName} Revenue for {xLabel} = USD {value}M'");
    return ret;
}

</cfscript>

<!--- All the years in the sample database --->
<cfquery name="allYears" datasource="cdsample">
    SELECT Year(timeStamp) As Year FROM Revenue GROUP BY Year(timeStamp)
    ORDER BY Year(timeStamp)
</cfquery>

<!--- Set currently selected year as according to user input, or to the latest year
      in the database if there is no user input --->
<cfset selectedYear = IIf(IsDefined("URL.year"), "URL.year",
    allYears["Year"][ArrayLen(allYears["Year"])])>

<!--- Query data from the selected year and read them into arrays --->
<cfquery name="selectedData" datasource="cdsample">
    SELECT * FROM Revenue WHERE Year(timeStamp) = #selectedYear# Order By timeStamp
</cfquery>
<cfset software = selectedData["Software"].toArray()>
<cfset hardware = selectedData["Hardware"].toArray()>
<cfset services = selectedData["Services"].toArray()>

<!--- Draw the charts --->
<cfset chart1 = createChart1(selectedYear, software, hardware, services)>
<cfset chart2 = createChart2(selectedYear, software, hardware, services)>

<html>
<cfoutput>
<body style="margin:5px 0px 0px 5px">
<div style="font-size:18pt; font-family:verdana; font-weight:bold">
    Database Integration Demo (2)
</div>
<hr style="border:solid 1px ##000080" />
<div style="font-size:10pt; font-family:verdana; width:600px">
<form>
    I want to obtain the revenue data for the year
    <select name="year"><cfloop query="allYears">
        <option value="#Year#" #IIf(Year EQ selectedYear, """Selected""", """""")#>
            #Year#
        </option>
    </cfloop></select>
    <input type="submit" value="OK">
</form>
</div>

<img src="getchart.cfm?#chart1.imageURL#" usemap="##map1" border="0" />
<map name="map1">#chart1.imageMap#</map>
<br><b>
<img src="getchart.cfm?#chart2.imageURL#" usemap="##map2" border="0" />
<map name="map2">#chart2.imageMap#</map>

</body>
</cfoutput>
</html>

The above code contains two methods for generating charts and putting the charts. The data for the charts are passed in as arguments.

function createChart1(selectedYear, software, hardware, services) { ... }
function createChart2(selectedYear, software, hardware, services) { ... }

In the code, database queries are used to obtain the data. The resulting query columns are read into array variables. This is the same as the previous example.

In this example, the data are passed to the two chart generating methods to create two charts.

<cfset chart1 = createChart1(selectedYear, software, hardware, services)>
<cfset chart2 = createChart2(selectedYear, software, hardware, services)>

The outputs are then used in the <IMG> and <MAP> tags for including the chart images and the image map in the HTML web page.