FusionCharts v3 offers tremendous integration capabilities with JavaScript. You can easily use FusionCharts and JavaScript to create client side dynamic charts.

Here, we'll see the JavaScript + URL method - where we ask the chart to fetch new data from server and update itself, without incurring any page refreshes. The entire application resides in a single page which makes it a seamless experience for your end viewers.

Before you proceed with the contents in this page, we strictly recommend you to please go through the sections "How FusionCharts works?" and "Basic Examples", as we'll directly use a lot of concepts defined in those sections.

The code discussed in this example is present in Download Package > Code > JSP > DB_JS_dataURL folder.

 
Mission for this example

Let us first define what we want to achieve in this example. We'll carry on from our previous drill-down example and convert it into a single page example. In our previous example, we were showing the Production Summary of all the factories in a pie chart. When the user clicked on a pie slice, he was taken to another page, where a detailed date-wise chart was shown for the required factory.

In this example, we'll assimilate both the charts in a single page and make them interact with each other using JavaScript, thereby making the end-user experience smooth. Effectively, we will do the following:

  1. Contain both the pie chart (summary) and column chart (detailed) in one page (Default.jsp).
  2. When the page loads, the pie chart would use dataXML method to show summary of all factories. This data will be built in Default.jsp itself.
  3. The column chart would initialize with no data, as the user has not selected a factory initially. We'll customize the "No data to display" message of the chart to show a friendly message.
  4. The pie chart would have JavaScript links defined for each pie slice. This JavaScript links refer to updateChart() JavaScript function present on the same page. We'll later see how to hand code this function. When a pie is clicked, the factory ID is passed to this function.
  5. The updateChart() function is responsible for updating the column chart. It generates a dataURL link by including the factoryId as a part of dataURL (FactoryData.jsp). FactoryData.jsp is the data provider page for the detailed column chart. Once the dataURL is built, it conveys this dataURL to the column chart.
  6. The column chart would now accept this dataURL, send a request to FactoryData.jsp for XML data, accept it, parse it and finally render.
 
Creating the charts container page
Both the charts and JavaScript functions to manipulate the charts is contained in Default.jsp. It has the following code:

