|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /home/queenjbs/www/FusionChart/Contents/Code/J2EE/ |
Upload File : |
<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Combining FusionCharts XT, JSP and JavaScript (dataUrl) method</title>
<link rel="stylesheet" href="../../assets/ui/css/style.css" type="text/css" />
<script type="text/javascript" src="../../assets/prettify/prettify.js"></script>
<link rel="stylesheet" type="text/css" href="../../assets/prettify/prettify.css" />
<script type="text/javascript" src="../../assets/ui/js/jquery.min.js" ></script>
<style type="text/css">
<!--
div.WebHelpPopupMenu { position:absolute;
left:0px;
top:0px;
z-index:4;
visibility:hidden; }
a.whtbtnhide, a.whtbtnshow, a.whtbtnhidenav , a.whtbtnshownav { border-bottom:none !important; }
-->
</style>
<script type="text/javascript" language="javascript1.2" src="../../assets/ui/js/whmsg.js"></script>
<script type="text/javascript" language="javascript" src="../../assets/ui/js/whver.js"></script>
<script type="text/javascript" language="javascript1.2" src="../../assets/ui/js/whproxy.js"></script>
<script type="text/javascript" language="javascript1.2" src="../../assets/ui/js/whutils.js"></script>
<script type="text/javascript" language="javascript1.2" src="../../assets/ui/js/whlang.js"></script>
<script type="text/javascript" language="javascript1.2" src="../../assets/ui/js/whtopic.js"></script>
<script type="text/javascript" src="../../assets/ui/js/lib.js"></script>
</head>
<body>
<!-- breadcrumb starts here -->
<div id="breadcrumb"></div>
<script type="text/javascript">
document.write( addFCBreadcrumb( [ "Home|../../Introduction/Overview.html", "Guide for web developers", "Using with J2EE|JSP_GettingStarted.html", "J2EE and JavaScript (Data URL) method" ] ) );
</script>
<!-- breadcrumb ends here -->
<table width="98%" border="0" cellspacing="0" cellpadding="3" align="center">
<tr>
<td class="pageHeader">Combining FusionCharts XT, JSP and JavaScript (Data URL) method</td>
</tr>
<tr>
<td valign="top" class="text"><p>FusionCharts XT offers tremendous integration capabilities with JavaScript. You can easily use FusionCharts XT and JavaScript to create client side dynamic charts. </p>
<p>Here, we will 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.</p>
<p><strong>Before you proceed with the contents in this page, we strictly recommend you to please go through the sections <a href="../../guide-for-web-developers/how-fusioncharts-works/HowFCWorks.html">How FusionCharts XT works?</a> and <a href="JSP_BasicExample.html">Basic Examples</a>, as we will directly use a lot of concepts defined in those sections.</strong></p>
<p class="highlightBlock">The code discussed in this example is present
in<span class="codeInline"> Download Package > Code > J2EE > DB_JS_dataURL
</span>folder. </p>
</td>
</tr>
<tr>
<td valign="top" class="header">Mission for this example </td>
</tr>
<tr>
<td valign="top" class="text"><p>Let us first define what we want to achieve in this example. We will 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. </p>
<p>In this example, we will assimilate both the charts in a single page and make them interact with each other using JavaScript, thereby, smoothening the end-user experience. This is done by:</p>
<ol>
<li>Containing both the pie chart (summary) and the column chart (detailed) in one page (<span class="codeInline">Default.jsp</span>).</li>
<li>Configuring the pie chart to use the <span class="codeInline">Data String </span> method to show the summary of all factories when the page loads. This data will be built in the bean <span class="codeInline">FactoriesBean</span>. </li>
<li>Customizing the "<span class="codeInline">No data to display</span>" message of the chart to show a friendly message. This message is required because the column chart will initialize with no data, as, initially, the user does not select a factory. The column chart will initialize with no data, as the user has not selected a factory initially. </li>
<li>Define the JavaScript links for each pie slice. These JavaScript links refer to the <span class="codeInline">updateChart()</span> JavaScript function present on the same page. We will later see how to manually code this function. When a pie slice is clicked, the <span class="codeInline">factory ID</span> is passed to this function.</li>
<li>Update the column chart using the <span class="codeInline"> updateChart()</span> function. It generates a dataURL link by including the <span class="codeInline">factoryId </span> as a part of dataURL (<span class="codeInline">FactoryData.jsp</span>). <span class="codeInline">FactoryData.aspx </span> is the data provider page for the detailed column chart. Once the <span class="codeInline">dataURL </span> is built, it conveys this dataURL to the column chart. The column chart now accepts this <span class="codeInline">dataURL</span>, sends a request to <span class="codeInline">FactoryData.jsp </span> for XML data, accepts it, parses it and finally gets rendered. The column chart now accepts this <span class="codeInline">dataURL</span>,
sends a request to <span class="codeInline">FactoryData.jsp</span> for
XML data, accepts it, parses it and finally gets rendered.</li>
</ol> </td>
</tr>
<tr>
<td valign="top" class="text"> </td>
</tr>
<tr>
<td valign="top" class="header">Creating the charts container page </td>
</tr>
<tr>
<td valign="top" class="text">
<p>Both the charts and JavaScript functions to
manipulate the charts is contained in <span class="codeInline">Default.jsp</span>.
It has the following code: </p>
</td>
</tr>
<tr>
<td valign="top" class="text"><pre class="code_container prettyprint"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags"%>
<%@ taglib uri="http://www.fusioncharts.com/jsp/core" prefix="fc"%>
<jsp:useBean id="factoriesBean"
class="com.fusioncharts.sampledata.FactoriesBean" />
<jsp:useBean id="chart2Data"
class="com.fusioncharts.sampledata.EmptyRenderData" />
<c:set var="folderPath" value="../../FusionCharts/" />
<c:set var="title" value="FusionCharts - Database + JavaScript Example"
scope="request" />
<c:set var="header1"
value="FusionCharts Database + JavaScript (dataURL method) Example"
scope="request" />
<c:set var="header2"
value="Inter-connected charts - Click on any pie slice to see detailed
chart below."
scope="request" />
<c:set var="intro"
value="The charts in this page have been dynamically generated using
data contained in a database."
scope="request" />
<c:set var="jsPath" value="../../FusionCharts/FusionCharts.js"
scope="request" />
<span class="codeComment"><!--
In this example, we show a combination of database + JavaScript (Data URL method)
rendering using FusionCharts XT.
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 will show detailed date-wise
output of that factory. The detailed data will 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.
--> </span>
<tags:template2>
<SCRIPT LANGUAGE="JavaScript">
<span class="codeComment">/**
* the 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.
*/</span>
function updateChart(factoryIndex) {
<span class="codeComment">//DataURL for the chart</span>
var strURL = "FactoryData.jsp?factoryId=" + factoryIndex;
<span class="codeComment">//Sometimes, the above URL and XML data gets cached by the browser.</span>
<span class="codeComment">//If you want your charts to get new XML data on each request,
//you can add the following line:</span>
//strURL = strURL + "&currTime=" + getTimeForURL();
<span class="codeComment">//the 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.</span>
<span class="codeComment"> //Get reference to chart object using Dom ID "FactoryDetailed"</span>
var chartObj = FusionCharts('FactoryDetailed');
<span class="codeComment">//Send request for XML</span>
chartObj.setXMLUrl(strURL);
}
<span class="codeComment">/**
* the getTimeForURL method returns the current time
* in a URL friendly format, so that it can be appended to
* dataURL for effective non-caching.
*/</span>
function getTimeForURL() {
var dt = new Date();
var strOutput = "";
strOutput = dt.getHours() + "_" + dt.getMinutes() + "_"
+ dt.getSeconds() + "_" + dt.getMilliseconds();
return strOutput;
}
</SCRIPT>
<span class="codeComment"><!-- Create the chart - Pie 3D Chart with data contained in bean --></span>
<fc:render chartId="${factoriesBean.chartId}"
swfFilename="${folderPath}${factoriesBean.filename}"
width="${factoriesBean.width}" height="${factoriesBean.height}"
debugMode="false" xmlData="${factoriesBean.xml}" />
<span class="codeComment"><!--
Column 2D Chart with changed "No data to display" message
We initialize the chart with <chart></chart>
--></span>
<fc:render chartId="${chart2Data.chartId}"
swfFilename="${folderPath}${chart2Data.filename}${chart2Data.noDataParameter}"
width="${chart2Data.width}" height="${chart2Data.height}"
debugMode="false" registerWithJS="true" xmlData="${chart2Data.xml}" />
</tags:template2></pre> </td>
</tr>
<tr>
<td valign="top" class="text">
<p>Dissecting the code in this page, we see that, </p>
<ul>
<li>This page uses template2 tag file and provides the path to the js file to it via the variable jsPath. </li>
<li>Then there are the JavaScript functions, which we will discuss in a while. </li>
<li>Finally, the two charts are rendered in the page using the <span class="codeInline">fc:render</span> tag. <br />
The data for the first chart is obtained from <span class="codeInline">FactoriesBean</span> and the second chart uses the <span class="codeInline">EmptyRenderData</span> bean. <br />
The data for the second chart will be provided dynamically on clicking on the pie slice in the first chart. </li>
</ul>
</td></tr>
<tr>
<td valign="top" class="text"> </td></tr>
<tr>
<td class="header">First Chart</td></tr>
<tr>
<td valign="top" class="text">
<p>The Pie 3D chart is created using Data String method. The Pie 3D chart has its DOM ID as <span class="codeInline">FactorySum</span> defined in the <span class="codeInline">FactoriesBean</span>:</p>
<pre class="code_container prettyprint">protected String chartId="FactorySum";</pre>
<p>Leaving aside the usual render tag, we will directly jump to the code in the bean used to construct the XML. This is similar to the one we saw in the drill-down example, only the link will be different this time.</p>
<pre class="code_container prettyprint">private String getFactoryXML(){
<span class="codeComment">//strXML will be used to store the entire XML document generated</span>
String strXML="";
try{
DBConnection dbConn = new DBConnection();
Connection oConn= dbConn.getConnection();
<span class="codeComment"> //Database Objects - Initialization </span>
Statement st1=null,st2=null;
ResultSet rs1=null,rs2=null;
String strQuery="";
Map<String,String> chartAttributes=new HashMap<String, String>();;
chartAttributes.put("caption", "Factory Output report");
chartAttributes.put("subCaption", "By Quantity");
chartAttributes.put("pieSliceDepth", "30");
chartAttributes.put("showBorder", "1");
chartAttributes.put("formatNumberScale", "0");
chartAttributes.put("numberSuffix", " Units");
DOMHelper domHelper = new DOMHelper();
Document chartDoc = domHelper.getDocument();
Element rootElement = chartDoc.createElement("chart");
domHelper.addAttributesToElement(rootElement, chartAttributes);
<span class="codeComment"> //Iterate through each factory </span>
strQuery = "select * from Factory_Master";
st1=oConn.createStatement();
rs1=st1.executeQuery(strQuery);
String factoryId=null;
String factoryName=null;
String totalOutput="";
while(rs1.next()) {
totalOutput="";
factoryId=rs1.getString("FactoryId");
factoryName=rs1.getString("FactoryName");
<span class="codeComment">//Now create second recordset to get details for this factory </span>
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");
}
<span class="codeComment"> //Generate <set label='..' value='..'/> </span>
Element setElem = chartDoc.createElement("set");
setElem.setAttribute("label", factoryName);
setElem.setAttribute("value", totalOutput);
<strong> setElem.setAttribute("link", "javaScript:updateChart("+factoryId + ")");</strong>
rootElement.appendChild(setElem);
<span class="codeComment"> //close the resultset,statement
//enclose them in try catch block
//code omitted here
</span> }
<span class="codeComment"> //Finally, close <chart> element </span>
chartDoc.appendChild(rootElement);
strXML=domHelper.getXMLString(chartDoc);
<span class="codeComment"> //close the resultset,statement,connection
//enclose them in try catch block
//code omitted here
</span> }catch(java.sql.SQLException e){
System.out.println("Could not close the statement");
}
return strXML;
}</pre>
<p class="text">We have provided the link to the updateChart JavaScript function with the factoryId as the parameter. Since we are using DOM to create the XML, our code for this turns out to be: </p>
<pre class="code_container prettyprint"><strong>setElem.setAttribute("link", "javaScript:updateChart("+factoryId + ")");</strong> </pre>
</td></tr>
<tr>
<td valign="top" class="text"> </td></tr>
<tr>
<td class="header">Drill-down Chart</td></tr>
<tr>
<td valign="top" class="text">
<p>The chart obtained on drilling-down is present in the same page, Default.jsp. The data to this chart is obtained from the JavaScript function updateChart (which in turn contacts FactoryData.jsp for detailed data for the factory). </p>
<p>We first create the XML data document for Pie chart - summary of factory output. For each <span class="codeInline"><set></span>, we provide a JavaScript link to the <span class="codeInline">updateChart()</span> function and pass the factory ID to it as shown in the line below:</p>
<p class="text">For the second chart, we render an empty Column 2D chart with <span class="codeInline"><chart></chart></span> data initially. We also change the "<span class="codeInline">No data to display.</span>" error to a friendly and intuitive "<span class="codeInline">Please select a factory from pie chart above to view detailed data.</span>" This chart has its DOM Id as <span class="codeInline">FactoryDetailed</span>. (in EmptyRenderData.java) </p>
<pre class="code_container prettyprint">protected String chartId="FactoryDetailed";</pre>
<p class="text">This chart has to be registered with JavaScript since it obtains its data through JavaScript. This can be done by setting the <span class="codeInline">registerWithJS</span> attribute to true as shown:</p>
<pre class="code_container prettyprint"><fc:render chartId="${chart2Data.chartId}"
swfFilename="${folderPath}${chart2Data.filename}${chart2Data.noDataParameter}"
width="${chart2Data.width}" height="${chart2Data.height}"
debugMode="false" <strong>registerWithJS="true"</strong> xmlData="${chart2Data.xml}" /></pre>
<p> 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 <span class="codeInline">updateChart()</span> JavaScript
function is called and the <span class="codeInline">factoryID</span> of
the pie is passed to it. This function is responsible for updating the
column chart and contains the following code: </p>
</td>
</tr>
<tr>
<td valign="top" class="text"><pre class="code_container prettyprint"><strong>function updateChart(factoryIndex){ </strong>
<span class="codeComment">//DataURL for the chart</span>
var strURL = "FactoryData.jsp?factoryId="
+ factoryIndex;
<span class="codeComment">//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.</span>
<span class="codeComment"> //Get reference to chart object using Dom ID "FactoryDetailed"</span>
var chartObj = FusionCharts("FactoryDetailed");
<span class="codeComment">//Send request for XML</span>
<strong>chartObj.setXMLUrl(strURL);</strong>
} </pre></td>
</tr>
<tr>
<td valign="top" class="text"><p>Here, </p>
<ol>
<li>We first create a <span class="codeInline">dataURL</span> string by
appending the <span class="codeInline">factoryID</span> to <span class="codeInline">FactoryData.jsp</span>. </li>
<li>Finally, we convey this <span class="codeInline">dataURL</span> to
the column chart. To do so, we first get a reference to the column chart
using its DOM Id <span class="codeInline">FactoryDetailed</span>. We
use the function defined
for FusionCharts object <span class="codeInline"></span> to do so. </li>
<li>Once we have the reference to the chart, we simply call the <span class="codeInline">setXMLUrl</span> method of the chart and pass it the URL to request data from. </li>
<li>This updates the chart with new data. </li>
</ol>
<p>This completes our front-end for the chart. We just need to build <span class="codeInline">FactoryData.jsp</span>
page, which is responsible to provide detailed data to column chart. It
contains the following code: </p>
</td>
</tr>
<tr>
<td valign="top" class="text"><pre class="code_container prettyprint"><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<jsp:useBean id="detailsBean"
class="com.fusioncharts.sampledata.FactoryDetailsBean" />
<strong><c:set target="${pageContext.response}" property="contentType" value="text/xml"/>
<c:set target="${detailsBean}" property="factoryId" value="${param.factoryId}"/>
<c:out value="${detailsBean.xml}" escapeXml="false"/></strong></pre></td>
</tr>
<tr>
<td valign="top" class="text"><p>In this page, we basically request the factory ID passed to it as querystring, set it to the bean <span class="codeInline">FactoryDetailsBean</span>, obtain the XMl from the bean and finally write it to output stream. </p>
<p>The construction of the XML in the bean is done every time the <span class="codeInline">setFactoryId</span> method is called. The code for building the XML for the given <span class="codeInline">factoryId</span> is shown below: (<span class="codeInline">getFactoryDetailsXML(String factoryId)</span>) </p>
<pre class="code_container prettyprint"><span class="codeComment">//strXML will be used to store the entire XML document generated</span>
String strXML="";
try{
DBConnection dbConn = new DBConnection();
Connection oConn= dbConn.getConnection();
<span class="codeComment"> //Database Objects - Initialization</span>
Statement st=null;
ResultSet rs=null;
java.sql.Date date=null;
java.util.Date uDate=null;
String uDateStr="";
String quantity="";
String strQuery="";
Map<String,String> chartAttributes=new HashMap<String, String>();
chartAttributes.put("caption", "Factory "+factoryId+" Output");
chartAttributes.put("subCaption", "(In Units)");
chartAttributes.put("xAxisName", "Date");
chartAttributes.put("showValues", "1");
chartAttributes.put("labelStep", "2");
chartAttributes.put("palette", "2");
DOMHelper domHelper = new DOMHelper();
Document chartDoc = domHelper.getDocument();
<strong> Element rootElement = chartDoc.createElement("chart");
domHelper.addAttributesToElement(rootElement, chartAttributes);</strong>
//Now, we get the data for that factory
<strong> strQuery = "select * from Factory_Output where FactoryId=" + factoryId+ " order by DatePro Asc ";</strong>
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);
}
//Generate <set label='..' value='..'/>
<strong> Element setElem = chartDoc.createElement("set");
setElem.setAttribute("label", uDateStr);
setElem.setAttribute("value", quantity);
rootElement.appendChild(setElem);</strong>
}
//Finally, close <chart> element
chartDoc.appendChild(rootElement);
strXML=domHelper.getXMLString(chartDoc);
//close the resultset,statement,connection
//enclose them in try catch block
// code omitted here
}catch(java.sql.SQLException e){
System.out.println("Could not close the statement");
}
return strXML;
} </pre>
<p class="text">Notice that we have used DOM to create the XML here. </p>
<p class="text">We iterate through each record in the table <span class="codeInline">Factory_Output</span> for the factory with the given <span class="codeInline">factoryId</span>. The output details are then appended to the XML. </p>
<p>When you now see the application, the initial state will look as under: </p>
<p><img src="../../guide-for-web-developers/Images/Code_JS_URL_Ini.jpg" width="511" height="458" class="imageBorder" /></p>
<p>And when you click a pie slice, the following will appear on the same page (without any browser refreshes): </p>
<p><img src="../../guide-for-web-developers/Images/Code_JS_URL_Fin.jpg" class="imageBorder" /></p>
<p>This example demonstrated a very basic sample of the integration capabilities possible with FusionCharts XT.</p> </td>
</tr>
</table>
<!-- footer links starts-->
<div id="fcfooter"></div>
<script type="text/javascript">
document.getElementById("fcfooter").innerHTML = addFCFooter("Creating Drill down charts|JSP_Drill.html","J2EE, JavaScript & dataStr|JSP_JS_XML.html");
</script>
<!-- footer links ends -->
<script type="text/javascript" language="javascript1.2">//<![CDATA[
<!--
highlightSearch();
//-->
//]]></script>
</body>
</html>