TIBCO Spotfire Community

Welcome to TIBCO Spotfire Community Sign in | Join | Help

Customizing TIBCO Spotfire Clinical Graphics

Introduction

TIBCO Spotfire Clinical Graphics (TSCG) is designed with extensibility in mind. You can use the point-and-click client application to create a wide variety of graphs. You can add custom graph types to the New Graph dialog using the Save As Template dialog, specifying graph title, help file, column labels, and potential elements. In most cases, no additional programming is required to meet your users’ graphing needs.

When you need capabilities not available in the TSCG application, you can add functionality using the same techniques that the TSCG developers and consultants used to develop the built-in graphs. Use C# to implement client extensions. Use Spotfire S+, XML, and XSLT to implement engine extensions.

This document provides the technical details on extending the TSCG system. Topics covered include:

  • Graph templates.
  • Graph elements.
  • Custom data selection interfaces.
  • Custom metadata and search.

Prerequisites

Before reading this guide, make sure you have a basic understanding of TSCG's capabilities and architecture.

Good resources include:

  • The TSCG Installation and Administration Guide.
  • The TSCG Graphics Object Model User’s Manual.
  • The TSCG client help files.
  • The TSCG GOM package help files.

Depending on the customization you want to perform, you will need some or all of the following tools:

  • TIBCO Spotfire S+ 8.1.
  • Microsoft Visual C# 2008 (Any edition).

Also, you need read/write access to a working TSCG Server.

How to Use this Article

  1. Explore the problem by asking questions.
  2. Define the problem steps by looking at your options.
  3. Read the details about each problem step involved.
  4. Implement the customization using this guide as a reference.

Questions

To determine what type of customization is needed, answer the following questions:

  • Can you produce the customization using the point-and-click interface available in the Save As Template dialog?
  • Does the customization require a graph template that you cannot create using the Save As Template dialog?
  • Does the customization require a data selection page that you cannot create using the Save As Template dialog?
  • Does the customization require a graph element that does not exist in TSCG?
  • Is the customization another kind of client modification, such as creating a custom metadata interface?

Options

The strategy you use to extend TSCG depends on the type of template you want to implement, what its arguments should be, what its plot elements should be, and whether implementing it affects the user interface.

This section outlines the options available for extending TSCG, along with a short list of basic steps and resources for each. You can use any or all of these options, depending on your template design.

You need a new graph template with different default settings.

  • Create the new graph template using either the Save As Template dialog or C#.

You need a new graph element.

  1. Write the S+ code implementing the graph element, and then expose it on the server.
  2. Write the C# code implementing the user interface for the graph element.
  3. Create a new graph template using the element to expose it in the interface.

You need a new data selection interface.

  1. Create a new data selection interface in C#.
  2. Create and add a new template that uses the data selection interface.

You need different server-side S+ code generation.

  • Modify the S+ configuration file and/or the XSLT used to convert XML to S+ code.

You need customized metadata.

  • Create the custom metadata interface in C#.

Example and Reference Files

The Examples folder distributed with this document contains three sets of files for the "line breaks" example that is discussed in Sections 1 and 2:

  • The ge.linebreaks.ssc file is an S-PLUS script defining a new graph element in the Spotfire S+ engine.
  • The LineBreakDemo folder contains a Visual C# project used to add a new graph element in the TSCG client for the line breaks element.
  • The LineBreakDemoDocumentCreator folder contains a Visual C# project for programmatically generating a new graph document using the line breaks element.

The References folder distributed with this document includes portions of the TSCG client application source code. This code is the basis for various kinds of extensions and customizations:

  • The ObjectModel folder contains a Resources subfolder with text files such as AreaBarDefinition.txt with the XML defining plot element options. Refer to these files when you are defining plot element options, as discussed in Section 1.
  • The ObjectModel folder also contains a Documents subfolder with the DefaultGraphDocuments.cs file defining the default graphs in TSCG. Refer to this file when you are defining new graph documents programmatically, as discussed in Section 2.
  • The DataSelection_MultipleX_MultipleY folder is the starting point for the custom data selection dialogs, as discussed in Section 3.
  • The Metadata_igd and Metadata_igt folders contain the metadata handle code for graph documents and graph templates respectively. These are the starting points for custom metadata as discussed in Section 4.

NOTEThe References files are provided for you convenience, if you are interested in extending TSCG 2.0. Because these files contain actual source code rather than interfaces, you should expect that this code will change in future versions of the product.

 

Section 1: Graph Elements

The LineBreaks example shows how to create a new Spotfire S+ graph element and use it in a graph template.

This example defines a new "line breaks" element that provides more line type options than were available in the previous version of Clinical Graphics. In that release, the "lines" element provided only type arguments for connected lines. The "line breaks" element adds type options for creating lines with breaks between them, specifically stairstep and candlestick lines.

NOTE  Because the stairstep and candlestick line type options now are available in the built-in "lines" element, the "line breaks" element no longer introduces functionality not previously available. Nonetheless, this example is useful to demonstrate the process involved in creating a new graph element.

Creating a Spotfire S+ Graph Element

The following section provides high-level instruction for the process of creating and using a new graph element. For further information, study the Graph Object Model User’s Guide.

A graph element is a Spotfire S+ graph object that you can create using the gom library, included with TSCG.

  1. Load the gom library into Spotfire S+ and make a copy of the most similar graph element (for example, ge.lines).
  2. Write a new graph element script (for example, ge.linebreaks.ssc) to extend the GOM.
  3. Test gom() calls in Spotfire S+ using the new graph element.

    gom(formula=Fuel~Weight, data= fuel.frame,
       groups=~Type, panel=ge.linebreaks)

  4. If you are creating a corresponding graph template programmatically rather than via the Save As Template dialog, save a PNG to use as a thumbnail. You can export this from your test environment within Spotfire S+.

    NOTE  To use the new graph element in the TSCG Spotfire Visualization extension, you might need to modify how the pkIndexIDs parameter is subset. This parameter maps to the original dataset and controls marking on the TSCG Spotfire Visualization. The ids from the pkIndexIDs parameter are placed into the tag for the element. See the example in ge.linebreaks.ssc.

    NOTE  To use the new graph element in the TSCG Spotfire Visualization extension, you might need to modify how the pkIndexIDs parameter is subset. This parameter maps to the original dataset and controls marking on the TSCG Spotfire Visualization. The ids from the pkIndexIDs parameter are placed into the tag for the element. See the example in ge.linebreaks.ssc.

To deploy your graph element to the server, use one of the following two options:

  • Load your script to the server. This method is easier, but it can decrease performance for all graphs and server calls.
  • Create a package containing the new functions and load it on the server. This method results in a better performance; however, it requires the developer to configure his or her computer for building Spotfire S+ packages. (See the Spotfire S+ Guide to Packages for more information.)

To load a script to the server:

  1. Browse to <TSCGHOME> (Your TSCG server installation directory) for the file init-TSCG.ssc. Check to make sure that it loads scripts. If it does not, add the following code.

      You might have to change the user.scripts.dir

    # load all *.ssc files from the local folder in alphabetic order
    user.scripts.dir <- "C:\\Program Files\\TIBCO\\tscg20\\local
      "user.scripts <- files.in.dir(user.scripts.dir)[grep(".ssc", 
      files.in.dir(user.scripts.dir))]
      sorted.user.scripts <- sort(user.scripts)
       sorted.user.scripts <- 
      sorted.user.scripts[order(toupper(sorted.user.scripts))]
     for (user.script in sorted.user.scripts)
       source(paste(user.scripts.dir, user.script, sep="\\"))
  2. Copy this script to <TSCGHOME>/local (or the comparable location).