<%@ 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 + JavaScript Example</TITLE>

        <%
        /*
        In this example, we show a combination of database + JavaScript (dataURL method)
        rendering using FusionCharts.

        The entire app (page) can be summarized as under. This app shows the break-down
        of factory wise output generated. In a pie chart, we first show the sum of quantity
        generated by each factory. These pie slices, when clicked would show detailed date-wise
        output of that factory. The detailed data would be dynamically pulled by the column
        chart from another JSP page. There are no page refreshes required. Everything
        is done on one single page.

        The XML data for the pie chart is fully created in JSP at run-time. JSP interacts
        with the database and creates the XML for this.
        Now, for the column chart (date-wise output report), each time we need the data
        we dynamically submit request to the server with the appropriate factoryId. The server
        responds with an XML document, which we accept and update chart at client side.
         */

        %>
        <SCRIPT LANGUAGE="Javascript" SRC="../../FusionCharts/FusionCharts.js">
            //You need to include the above JS file, if you intend to embed the chart using
            //JavaScript.

            //Embedding using JavaScripts avoids the "Click to Activate..." issue in Internet
            // Explorer

            //When you make your own charts, make sure that the path to this JS file is correct.
            //Else, you would get JavaScript errors.


        </SCRIPT>

        <SCRIPT LANGUAGE="JavaScript">

            /**
             * updateChart method is invoked when the user clicks on a pie slice.
             * In this method, we get the index of the factory after which we request for XML data
             * for that that factory from FactoryData.asp, and finally
             * update the Column Chart.
             * @param factoryIndex Sequential Index of the factory.
             */
            function updateChart(factoryIndex){
                //DataURL for the chart
                var strURL = "FactoryData.jsp?factoryId=" + factoryIndex;

                //Sometimes, the above URL and XML data gets cached by the browser.
                //If you want your charts to get new XML data on each request,
                //you can add the following line:
                //strURL = strURL + "&currTime=" + getTimeForURL();
                //getTimeForURL method is defined below and needs to be included
                //This basically adds a ever-changing parameter which bluffs
                //the browser and forces it to re-load the XML data every time.

                //URLEncode it - NECESSARY.
                strURL = escape(strURL);

                //Get reference to chart object using Dom ID "FactoryDetailed"
                var chartObj = getChartFromId("FactoryDetailed");
                //Send request for XML
                chartObj.setDataURL(strURL);
            }
            /**
             * getTimeForURL method returns the current time
             * in a URL friendly format, so that it can be appended to
             * dataURL for effective non-caching.
             */

            function getTimeForURL(){
                var dt = new Date();
                var strOutput = "";
                strOutput = dt.getHours() + "_" + dt.getMinutes() + "_" + dt.getSeconds() + "_" + dt.getMilliseconds();
                return strOutput;
            }
        </SCRIPT>
        <style type="text/css">
            <!--
            body {
                font-family: Arial, Helvetica, sans-serif;
                font-size: 12px;
            }
            .text{
                font-family: Arial, Helvetica, sans-serif;
                font-size: 12px;
            }
            -->
        </style>
    </HEAD>
    <BODY>
        <CENTER>
            <h2>FusionCharts Database + JavaScript (dataURL method) Example</h2>
            <h4>Inter-connected charts - Click on any pie slice to see detailed
            chart below.</h4>
            <p>The charts in this page have been dynamically generated using
            data contained in a database.</p>
        <%
        //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 = "";

        //Generate the chart element
        strXML = "<chart caption='Factory Output report' subCaption='By Quantity' pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units' >";

        //Iterate through each factory
        strQuery = "select * from Factory_Master";
        st1 = oConn.createStatement();
        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 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 + "' link='javaScript:updateChart(" + factoryId + ")'/>";
            //close the resultset,statement
            //enclose them in try catch block

            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>";
        //close the resultset,statement,connection
        //enclose them in try catch block

        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
        %>
            <jsp:include page="../Includes/FusionChartsRenderer.jsp" flush="true">
                <jsp:param name="chartSWF" value="../../FusionCharts/Pie3D.swf" />
                <jsp:param name="strURL" value="" />
                <jsp:param name="strXML" value="<%=strXML%>" />
                <jsp:param name="chartId" value="FactorySum" />
                <jsp:param name="chartWidth" value="500" />
                <jsp:param name="chartHeight" value="250" />
                <jsp:param name="debugMode" value="false" />
                <jsp:param name="registerWithJS" value="false" />
            </jsp:include>
            <BR>
        <%
        //Column 2D Chart with changed "No data to display" message
        //We initialize the chart with <chart></chart>

        %>
            <jsp:include page="../Includes/FusionChartsRenderer.jsp" flush="true">
                <jsp:param name="chartSWF" value="../../FusionCharts/Column2D.swf?ChartNoDataText=Please select a factory from pie chart above to view detailed data." />
                <jsp:param name="strURL" value="" />
                <jsp:param name="strXML" value="<chart></chart>" />
                <jsp:param name="chartId" value="FactoryDetailed" />
                <jsp:param name="chartWidth" value="600" />
                <jsp:param name="chartHeight" value="250" />
                <jsp:param name="debugMode" value="false" />
                <jsp:param name="registerWithJS" value="true" />
            </jsp:include>
            <BR>
            <BR>
        <a href='../NoChart.html' target="_blank">Unable to see the charts above?</a></CENTER>
    </BODY>
</HTML>

Before we get to the JavaScript functions, let's first see what we're doing in our JSP Code.

We first create the XML data document for Pie chart - summary of factory output. For each <set>, we provide a JavaScript link to the updateChart() function and pass the factory ID to it as shown in the line below:

  strXML += "<set label='" + factoryName + "' value='" +totalOutput+ "'
 link='javaScript:updateChart("+factoryId + ")'/>";

We now create the Pie 3D chart using dataXML way and render it. The Pie 3D chart has its DOM Id as FactorySum:

<jsp:include page="../Includes/FusionChartsRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="../../FusionCharts/Pie3D.swf" />
<jsp:param name="strURL" value="" />
<jsp:param name="strXML" value="<%=strXML%>" />
<jsp:param name="chartId" value="FactorySum" />
<jsp:param name="chartWidth" value="500" />
<jsp:param name="chartHeight" value="250" />
<jsp:param name="debugMode" value="false" />
<jsp:param name="registerWithJS" value="false" />
</jsp:include>

Now, we render an empty Column 2D chart with <chart></chart> data initially. We also change the "No data to display." error to a friendly and intuitive "Please select a factory from pie chart above to view detailed data." This chart has its DOM Id as FactoryDetailed.

