The Spotfire Community is moving to TIBCOmmunity and this forum location has closed. During the transition, you can still search the old forums but posting has been disabled. We encourage you to pick up the discussion at the new Spotfire community on TIBCOmmunity.
Use the TIBCO Spotfire S+ Server C# API to Develop an ASP.NET Web Application - Knowledge Base

TIBCO Spotfire Community

Welcome to TIBCO Spotfire Community Sign in | Join | Help

Use the TIBCO Spotfire S+ Server C# API to Develop an ASP.NET Web Application

This article targets: TIBCO Spotfire S+® Server 8.1 and forward                DemographicsStepByStep_CSharpAPI.zip

The TIBCO Spotfire S+ Server includes Java and C# APIs for easy integration of computational analytics into any application. In this article, we discuss developing a simple ASP.NET Web application using the C# API.

  • This article is meant for C# programmers familiar with ASP.NET programming. For more information about developing for the Spotfire S+ Server, see the TIBCO Spotfire S+ Server User's Guide and the TIBCO Spotfire S+ Server C# API reference.

    For more detailed information about each step described below. see its corresponding .txt file in the /docs directory of the downloaded tutorial source.

Overview

The architecture of the TIBCO Spotfire S+ Server conforms to standard service oriented architecture (SOA) design patterns. It provides several computational and administrative services that rely on open communication and data interchange protocols (that is, XML over HTTP). The service oriented architecture of the Spotfire S+ Server enables rapid integration of loosely-coupled systems and applications. Additionally, the Java and C# APIs handle the lower level HTTP communication and XML handling tasks so the developer can focus on building business applications that leverage the powerful computational services the Spotfire S+ Server provides.

In this article, we build a Web application that uses the Spotfire S+ Server Expression Client. Using the application, we can develop and submit S-PLUS® expressions on-the-fly, in contrast with the Function Client (where we predefine, prepackage, and pre-deploy functions to the Spotfire S+ Server). For most implementations, we recommend using the Function Client for its ability to encapsulate Spotfire S+ code and to provide separation from client code. However, to simplify this tutorial, we use the Expression Client to reduce the deployment steps by submitting the Spotfire S+ code in-line.

As with any Web application architecture, the client browser communicates with the Web application server (in this case, Microsoft® IIS) via HTTP. The client makes HTTP requests, and the application server renders its response as HTML. Then the Web application server communicates with TIBCO Spotfire S+ Server by making HTTP requests containing XML, and the Spotfire S+ Server renders its response as XML.

Getting Started

Prerequisites:

  • Familiarity with building ASP.NET Web applications in C#.
  • Microsoft Visual Studio® 2008 (including Visual Web Developer, Express Edition, Developer Edition, and higher).
  • Spotfire S+ Server C# API .DLLs - Download these as a .zip file from your Spotfire S+ Server landing page for example, http://<servername:port>/SplusServer). 
  • Spotfire S+ Graphlet® Viewer .jar - Find this .jar file at SHOME\library\winspj (where SHOME is your Spotfire S+ installation directory), or you can download it from
    http://www.insightful.com/products/graphlets/gallery/graphlet_info.asp
  • Spotfire S+ Server C# API Reference - Download this .chm help format file from your Spotfire S+ Server landing page.
  • Sample source code.

Each step in the tutorial below corresponds with a directory in the source .zip file. For each step, we describe the purpose of the step and highlight the interesting aspects of its development. For more detailed instructions, refer to the documentation included in the source .zip file or the source.

You can start by creating a new ASP.NET Web application and follow the high-level instructions in this tutorial, or you can start by opening the corresponding step's file and exploring the source. Remember to add references to the binaries (.DLLs) listed above when you create or open your ASP.NET solution.

Step 1: Establish a connection to the Spotfire S+ Server and retrieve the current API version.

