Combining FusionCharts, ASP & JavaScript (dataXML) method |
In our previous example, we had combined FusionCharts, ASP and JavaScript to create client side dynamic charts. We were updating the chart by asking it to fetch new data from server and update itself, without incurring any page refreshes. In this example, instead of asking the chart to get XML data from server, we'll provide updated XML data to chart using JavaScript functions. The chart will simply accept that XML data and render. This method can effectively be used in your AJAX applications, where your JavaScript code gets the updated XML from server and then provides it to charts locally. You can process the data received from AJAX Calls, build XML from it and finally provide it to the chart. 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 > ASP > DB_JS folder. |
| Defining the applicaton |
|
We'll carry on from our previous "JSP, JavaScript and dataURL" example and convert it to use JavaScript + XML, so that the new XML is provided to the chart using JavaScript functions - the charts NO more directly request data from server. To attain this, we send all the pertinent data from our server to the end viewer as JavaScript arrays in the same page. The JavaScript arrays are dynamically generated by ASP pages at run-time and filled with data. Effectively, we will do the following:
|
| Creating the page - Default.jsp |
| Both the charts and JavaScript functions to manipulate the charts is contained in Default.jsp. It has 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"%> <%@ page import="java.text.SimpleDateFormat"%> <HTML> <HEAD> <TITLE>FusionCharts - Database + JavaScript Example</TITLE> <% /* In this example, we show a combination of database + JavaScript rendering using FusionCharts. Before the page is rendered, we need to connect to the database and get the data, as we'll need to convert this data into JavaScript variables. The following string will contain the JS Data and variables. This string will be built in JSP and rendered at run-time as JavaScript. */ String jsVarString = ""; //Initialise Database Objects Statement st1=null,st2=null; ResultSet rs1=null,rs2=null; String strQuery=""; int indexCount = -1; //Create the recordset to retrieve data //We need to create a Scrollable ResultSet so that we can reuse it for creating the chart later st1=oConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); //Create the query strQuery = "select * from Factory_Master"; rs1 = st1.executeQuery(strQuery); String factoryId=null; String factoryName=null; String quantity=""; java.sql.Date date=null; java.util.Date uDate=null; String uDateStr=""; while(rs1.next()) { indexCount += 1; factoryId=rs1.getString("FactoryId"); factoryName=rs1.getString("FactoryName"); //Create JavaScript code to add sub-array to data array //data is an array defined in JavaScript (see below) //We've added \t & \n to data so that if you View Source of the //output HTML, it will appear properly. It helps during debugging jsVarString += "\t\t"+ "data[" + indexCount + "] = new Array();\n" ; //Now create second recordset to get date-wise details for this factory strQuery = "select * from Factory_Output where FactoryId=" +factoryId+ " order by DatePro Asc "; st2=oConn.createStatement(); rs2 = st2.executeQuery(strQuery); while(rs2.next()){ date=rs2.getDate("DatePro"); quantity=rs2.getString("Quantity"); if(date!=null) { uDate=new java.util.Date(date.getTime()); SimpleDateFormat sdf=new SimpleDateFormat("dd/MM"); uDateStr=sdf.format(uDate); } //Put this data into JavaScript as another nested array. //Finally the array would look like data[factoryIndex][i][dataLabel, // dataValue] jsVarString +="\t\t"+"data[" + indexCount + "].push(new Array('" + uDateStr + "'," +quantity+"));" +"\n\r"; } 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"); } } %> <SCRIPT LANGUAGE="Javascript" SRC="../../FusionCharts/FusionCharts.js"> </SCRIPT> <SCRIPT LANGUAGE="JavaScript"> //Here, we use a mix of server side code (jsp) and JavaScript to //render our data for factory chart in JavaScript variables. We'll later //utilize this data to dynamically plot charts. //All our data is stored in the data array. From jsp, we iterate through //each resultset of data and then store it as nested arrays in this data array. var data = new Array(); <% /*Write the data as JavaScript array here. The array code is in our JSP variable. Local JavaScript functions can access it and make use of it. We'll see how to make use of it. */ %> <%=jsVarString%> /** * updateChart method is invoked when the user clicks on a pie slice. * In this method, we get the index of the factory, build the XML data * for that that factory, using data stored in data array, and finally * update the Column Chart. * @param factoryIndex Sequential Index of the factory. * @param factoryName For display purpose */ function updateChart(factoryIndex,factoryName){ //Storage for XML data document var strXML = "<chart palette='2' caption='Factory: " + factoryName + " Output ' subcaption='(In Units)' xAxisName='Date' showValues='1' labelStep='2' >"; //Add <set> elements var i=0; for (i=0; i<data[factoryIndex].length; i++){ strXML = strXML + "<set label='" + data[factoryIndex][i][0] + "' value='" + data[factoryIndex][i][1] + "' />"; } //Closing Chart Element strXML = strXML + "</chart>"; //Get reference to chart object using Dom ID "FactoryDetailed" var chartObj = getChartFromId("FactoryDetailed"); //Update it's XML chartObj.setDataXML(strXML); } </SCRIPT> </HEAD> <BODY> <% //Initialize the Pie chart with sum of production for each of the factories //strXML will be used to store the entire XML document generated String strXML =""; String totalOutput=""; //Re-initialize Index indexCount=-1; //Generate the chart element strXML = "<chart caption='Factory Output report' subCaption='By Quantity' pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units' >"; //Move back to first index of the factory master recordset rs1.beforeFirst(); while(rs1.next()){ // Update index count - sequential indexCount = indexCount + 1; 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='..' link='..' /> //Note that we're setting link as updateChart(factoryIndex,factoryName) - JS Function strXML += "<set label='" +factoryName+ "' value='" +totalOutput+"' link='javaScript:updateChart("+indexCount + ",""+factoryName+"")'/>"; 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 String chartCode= createChart("../../FusionCharts/Pie3D.swf", "", strXML, "FactorySum", 500, 250, false, false); %> <%=chartCode%> <BR> <% //Column 2D Chart with changed "No data to display" message //We initialize the chart with <chart></chart> String chartCode2= createChart("../../FusionCharts/Column2D.swf? ChartNoDataText=Please select a factory from pie chart above to view detailed data.", "", "<chart></chart>", "FactoryDetailed", 600, 250, false, false); %> <%=chartCode2%> </BODY> </HTML> |
|
In this page, before rendering any HTML code, we first generate all the data in database as JavaScript array. To do so, we use string concatenation in JSP variables to store all data as JavaScript array code. Once the JavaScript code is built in our JSP variable, we write it out in the <SCRIPT> section of HTML <HEAD>. <SCRIPT LANGUAGE="JavaScript"> If you run this page and view the source JavaScript code, you'll see the following: |
| var data = new Array(); data[1] = new Array(); data[1].push(new Array('1/1',21)); data[1].push(new Array('2/1',23)); data[1].push(new Array('3/1',22)); data[1].push(new Array('4/1',24)); data[1].push(new Array('5/1',32)); data[1].push(new Array('6/1',21)); data[1].push(new Array('7/1',34)); data[1].push(new Array('8/1',32)); data[1].push(new Array('9/1',32)); data[1].push(new Array('10/1',23)); data[1].push(new Array('11/1',23)); data[1].push(new Array('12/1',32)); data[1].push(new Array('13/1',53)); data[1].push(new Array('14/1',23)); data[1].push(new Array('15/1',26)); data[1].push(new Array('16/1',43)); data[1].push(new Array('17/1',16)); data[1].push(new Array('18/1',45)); data[1].push(new Array('19/1',65)); data[1].push(new Array('20/1',54)); data[2] = new Array(); data[2].push(new Array('1/1',121)); data[2].push(new Array('2/1',123)); data[2].push(new Array('3/1',122)); data[2].push(new Array('4/1',124)); data[2].push(new Array('5/1',132)); data[2].push(new Array('6/1',121)); data[2].push(new Array('7/1',134)); data[2].push(new Array('8/1',132)); data[2].push(new Array('9/1',132)); data[2].push(new Array('10/1',123)); data[2].push(new Array('11/1',123)); data[2].push(new Array('12/1',132)); data[2].push(new Array('13/1',153)); data[2].push(new Array('14/1',123)); data[2].push(new Array('15/1',126)); data[2].push(new Array('16/1',143)); data[2].push(new Array('17/1',116)); data[2].push(new Array('18/1',145)); data[2].push(new Array('19/1',165)); data[2].push(new Array('20/1',154)); data[3] = new Array(); data[3].push(new Array('1/1',54)); data[3].push(new Array('2/1',56)); data[3].push(new Array('3/1',89)); data[3].push(new Array('4/1',56)); data[3].push(new Array('5/1',98)); data[3].push(new Array('6/1',76)); data[3].push(new Array('7/1',65)); data[3].push(new Array('8/1',45)); data[3].push(new Array('9/1',75)); data[3].push(new Array('10/1',54)); data[3].push(new Array('11/1',75)); data[3].push(new Array('12/1',76)); data[3].push(new Array('13/1',34)); data[3].push(new Array('14/1',97)); data[3].push(new Array('15/1',55)); data[3].push(new Array('16/1',43)); data[3].push(new Array('17/1',16)); data[3].push(new Array('18/1',35)); data[3].push(new Array('19/1',78)); data[3].push(new Array('20/1',75)); |
|
You can clearly see that our JSP code has outputted JavaScript code that can now locally create an array and feed it with requisite data. Now, 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+"' We now render the Pie 3D chart using dataXML method. The Pie 3D chart has its DOM Id as FactorySum: String chartCode= createChart("../../FusionCharts/Pie3D.swf", "", <%=chartCode%> 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. String chartCode2= createChart("../../FusionCharts/Column2D.swf? <%=chartCode2%> Effectively, our page is now set to show two charts. The pie chart shows the summary data provided to it using dataXML method. 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){ //Storage for XML data document var strXML = "<chart palette='2' caption='Factory " + factoryIndex + " Output ' subcaption='(In Units)' xAxisName='Date' showValues='1' labelStep='2' >"; //Add <set> elements var i=0; for (i=0; i<data[factoryIndex].length; i++){ strXML = strXML + "<set label='" + data[factoryIndex][i][0] + "' value='" + data[factoryIndex][i][1] + "' />"; } //Closing Chart Element strXML = strXML + "</chart>"; //Get reference to chart object using Dom ID "FactoryDetailed" var chartObj = getChartFromId("FactoryDetailed"); //Update it's XML chartObj.setDataXML(strXML); } |
Here,
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. |