In this example, we will see how to provide updated XML data to chart using JavaScript functions. The chart will simply accept that XML data and then 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 "Plotting from Database Example", 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 > VBNET > DB_JS folder.

 
Defining the applicaton

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 will put both the charts together on a single page where clicking on a pie slice of the Production Summary chart will open the detailed chart on the same page without page refresh.

  1. Contain both the pie chart (summary) and column chart (detailed) in one page (Default.aspx).
  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.aspx itself.
  3. There will be a JavaScript array named as data in this page. This array will contain detailed data for the factories. The array will be dynamically built using ASP.NET and then outputted as JavaScript code.
  4. Apart from the data in JavaScript, we'll also have a local JavaScript function updateChart(), which would process the data in this array and convert it to XML data document, for direct usage by the column chart.
  5. 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.
  6. 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.
  7. The updateChart() function is responsible for udapting the column chart. It generates the XML data from data stored in JavaScript data array and conveys it to the column chart.
  8. The column chart would now accept this XML data, parse it and finally render.
 
Creating the page - Default.aspx
Both the charts and JavaScript functions to manipulate the charts is contained in Default.aspx. It has the following code:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="DB_JS_Default" %>

<HTML>
  <HEAD>
    <TITLE>
      FusionCharts Free - Client Side Dynamic Chart ( using Database) Example
    </TITLE>

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

    <SCRIPT LANGUAGE="JavaScript" >
      //Here, we use a mix of server side script (ASP.NET) 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 ASP.NET, we iterate through
      //each recordset of data and then store it as nested arrays in this data array.

      var data = new Array();

      //Write the data as JavaScript variables here
      <%=jsVarString%>


      //The data is now present as arrays in JavaScript. Local JavaScript functions
      //can access it and make use of it. We'll see how to make use of it.

      /**
      * 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.
      */

      function updateChart(factoryIndex)
      {
        //defining array of colors
        //We also initiate a counter variable to help us cyclically rotate through
        //the array of colors.

        var FC_ColorCounter=0;
        //var arr_FCColors= new Array(20);
        var arr_FCColors= new Array("1941A5" , "AFD8F8", "F6BD0F", "8BBA00", "A66EDD", "F984A1", "CCCC00", "999999", "0099CC", "FF0000", "006F00", "0099FF", "FF66CC", "669966", "7C7CB4", "FF9933", "9900FF", "99FFCC", "CCCCFF", "669900");


        //Storage for XML data document
        var strXML = "<graph caption='Factory " + factoryIndex + " Output ' subcaption='(In Units)' xAxisName='Date' decimalPrecision='0' rotateNames='1' >";

        //Add <set> elements
        var i=0;
        for (i=0; i<data[factoryIndex].length; i++)
       {
          strXML = strXML + "<set name='" + data[factoryIndex][i][0] + "' value='" + data[factoryIndex][i][1] + "' color='"+ arr_FCColors[++FC_ColorCounter % arr_FCColors.length] +"' />";
       }

      //Closing graph Element
      strXML = strXML + "</graph>";

      //Update it's XML
      updateChartXML("FactoryDetailed",strXML);

    }
  </SCRIPT>

  </HEAD>

  <BODY>
   <asp:Literal ID="FCLiteral1" runat="server"></asp:Literal>
   <asp:Literal ID="FCLiteral2" runat="server"></asp:Literal>

  </BODY>

</HTML>



Code in code behind page (Default.aspx.vb file in DB_JS folder):

Imports DataConnection
Imports InfoSoftGlobal


