Skip to main content
Previous sectionNext section

Defining Advanced KPIs

This chapter describes how to implement KPIs that use advanced features. It discusses the following:

Also see the chapters “Defining Basic KPIs” and “Defining KPIs with Filters and Listings.”

Defining Manual KPIs

Any KPI is an instance of a subclass of %DeepSee.KPI. In a manual KPI, callback methods set properties of that instance. This section discusses the following topics:

Available Properties

In the callback methods of your KPI instance, the following properties are available:

  • %seriesCount — Specifies the number of series (rows) in this KPI.

  • %seriesNames(n) — Specifies the name of the series n, where n is an integer.

  • %data(n,propname) — Specifies the value of the given property (propname), for the series n.

  • %rangeLower — Specifies the lower range value, which sets the default lower range indicator when this KPI is displayed in a meter.

  • %rangeUpper — Specifies the upper range value, which sets the default upper range indicator when this KPI is displayed in a meter.

  • %thresholdLower — Specifies the lower threshold value, which sets the default lower threshold indicator when this KPI is displayed in a meter.

  • %thresholdUpper — Specifies the upper threshold value, which sets the default upper threshold indicator when this KPI is displayed in a meter.

  • %filterValues — Contains the values of any filters. For details, see the previous chapter.

Overriding KPI Properties

The %OnLoadKPI() callback enables you to override properties of the KPI object instance before it is displayed. You can use this to specify the range and threshold values at run time. This callback has the following signature:

Method %OnLoadKPI() As %Status

You can also set these properties within other methods of the KPI class.

Example

The following example is from HoleFoods.KPISalesVsTarget:

Method %OnLoadKPI() As %Status
{
    Set tSC = $$$OK

    // Compute additional values
    Set tFilters = ..%filterValues

    // compute recent history using query
    If ((tFilters.Year'="")&&(tFilters.Year'="*")) {
        // Take &[] off of Year value!
        Set tStartMonth = "Jan-"_$E(tFilters.Year,3,6)
        Set tEndMonth = "Dec-"_$E(tFilters.Year,3,6)
    }
    Else {
        Set tStartMonth = "NOW-12"
        Set tEndMonth = "NOW"
    }

    Set tROWS = ..RowsClause
    Set tMDX = "SELECT "_tROWS_"%LIST(DateOfSale.[MonthSold].["_tStartMonth_"]:["_tEndMonth_"]) "
      _"ON COLUMNS FROM HOLEFOODS WHERE Measures.[Amount Sold] " _ ..FilterClause
    Set tRS = ##class(%DeepSee.ResultSet).%New()
    Set tSC = tRS.%PrepareMDX(tMDX)
    If $$$ISERR(tSC) Quit tSC
    Set tSC = tRS.%Execute()
    If $$$ISERR(tSC) Quit tSC

    For n = 1:1:..%seriesCount {
        Set tValue = tRS.%GetOrdinalValue(1,n)
        Set ..%data(n,"History") = tValue
    }
    Quit tSC
}
Copy code to clipboard

This method populates the History property of this KPI. For each product, this property is a comma-separated list of the past sales, month by month.

Defining a Manual Query

To base a KPI on a manual (custom) query, do the following:

  • Specify sourceType="manual" within the <kpi> element.

  • Override the %OnExecute() callback method of the KPI class. This method has the following signature:

    method %OnExecute() as %Status 
    

In this method, define a query using any logic you need. Then set the %seriesCount, %seriesNames, and %data properties.

Example

The following shows a simple example with hardcoded values:

Method %OnExecute() As %Status
{
    Set ..%seriesCount=3
    Set ..%seriesNames(1)="alpha"
    Set ..%seriesNames(2)="beta"
    Set ..%seriesNames(3)="gamma"
    Set ..%data(1,"property1")=123
    Set ..%data(1,"property2")=100000
    Set ..%data(1,"property3")=1.234
    Set ..%data(2,"property1")=456
    Set ..%data(2,"property2")=200000
    Set ..%data(2,"property3")=2.456
    Set ..%data(3,"property1")=789
    Set ..%data(3,"property2")=300000
    Set ..%data(3,"property3")=3.789
    Quit $$$OK
}
Copy code to clipboard

Defining Cacheable KPIs

By default, a KPI that uses an MDX query is cached (along with all other MDX queries). This cache may or may not be recent enough for your purposes; that is, you can also cache the KPI specifically as described in this section.

By default, non-MDX KPIs are not cached.

To modify a KPI so that its results are cached, make the following changes to the KPI class:

  • Specify the CACHEABLE class parameter as 1.

  • Implement the %OnComputeKPICacheKey() method.

    Method %OnComputeKPICacheKey(Output pCacheKey As %String, 
                                pQueryText As %String = "") As %Status
    Copy code to clipboard

    Where pQueryText is the text of the KPI query and pCacheKey is a unique key to associated with the cached results. Typically this is a hashed version of the query text.

  • Implement the %OnComputeKPITimestamp() method.

    Method %OnComputeKPITimestamp(ByRef pTimestamp As %String, 
                                 pSourceType As %String, 
                                 pQueryText As %String = "") As %Status
    Copy code to clipboard

    Where pSourceType is a string that indicates the query type ("mdx", "sql", or "manual"), pQueryText is the text of the KPI query, and pTimestamp is the timestamp of the KPI.

    For a given KPI, if %OnComputeKPITimestamp() returns the same timestamp stored in the KPI cache for the given key, DeepSee uses the cached value. Otherwise, DeepSee reruns the KPI.

    By default, %OnComputeKPITimestamp() returns a timestamp that is precise to the minute. This means that the cache is kept for a minute (at most) by default.

To clear the cache for a given KPI, call its %ClearKPICache() method.

Defining Asynchronous KPIs

Except for plugins (in the next chapter), KPIs are executed synchronously.

To modify a KPI so that it executes asynchronously, make the following changes to the KPI class:

  • Specify the ASYNC class parameter as 1.

  • Also modify the KPI so that its results are cached. See the previous section.

    This is required so that DeepSee has a place to store the results.

  • Within %OnCompute(), optionally call %SetPercentComplete() to indicate the state of processing. For details, see “Indicating State of Completion” in the next chapter.