To create and load a package to the server:

  1. Create a dummy function and use package.skeleton.

     library(pkgutils)
     library(gom)
     ge.linebreaks<-function(){return(0)}
     package.skeleton(name="gomlinebreaks", list=c("ge.linebreaks"))
  2. Go to <S project folder>\gomlinebreaks\R\ge.linebreaks.S.
  3. Copy in the contents of the real script, so the beginning of the file looks like the following:

     "ge.linebreaks" <-
     GraphicElement(...
  4. Update the files that create the documentation.
  5. Update the DESCRIPTION file, changing it as necessary.

    Package: gomlinebreaks
    Type: Package
    Title: gomlinebreaks
    Version: 1.0
    Date: Thu Feb 07 08:58:04 PST 2009
    Author: TIBCO Software Inc.
    Maintainer: TIBCO Software Inc.
    Description: gomlinebreaks defines a "line breaks" graph element
    Depends: SPOTFIRE S+ (>= 8.1), gom
    Dialect: S-PLUS
    License: TIBCO Software Inc.
  6. Run the following command:

      "<SHome>\splus" CMD install
      gomlinebreaks_1.0_S_WIN386.zip

    to install the library.
  7. From the top directory of the package:
    1. Delete the src directory.
    2. Delete the Data directory.
    3. Delete the README.
  8. From <S project folder>, run the following:

     "<SHome>\splus" CMD build -binary gomlinebreaks
  9. Extract the zip file to <SHome>\local\library and, from within Spotfire S+, verify with the following code:

     rm(ge.linebreaks)
     library(gomlinebreaks)
     ge.linebreaks
     gom(formula=y~x,data=linebreak,groups=~group,
        panel=ge.linebreaks)
  10. 10. Copy the folder to <TSCGHOME>\local\library.
Note  If the package fails to build, load a script (as described above).

Extending the C# Interface

After you have created a new Spotfire S+ graph element on the server, you must make it available in the TSCG client application<. This involves creating a .NET assembly with information on the "display name" of the graph element, the corresponding function name, and the plot element options. You can define multiple plot elements in the same C# project and distribute them in a single assembly.

The LineBreakDemo project in the Examples folder included with this document shows how to create this assembly using Visual Studio C# 2008. This project was created using Visual Studio C# 2008 Express Edition, but any edition of Visual Studio 2008 works.

This section discusses how to create an assembly for a new plot element by modifying the LineBreakDemo project.

NOTE  On your first pass through, you might want to skip straight to Building and Deploying the Assembly to build the project as-is.
General Name Changes

The simplest way to start a new plot element definition is to copy the LineBreakDemo project and change all occurrences of "LineBreak" to a name appropriate for the new element. Changes include:

  1. Change all file names that include "LineBreak".
  2. Change namespaces, class names, constructors, and assembly names that include "LineBreak".
  3. Update the company and copyright information in the "Assembly Information".
  4. Create a new GUID for the assembly and update the GUID in the "Assembly Information". (You can create a GUID by using a Visual Studio tool or by using an online GUID generation utility.)

The PlotElementSpec Class

Each Spotfire S+ graph element has a corresponding .NET class extending PlotElementSpec. The convention gives the class a name matching the graph element name, such as LineBreakPlotElement. This class name is used within graph documents and the TSCG client code to refer to the element. In particular, it is used to display the options for the element in the "Elements" pane of the "Data Selection" dialog. It is also used in the Save As Template dialog when listing the optional and required elements for the template.

In the LineBreakDemo, the code for this class is:

   public class LineBreakPlotElement : PlotElementSpec
   {
      public LineBreakPlotElement()
        {
           ElementName = "ge.linebreaks"
            Title = "Line Breaks";
        }
       public override String GetPlotElementDefinition()
        {
            return LineBreakDemo.Properties.Resources.LineBreakDefinition;
        }
   }

After the name changes, modify the code in the following three places:

  1. Set the name of the ElementName property in the PlotElementSpec to the name of the Spotfire S+ function such as "ge.linebreaks".
  2. Set the Title property in the PlotElementSpec to the "display name" for the element, such as "Line Breaks". (This is the name displayed as the check box label in the list of elements in Elements tab of the Data Selection dialog.)
  3. Set the property reference to LineBreakDefinition to the new property name corresponding to the LineBreakDefinition.txt file. If you have replaced all occurrences of "LineBreak", you will have changed this already.

The Plot Element Options Definition

As you have seen, the changes to the LineBreakPlotElement class are quick and easy. The changes to define the plot element options can be more complex. For the purposes of this example, assume that the new plot element has the same set of options as the line break element, in which case you can just change a few function and argument names.

The LineBreakDefinition.txt file contains XML describing the arguments available and the types of controls to use. This example exposes options for the linesType, linesJitterX, linesJitterY, and linesDoGroup arguments:

  <Description Name="ge.linebreaks"
    Text="Define line breaks with these settings:">
    <Clause Text="Draw {0}." Name="typeClause">
      <Option Type="Choice" Name="linesType"
        Options="lines only|lines overlaid on points|lines to points|lines to isolated points|left base stepped lines only|right base stepped lines only|vertical candlestick lines to X Axis only|horizontal candlestick lines to Y Axis only"
        Value="lines only" />
  </Clause>
    <Clause Text="{0} the points horizontally (X)."
      Name="jitterXClause">
      <Option Type="BooleanChoice"
        Name="linesJitterX"
        Options="Jitter|Do not jitter"
        Value="Do not jitter" />
    </Clause>
    <Clause Text="{0} the points vertically (Y)."
      Name="jitterYClause">
      <Option Type="BooleanChoice"
        Name="linesJitterY"
        Options="Jitter|Do not jitter"
        Value="Do not jitter" />
    </Clause>
    <Clause Text="{0} the style by group."
      Name="groupClause">
      <Option Type="BooleanChoice"
        Name="linesDoGroup"
        Options="Vary|Do not vary" Value="Vary" />
    </Clause>
  </Description>
 

The S-PLUS function name is the Name attribute of the Description element, and the S-PLUS function arguments are the Name attributes of the Option elements. Change these to the appropriate name for the new Spotfire S+ graph element function and its arguments.

The definition of plot element options is discussed in detail in a later section.

Building and Deploying the Assembly

After modifying the code to match the new plot element, you are ready to build and deploy the assembly.

Assembly References

The C# project references three standard .NET assemblies (System, System.Data, and System.Xml) and one TSCG assembly (Insightful.GraphObjectModel).

The TSCG reference in the LineBreakDemo project is to the default TSCG Client install location:

<<TSCGCLIENTHOME>2.0.1\Insightful.GraphObjectModel.dll

TSCGCLIENTHOME is the default TSCG Client install location: typically C:\Program Files\TIBCO\Spotfire\Clinical Graphics. (You must modify this reference if the DLL is at a different location.)

Building the Assembly

Use the standard build operation for your version of Visual Studio. In Visual Studio C# 2008 Express Edition, this is the Build>Build Solution menu item.

Deploying the Assembly

To use the assembly, place it in the client-side directory with the other TSCG assemblies:

<<TSCGCLIENTHOME>\2.0.1

(During development, you can just copy it there manually.)

After you have debugged the assembly and it is ready for distribution, place it in the server-side DataSelectionCustomizations directory. For example:

<SPServerHome>\data\tscg\files\Resources\DataSelectionCustomizations

The assemblies in this directory are downloaded automatically by the TSCG client during startup.

Plot Element Options

Each type of plot element has non-style options. For example, line plot elements might have the option to represent a step function on the data. The plot elements can have a clause for each desired non-style option. The universe of possible non-style options is defined in the Spotfire S+ graph element used.

The options and their controls are specified via an XML file included in the assembly containing the plot element user interface information. The definitions for most of the default plot elements in TSCG are available in the References/GraphObjectModel/Resources folder distributed with this document.

Guidelines for Plot Elements Settings Dialogues

The name of the dialogue must reference an instance in the C# GOM interface. We discuss this further in the C# section.

Plot Elements settings begin with the description tag. The description tag contains:

  • An xmlns assignment, which should not change.
  • A Name assignment, which references the graph element used.
  • A text assignment which is displayed at the top of the plot elements UI.

Example:

<Description
  Name="ge.bars"
  Text="Define bars with these settings:"

<!--clauses go here-->

</Description>

Creating Clauses to Plot Elements Dialogues

This section describes defining all of the appropriate plot element clauses. Each clause takes text, a name, and an Option Type. The Option Type contains the following parameters.

Clause Text

Provide the sentence with "{0}" representing the option. If the sentence has more than one option, the first is "{0}", the second is "{1}", and so on.

Clause Name

Provide a unique clause name.

Option Type

The Option Type sets the kind of interface the option will have; restricting the possible options. When you choose an Option Type, first consider which options must be exposed. The Option Type can accept Options, GomOptions, and Value parameters.

Option Type Name

The Option Type Name is not displayed in the UI, but it should match the GOM parameters exactly. There is one exception: DoSave="false," which is discussed later.

Option Type Options

Option values depend on the values the GOM parameter can accept, and the Option Type that is used. They are discussed further in the Option Type examples below.

Option Type GomOptions

GomOptions is used for some Option Types. They have values that are related directly to Options but represent the value sent to the GOM function call, while Options represent the value displayed in the UI. They are discussed further within the Option Type examples below.

Option Type Value

Value is used to select which, if any, of the Options will be the default. They are discussed further within the Option Type examples below.

Examples for Option Types

The following table discusses available option types.

Option Description Example
BooleanChoice Use when the GOM parameter requires either "True" or "False". Options should list first the UI representation of "True", and second the UI representation of "False". The two values are separated by "|". Value sets the default choice.

<Clause Text="{0} the style by
group." Name="groupClause">
<Option Type="BooleanChoice"
  Name="intervalDoGroup"  
  Options="Vary|Do not vary"
  Value="Vary" />
</Clause>
Choice Use when the GOM parameter requires a single choice made from a list of possibilities. Options should be a "|"-separated list of the set of possibilities that the user will see. The values should correspond with possible values that the GOM parameter can accept, but the text can be modified. Value sets the default value for Options.GomOptions corresponds to the Options list and matches the exact syntax of the GOM parameter value possibilities.

<Clause Text="Display intervals as {0}." Name="geometryClause">
<Option Type="Choice"
  Name="intervalGeometry"
  Options=
  "bands|bars|envelopes|whiskers"   GomOptions=
  "band|bar|envelope|whisker"   Value="bands" />
</Clause> 
ColumnChoice Use when the GOM parameter requires a column name from the dataset. <Clause Text="Lower horizontal
(X) interval bound is {0}."
Name="xLowerLimitClause">
<Option Type="ColumnChoice"
  Name="lowerX" />
</Clause>

ColumnMultipleSelect Use when the GOM parameter can accept multiple columns of data from the dataset.

 
IntegerRange Use when the GOM parameter requires an integer. You can use Options; it is analogous to the use in NumericRange. Value sets the default value.

<Clause Text="Use {0} contour
levels." Name="numLevelsClause">
 
<Option Type="IntegerRange"
  Name="contourNLevels" Value="9"/>
</Clause>
LevelChoice Use when the GOM requires a data-dependent selection. You can set the Options to "X" "Y" or "groups", referencing the columns selected in the data selection UI. <Clause Text="Align bars using {0} as a base." Name="stackedBarBaseClause">
<Option Type="LevelChoice"   Name="barsStackedGroupLevelBase"
  Options="groups"/>
</Clause>

MultiSelectChoice Use when the GOM parameter requires a list from which the user selects an option. Value sets the default value. Note GomOptions must correspond to the Options list and match the exact syntax of the GOM parameter value possibilities. 

<Option Type="MultiSelectChoice"
Name="refXAreaColumnStats"
Options="Range|Standard
Deviation|Standard Error of the
Mean|Inter-Quartile Range"
GomOptions="Range|Standard
Deviation|Standard Error of the
Mean|Inter-Quartile Range"
Value="Range" />


NumericList Use when the GOM parameter requires a vector of numerics. For example, for a reference area reXAreaPositions parameter, sets the position of the reference area. Value sets the default value.

<Clause Text="The reference area
boundaries are {0}."
Name="locationClause">
<Option Type="NumericList"
  Name="refXAreaPositions"
  Value="" />
</Clause>

NumericRange Use when the GOM parameter requires a number from a dataset-independent interval. Options requires a "|"-separated list of two values: the inclusive lower limit and the inclusive upper limit. A missing value indicates no limit. Value sets the default value.

<Clause Text="Use a bar width of {0},
where one (1) uses two-thirds of
 the available space."
Name="barWidthClause">
<Option Type="NumericRange"
  Name="barsWidth" Options="1|"
  Value="1" />
</Clause>
StringList Use when the GOM parameter requires a vector of strings. For example, for line labeling parameter, sets the text for the line labels.

Value sets the default value.


<Clause Text="The reference area
 boundaries are {0}."
Name="locationClause">
   <Option Type="StringList"
  Name="linesLabels"
   Value="" />
</Clause>
Percent Use when the GOM parameter requires a number between 0 and 1. Value sets the default value. <Clause Text="Include intervals at the
 {0} confidence level."
  Name="levelClause">
<Option Type="Percent"
  Name="cifitFunctionArgs"
  Value="0.95" />
</Clause>

Advanced Clause Techniques

DoSave

An optional Option Type parameter is DoSave. The default is true. You can change it by adding DoSave="false" to your Option Type. Use this setting when the parameter is relevant to the UI but not to the GOM. The option and its parameter are not saved in the XML, but they can be referenced for use by Sub.Clauses (discussed below).

Example:

<Clause Text="{0} the number of bars." Name="barsClause">
  <Option Type="Choice" Name="barsMethod" Options="Estimate|Specify"
   Value="Estimate" DoSave="false"/>
</Clause>

Implementing Sub.Clauses

Use the Sub.Clauses setting when you want to create a user interface that changes based on the input of the user. First, it is structured using the Clause.Subclauses tag, then each subclause uses the DependsOn option to specify which values of which clauses are necessary for it to be relevant. In the following example, the histogramBinMethod is relevant only if the user first selects continuous data, and then selects estimate the number of bars. The Specify clause is relevant only if the user selects continuous and then selects Specify.

Sub.Clauses Example:

<Clause Text="The data is {0}." Name="dataClause">
  <Clause.SubClauses><ClauseList>

     <Clause Text="{0} the number of bars." Name="barsClause"
      <Option Type="Choice" Name="barsMethod"
      Options="Estimate|Specify"
      Value="Estimate" DoSave="false"/>
    </Clause>

    <Clause DependsOn="//Description/Clause[@Name='dataClause']/
      Option[@Name='histogramDiscrete']/@Value='continuous' and
       //Description/Clause[@Name='dataClause']/Clause.SubClauses/
      ClauseList/Clause[@Name='barsClause']/Option[@Name='barsMethod']/
      @Value='Estimate'"
      Text="Calculate the number of bins using the {0} method."
      Name="estimateClause">

      <Option Type="Choice" Name="histogramBinMethod"
        Options="Scott|Sturges|Freedman-Diaconis"
        GomOptions="scott|sturges|fd" Value="Scott" />
    </Clause>

    <Clause DependsOn="//Description/Clause[@Name='dataClause']/
      Option[@Name='histogramDiscrete']/@Value='continuous' and
      //Description/Clause[@Name='dataClause']/Clause.SubClauses/
      ClauseList/Clause[@Name='barsClause']/Option[@Name='barsMethod']/
      @Value='Specify'"
      Text="Calculate the histogram with {0} bars."
      Name="specifyClause">
      <Option Type="IntegerRange" Name="histogramBinNumber"
       Options="1|" Value="20" />
    </Clause>
 
  </ClauseList></Clause.SubClauses>
 
  <Option Type="BooleanChoice" Name="histogramDiscrete"
    Options="categorical|continuous" Value="categorical"/>
</Clause>

Complete Plot Elements Example

You can view and explore the results of the following example by opening TSCG, selecting a line plot, selecting a data source, clicking the Elements tab, and inspecting the Lines plot element options.

<Description Name="ge.lines"
 Text="Define lines with these settings:">
  <Clause Text="Draw {0}." Name="typeClause">
  <Option Type="Choice" Name="linesType"
    Options="lines only|lines overlaid on points|lines to points|lines to isolated points|left base stepped lines only|right base stepped lines only|vertical candlestick lines to X Axis only|horizontal candlestick lines to Y Axis only"
    GomOptions="lines|overlaid|both|isolated|stepleft|stepright|xcandle|ycandle" Value="lines only" />
 </Clause>

 <Clause Text="Draw the lines through the {0}." Name="methodClause">
  <Clause.SubClauses><ClauseList>
   <Clause DependsOn="//Description/Clause[@Name='methodClause']/Option[@Name='linesMethod']/@Value='data values'"
    Text="{0} the values on X." Name="sortClause">
    <Option Type="BooleanChoice" Name="linesSortOnX" Options="Sort|Do not sort" Value="Sort" />
   </Clause>
  </ClauseList></Clause.SubClauses>
  <Option Type="Options" Name="linesMethod"
    Options="data values|mean Y value at each unique X value|median Y value at each unique X value|mean X value at each unique Y value|median X value at each unique Y value"
   GomOptions="none|mean|median|meanXatY|medianXatY" Value="data values" />
 </Clause>

 <Clause Text="{0} the lines horizontally (X)." Name="jitterXClause">
  <Option Type="BooleanChoice" Name="linesJitterX" Options="Jitter|Do not jitter" Value="Do not jitter" />
 </Clause>

 <Clause Text="{0} the lines vertically (Y)." Name="jitterYClause">
  <Option Type="BooleanChoice" Name="linesJitterY" Options="Jitter|Do not jitter" Value="Do not jitter" />
 </Clause>

 <Clause Text="{0} the style by group." Name="groupClause">
  <Option Type="BooleanChoice" Name="linesDoGroup" Options="Vary|Do not vary" Value="Vary" />
 </Clause>
</Description>

 

Section 2: Graph Templates

The easiest way to create a new graph template is with the Save As Template dialog. This dialog was enhanced in TSCG 2.0 to allow the user to set all the relevant information contained in a graph template using the point-and-click application. See the TSCG help files for more information on this dialog.

In earlier versions, the information on graph elements available for a template could not be set in the client application. Instead, you used a C# project to create a new template requiring different elements from any existing template. It is still possible to create a new template using C# if you choose.

Creating a Graph Template with C#

The LineBreakDemoGraphDocumentCreator example directory includes a Visual Studio solution for creating a new graph template that includes the "line breaks" element defined in a previous example.

  1. Open the solution titled LineBreakDemoGraphDocumentCreator.
  2. Update the assembly references to point to the TSCG client assemblies on your machine and to the line break element assembly created in the previous section.
  3. Review and modify the Program.cs file and the AssemblyInfo.cs file.
    1. Namespace and assembly (optional): Set the name of the .exe used to generate the .dll.
      namespace LineBreaksDemoDocumentCreator

      [assembly: AssemblyTitle("LineBreaksDemoDocumentCreator")]
      [assembly: AssemblyDescription("")]
      [assembly: AssemblyConfiguration("")]
      [assembly: AssemblyCompany("TIBCO Software Inc.")]
      [assembly: AssemblyProduct("LineBreaksDemoDocumentCreator")]
      [assembly: AssemblyCopyright("Copyright © TIBCO Software Inc 2009")]
      [assembly: AssemblyTrademark("")]
      [assembly: AssemblyCulture("")]
    2. args:  Specify the file name for the graph document to be generated.
      // Save the GraphDocument to a file
       if (args.Length == 0)
       {
         args = new string[] { "D:/tscgCustomization/LineBreaksPlot.igd" };
       }
       doc.Save(args[0]);
    3. Graph Name/Title:  Displayed in the client; the title of the plot.
      // Change the graph name to "Line Break Plot"
      def.DocumentProperties.Title = "Line Break Plot";
    4. GUID:  A unique ID that is part of the .igd file.
      // Specify a GUID. Use Tools:Create GUID in VS to generate.
      def.UserInterfaceProperties.Add("GUID", "0A5C2015DAF241399A5…CA");
    5. Thumbnail:  Displayed in the client when you select the template.
      // Change the Thumbnail
      def.Thumbnail = Utilities.InternalBitmapImage(Properties.Resources.LineBreakPreview);
    6. Required Plot element (should match step3).
      // Include a LineBreakPlotElement
      PlotElementSpec LineBreakElt = new Insightful.ClinicalGraphics.Demo.LineBreakPlotElement();
      def.GraphSpec.PlotElements.Add(LineBreakElt);
      def.UserInterfaceProperties.Add("DataSelectionRequiredElementClasses", LineBreakElt.GetType().AssemblyQualifiedName);
    7. ContentType and Keywords.
      def.DocumentProperties.ContentType = "Line Plot";def.DocumentProperties.Keywords = "General";
    8. Help.
      def.UserInterfaceProperties.Add("Help", "graphs/line_plot.html");
    9. Data Selection: Add the following line, and then add your customized DLL if you created a customized data selection interface.
      if (def.UserInterfaceProperties.ContainsKey("DataSelectionXaml"))
         def.UserInterfaceProperties.Remove("DataSelectionXaml");

      def.UserInterfaceProperties.Add("DataSelectionXaml",
      "DataSelection_SingleX_SingleY.dll");
    10. Optional Plot Elements.
      def.UserInterfaceProperties.Add("DataSelectionOptionalElementClasses", "IntervalPlotElement");
    11. Other UI options.
      def.UserInterfaceProperties.Add("AllowSmoothers", "true");
      def.UserInterfaceProperties.Add("AllowReferenceLines", "true");
  4. Update icon resources:
    1. Move files in Windows.
    2. Move files in VS Resources.
    3. Move files in Resources.resx.
    4. Verify update in Resources.Designer.cs.
    5. Verify name against Program.cs, step 2c.
  5. Build and run the solution to create an .igd file.
  6. Copy the .igd file to
    C:\Program Files\TIBCO\splusserver81\data\tscg\files\
    Resources\DefaultGraphs\Shared
    (or the comparable location).
  7. Open the client from that server on your local machine.
  8. Select New Graph to create a new graph, and then find your graph template in the graph type (for example, Scatter Plot).
  9. Select the created template and run your graph.

 

Section 3: Data Selection

Create a new data selection interface DLL. This task should be rare because the save template feature in the GUI allows you to select from several built-in data selection options, and the data selection interface is independent of your primary and optional plot elements.

Overview of a Data Selection Project

The data selection project contains four main code files:

  • Customize.xaml is an xml file that sets the cosmetic level display and appearance of the UI. You can modify this file from the client.
  • DataSelection.xaml is an xml file that sets the XAML controls.
  • Customize.xaml.cs is a C# file that relates the cosmetic labels in Customize.xaml to the hashtable values.
  • [Description].cs (for example, MultipleX_MultipleY.cs) is a C# file that handles the primary events, such as changing a selection or submitting.

Additionally, major changes to the data selection UI require changes to the referenced Insightful.GraphObjectModel< project, as well as the XSLT. Both are discussed in separate sections.

As an example, examine how trellis column selection is coordinated across all four files.

File and Comments Example
Customize.xaml <StackPanel Margin="5,5,5,5" x:Name="stackTrellis">
<TextBox Text="Trellis Columns:"
x:Name="trellisLabel" Margin="0,20,0,0"/>

  <ListBox Width="130" Height="70"

SelectionMode="Multiple"

      IsEnabled="False" HorizontalAlignment="Left"/>

</StackPanel>

DataSelection.xaml <StackPanel Margin="5,5,5,5" x:Name="stackTrellis">
<Label Content="Trellis Columns:"

HorizontalAlignment="Left" VerticalAlignment="Top"

x:Name="labelTrellis"/>
  <pecontrols:ColumnMultipleSelect x:Name="trellis"

Width="150" Height="240"

HorizontalAlignment="Left" VerticalAlignment="Top" SelectionMode="Multiple"
TSCG:DataSelection.ItemsSource="ColumnList"/>

</StackPanel>

Customize.xaml.cs public void OnOK(object sender, RoutedEventArgs e)
{

//… Other Customizations…

_htCustomizations.Add("labelTrellis",

this.trellisLabel.Text);

  //… Other Customizations…

this.DialogResult = true;

this.Close();

}

 

public override void OnInit(object sender, Hashtable htCustomizations,

Insightful.GraphObjectModel.Documents.GraphDocument

gdoc)

{

//…

// Handle trellis columns

ColumnMultipleSelect trellis =

LogicalTreeHelper.FindLogicalNode(Root,

        "trellis") as ColumnMultipleSelect;

if (trellis != null)

  {

    trellis.OnSelectionChanged += new

       EventHandler<SelectionChangedEventArgs>

(Default_SelectionChanged);

  }  
MultipleX_MultipleY.cs private void Default_SelectionChanged(object sender, SelectionChangedEventArgs e)

{

//…
// Handle trellis columns

ColumnMultipleSelect trellis =

LogicalTreeHelper.FindLogicalNode(Root, "trellis")

as ColumnMultipleSelect;

if (trellis != null)

  {

    // Number the selections made

    this.ListBox_NumberSelections(trellis);

  }

//…

} 

public override object OnSubmit(object sender,

    GraphSpec gspec)

{
  //…


  // Handle trellis columns

ColumnMultipleSelect trellis =

LogicalTreeHelper.FindLogicalNode(Root, "trellis")

as ColumnMultipleSelect;

if (trellis != null)

{

  if (trellis.SelectedItems.Count > 0)

    {

     foreach (ListBoxItem lbItem in

trellis.SelectedItems)

      {

       string sValue =

this.ListBox_GetItemText(lbItem);

       if (sValue != null && sValue.Length > 0)

         gspecToUse.TrellisColumns.Add(sValue);

      }

    }

}  
MultipleX_MultipleY.cs  public object StoreSelections(object sender)
{

//…

// Handle trellis columns

ColumnMultipleSelect trellis =

LogicalTreeHelper.FindLogicalNode(root, "trellis")

as ColumnMultipleSelect;

if (trellis != null)

{

  if (trellis.SelectedItems.Count > 0)

    {

     ArrayList arrayValues = new ArrayList();

     foreach (ListBoxItem lbItem in trellis.SelectedItems)

      {

     string sSelection = this.ListBox_GetItemText(lbItem);

       if ( sSelection != null )arrayValues.Add(sSelection);

    }

  ht.Add("trellis", arrayValues);
} }  }

public void RestoreSelections(object sender, object oControlSettingsHash)

{

//…

{

if (ht[sControlName] is ArrayList)

  {

    ArrayList arrayValues = ht[sControlName] as ArrayList;

    ColumnMultipleSelect lb = ctrl as ColumnMultipleSelect;

// If the control has not yet been populated, then

// use the control Tag property to set a 'selections'

// hashtable that will be used by the callback filling

// the control to set selections later

  if (lb.Items.Count <= 0)

    {

      Hashtable htSelections = new Hashtable();

      htSelections.Add("selections", arrayValues);

    lb.Tag = htSelections;

    }

// otherwise, set the selections now

  else

  {

      foreach (string sCompare in arrayValues)

    {

     foreach (ListBoxItem lbitem in lb.Items)

      {

       string sFound = this.ListBox_GetItemText(lbitem);

      if (sFound == sCompare)

        {

       lbitem.IsSelected = true;

       break;

}} } } } }

Additional interesting items include:

About.xml
<DataSelection Title=Multiple X, Multiple Y/>

AssemblyInfo.cs
// The following GUID is for the ID of the typelib if this project is exposed to COM

[assembly Guid("65f58f12-f838-49f4-b014-d12a66510095")]

References

Insightful.GraphObjectModel

Steps to create a new Data Selection Interface

  1. Find the DataSelection_MultipleX_MultipleY project files included in the References directory that is distributed with this documentation.
  2. Copy and rename the entire folder. Change the name of the csproj project file.
  3. Update the assembly references to point to the TSCG assemblies on your machine.
  4. Within Visual Studio, change the file names and all references.
    1. Change the name of the *.cs file.
  5. Change the code and the properties.
    1. Change the Properties/AssemblyInfo.cs file.
      1. Change the AssemblyTitle.
      2. Change the AssemblyProduct.
      3. Change the Guid using the Tools > Create GUID menu.
    2. Update the About.xml.
    3. Right-click the project and update the assembly name.
    4. Change the DataSelection.xaml file.
      1. Modify the references as appropriate:

        TSCG:DataSelection.OnSubmit=
          "DataSelection_Custom.dll;DataSelection.DSCustom;OnSubmit"

        TSCG:DataSelection.OnInit=
          "DataSelection_Custom.dll;DataSelection.DSCustom;OnInit"

        TSCG:DataSelection.StoreSelections=
        "DataSelection_Custom.dll;DataSelection.DSCustom;StoreSelections"

        TSCG:DataSelection.RestoreSelections=
          "DataSelection_Custom.dll;DataSelection.DSCustom;RestoreSelections"

        TSCG:DataSelection.HelpContext=
        "DataSelection_Custom.dll;DataSelection.DSCustom;HelpContext"


      2. Change the appearance of the data selection dialogue.
    5. Return to the *.cs file and make sure it handles any additions or changes made to the DataSelection.xaml file.
    6. Test, as described in step 7.
    7. Change the customized .xaml and .cs files, as necessary.
  6. Build the solution, check for errors, and find the DLL.
  7. Copy the DLL to the server:
    C:\Program Files\TIBCO\splusserver81\data\tscg\files\Resources\DataSelectionCustomizations
    or copy to your local machine’s client startup directory:
    C:\Program Files\TIBCO\Spotfire\Clinical Graphics\2.0.1
  8. To use the data selection interface, you must reference it in a graph document that you create. See Section 2, Graph Templates, particularly the discussion about Data Selection.

  

Section 4: Custom Metadata

Overview

In TSCG, you can customize completely the metadata that is saved with graphs and graph themes. The customization applies across an entire TSCG customer installation. Also, you can design a UI for editing this metadata and viewing it in the metadata palette in TSCG.

In addition, you can customize the columns of matched data in the Find Graphs and Find Themes dialogs so they display the important metadata you specify for each matched graph or theme file. All of this customization is managed in a completely modular way with a simple plug-in architecture that can be managed on the server and transferred automatically to each client program when it starts.

Architectural Overview

The metadata customization feature is a plug-in that is based on a Windows Presentation Foundation (WPF) user control. It has an embedded XML resource that defines the metadata structure (that is, the available fields and how they link to your UI controls).

The plug-in DLL is implemented in C# only. The plug-in requires a reference to the Insightful.GraphObjectModel assembly that ships with TSCG. The control classes in this plug-in are inherited from specific classes in the Insightful.GraphObjectModel assembly that ships with TSCG. This inheritance allows virtual methods in the base classes to be overridden in your implementation of the plug-in. This design enables TSCG to call into your plug-in to control the UI, metadata serialization, and more.

TSCG contains two plug-ins: one for graph metadata and one for graph theme metadata. To override the plug-in shipped with TSCG, place your plug-in in a specific directory on the server, and, when clients start up, your plug-in downloads automatically and replaces the shipped plug-in. The standard directory in which to place the plug-in is the following directory under the Spotfire S+ Server installation:

data/tscg/files/Resources/DataSelectionCustomizations

Your plug-in must provide the services listed below. That is, you must implement in your plug-in each of the following services to avoid errors in the client. These services are implemented as separate classes derived from specific base classes in Insightful.GraphObjectModel. These service classes are marked with special attributes to indicate the service they provide to the program.

  • UIProvider(UIProviderType.Dialog)  -  The Metadata dialog UI.
  • UIProvider(UIProviderType.Palette)  -  The metadata palette UI.
  • UIProvider(UIProviderType.FindGridView)  -  The data grid columns in the Find Graphs/Find Themes dialog.
  • UIProvider(UIProviderType.Preview)  -  The metadata preview displayed when the user selects a document in the Find Graphs or Find Themes dialog. It is also displayed in the tooltip when the user hovers the mouse pointer over a graph preview picture.
  • MetadataSerializer()  -  Provides support for serializing metadata to and from documents and provides methods that support finding document matches when users use the Find Graphs/Find Themes dialogs.

Steps to Create New Metadata Structure and UI

This section provides a set of high-level steps for creating a metadata plug-in.

The best way to start planning your own metadata structure and UI for graphs, themes, or both graphs and themes, is to examine those shipped with TSCG as examples. The plug-in that handles metadata for graphs is called Metadata_igd. The plug-in that handles metadata for themes is called Metadata_igt.

The following describes steps for creating a Metadata_igd and handling graph documents; however, the same steps apply to Metadata_igt for graph theme documents.

Part 1: Creating a WPF User Control Library

  1. Create a WPF User Control Library.

    In Visual Studio 2008, create a new project of type WPF User Control Library under Visual Studio C# Windows Project Types. You must name the project and the assembly Metadata_igd (for a graph plug-in) or Metadata_igt (for a theme plug-in).
  2. Add a reference.

    In the User Control Library, add a reference to Insightful.GraphObjectModel assembly.
  3. Modify the inheritance of the metadata dialog control class.

    By default, when you create a new WPF User Control Library project, a new control class is added, which derives from UserControl, a WPF base class for all user controls. For example, if you call it DialogControl, rename the default class to that. You can make this control the one used for the Metadata dialog UI in TSCG, but you must change the base class to Insightful.GraphObjectModel.MetadataUserControl:
    public partial class DialogControl : MetadataUserControl
       {
       ...
  4. Modify inheritance for the DialogControl XAML.

    In addition to modifying the inheritance of the C# class that represents your DialogControl, you must also change the inheritance of the XAML class. To do this, add an xmlns reference to the Insightful.GraphObjectModel assembly and namespace in the preamble for the DialogControl XAML:

    <UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
       xmlns:gobj="clr-namespace:Insightful.GraphObjectModel;
       assembly=Insightful.GraphObjectModel"
    x:Class="Metadata_igd.DialogControl"
    Height="400" Width="747">

    Also, change the base class name of the control to MetadataUserControl:

    <gobj:MetadataUserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
       xmlns:gobj="clr-namespace:Insightful.GraphObjectModel;
       assembly=Insightful.GraphObjectModel"
    x:Class="Metadata_igd.DialogControl"
    Height="400" Width="747">

    ...

    </gobj:MetadataUserControl>

Part 2: Creating the User Interface

  1. Lay out the new UI for your metadata dialog.

    The following guidelines standardize UI design and are considered good practice.
    • Add tabs to organize metadata by type.
    • Name all controls, especially those you want to associate directly with metadata values.
    • You can assign special attributes to  controls in the XAML code to specify a call to a routine in your plug-in when special events occur. Do this for controls that provide special handling (that is, above and beyond automatic handling) when the dialog loads or when the user clicks OK, The special attributes are as follows:
      • gobj:MetadataUserControl.OnMetadataInit  -  Used to assign the name of a routine in your plug-in. Called when the dialog loads.
      • gobj:MetadataUserControl.OnMetadataSubmit  -  Used to assign the name of a routine in your plug-in. Called when the user clicks OK in the dialog.

      Example

      <TreeView x:Name="uiCommentTree"
      gobj:MetadataUserControl.OnMetadataInit="CommentTreeOnInit"
      gobj:MetadataUserControl.OnMetadataSubmit="CommentTreeOnSubmit"
      />

      In this example, the plug-in code calls the routines CommentTreeOnInit and CommentTreeOnSubmit. The prototypes for methods assigned in these XAML attributes must be written as follows:

      public bool OnInit(MetaDataElement metadataElement)
      public bool OnSubmit(MetaDataElement metadataElement)

      In the case of the OnInit method, the current metadata element (either list or item) that corresponds to the control is passed as the parameter to the method. In the case of the OnSubmit method, the metadata element (either list or item) that should be updated from the value in the control is passed in.

      In both cases, returning true allows the dialog to proceed normally. Returning false results in an error reported in the client indicating that the dialog failed to load or close.

    • Create the MetadataTemplate.xml.

      Specify the metadata to store with each graph document in an XML file, which you add to the plug-in project as an embedded resource. For more information, examine the example provided with the shipping Metadata_igd plug-in. This file can have any name, but it must have an .xml file extension.

      Each MetaDataSection tag in this file organizes a set of MetaDataItem tags and/or MetaDataList tags below it.

      • Use a MetaDataItem when the represented metadata has only one value associated with it.
      • Use a MetaDataList when the represented metadata contains a list of values.

      To associate a MetaDataSection, a MetaDataItem, or a MetaDataList with a control in DialogControl XAML, set the tag attribute 'ControlName' to the name of the control in the XAML. This establishes an automatic relationship between the metadata element and your control. When the dialog is loaded, your control is populated with the current value of the metadata, and when the user clicks OK, the metadata is populated with the current control value. Establishing this relationship via 'ControlName' in MetadataTemplate.xml enables this behavior without you having to write code.

      You can create a default value for any MetaDataItem in the template XML just by specifying a value for the tag. For example:

      <MetaDataItem Name="ApprovalStatus" ControlName="uiProdStatusApproval">Approved</MetaDataItem>

      In the above example, the default value for the metadata ApprovalStatus is Approved and, because ControlName is specified, the XAML control named uiProdStatusApproval automatically displays Approved as the default value if no value is currently set in the metadata.

      Key method overrides:

      Override the following methods from the MetadataUserControl base class in your DialogControl class:

      • OnInitMetadataDialog  -  Called when the Metadata dialog is loaded in TSCG. In this method, initialize controls that require extra code beyond that which is automatically done by setting the ControlName attribute in the MetadataTemplate.xml embedded resource file.
      • OnSubmitMetadataDialog  -  Called when the user clicks OK in the Metadata dialog in TSCG. In this method, collect information from controls or perform any final activities on the ControlName attribute in the MetadataTemplate.xml embedded resource file.
      • OnHelpMetadataDialog  -  Called when the user requests help in the Metadata dialog in TSCG. In this method, handle displaying help for specific parts of your Metadata dialog. You can use the utility function TSCGMetaData.DisplayContextHelp to display a help topic, given the topic partial pathname on the server.

    • Add a class attribute for the Metadata dialog UI.

      This class attribute indicates that the new control class provides the Metadata dialog UI. In the C# code, you can assign the class attribute UIProvider to any class in your project to indicate to TSCG that the class provides a specific type of UI for metadata. For the Metadata dialog, the following attribute

      [UIProvider(UIProviderType.Dialog)]

      must precede the class definition. For example:

      [UIProvider(UIProviderType.Dialog)]
        public partial class DialogControl : MetadataUserControl
        {
      ...

      The TSCG program now recognizes that the DialogControl class provides the UI for the Metadata dialog.

    • Create the class that provides the UI for the TSCG Metadata palette.

      Add a new WPF User Control class to your project using any name. For our example, it is called PaletteControl.

    • Modify the inheritance of the palette control class.

      Change the base class of your new palette control from UserControl to Insightful.GraphObjectModel.MetadataPaletteControl:

      public partial class PaletteControl : MetadataPaletteControl
        {
        ...
    • Modify the inheritance for the PaletteControl XAML.

      Change the inheritance of the XAML class by adding an xmlns reference to the Insightful.GraphObjectModel assembly and namespace in the preamble for the PaletteControl XAML:

      <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/
          xaml"xmlns:gobj="clr-namespace:Insightful.GraphObjectModel;
          assembly=Insightful.GraphObjectModel"
        x:Class="Metadata_igd.PaletteControl">

      Change the base class name of the control to MetadataPaletteControl:

      <gobj:MetadataPaletteControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:gobj="clr-namespace:Insightful.GraphObjectModel;
          assembly=Insightful.GraphObjectModel"
        x:Class="Metadata_igd.PaletteControl">
      ...

        </gobj:MetadataPaletteControl>
    • Lay out the UI for the metadata palette.

      Controls in the palette typically should be read-only labels or text blocks because the pallette already has a button to display the Metadata dialog for editing. Like the dialog layout, the palette should have tabs to organize metadata. Unlike the Metadata dialog, the palette provides no automatic marshalling of metadata to controls and back. You must provide this functionality in an overridden method in the class.

      Key method overrides

      Override the following method from the MetadataPaletteControl base class in the PaletteControl class:

      • OnInitMetadataPalette  -  Called when the Metadata palette is initialized in TSCG. The initialization event happens whenever a document is loaded and new metadata is available, when a document is closed and the fields in the palette should be cleared, and whenever a change is made to metadata related to the current document. In this method, you can initialize any controls that correspond to metadata.
    • Add the class attribute to indicate your new control class provides the metadata palette UI.

      In the C# code, the class attribute UIProvider can be assigned to any class in your project to signify to TSCG that the class provides a specific type of UI for metadata. For the metadata palette, the attribute

      [UIProvider(UIProviderType.Palette)]

      should precede the class definition. For example:

      [UIProvider(UIProviderType.Palette)]
        public partial class PaletteControl : MetadataPaletteControl
        {
        ...

      The TSCG program now recognizes that your PaletteControl class provides the UI for the Metadata palette.

    • Create the Grid Columns UI class.

      The Grid Columns UI class provides the UI for the grid columns in the Find Graphs dialog in TSCG. Add a new regular class to your project and name it anything. For this example, it is called GridView.

    • Modify the inheritance of the GridView class.

      Change the base class of your new GridView class from nothing to Insightful.GraphObjectModel.MetadataFindGridView:

      public class GridView : MetadataFindGridView
        {

      ...

      Key method overrides

      Override the following method from the MetadataFindGridView base class in your GridView class:

      • OnGetMetadataGridViewInfo  -  Called when the dialog needs to display the grid view of matched documents in the Find Graphs or Find Themes dialog. In this method, create a new MetadataFindGridInfoArray and add new MetadataFindGridInfo objects for each column to display in the Find dialog grid view.
    • Add the class attribute.

      The class attribute indicates your new GridView class provides the metadata grid view UI. In the C# code, you can assign the class attribute UIProvider to any class in your project  to signify to TSCG that the class provides a specific type of UI for metadata. For the metadata grid view, the attribute

      [UIProvider(UIProviderType.FindGridView)]
      should precede the class definition. For example:
      [UIProvider(UIProviderType.FindGridView)]
        public class GridView : MetadataFindGridView
        {
        ...

      The TSCG program now recognizes that your GridView class provides the UI for the grid view in the Find Graphs dialog.

    • Create the class that provides the UI for previewing document metadata in TSCG.

      Add a new regular class to your project and call it anything you want. For this example, it is called Preview.

    • Modify the inheritance of the Preview class.

      Change the base class of your new Preview class from nothing to Insightful.GraphObjectModel.MetadataPreview:

      public class Preview: MetadataPreview
        {
        ...

      Key method overrides

      Override the following method from the MetadataPreview base class in your Preview class.

      • OnGetMetadataPreview   -  Called when the user wants to see a preview of the metadata. For example, it is called when the user hovers the mouse pointer over a preview image of a graph in the History palette, or when the user clicks a matched graph document in the Find Graphs dialog. You return a string from this method that is formatted with the metadata to display when previewed.
    • Add the class attribute to indicate that the new Preview class provides the metadata preview UI.

      In the C# code, you can assign the class attribute UIProvider to any class in your project to indicate to TSCG that the class provides a specific type of UI for metadata. For the metadata preview, the attribute

      [UIProvider(UIProviderType.Preview)]

      should precede the class definition. For example:

      [UIProvider(UIProviderType.Preview)]
        public class Preview : MetadataPreview
        {
        ...

      The TSCG program now recognizes that your Preview class provides the UI for the metadata preview.

      Part 3: Adding Serialization Support

      1. Create the class that provides metadata serialization support in TSCG.

        Add a new regular class to your project and call it anything. For this example, it is called SerializationHandler.

      2. Modify the inheritance of the SerializationHandler class.

        Change the base class of your new class from nothing to Insightful.GraphObjectModel.MetadataSerializationHandler:

        public class SerializationHandler: MetadataSerializationHandler
        {
        ...

        Key method overrides

        Override the following methods from the MetadataSerializationHandler base class in your SerializationHandler class.

        • OnLoadMetadata  -  Called when a document that might contain metadata is loaded. The current document being loaded is passed in as a parameter. Always call the base class OnLoadMetadata first in your override. The base class method automatically creates and adds your metadata structure to the document based on your MetadataTemplate.xml set up in Step 6 of Section 1: Creating a WPF User Control Library. Return TRUE to allow loading to continue. Return FALSE to stop and report an error.
        • OnSaveMetadata  -  Called when a document containing metadata is saved. In this method, you can do any necessary metadata initialization before it is saved with the document.
        • OnFixupMatchedDocumentUri  -  Called when a new match is found in the Find Graphs or Find Themes dialog. The relative path of the matched document file is passed in as a parameter; however, you should return the full path string to this document. You can use the useful utility functions provided in TSCGMetaData to do this:
          • TSCGMetaData.GraphsPath  -  Returns the path to saved graph documents.
          • TSCGMetaData.ThemesPath  -  Returns the path to saved graph theme documents.
        • OnNewMatch  -  Called when a new match is found in the Find Graphs or Find Themes dialog. This method is called after OnFixupMatchedDocumentUri. In this method, you can initialize any variables to deal with processing matches from the search process.
        • OnNewMetadataPath  -  Called when a new metadata path is returned for a matched document. When a match is found, the metadata values for this document are returned as slash-delimited paths, with the names of the metadata elements in the hierarchy as parts of this path. The method is used for both the metadata path found and the value at this path. You can use the path and the value to set metadata values into a map of metadata properties that is used later to do the actual searching. Use the following utility functions:
          • GMetaData.SetMetadataPropertyValue  -  Sets a metadata name and value on the map. Using this function, you can specify that the value should be part of all unique values for the specific metadata name displayed in the Find Graphs or Find Themes dialog when the user specifies search criteria using the Is option from the dialog's drop-down list.
          • TSCGMetaData.GetMetadataPropertyValue  -  Returns a metadata value as an object when given the name of the metadata from the map of metadata properties.
      3. Add the class attribute to indicate your new SerializationHandler class provides serialization.

        In the C# code, you can assign the class attribute MetadataSerializer to any class in your project to provide metadata serialization and indexing support. Add the attribute to your SerializationHandler class as follows:

        [MetadataSerializer()]
        public class SerializationHandler : MetadataSerializationHandler
        {
        ...

        The TSCG program now recognizes that the SerializationHandler class provides metadata serialization and indexing support.

       

      Section 5: Spotfire S+ Script Generation

      TSCG uses the following steps to convert a user’s point-and-click graph specification into a graph displayed in the client application:

      1. The user interacts with the TSCG client application to modify an in-memory C# object containing the graph settings.
      2. The C# object is converted into XML that is sent to Spotfire S+.
      3. Spotfire S+ applies an XSL transform to convert the XML into a Spotfire S+ script. This conversion is specified by an XSL file.
      4. The Spotfire S+ script is evaluated to generate a graph file, which is retrieved and displayed by the client.

      The process is essentially the same in production use, with the XML retrieved from within a TSCG graph document and the generated graph file converted to PDF, WMF, or other format.

      The generation of the S+ script can be modified by changing the XSLT file.

      Inspecting the Original XSL file

      The default file is in the following location:

      <TSCGHome>\library\tscg\xml\tscgGraphJobXmlToSplusScript20.xsl

      Where <TSCGHome> is the server installation directory.

      The beginning of the file resembles the following:

      <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
      xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
      xmlns:gom= "clr-namespace:Insightful.GraphObjectModel;assembly=Insightful.GraphObjectModel" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">

      Stylesheet for generating SPOTFIRE S+ code calling the TSCG function to generate a graph using "gom" graphics. -->

      The file performs the following steps:

      1. Sets some XSLT variables that are used later.
      2. Opens a graphics device generating a local SPJ graph file.
      3. Imports the data file as a data frame.
      4. Uses a gom() graphics function call whose arguments describe the graph elements and other settings. This step uses many <xsl:template> entries defined later in the XSLT file.
      5. Closes the graphics device.
      6. Copies the SPJ file to the requested output location and/or generates PDF, WMF, etc. files based on the SPJ file.

      Customizing the XSLT

      To create a custom XSLT with different behavior:

      1. Copy the default XSLT file.
      2. Modify the file.
      3. Place the file in a sensible server-side location accessible to the Spotfire S+ engine. A reasonable location is the TSCG Resources directory that is used for UI customizations.

      Directing TSCG to use the new XSLT

      The original XSLT file is still in place on the server. Its location is defined by the .First.lib() function in the TSCG package with a section that resembles the following:

      # Store the XSL file path for use by tscgCreateScript().
      #Typically we will be using the xsl script included in the TSCG package,
      #but the user can specify that an alternative XSL file should be used
      #via the TSCG.XSL.FILENAMES variable.
      # Make TSCG.XSL.FILENAMES a list with the names implying which version
      if (!exists("TSCG.XSL.FILENAMES", where=0))
      {
         xslFileName <- file.path(lib.loc, section, "xml", "tscgGraphJobXmlToSplusScript.xsl")
         xslFileNames <- list()
         if (file.exists(xslFileName))
            xslFileNames[["default"]] <- xslFileName
         xslFileName <- file.path(lib.loc, section, "xml", "tscgGraphJobXmlToSplusScript20.xsl")
         if (file.exists(xslFileName))
            xslFileNames[["2.0"]] <- xslFileName
         assign("TSCG.XSL.FILENAMES", xslFileNames, where=0)
         setenv("TSCG_XSL_PACKAGE", "tscg")}

      Note that this code checks for a previous definition of the variable TSCG.XSL.FILENAMES. It handles the cases where one needs to support previous versions. To bypass the default set a new variable in the init_TSCG.ssc file with code similar to the following:

      xslFileName <- "[Insert the modified XSL file path here]"
      assign("TSCG.XSL.FILENAMES", list("2.0"=xslFileName))

       

      Comments