<jsp:include page="../Includes/FusionChartsRenderer.jsp" flush="true">
<jsp:param name="chartSWF" value="../../FusionCharts/Column2D.swf?ChartNoDataText=Please select a factory from pie chart above to view detailed data." />
<jsp:param name="strURL" value="" />
<jsp:param name="strXML" value="<chart></chart>" />
<jsp:param name="chartId" value="FactoryDetailed" />
<jsp:param name="chartWidth" value="600" />
<jsp:param name="chartHeight" value="250" />
<jsp:param name="debugMode" value="false" />
<jsp:param name="registerWithJS" value="true" />
</jsp:include>

Note that the registerWithJS parameter for this chart should be set to true. Effectively, our page is now set to show two charts. The pie chart shows the summary data provided to it using dataXML way. The column chart shows the above "friendly" error message. Now, when each pie slice is clicked, the updateChart() JavaScript function is called and the factoryID of the pie is passed to it. This function is responsible for updating the column chart and contains the following code:

 function updateChart(factoryIndex){
         //DataURL for the chart
         var strURL = "FactoryData.jsp?factoryId=" + factoryIndex;

         //Sometimes, the above URL and XML data gets cached by the browser.
         //If you want your charts to get new XML data on each request,
         //you can add the following line:
         //strURL = strURL + "&currTime=" + getTimeForURL();
         //getTimeForURL method is defined below and needs to be included
         //This basically adds a ever-changing parameter which bluffs
         //the browser and forces it to re-load the XML data every time.


         //URLEncode it - NECESSARY.
         strURL = escape(strURL);

         //Get reference to chart object using Dom ID "FactoryDetailed"
         var chartObj = getChartFromId("FactoryDetailed");
         //Send request for XML
         chartObj.setDataURL(strURL);
      }   

Here,

  1. We first create a dataURL string by appending the factoryID to FactoryData.jsp.
  2. Thereafter, we URL Encode this dataURL.
  3. Finally, we convey this dataURL to the column chart. To do so, we first get a reference to the column chart using it's DOM Id FactoryDetailed. We use the getChartFromId() function defined in FusionCharts.js to do so.
  4. Once we've the reference to the chart, we simply call the setDataURL method of the chart and pass it the URL to request data from.
  5. This updates the chart with new data.

This completes our front-end for the app. We now just need to build FactoryData.jsp page, which is responsible to provide detailed data to column chart. It contains the following code:

<%@ include file="../Includes/DBConn.jsp"%>
<%@ page import="java.sql.Statement"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.text.SimpleDateFormat"%>
<%
    /*
    This page is invoked from Default.jsp. When the user clicks on a pie
    slice in Default.jsp, the factory Id is passed to this page. We need
    to get that factory id, get information from database and then write XML.
    */

    //First, get the factory Id
    String factoryId=null;
    //Request the factory Id from Querystring
    factoryId = request.getParameter("factoryId");
    String strXML="";
    if(null!=factoryId){
    
        ResultSet rs;
        String strQuery;
        Statement st;
        java.sql.Date date=null;
        java.util.Date uDate=null;
        String uDateStr="";
        String quantity="";

        //Generate the chart element string
        strXML = "<chart palette='2' caption='Factory " +factoryId+" Output ' 
        subcaption='(In Units)' xAxisName='Date' showValues='1' labelStep='2' >";
        //Now, we get the data for that factory
        strQuery = "select * from Factory_Output where FactoryId=" + factoryId;
        st=oConn.createStatement();
        rs = st.executeQuery(strQuery);

        while(rs.next()){
            date=rs.getDate("DatePro");
            quantity=rs.getString("Quantity");
            if(date!=null) {
              uDate=new java.util.Date(date.getTime());
              SimpleDateFormat sdf=new SimpleDateFormat("dd/MM");
              uDateStr=sdf.format(uDate);
            }
            strXML += "<set label='" +uDateStr+"' value='" +quantity+"'/>";
        }
        //Close <chart> element
        strXML +="</chart>";
        try {
            if(null!=rs){
                rs.close();
                rs=null;
            }
        }catch(java.sql.SQLException e){
             System.out.println("Could not close the resultset");
        }            
        try {
            if(null!=st) {
                st.close();
                st=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");
            }
        //Just write out the XML data
        //NOTE THAT THIS PAGE DOESN'T CONTAIN ANY HTML TAG, WHATSOEVER
        response.setContentType("text/xml");
    }
%>
<%=strXML%>

In this page, we basically request the factory Id passed to it as querystring, query the database for required data, build XML document out of it and finally write it to output stream.

When you now see the application, the initial state would look as under:

And when you click on a pie slice, the following would appear on the same page (without involving any browser refreshes):
This example demonstrated a very basic sample of the integration capabilities possible with FusionCharts v3. For advanced demos, you can see and download our FusionCharts Blueprint/Demo Applications.