Partial Class DB_JS_Default
   Inherits System.Web.UI.Page
   Public jsVarString As String
   Public indexCount As String

   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

      ' This string will be built in ASP.Net and rendered at run-time as JavaScript
      GetjsVar()
      ' Generate chart in Literal Control
      ' Pie chart with sum of production for each of the factories

      FCLiteral1.Text = CreateChart()
      ' Generate chart in Literal Control
      ' Column 2D Chart with changed "No data to display" message

      FCLiteral2.Text = ShowNextChart()
   End Sub


  
  Public Sub GetjsVar()

  'In this example, we show a combination of database + JavaScript 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 XML data for the pie chart is fully created in ASP.NET at run-time. ASP.NET interacts
  'with the database and creates the XML for this.
  'Now, for the column chart (date-wise output report), we do not submit request to the server.
  'Instead we store the data for the factories in JavaScript arrays. These JavaScript
  'arrays are rendered by our ASP.NET Code (at run-time). We also have a few defined JavaScript
  'functions which react to the click event of pie slice.

  'We've used an Access database which is present in ../DB/FactoryDB.mdb.
  'It just contains two tables, which are linked to each other.

  '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 ASP.NET and rendered at run-time as JavaScript.

  jsVarString = ""

  'Database Objects
  Dim oRs As DbConn, strQuery As String
  indexCount = 0

  'Iterate through each factory
  strQuery = "select * from Factory_Master"
  oRs = New DbConn(strQuery)

  While oRs.ReadData.Read()
    indexCount = indexCount + 1

    'Create JavaScript code to add sub-array to data array
    'data is an array defined in JavaScript (see below)
    'We've added vbTab & vbCRLF to data so that if you View Source of the
    'output HTML, it will appear properly. It helps during debugging

    jsVarString = jsVarString & vbTab & vbTab & "data[" & indexCount & "] = new Array();" & vbCrLf

    'Now create second recordset to get date-wise details for this factory
    strQuery = "select * from Factory_Output where FactoryId=" & oRs.ReadData("FactoryId").ToString() & " order by DatePro Asc" & vbCrLf
    Dim oRs2 As New DbConn(strQuery)
    While oRs2.ReadData.Read()
      'Put this data into JavaScript as another nested array.
      'Finally the array would look like data[factoryIndex][i][dataLabel,dataValue]

      jsVarString = jsVarString & vbTab & vbTab & "data[" & indexCount & "].push(new Array('" & Convert.ToDateTime(oRs2.ReadData("DatePro")).ToString("dd/MM/yyyy") & "'," & oRs2.ReadData("Quantity").ToString() & "));" & vbCrLf

    End While
    'Close recordset
    oRs2.ReadData.Close()

  End While
  oRs.ReadData.Read()

  End Sub

  Public Function CreateChart() As String
    'Initialize the Pie chart with sum of production for each of the factories
    'strXML will be used to store the entire XML document generated

    Dim strXML As String, strQuery As String

    'Re-initialize Index
    indexCount = 0

    'Generate the graph element
    strXML = "<graph caption='Factory Output report' subCaption='By Quantity' decimalPrecision='0' showNames='1' numberSuffix=' Units' pieSliceDepth='20' formatNumberScale='0' >"

    'Iterate through each factory
    strQuery = "select * from Factory_Master"
    Dim oRs As New DbConn(strQuery)

    While oRs.ReadData.Read()
      'Update index count - sequential
      indexCount = indexCount + 1
      'Now create second recordset to get details for this factory
      strQuery = "select sum(Quantity) as TotOutput from Factory_Output where FactoryId=" & oRs.ReadData("FactoryId").ToString()
      Dim oRs2 As New DbConn(strQuery)
      oRs2.ReadData.Read()
      'Generate <set name='..' value='..' link='..' />
      'Note that we are setting link as updateChart(factoryIndex) - JS Function

      strXML = strXML & "<set name='" & oRs.ReadData("FactoryName").ToString() & "' value='" &       oRs2.ReadData("TotOutput").ToString() & "' link='javascript:updateChart(" & indexCount & ")'/>"
      'Close recordset
      oRs2.ReadData.Close()
      oRs2 = Nothing
    End While
    'Finally, close <graph> element
    strXML = strXML & "</graph>"
    oRs.ReadData.Read()
    oRs = Nothing

    'Create the chart - Pie 3D Chart with data from strXML
    Return FusionCharts.RenderChart("../FusionCharts/FCF_Pie3D.swf", "", strXML, "FactorySum", "650", "300", False, True)

  End Function

  Public Function ShowNextChart() As String
    'Column 2D Chart with changed "No data to display" message
    'We initialize the chart with <graph></graph>

    Return FusionCharts.RenderChart("../FusionCharts/FCF_Column2D.swf?ChartNoDataText=Please click on a pie slice above to view detailed data.", "", "<graph></graph>", "FactoryDetailed", "600", "300", False, True)
   End Function

End Class

In this page, before rendering any HTML code, we first fetch all the data in database and sotre it as JavaScript array. To do so, we use string concatenation in ASP.NET variables to store all data as JavaScript array code. Once the JavaScript code is built in our ASP.NET variable, we write it out in the <SCRIPT> section of HTML <HEAD>.

<SCRIPT LANGUAGE="JavaScript" >

var data = new Array();^%^

<%=jsVarString%>

........

</SCRIPT>

Also, the Page_Load event listener calls the GetjsVar() function which creates and intialises all the JavaScript variables.



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 ASP.NET 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 ASP.NET 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 = strXML & "<set name='" & oRs.ReadData("FactoryName").ToString() & "' value='" & oRs2.ReadData("TotOutput").ToString() & "' link='javascript:updateChart(" & indexCount & ")'/>"


  • We now render the Pie 3D chart using dataXML method. The Pie 3D chart has its DOM Id as FactorySum:

    FusionCharts.RenderChart("../FusionCharts/FCF_Pie3D.swf", "", strXML, "FactorySum", "650", "300", False, True)


  • Now, we render an empty Column 2D chart with <graph></graph> 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.

    FusionCharts.RenderChart("../FusionCharts/FCF_Column2D.swf?ChartNoDataText=Please click on a pie slice above to view detailed data.", "", "<graph></graph>", "FactoryDetailed", "600", "300", False, True)

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){
  //defining array of colors
  //We also initiate a counter variable to help us cyclically rotate through
  //the array of colors.

  var FC_ColorCounter=0;
  //var arr_FCColors= new Array(20);
  var arr_FCColors= new Array("1941A5" , "AFD8F8", "F6BD0F", "8BBA00", "A66EDD", "F984A1", "CCCC00", "999999", "0099CC", "FF0000", "006F00", "0099FF", "FF66CC", "669966", "7C7CB4", "FF9933", "9900FF", "99FFCC", "CCCCFF", "669900");


  //Storage for XML data document
  var strXML = "<graph caption='Factory " + factoryIndex + " Output ' subcaption='(In Units)' xAxisName='Date' decimalPrecision='0' rotateNames='1' >";

  //Add <set> elements
  var i=0;
  for (i=0; i<data[factoryIndex].length; i++){
strXML = strXML + "<set name='" + data[factoryIndex][i][0] + "' value='" + data[factoryIndex][i][1] + "' color='"+ arr_FCColors[++FC_ColorCounter % arr_FCColors.length] +"' />";
  }

  //Closing graph Element
  strXML = strXML + "</graph>";

  //Update it's XML
  updateChartXML("FactoryDetailed",strXML);

}

Here,
  1. We first create the XML data document for the column chart by iterating through data contained in our JavaScript data array.
  2. This XML data is stored in strXML.
  3. Thereafter, we convery this XML data and DOM Id FactoryDetailed to updateChartXML() method of the chart.
  4. This updates the chart with new data.

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 Free. For advanced demos, you can see and download our FusionCharts Blueprint/Demo Applications.