In this section, we'll show you how to use FusionCharts and JSP to plot charts from data contained in a database. We'll create a pie chart to show "Production by Factory" using:

  • dataXML method first.
  • Thereafter, we'll convert this chart to use dataURL method.

For the sake of ease, we'll use an Access Database. The database is present in Download Package > Code > JSP > DB folder. You can, however, use any database with FusionCharts including MySQL,MS SQL, Oracle. Database creation script for MySQL is also present in the Download Package.

Before you go further with this page, we recommend you to please see the previous section "Basic Examples" as we start off from concepts explained in that page.

The code examples contained in this page are present in Download Package > Code > JSP > DBExample folder. The Access database is present in Download Package > Code > JSP > DB.

 
Database Structure
Before we code the JSP pages to retrieve data, let's quickly have a look at the database structure.

The database contains just 2 tables:

  1. Factory_Master: To store the name and id of each factory
  2. Factory_Output: To store the number of units produced by each factory for a given date.

For demonstration, we've fed some dummy data in the database. Let's now shift our attention to the JSP page that will interact with the database, fetch data and then render a chart.

 
Building the JSP Page for dataXML Method
The JSP page for dataXML method example is named as BasicDBExample.jsp (in DBExample folder). It contains the following code:

<%@ include file="../Includes/FusionCharts.jsp"%>
<%@ include file="../Includes/DBConn.jsp"%>

<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.sql.Date"%>
<HTML>
   <HEAD>
       <TITLE>FusionCharts - Database Example</TITLE>
       <SCRIPT LANGUAGE="Javascript" SRC="../../FusionCharts/FusionCharts.js"></SCRIPT>
   </HEAD>
   <BODY>
   
 
   <%
       /*
       In this example, we show how to connect FusionCharts to a database.
       For the sake of ease, we've used a database which contains two tables,
       which are linked to each  other.
       */

           
       //Database Objects - Initialization
       Statement st1,st2;
       ResultSet rs1,rs2;
   
       String strQuery="";
   
       //strXML will be used to store the entire XML document generated
       String strXML="";
       
       
       //Generate the chart element
       strXML = "<chart caption='Factory Output report' subCaption='By Quantity' 
       pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units'>";
       
       //Construct the query to retrieve data
       strQuery = "select * from Factory_Master";
       
       
       st1=oConn.createStatement();
       rs1=st1.executeQuery(strQuery);
   
       String factoryId=null;
       String factoryName=null;
       String totalOutput="";
       //Iterate through each factory        
       while(rs1.next()) {
           
           factoryId=rs1.getString("FactoryId");
           factoryName=rs1.getString("FactoryName");
           //Now create second recordset to get details for this factory
           strQuery = "select sum(Quantity) as TotOutput from Factory_Output where 
           FactoryId=" + factoryId;
           st2=oConn.createStatement();
           rs2 = st2.executeQuery(strQuery);
           if(rs2.next()){
               totalOutput=rs2.getString("TotOutput");
           }
           //Generate <set label='..' value='..'/>        
           strXML += "<set label='" + factoryName + "' value='" +totalOutput+ "'/>";
           //Close resultset
           try {
                   if(null!=rs2){
                       rs2.close();
                       rs2=null;
                   }
           }catch(java.sql.SQLException e){
                //do something
                System.out.println("Could not close the resultset");
           }
           try{
                   if(null!=st2) {
                       st2.close();
                       st2=null;
                   }
           }catch(java.sql.SQLException e){
                //do something
                System.out.println("Could not close the statement");
           }
       } //end of while
       //Finally, close <chart> element
       strXML += "</chart>";
       //close the resulset,statement,connection
       try {
           if(null!=rs1){
               rs1.close();
               rs1=null;
           }
       }catch(java.sql.SQLException e){
            System.out.println("Could not close the resultset");
       }    
       try {
           if(null!=st1) {
               st1.close();
               st1=null;
           }
           }catch(java.sql.SQLException e){
            System.out.println("Could not close the statement");
           }
       try {
           if(null!=oConn) {
               oConn.close();
               oConn=null;
           }
           }catch(java.sql.SQLException e){
            System.out.println("Could not close the connection");
           }
           
       //Create the chart - Pie 3D Chart with data from strXML
       String chartCode=createChart("../../FusionCharts/Pie3D.swf", "", strXML, 
       "FactorySum", 600, 300, false, false);
       
   %> 
   <%=chartCode%> 
   
   </BODY>
</HTML>

