Share via


How to: Create Scorecard Transforms

In PerformancePoint Monitoring Server, transforms modify the data in scorecards before the views are rendered in a dashboard or in PerformancePoint Dashboard Designer. This topic contains code examples for two simple scorecard transforms:

Note

To download a code sample of a transform that hides empty rows in scorecards, see Hiding Empty Rows in a Scorecard - Code Sample on the Microsoft PerformancePoint Team Blog.

Procedures

Prerequisites

Before you create your transform, ensure you have met the following prerequisites:

  • Install Monitoring Server.

  • Be prepared to sign your DLL with a strong name. In addition, ensure that all assemblies referenced by your DLL have strong names. For information about how to sign an assembly with a strong name and how to create a public/private key pair, see How to: Create a Public/Private KeyPair.

To create a scorecard transform

  1. Create a class library and add the Microsoft.PerformancePoint.Scorecards.Client assembly as a project reference.

  2. Add the following using directives.

    using System;
    using System.Collection.Generic;
    using System.Text;
    using Microsoft.PerformancePoint.Scorecards;
    using Microsoft.PerformancePoint.Scorecards.Extensions; 
    using Microsoft.PerformancePoint.Scorecards.GridViewTransforms;
    
  3. Inherit from the IGridViewTransform interface.

  4. To return the string identifier for your transform, override the GetId method.

  5. To specify when to run the transform, override the GetTransformType method. The point at which a transform runs depends on its types: PreQuery, PostQuery, or PreRender. For more information, see Types of Transforms.

  6. To define how to transform the scorecard, override the Execute method.

  7. Build the scorecard transform DLL. Ensure that the DLL is signed with a strong name.

  8. Install your transform on the servers in your Monitoring Server deployment. For information, see How to: Install Scorecard Transforms.

Examples

The following code examples demonstrate how to create global and conditional scorecard transforms.

Change the Default Format

The transform created by the following code example changes the default font and background colors for row and column headers on all scorecards on a server. This transform resets properties in the GridViewData class.

Note

For information about modifying dashboard settings by editing the CSS files, see Working with the Monitoring CSS Files to Adjust Settings in Deployed Dashboards on the Microsoft PerformancePoint Team Blog. For information about the scorecard formatting process, see Scorecard Formatting.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.Extensions;
using Microsoft.PerformancePoint.Scorecards.GridViewTransforms;

namespace Extensions.Dashboard
{

    public class FormattingTransform : IGridViewTransform
    {

        // Set the "PreRender" transform type to run the transform
        // immediately before the scorecard is rendered.
        public GridViewTransformType GetTransformType()
        {
            return GridViewTransformType.PreRender;
        }

        // Return the string idenfitier of your transform.
        public string GetId()
        {
            return "FormattingTransform";
        }

        // Run the transform. This transform changes the font and background 
        // color for all scorecards.
        public void Execute(GridViewData viewData, PropertyBag parameters, IGlobalCache cache)
        {

            // Change the default font.
            viewData.DefaultCellFormatInfo.FontInfo.FamilyName = "Cambria";

            // Change the default header background color by creating new GridColor
            // objects and then assigning them as the value for the BackColor property.
            GridColor columnHeaderBackColor = new GridColor(0xaa, 0xee, 0xff, 0xaa);
            GridColor rowHeaderBackColor = new GridColor(0xff, 0xee, 0xff, 0xcc);
            viewData.DefaultColumnHeaderFormatInfo.BackColor = columnHeaderBackColor;
            viewData.DefaultRowHeaderFormatInfo.BackColor = rowHeaderBackColor;

        }
    }
}

Show When an Annotation Was Last Updated

The transform created by the following code example shows when a cell annotation was last updated by inserting a string into a "Comment" column. If an annotation in the row was updated within the last day, it inserts the string "NEW." Otherwise, the string displays the number of days since it was last updated.

This conditional transform runs only on scorecards on which the Allow Comments feature is enabled. It is designed for dashboards that contain one scorecard and is best suited for scorecards in which only one column receives comments. This transform requires the following setup from Dashboard Designer:

  • A target KPI named "Comment" is added to the KPIs that are used in the scorecard.

  • The "Comment" KPI is added to the scorecard as a column.

  • In addition to the Allow Comments feature, the Enable Comments feature is enabled on the server. See the Dashboard Designer online help documentation for information about enabling these features.

Note

Update the scorecard or refresh the dashboard page after adding a comment to see the results of this transform.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.PerformancePoint.Scorecards;
using Microsoft.PerformancePoint.Scorecards.Extensions;
using Microsoft.PerformancePoint.Scorecards.GridViewTransforms;