In the first step, use the Spotfire S+ Server Administration Client to set up a simple connection to the Spotfire S+ Server and test that the environment is configured properly.

  1. Create a three-column table to control the layout.
  2. In the first table row, add a text box to contain the base URL of our Spotfire S+ Server (for example, http://<servername:port>/SplusServer) and a button whose Click event handler calls the Spotfire S+ Server to retrieve the current API version.
  3. In the second table row, add a text box to contain the result of the GetServerVersion call.
  4. Add the following to the list of imports:
    using Tibco.SplusServer.Api;
    using Tibco.SplusServer.Api.Administration; 

    and create the Click event handler for ButtonGetServerVersion:

    IAdministrationClient adminClient = ClientFactory.GetAdministrationClient(TextBoxServerName.Text);
    string serverVersion = adminClient.GetServerVersion();
    TextBoxServerVersion.Text = serverVersion;
  5. When you run the Web application, click the button to retrieve the Spotfire S+ Server API version, and the server should return the version: v8.


Step 2: Call an S-PLUS expression and retrieve the result.

In the second step, use the Spotfire S+ Server Expression Client to retrieve the list of columns from the included state.x77 data set. The resulting list of columns are the Demographics criteria used in a later step.

  1. In the third table row, add a button to initiate the Spotfire S+ Expression Client Eval call.
  2. In the fourth table row, add a drop-down list box, which is populated with the results of the Eval call.
  3. Amend the list of imports:
    using Tibco.SplusServer.Api.Domain;
    using Tibco.SplusServer.Api.Expression;
  4. Create the Click event handler for ButtonGetDemographicsCriteria:
    //obtain an instance of a client to execute an S-PLUS expression.
    IExpressionClient expressionClient = ClientFactory.GetExpressionClient 
       (TextBoxServerName.Text);
    
    //evaluate an expression to obtain the IDs of the columns in the built 
    //in the data set called state.x77.
    //one of these values must be specified to produce the graphs later.
    SplusDataRequest request = null;
    SplusDataResult res = expressionClient.Eval("colIds(state.x77)", false, request);
    
         //check if a function evaluated successfully
         if ((res.Status == SplusStatus.Done) &&
             !res.HasError &&
             res.HasReturnValue)
         {
             DropDownListDemographicsCriteria.Enabled = true;
             // Next, extract the demographic criteria, returned as a vector object
             string[] items = ((Vector)res.ReturnValue.SplusValue.Value[0]).StringItems;
             foreach(string item in items) 
             {              DropDownListDemographicsCriteria.Items.Add(new ListItem(item));          }      }      else      {          //otherwise throw an exception          throw new Exception("Unable to call the server due to error: " + res.Error);      }
  5. When you run the Web application, click the button to retrieve the Demographics criteria. The server should populate the drop-down list box.

Step 3: Generate an S+ graph based on user-selected parameter and predefined data.

Again, use the Spotfire S+ Server Expression Client. This time, submit an expression that defines an S-PLUS function statesStatsPlot, and then call the function with a column name as a parameter. This generates a graph based on the Demographics criterion chosen by the user.

  1. In the last table row, add a button to initiate the Spotfire S+ Server Expression Client Eval call.
  2. Add an image control after the table to contain the results of the S-PLUS function.
  3. Create the Click event handler for ButtonGetGraph:
    // Only generate graphic if a demographic criteria is selected
    if (!DropDownListDemographicsCriteria.SelectedValue.Equals("null"))
    {
      // Set url of the generated graphic
      imgGraph.ImageUrl = GetStatesPlot(DropDownListDemographicsCriteria.SelectedValue);
      // Make graphic visible
      imgGraph.Visible = true; }
  4. Add a utility method to execute the S-PLUS function:
    private String GetStatesPlot(String variable)
    {
        StringBuilder plotUrl = new StringBuilder();
    
        IExpressionClient api = ClientFactory.GetExpressionClient(TextBoxServerName.Text);
    
        // Executes a script that:
        // - invokes an eval() built-in S-PLUS function to define a new     //   function called statesStatsPlot.       // - calls the newly defined statesStatsPlot function to generate a     // .jpg image.     // The function takes variable argument that determines the column in      // the data set to use when generating a graph, a file name for the     // generated graph, and an output type (either .spj, .jpg, or .pdf).     SplusDataResult res = api.Eval(         String.Format("eval({0});statesStatsPlot(\"{1}\",\"{2}\", \"{3}\")",             statesStatsPlotSplusFunction, variable, "statesStats.jpg", "jpg"),              false);     if (res.Status == SplusStatus.Done && !res.HasError)     {         // The function executed without errors. Generate the URL for the          // graphic by appending graphic name to the results directory where          // the graphic is produced.         plotUrl.Append(res.ResultsDir).Append("statesStats.jpg");     }     else      {         // The function executed but produced S-PLUS errors.         // Both the error and text output might contain useful information.         throw new Exception("Expression executed but produced S-PLUS error: " + res.Error);     }     return plotUrl.ToString();     }
  5. Create a string constant to store the contents of the S-PLUS function definition, as described in the detailed documentation for Step 3 in the source .zip file.
  6. Run the Web application, click the button to retrieve the Demographics criteria, and then choose the column Spotfire S+ should use to generate the graph.
  7. Click the button to create the graph, and the Server should return an image of a map, color-coded by the chosen Demographics criterion.

Step 4: Add an option for the user to select the graph display format.

In the fourth step, add the option choosing the graph format (that is, .jpg, .spj, or .pdf). The S-PLUS function defined in Step 3 already accepts the graph output format as a parameter. Add the code in the ASP.NET code to support displaying multiple file formats.

  1. Add some radio controls to select the graph output format and a literal text control to contain the text of the applet or object embeds for the .spj and .pdf viewers, respectively.

    The Spotfire S+ interactive graphlet (.spj) file displays in a Java applet.

    NOTE The Web application server and the Spotfire S+ Server might not be on the same server, and the browser can prohibit a client-side applet from reading a file on a different server than the Web application server. To work around these cross-domain security problems, create a server-side Web handler to proxy files from the Spotfire S+ Server to the Web application server. Specifically, add a server-side Web handler and override the ProcessRequest method:
    string fileToProxy = context.Request.QueryString["fileToProxy"];
    context.Response.ContentType = "text/plain";
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(fileToProxy);
    Stream responseStream = request.GetResponse().GetResponseStream();
    byte[] buffer = new byte[1000];
    int bytesRead;
    while ((bytesRead = responseStream.Read(buffer, 0, 1000)) > 0)
    {
        context.Response.OutputStream.Write(buffer, 0, bytesRead);
    }
    context.Response.OutputStream.Close();
  2. Modify the GetStatesPlot method to accept different graph file formats.
  3. Modify the ButtonGetGraph's Click event handler to pass along the file format whose radio button the user selects. (Refer to the detailed documentation for Step 4 in the source .zip file.)
  4. Run the Web application, click the button to retrieve the Demographics criteria, and then choose the column Spotfire S+ should use to generate the graph.
  5. Choose the graph file format, and then click the button to create the graph. The Server should return the map image in the format requested.

Step 5: Add data editing capabilities, and then post the updated data.

In the final step, add code to allow the user to edit the small data set locally in the browser, and then submit the modified data to the S-PLUS function to generate an updated graph.

  1. Instead of using the built-in state.x77 data set, modify the S-PLUS function to accept a custom data set, as described in the detailed documentation for Step 5 in the source .zip file.
  2. Add a button to allow the user to edit the data. When the user clicks the button, the Web application displays a grid view of the data, which is populated by the GetDataSet method on a new DataSourceStates class. The DataSourceStates.Update method handles updating the underlying data representation.
  3. Modify the GetStatesPlot method to pass in a SplusDataRequest object containing the updated data set:

    SplusDataResult res = api.Eval(
        String.Format("eval({0});statesStatsPlot(\"{1}\",\"{2}\", \"{3}\", {4})",
          statesStatsPlotSplusFunction, variable, fileName, outputType, "statesSet"),
          false, new SplusDataRequest(new Argument("statesSet", new Splus(new DisplayOptions(),
          new Header(), matrix))));
  4. Run the Web application, click the button to retrieve the Demographics criteria, and then choose the column S-PLUS should use to generate the graph.
  5. Choose the graph file format, and then click the button to create the graph. The server should return the map image in the format requested.
  6. Edit some of the values in the data table, and then click the button to create the graph. The server should generate a new map image that reflects the data changes.

Comments