The following actions are taking place in this code:

  1. We first include FusionCharts.js JavaScript class and FusionCharts.jsp , to enable easy embedding of FusionCharts.
  2. We then include DBConn.jsp, which connects to Access database.
  3. Thereafter, we generate the XML data document by iterating through the resultset and store it in strXML variable.
  4. Finally, we create the chart using createChart() method and pass strXML as dataXML and then render it.

When you now run the code, you'll get an output as under:

 
Converting the example to use dataURL method

Let's not convert this example to use dataURL method. As previously explained, in dataURL mode, you need two pages:

  1. Chart Container Page - The page which embeds the HTML code to render the chart. This page also tells the chart where to load the data from. We'll name this page as Default.jsp.
  2. Data Provider Page - This page provides the XML data to the chart. We'll name this page as PieData.jsp

The pages in this example are contained in Download Package > Code > JSP > DB_dataURL folder.

 
Chart Container Page - Default.jsp
Default.jsp contains the following code to render the chart:
<%@ include file="../Includes/FusionCharts.jsp"%>
<HTML>
   <HEAD>
      <TITLE>FusionCharts - dataURL and Database Example</TITLE>
      <SCRIPT LANGUAGE="Javascript" SRC="../../FusionCharts/FusionCharts.js"></SCRIPT>
   </HEAD>
   <BODY>
      <%
      /*
      In this example, we show how to connect FusionCharts to a database
      using dataURL method. In our other examples, we've used dataXML method
      where the XML is generated in the same page as chart. Here, the XML data
      for the chart would be generated in PieData.jsp.
      */

      
      /*
      To illustrate how to pass additional data as querystring to dataURL,
      we've added an animate property, which will be passed to PieData.jsp.
      PieData.jsp would handle this animate property and then generate the
      XML accordingly.
      */

      
      /*For the sake of ease, we've used an Access database which contains two tables,
         which are linked to each other.
      */

      
      //Variable to contain dataURL
      String strDataURL="";
      
      //Set DataURL with animation property to 1
      //NOTE: It's necessary to encode the dataURL if you've added parameters  to it
      strDataURL = encodeDataURL("PieData.jsp?animate=1","false",response);
      
      //Create the chart - Pie 3D Chart with dataURL as strDataURL
      String chartCode= createChart("../../FusionCharts/Pie3D.swf",       
      strDataURL, "", "FactorySum", 600, 300, false, false);
      %>
      <%=chartCode%>
      <BR>
      <BR>
      <a href='../NoChart.html' target="_blank">Unable to see the chart above?</a>
   </BODY>
</HTML>

In the above code, we're:

  1. Including FusionCharts.js JavaScript file and FusionCharts.jsp
  2. Create the dataURL string and store it in strDataURL variable. We append a property animate to show how to pass parameters to dataURL. After building the dataURL, we encode it using encodeDataURL function defined in FusionCharts.jsp.
  3. Finally, we create the chart using createChart() method and set dataURL as strDataURL and render it.
Creating the data provider page PieData.jsp
PieData.jsp contains the following code to output XML Data:
<%@ include file="../Includes/DBConn.jsp"%>