namespace Extensions.Dashboard
{
    public class ShowAnnotationDate : IGridViewTransform
    {

        // Set transform type to "PreRender," which runs the 
        // transform immediately before the scorecard is rendered.
        public GridViewTransformType GetTransformType()
        {
            return GridViewTransformType.PreRender;
        }

        // Return the string identifier of your transform.
        public string GetId()
        {
            return "ShowAnnotationDate";
        }

        // Run the transform to show the number of days since the
        // annotation was last updated. This number is inserted
        // into an existing target KPI column in the scorecard.
        // The scorecard view is represented by the GridViewData class.
        public void Execute(GridViewData viewData, PropertyBag parameters, IGlobalCache cache)
        {

            #region Make sure "Allow Comments" is enabled

            // Check to see if the Allow Comments feature (View Options menu)
            // is enabled for the scorecard view. This example assumes that
            // there is only one scorecard in the dashboard.
            Scorecard scorecardInlocalCache = cache.GetScorecard(viewData.ScorecardId);
            ConfiguredView configuredView = scorecardInlocalCache.ConfiguredViews[0];
            if (configuredView == null || configuredView.AllowAnnotations != true)
            {
                return;
            }

            #endregion

        #region Find the "Comments" column

            // Create a placeholder object to represent the "Comment" column.
            // Row and column headers are GridHeaderItem objects.
            GridHeaderItem commentColumn = new GridHeaderItem();

            // Get the "Comment" column by finding the column headers
            // with the display text "Comment". 
            List<GridHeaderItem> allColumnHeaders = viewData.RootColumnHeader.GetAllLeafHeadersInTree();
            foreach (GridHeaderItem colHeader in allColumnHeaders)
            {
                if (colHeader.DisplayText == "Comment")
                {

                  // Set the placeholder to the "Comment" column.
                  commentColumn = colHeader;
                }
            }

            #endregion


            #region Find cells with comments and add the updated date to the "Comment" column

            // Loop through each row header.
            List<GridHeaderItem> leafRowHeaders = viewData.RootRowHeader.GetAllHeadersInTree();
            foreach (GridHeaderItem rowHeader in leafRowHeaders)
            {

               // Loop through each column header.
               List<GridHeaderItem> leafColumnHeaders = viewData.RootColumnHeader.GetAllLeafHeadersInTree();
               foreach (GridHeaderItem columnHeader in leafColumnHeaders)
               {
                    // Get the scorecard cells, which are represented by the
                    // GridCell class. Cell coordinates can be identified
                    // by the intersection of a row and column header.
                    GridCell cell = viewData.Cells[rowHeader, columnHeader];

                    // Look at only those cells that have an annotation, which
                    // contains a collection of Comment objects.
                    if (cell.HasAnnotation == true)
                    {

                        // Create the DateTime and TimeSpan objects to use to
                        // compare against the last updated DateTime object.
                        DateTime lastUpdatedDate = cell.CellAnnotation.LastUpdatedOn;
                        TimeSpan daysSinceLastUpdate = DateTime.Now - lastUpdatedDate;

                        // Create the string that will populate the cells in
                        // the "Comment" column.
                        string sTimeDiff = "";

                        // Set the string contents based on the number of
                        // days since the annotation was last updated.
                        int iTimeDiff = daysSinceLastUpdate.Days;
                        if (iTimeDiff < 0)
                        {
                            sTimeDiff = "error";
                        }
                        else
                        {
                            switch (iTimeDiff)
                            {
                                case 0:

                                    // The string "NEW" indicates that the
                                    // annotation was updated in the
                                    // last day.
                                    sTimeDiff = "NEW";
                                    break;
                                case 1:
                                    sTimeDiff = iTimeDiff.ToString() + " day";
                                    break;
                                default:
                                    sTimeDiff = iTimeDiff.ToString() + " days";
                                    break;
                            }
                        }

                        // Get the cell in the "Comment" column that
                        // corresponds to the cell with the annotation.
                        // Get these cells by passing in the "commentColumn"
                        // GridHeaderItem that was created earlier.
                        GridCell commentCell = viewData.Cells[rowHeader, commentColumn];
                        
                        // Set the GridDisplayElement.Text property used
                        // by the GridCell object for the display text
                        // of the cell.
                        foreach (GridDisplayElement cellDisplayElement in commentCell.DisplayElements)
                        {
                            cellDisplayElement.Text = sTimeDiff;
                        }
                    }
                }

            #endregion

            }
        }
    }
}

See Also

Concepts

Types of Transforms

Other Resources

Hiding Empty Rows in a Scorecard - Code Sample
Working with the Monitoring CSS Files to Adjust Settings in Deployed Dashboards