<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.ResultSet"%>
<%
    /*This page generates the XML data for the Pie Chart contained in
    Default.jsp.     
    
    For the sake of ease, we've used an Access database which is present in
    ../DB/FactoryDB.mdb. It just contains two tables, which are linked to each
    other. 
    */

        
    //Database Objects - Initialization
    Statement st1=null,st2=null;
    ResultSet rs1=null,rs2=null;
    
    String strQuery="";

    //strXML will be used to store the entire XML document generated
    String strXML="";
    
    //Default.jsp has passed us a property animate. We request that.
    String animateChart;
    animateChart = request.getParameter("animate");
    //Set default value of 1
    if(null==animateChart||animateChart.equals("")){
        animateChart = "1";
    }

    //Generate the chart element
    strXML = "<chart caption='Factory Output report' subCaption='By Quantity' 
    pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units' 
    animation=' " + animateChart + "'>";
    
    //Query to retrieve data about factory
    strQuery = "select * from Factory_Master";
    //Create the statement
    st1=oConn.createStatement();
    //Execute the query
    rs1=st1.executeQuery(strQuery);
    
    String factoryId=null;
    String factoryName=null;
    String totalOutput="";
    
    while(rs1.next()) {
        factoryId=rs1.getString("FactoryId");
        factoryName=rs1.getString("FactoryName");
        //Now create second resultset to get details for this factory
        strQuery = "select sum(Quantity) as TotOutput from Factory_Output where
        FactoryId=" + factoryId;
        st2=oConn.createStatement();
        rs2 = st2.executeQuery(strQuery);
        if(rs2.next()){
            totalOutput=rs2.getString("TotOutput");
        }
        //Generate <set label='..' value='..'/>        
        strXML += "<set label='" + factoryName + "' value='" +totalOutput+ "' />";
        try {
            if(null!=rs2){
                rs2.close();
                rs2=null;
            }
        }catch(java.sql.SQLException e){
             System.out.println("Could not close the resultset");
        }
        try{
            if(null!=st2) {
                st2.close();
                st2=null;
            }
        }catch(java.sql.SQLException e){
             System.out.println("Could not close the statement");
        }
    }
    //Finally, close <chart> element
    strXML += "</chart>";
    
    try {
        if(null!=rs1){
            rs1.close();
            rs1=null;
        }
    }catch(java.sql.SQLException e){
         System.out.println("Could not close the resultset");
    }    
    try {
        if(null!=st1) {
            st1.close();
            st1=null;
        }
        }catch(java.sql.SQLException e){
             System.out.println("Could not close the statement");
        }
    try {
        if(null!=oConn) {
            oConn.close();
            oConn=null;
        }
        }catch(java.sql.SQLException e){
             System.out.println("Could not close the connection");
        }
    //Set Proper output content-type
     response.setContentType("text/xml"); 
    
    //Just write out the XML data
    //NOTE THAT THIS PAGE DOESN'T CONTAIN ANY HTML TAG, WHATSOEVER
    
%>
<%=strXML%>

In the above page:

  1. We first request the animate property which has been passed to it (from dataURL)
  2. We generate the data and store it in strXML variable
  3. Finally, we write this data to output stream without any HTML tags.

When you view this page, you'll get the same output as before.

About the database connection:
Database connection can be achieved in 2 ways:
  1. By including DBConn.jsp in the page as shown in the above example
  2. By using the DBConnection class as a bean in the application scope
We have seen how to use DBConn.jsp to get a Connection. Now let us see how to achieve the same result using DBConnection bean.
 
Connecting to the database using bean

The JSP page using DBConnection class is named as BasicDBExampleUsingConnectionClass.jsp (in DBExample folder).

In order to get a connection using the Java class DBConnection, first you need to use the DBConnection class as a bean
in application scope and import java.sql.Connection class. You may also need to import com.infosoftglobal.fusioncharts.Constants class to compare database names in DBConnection class with MSAccess/MySQL.

<jsp:useBean id="dbConn" class="com.infosoftglobal.fusioncharts.DBConnection" scope="application" />

<%@ page import="com.infosoftglobal.fusioncharts.Constants"%>
<%@ page import="java.sql.Connection"%>

Wherever a Connection to the database is required, call the getConnection method in the DBConnection class as follows.
Connection oConn=dbConn.getConnection();
Once the connection is achieved, use it to create statements, ResultSet objects and finally close it. This can be done in a try-catch block in the following manner.
   try {
      if(null!=oConn) {
         oConn.close();
         oConn=null;
      }
   }catch(java.sql.SQLException e){
      //do some exception handling
      System.out.println("Could not close the connection");
   }

The getConnection method in DBConnection class is overloaded. There is another public getConnection method, which takes the ServletContext as parameter. So, any jsp can pass the ServletContext to the DBConnection class and the class does all the job of checking which database it has to contact and getting the appropriate Connection.

All this work of setting the database name, access db path, MySQL db Datasource name (i.e, all the database related configuration) is done by InitServlet present in the com.infosoftglobal.fusioncharts package. It also creates an instance of DBConnection class with the current configuration and sets it in the Application Context so that all jsps can use this single instance. This servlet loads on startup of the servlet container as configured in the web.xml. So, your jsp just needs to call the getConnection() method on the bean as shown above.

To determine which database has been configured for the current application, again we get it from the bean. To check whether it is Access DB or MySQL DB, we use the Constants file present in the package com.infosoftglobal.fusioncharts which contains Database Names as final String. This can then be used to write database-specific queries.

/*
Note: here, the query is the same for Access and MySQL db.
*/

oConn = dbConn.getConnection();
String dbName = dbConn.getDbName();
if(dbName.equals(Constants.ACCESSDB)){
   strQuery = "select * from Factory_Master";
}
else if(dbName.equals(Constants.MYSQLDB)){
   strQuery = "select * from Factory_Master";
}

If your sql queries are specific to a database then you should construct the query in the if or else block. For further information about the DBConnection class or InitServlet refer to the java documentation.