254
Developer Guide FICO® Xpress Optimization FICO ® Xpress Insight 4.9 Make every decision count™ www.fico.com

Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

  • Upload
    lamtruc

  • View
    238

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Developer Guide

FICO® Xpress Optimization

FICO® Xpress Insight

4.9

Make every decision count™www.fico.com

Page 2: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

This material is the confidential, proprietary, and unpublished property of Fair Isaac Corporation. Receipt or possession of this material does not convey rights to divulge, reproduce, use, or allow others to use it without the specific written authorization of Fair Isaac Corporation and use must conform strictly to the license agreement. The information in this document is subject to change without notice. If you find any problems in this documentation, please report them to us in writing. Neither Fair Isaac Corporation nor its affiliates warrant that this documentation is error-free, nor are there any other warranties with respect to the documentation except as may be provided in the license agreement. © 2013–2017 Fair Isaac Corporation. All rights reserved. Permission to use this software and its documentation is governed by the software license agreement between the licensee and Fair Isaac Corporation (or its affiliate). Portions of the program may contain copyright of various authors and may be licensed under certain third-party licenses identified in the software, documentation, or both. In no event shall Fair Isaac Corporation or its affiliates be liable to any person for direct, indirect, special, incidental, or consequential damages, including lost profits, arising out of the use of this software and its documentation, even if Fair Isaac Corporation or its affiliates have been advised of the possibility of such damage. The rights and allocation of risk between the licensee and Fair Isaac Corporation (or its affiliates) are governed by the respective identified licenses in the software, documentation, or both. Fair Isaac Corporation and its affiliates specifically disclaim any warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. The software and accompanying documentation, if any, provided hereunder is provided solely to users licensed under the Fair Isaac Software License Agreement. Fair Isaac Corporation and its affiliates have no obligation to provide maintenance, support, updates, enhancements, or modifications except as required to licensed users under the Fair Isaac Software License Agreement. FICO is a registered trademark of Fair Isaac Corporation in the United States and may be a registered trademarks of Fair Isaac Corporation in other countries. Other product and company names herein may be trademarks of their respective owners. FICO® Xpress Insight Deliverable Version: A Last Revised: October 2017 Version 4.9

Page 3: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 3

Contents

CHAPTER 1 Introduction ..................................................................................... 13

Developer Prerequisites .......................................................................................................... 13

Xpress Insight Documentation ................................................................................................. 14

Key Concepts .......................................................................................................................... 14

Change of Name ..................................................................................................................... 15

Change in terminology: Project to App .................................................................................... 15

CHAPTER 2 Getting Started with Xpress Insight .............................................. 17

Prerequisites ............................................................................................................................ 17

Setting up a Development Environment for the Example App ................................................ 17

Setting up Xpress Insight and Xpress Workbench on the FAC ........................................ 18

Building an Xpress Insight App............................................................................................... 19

Introducing the Example Business Problem ..................................................................... 19

Formulating the Model ...................................................................................................... 20

Running the Model in Xpress Workbench ............................................................................... 22

Up and Running in Xpress Insight ........................................................................................... 24

Making the Minimum, Mandatory Changes ...................................................................... 25

Commentary ...................................................................................................................... 26

Publishing to Xpress Insight .............................................................................................. 27

Completing the Recommended Directory Structure ......................................................... 31

Working with Annotations ................................................................................................. 32

Introducing the Companion File ........................................................................................ 34

Page 4: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Contents

4 Fair Isaac Confidential and Proprietary

Adding a Custom User Interface .............................................................................................. 35

Adding a VDL View to the Example App ........................................................................... 36

Binding the User Interface to Scenario Data ..................................................................... 37

Using Expressions ............................................................................................................. 40

Adding Forms and Fields ................................................................................................... 43

Improving the User Interface ............................................................................................. 45

Validating User Input and Adding Tooltips ........................................................................ 47

Adding a Visualization Using Tableau for FICO ...................................................................... 50

Exposing Mirror Data to Tableau and Configuring a Data Source .................................... 50

Creating a Simple Tableau View ....................................................................................... 51

Using Attachments ................................................................................................................... 53

Adding an Attachment in Development ............................................................................. 53

Reviewing and Changing an Attachment at Runtime ........................................................ 55

Understanding Execution Modes ............................................................................................. 57

Adding a Custom Execution Mode .................................................................................... 57

Moving to the Next Level ......................................................................................................... 59

CHAPTER 3 Developing an Application with Xpress Insight .......................... 60

How Xpress Insight Interacts with a Mosel Model ................................................................... 60

Xpress Insight Model Requirements ........................................................................................ 61

Supported Mosel Features, Types and Data Sources ............................................................. 62

Supported Mosel Types ..................................................................................................... 62

Supported Data Sources ................................................................................................... 64

Models using mmjobs ........................................................................................................ 65

The Xpress Insight Repository ................................................................................................. 65

Page 5: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 5

The App ................................................................................................................................... 65

Configuring the App ................................................................................................................. 67

App Name and Version ..................................................................................................... 67

Custom Execution Modes ........................................................................................................ 68

Defining Custom Execution Modes ................................................................................... 68

Using Custom Execution Modes from the model .............................................................. 68

App Resources Files ............................................................................................................... 70

Model Resources .............................................................................................................. 70

User Interface Resources ................................................................................................. 70

App Attachments ............................................................................................................... 70

Data Management and Scalability ........................................................................................... 71

Basic Presentation Customizations ......................................................................................... 72

Debugging Aids ....................................................................................................................... 73

Adding an App Icon ................................................................................................................. 74

Configuring App specific help .................................................................................................. 74

Using Attachments .................................................................................................................. 75

CHAPTER 4 Authoring Custom Views ............................................................... 79

Options for Custom View Authoring ........................................................................................ 79

The View Definition Language .......................................................................................... 79

The JavaScript API ........................................................................................................... 79

Tableau® for FICO Reporting ........................................................................................... 79

Setting up your Development Environment ............................................................................. 80

Manually updating an Xpress Insight App from the Web Client ....................................... 80

Automatic Code Refresh ................................................................................................... 81

Page 6: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Contents

6 Fair Isaac Confidential and Proprietary

CHAPTER 5 Authoring a Custom View with the View Definition Language ............................................... 83

VDL Fundamentals .................................................................................................................. 83

Controlling page layout and styling ................................................................................... 84

Expressions ....................................................................................................................... 89

Loops ................................................................................................................................. 98

Conditionals ....................................................................................................................... 99

VDL includes.................................................................................................................... 100

Core Components .................................................................................................................. 101

VDL tables (vdl-table) ...................................................................................................... 101

VDL forms (vdl-form and vdl-field) ................................................................................... 111

VDL charts (vdl-chart) ...................................................................................................... 115

Validators ......................................................................................................................... 122

Execute buttons ............................................................................................................... 125

Attachment buttons .......................................................................................................... 126

VDL text ........................................................................................................................... 128

Tooltips ............................................................................................................................ 128

Advanced VDL ....................................................................................................................... 129

Dynamic attributes ........................................................................................................... 129

Image attachments .......................................................................................................... 130

No-Results overlays ........................................................................................................ 130

View links ......................................................................................................................... 131

Custom Extensions .......................................................................................................... 131

DOM Events .................................................................................................................... 135

Page 7: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 7

VDL Hints ........................................................................................................................ 136

Entity Preloading ............................................................................................................. 137

CHAPTER 6 Authoring a Custom View with the JavaScript API ................................................................ 139

Loading the API ..................................................................................................................... 139

Concepts ................................................................................................................................ 140

The Selection .................................................................................................................. 140

Example: Hello, World! .......................................................................................................... 141

The View ......................................................................................................................... 143

Observers ........................................................................................................................ 143

AutoText .......................................................................................................................... 144

CSS Styling ..................................................................................................................... 145

Common Issues .............................................................................................................. 145

The ScenarioObserver .......................................................................................................... 145

Array Filters ..................................................................................................................... 149

Accessing Data ............................................................................................................... 150

Accessing Array Data ..................................................................................................... 151

View Properties ..................................................................................................................... 151

View Properties and Array Filters ................................................................................... 153

Promise API ........................................................................................................................... 153

Modifying Scenario Data ....................................................................................................... 155

Local Data Changes........................................................................................................ 156

Executing a scenario ....................................................................................................... 157

The AutoComponents ............................................................................................................ 158

Page 8: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Contents

8 Fair Isaac Confidential and Proprietary

AutoText .......................................................................................................................... 158

AutoForm ......................................................................................................................... 159

AutoTable ........................................................................................................................ 163

Entity Validation ............................................................................................................... 168

Creating a Custom Table ....................................................................................................... 169

Entity Formatting .................................................................................................................... 171

Entity Validation ..................................................................................................................... 172

Custom Set Sorting ................................................................................................................ 172

View Configuration ................................................................................................................. 172

Overlays ........................................................................................................................... 172

Exception Handling .......................................................................................................... 174

Working with Unloaded Scenarios .................................................................................. 174

Using Modal Dialog Boxes .............................................................................................. 176

Including Additional JavaScript Libraries ......................................................................... 176

Working with Attachments...................................................................................................... 176

The Attachments API ....................................................................................................... 177

The Attachment Tags API ............................................................................................... 180

Displaying Attachment Data with AutoText ..................................................................... 181

Displaying Attachment Tag Data with AutoText .............................................................. 182

Image attachments .......................................................................................................... 183

Advanced Subjects ................................................................................................................ 183

Configuring the Web Client Welcome Page .................................................................... 183

Reflection and the Model Schema .................................................................................. 183

Web Client Performance Specifics .................................................................................. 184

Data Dimensions ............................................................................................................. 184

Page 9: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 9

Debugging Custom Views in the Web Client ......................................................................... 185

Common Issues ..................................................................................................................... 186

CHAPTER 7 Authoring a Custom View with Tableau for FICO ................................................................... 187

Configuring the Mirror to Expose Data to Tableau ................................................................ 187

Creating a Workbook ............................................................................................................. 189

Creating a Simple View ......................................................................................................... 199

Adding Tableau Workbooks to an Xpress Insight App .......................................................... 203

Managed Workbooks ...................................................................................................... 204

Unmanaged Workbooks ................................................................................................. 204

Adding a Tableau Workbook as a Managed Workbook ................................................. 204

Adding a Tableau Workbook as an Unmanaged Workbook ........................................... 205

Publishing Workbooks Manually via the Web Client ............................................................. 206

Publishing Workbooks Manually via Tableau Desktop ......................................................... 209

Configuring a data source in Xpress Insight to expose data to Tableau ............................... 210

Securing Tableau Workbooks ............................................................................................... 212

Restricting the Data Source to Authorized Users ........................................................... 212

Restricting the View to Only the Selected Scenarios in the Client ................................. 217

Restricting the Data Source to Authorities and Authority Groups ................................... 218

Tableau Global Filters ........................................................................................................... 218

Defining Tableau Global Filters ....................................................................................... 219

When defining Filters and Parameters in Tableau that will be used as Tableau Global Filters .............................................................................................................................. 220

Tableau Global Filters in the Web Client ........................................................................ 221

Developing Workbooks for the FICO Analytic Cloud............................................................. 222

Page 10: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Contents

10 Fair Isaac Confidential and Proprietary

Tableau Packaged Workbooks (TWBX) ................................................................................ 223

Advanced Mirror Configuration .............................................................................................. 223

Controlling On-demand Mirror Table Population ............................................................. 223

Controlling Post-execution Mirror Table Population ........................................................ 225

CHAPTER 8 Accessing the Xpress Insight Server Using the REST API ...................................................................... 228

Authentication ........................................................................................................................ 228

Logout .............................................................................................................................. 228

Mime Types ............................................................................................................................ 229

Identifiers ................................................................................................................................ 229

Locking ................................................................................................................................... 229

Pagination .............................................................................................................................. 230

CHAPTER 9 Advanced Topics .......................................................................... 232

Understanding Inter-Scenario Data Access ........................................................................... 232

Using Inter-Scenario Data Access .................................................................................. 232

Repository Paths ............................................................................................................. 233

Supported Types ............................................................................................................. 233

Limitations ........................................................................................................................ 233

Controlling Access to VDL, JavaScript, and Tableau Views .................................................. 234

Multiple Users and Authorization ........................................................................................... 235

Building Apps that use the Decision Tree Editor ................................................................... 236

APPENDIX A Upgrade Guide .............................................................................. 238

Migrating from Companion File 2.0 to 3.0 and using Mosel Annotations .............................. 238

Page 11: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 11

Migrating VDL 2.0 apps to VDL 4.0 ....................................................................................... 239

Change the version of your VDL file ............................................................................... 239

Namespacing tags and attributes ................................................................................... 239

AutoText changes ........................................................................................................... 240

Convert custom runner code to script blocks .................................................................. 240

Table modifiers ................................................................................................................ 240

Remove custom runner references from c-file ................................................................ 241

Remove Handlebars references ..................................................................................... 241

Upgrading to Xpress Insight 4.2 ............................................................................................ 242

Changes to mminsight .................................................................................................... 242

Upgrading from Xpress Insight 4.0 or earlier ......................................................................... 243

VDL 2.0 ........................................................................................................................... 243

JavaScript API 2.X .......................................................................................................... 244

Migrating to Bootstrap 3 .................................................................................................. 245

Loading the JavaScript API ............................................................................................. 245

New Companion File Format .......................................................................................... 247

Summary of Companion File Changes ........................................................................... 248

APPENDIX B Third-party Libraries Bundled with Xpress Insight JavaScript API ............................................. 251

APPENDIX C Contacting FICO............................................................................ 253

Product Support ..................................................................................................................... 253

Product Education ................................................................................................................. 253

Product Documentation ......................................................................................................... 253

Sales and Maintenance ......................................................................................................... 254

Page 12: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Contents

12 Fair Isaac Confidential and Proprietary

Related Services .................................................................................................................... 254

About FICO ............................................................................................................................ 254

Page 13: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 13

CHAPTER 1 Introduction

Developer Prerequisites This guide describes how to develop and deploy optimization applications using FICO® Xpress Insight. The optimization model at the heart of the application is authored using the FICO® Xpress-Mosel modeling language and solved using Xpress Solver. As such, it is assumed that the developer has experience with developing optimization models using Mosel, the Xpress Workbench editor, and the Solver algorithms. The solver algorithms are documented in the Optimizer Reference Manual. You can customize the interaction between Xpress Insight and the Mosel model and how the model is presented to the end user. The configuration options are specified in an XML file. As such, a basic understanding of how to create and edit XML documents is required. Custom views can be added using the following methods. As embedded web pages using the View Definition Language (VDL). To

implement a VDL-based view, the developer will need a working knowledge of XML notation and optionally, HTML. For more information on VDL view authoring please see Authoring a Custom View with the View Definition Language.

Custom views can be created as embedded web pages using JavaScript. To implement a JavaScript based page, the developer will need a working knowledge of JavaScript, HTML, and CSS. The principles and API for creating JavaScript Views are documented in the chapter Authoring a Custom View with the JavaScript API.

Custom views can be created in Tableau®, published to the Tableau Server and made available from Xpress Insight. To create views using Tableau, it is expected that the author is already familiar with doing so in Tableau. For information about how to create views for Xpress Insight with Tableau, see Authoring a Custom View with Tableau for FICO. You also need to be familiar with the user interface of the Xpress Insight web client software to understand how the model will appear to the business user and what the impact of the customization options might be.

Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User Guide, available in desktop or hosted variants.

Page 14: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

14 Fair Isaac Confidential and Proprietary

Xpress Insight Documentation The following list describes the development resources that are available for Xpress Insight: The FICO® Xpress Insight Developer Guide describes how to develop and

deploy optimization applications using Xpress Insight. The Xpress Workbench User Guide describes how to develop and publish

Xpress Insight apps. The Xpress Insight REST API documentation is located at

<installdir>\docs\insight\rest_api\ The Xpress Insight JavaScript API documentation is located at

<installdir>\docs\insight\javascript_api\ The Xpress Insight mminsight interface to Mosel documentation is located at

<installdir>\docs\insight\mminsight\ Information about XML configuration options that are available to developers

is located in <installdir>\docs\insight\xml_reference\. A number of examples located in <installdir>\examples\insight. FICO training course. Contact your FICO representative for details.

Key Concepts The architectural components of an Xpress Insight system include Xpress Insight Server, Xpress Insight Repository, one or more Xpress Insight Clients, and one or more optimization servers. These components are described below: Xpress Insight Server: The core of the application. It may be located on the

same local machine as the client or on a remote server, depending on the system configuration of Xpress Insight. The Server is typically installed as a service but may also be manually started and stopped from Start menu options.

Xpress Insight Repository: A hierarchical database used to store all of the data that Xpress Insight manages. By default the database is located on the same machine as the Xpress Insight Server.

Xpress Insight client: The Xpress Insight web client offers a web browser-based interface.

Xpress Insight Execution Workers: Execution Workers (‘workers’) are the individual machines on which scenarios ultimately execute. Their processing resources can be logically partitioned by creating, provisioning and mapping one or more execution services. The division of responsibilities between workers, execution services and their mappings provides for fine-grained control of the compute resources that can be dedicated to or consumed by executing jobs.

Tableau for FICO – Server: An optional component that allows Tableau visualizations to integrate into the Xpress Insight user interface as custom

Page 15: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 15

views for advanced reporting.

The following list describes the key data artifacts in the Xpress Insight system: App: The parent object. It contains one model and one or more scenarios

created by the user (optionally arranged into folders) as defined below. Apps can be loaded as standalone bim (compiled Mosel model) files or as a zip archive of bim file and associated resources.

Model: The optimization model. It defines a set of input entities to receive scenario data and a set of result entities that will be populated with the optimization solution. The solution is the set of values representing the decisions identified by the optimization process, and other data synthesized from these values. The model contains a set of constraints that place restrictions on what is a valid solution to the optimization model.

Scenario: A scenario contains the input data and results data from the model. If the scenario has not been loaded, the input data section will be empty. The result data section is only present if the scenario has been run.

Clients connected to the Xpress Insight server receive notifications when the state of the system changes. Clients are expected to display the live state of the persisted data whenever possible. (An exception is when the client has data or state modifications that have not yet been saved or applied.) To allow multi-client access and data updates, the Xpress Insight system implements a lock mechanism. Artifacts in the repository have an associated lock that must be obtained by a client or the server before any modification to that item is allowed. Only one client or the server can hold the lock at any time. Xpress Insight clients are expected to reflect the status of the locks as an editable/read-only mode in the client user interface. The web client holds a lock for the minimal time required to commit an atomic edit of the user.

Change of Name With version 4.8, the name of the system has changed from Optimization Modeler to Xpress Insight.

Change in terminology: Project to App Prior to Xpress Insight 4.7, what is now known as an app was then called a Project. The name has been change in order to avoid confusion with the notion of a Project in FICO® Decision Optimizer. While this document and related Xpress Insight documentation will use “App” throughought, for compatibility there are developer-specific uses of “Project”. The APIs have been not been updated to reflect this change from previous versions, so you will see e.g. a Javascript function getProject() rather than getApp(). The same is true of the file system, hence references to the project_attachments folder and the project-icon.png file.

Page 16: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

16 Fair Isaac Confidential and Proprietary

The system authorities covering permissions relating to apps have been cosmetically changed in the user interface, but the underlying names are the same as before. Thus the authority concerning app deletion is actually called “PROJECT_DELETE”, and this is how you would refer to it in your code, even though if you were to look in the Administration User Interface it would appear to be called “APP_DELETE”. (This only applies to authorities defined by Xpress Insight itself; those defined by users or apps are unaffected.)

Page 17: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 17

CHAPTER 2 Getting Started with Xpress Insight

This chapter is a self-contained introduction to using Xpress Insight alongside Xpress Workbench – a modern development environment that supports the development and publishing of Xpress Insight apps. In this chapter, we walk through a workflow in which a business problem is formulated as a Mosel model and transformed by stages into an interactive Xpress Insight app. This is not an exhaustive introduction - rather, it provides a flavor of the activities necessary to build an Xpress Insight solution using Xpress Workbench as a development environment. Its goal is to get you started on the road to building your own Xpress Insight apps, not to make you an expert.

Prerequisites To get the most benefit from this chapter, you should: Have access to hosted versions of Xpress Insight and Xpress Workbench.

They will typically either be hosted on your own on-premises infrastructure, or on the FICO Analytic Cloud (FAC).

Note: If you are using the desktop version of Xpress Workbench, there are some minor differences when compared to the hosted version. With a few common-sense accommodations, you will still be able to follow the exercises and progression of this chapter. Be familiar with Mosel (at least able to read simple models), HTML and XML.

View Definition Language (VDL) is largely composed of a set of HTML extensions.

Have some experience of programming and the usual edit-compile-run development cycles.

More advanced use of Xpress Insight will benefit from a good knowledge of JavaScript and further experience with Mosel.

Setting up a Development Environment for the Example App

This section describes how to set up a FICO Decision Management Platform (DMP) environment incorporating Xpress Workbench and Xpress Insight on the FICO Analytic Cloud (FAC). If you are using the desktop version of Xpress Workbench and a local installation of Xpress Insight, you can skip this section and move on to Building an Xpress Insight App which follows the next section.

Page 18: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

18 Fair Isaac Confidential and Proprietary

If you are accessing Xpress Insight and Xpress Workbench from your own on- premises infrastructure, you can also skip this section and move on to Building an Xpress Insight App which follows the next section. If you are unsure of the URL to visit to launch your version of Xpress Workbench, contact your system administrator.

Setting up Xpress Insight and Xpress Workbench on the FAC Before you can start building an Xpress Insight app using Xpress Workbench, you need to set up your FAC environment correctly. If you or your organization has already configured your FAC account, visit and log in to https://www.ficoanalyticcloud.com click on your name in the top right, select My Apps and launch the appropriate app. If you are setting up a trial account for the first time, follow these steps:

1 Visit https://www.ficoanalyticcloud.com and sign up if you have not yet done so.

2 Click the Log in menu option, provide your Email and Password and click Log in to log in.

3 Click Decision Management Suite, scroll down to the Optimization section and click Learn More.

4 Click Free 60 day trial, and then Go to my Apps. Your browser is transferred to your Apps page. If no Go to my Apps option is available, click on your name in the top right and select My Apps.

5 Click on the tile for FICO® Optimization Trial. Options for launching Xpress Insight and Xpress Insight are available:

6 Click Launch Xpress Workbench and wait for a few moments while its design instance (and that for Xpress Insight is

Page 19: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 19

provisioned).

Building an Xpress Insight App This main section walks through the key steps in building an Xpress Insight app. They are typical of the stages through which all models progress as they are transformed into independent Xpress Insight apps.

1 An example business problem is introduced and formulated as a simple Mosel model.

2 This initial model is executed from within Xpress Workbench, without any Xpress Insight-specific enhancements.

3 Next, a set of minimal, but mandatory changes are made to the model - these allow it to be published and executed within an Xpress Insight environment.

4 A standard Xpress Insight directory structure is created, the model is annotated with metadata that provides Xpress Insight with further application configuration information, and the groundwork for a custom user-interface is prepared with the creation of a companion file, which describes some of the organizational features of a proposed user interface.

5 The main user interface is built from a combination of VDL elements, introducing the techniques required to use familiar, industry-standard components like tables, forms and fields.

6 A Tableau view is added, illustrating how to provide more complex visualizations of the underlying model data.

7 Finally, the app is enhanced by adding the capability to manipulate attached files from both the model and the user interface, together with the creation of a custom execution mode which offers opportunities to select and trigger model actions.

Introducing the Example Business Problem All models start off with a problem to be solved - in this case, we are going to be working with and extending a portfolio optimization problem introduced in Getting Started with Xpress, part of the Xpress documentation set. Stating the problem: An investor wishes to invest a certain amount of money. She is evaluating ten different share types and their countries of origin for her investment. She has made estimates of the percentage return on investment (ROI) for each share type over a period of one year. The following table contains the details of each share type, its country of origin, its risk category (R: high risk, N: low risk) and the expected ROI.

Page 20: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

20 Fair Isaac Confidential and Proprietary

Number Description Country of Origin

Risk ROI (percentage)

1 Treasury Canada N 5

2 Hardware NA (North America)

R 17

3 Theater NA R 26

4 Telecom NA R 12

5 Brewery UK N 8

6 Highways France N 9

7 Cars Germany N 7

8 Bank Luxemburg N 6

9 Software India R 31

10 Electronics Japan R 21

The investor specifies certain constraints. To spread the risk, she wishes to invest at most 30% of the capital into any individual share type. She further wishes to invest at least half of her capital in North American shares, and at most one third in high-risk shares. How should the capital be divided among the share types to obtain the highest expected ROI?

Formulating the Model This section offers one approach to formulating the initial real-world problem as a Mosel model. Even if you are not a Mosel expert, this model is simple enough for you to be able to glean its intent if you have some programming experience.

Note: The following code fragment contains line numbers, so that they can be referenced in the subsequent commentary. You will need to remove them if you intend to copy and paste into your own development environment.

This file is also available as foliodata.mos from https://examples.xpress.fico.com/example.pl?id=mosel_model_10_1 01: model "Portfolio optimization with LP" 02: uses "mmxprs" ! Use Xpress-Optimizer 03: 04: parameters

05: DATAFILE= "folio.dat" ! File with problem data 06: OUTFILE= "result.dat" ! Output file 07: MAXRISK = 1/3 ! Max. investment into high-risk values 08: MAXVAL = 0.3 ! Max. investment per share

Page 21: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 21

09: MINAM = 0.5 ! Min. investment into N.-American values 10: end-parameters 11: 12: declarations 13: SHARES: set of string ! Set of shares 14: RISK: set of string ! Set of high-risk values among shares 15: NA: set of string ! Set of shares issued in N.-America 16: RET: array(SHARES) of real ! Estimated return in investment 17: end-declarations 18: 19: initializations from DATAFILE 20: RISK RET NA 21: end-initializations 22: 23: declarations 24: frac: array(SHARES) of mpvar ! Fraction of capital used per share 25: end-declarations 26: 27: ! Objective: total return 28: Return:= sum(s in SHARES) RET(s)*frac(s) 29: 30: ! Limit the percentage of high-risk values 31: sum(s in RISK) frac(s) <= MAXRISK 32: 33: ! Minimum amount of North-American values 34: sum(s in NA) frac(s) >= MINAM 35: 36: ! Spend all the capital 37: sum(s in SHARES) frac(s) = 1 38: 39: ! Upper bounds on the investment per share 40: forall(s in SHARES) frac(s) <= MAXVAL 41: 42: ! Solve the problem 43: maximize(Return) 44: 45: ! Solution printing to a file 46: fopen(OUTFILE, F_OUTPUT) 47: writeln("Total return: ", getobjval) 48: forall(s in SHARES) 49: writeln(strfmt(s,-12), ": \t", strfmt(getsol(frac(s))*100,5,2), "%") 50: fclose(F_OUTPUT) 51: 52: end-model

Page 22: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

22 Fair Isaac Confidential and Proprietary

Commentary Lines 4-10 establish the model's runtime parameters. The specified default values can be changed for every model execution without any need to edit the model source. Lines 12-17 and 23-25 contain the entity declarations. Lines 19-21 initialize the entities with values from a data file in text format called folio.dat which as provided contains the following data: ! Data file for ‘foliodata.mos’

RET: [("treasury") 5 ("hardware") 17 ("theater") 26 ("telecom") 12 ("brewery") 8 ("highways") 9 ("cars") 7 ("bank") 6 ("software") 31 ("electronics") 21 ] RISK: ["hardware" "theater" "telecom" "software" "electronics"] NA: ["treasury" "hardware" "theater" "telecom"]

Note that this file is available as folio.dat from https://examples.xpress.fico.com/example.pl?id=mosel_model_10_1 (... if you download the file, it contains a few more entities that are not used in this guide). Line 28 contains an expression whose value is assigned to an entity called Return - the goal of the problem is ultimately to maximize this expression Lines 30-40 establish the constraints of the problem, while line 43 starts the optimization solver to maximize the value of Return. Finally, lines 45-50 display the results of the optimization run, the output is redirected into a text file called result.dat

Running the Model in Xpress Workbench At this stage, you can run the model via the Mosel command line or from Xpress Workbench. This guide follows a workflow that uses the facilities provided by the browser-based variant of Xpress Workbench and (later) its close integration with Xpress Insight. Before trying to run anything, ensure that you have prepared two files:

■ foliodata.mos - the model source file as described earlier.

■ folio.dat - the separate data file containing values for the RET, RISK and NA entities, and implicitly the SHARES entity - again as described earlier.

To load and run the model within Xpress Workbench: 1 Visit the Xpress Workbench URL and log in. 2 In the Xpress Workbench Home page, click Create Project,

enter a value of Portfolio Optimization in the Name field in the subsequent Create Project dialog and then click Save.

Page 23: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 23

A new tile called Portfolio Optimization appears in the Xpress Workbench Home page.

Note Depending upon your installation, you may see an existing project tile labeled Portfolio - an Optimization Model Example on the Xpress Workbench Home page. This is a more advanced portfolio optimization model provided as an example, and is unrelated to the new Portfolio Optimization project just created.

3 Click on the Portfolio Optimization tile.

Xpress Workbench launches your new project in which it has created a template application structure. Examine the contents of the vertical Project tab:

This arrangement of new files and folders is designed to help you start quickly with a new Xpress Insight app.

4 However, for this first walk-through, we are going to start from scratch, so right-click on the following resources, choose Delete, and confirm: ■ client_resources - folder ■ model_resources - folder ■ source - folder ■ application.xml - file You are left with a single empty Portfolio Optimization root directory.

5 In the File menu, choose Upload Local Files and follow the prompts to upload your prepared files - foliodata.mos and folio.dat - to the Portfolio Optimization root folder. The project structure now appears as:

Page 24: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

24 Fair Isaac Confidential and Proprietary

6 In the Run menu, choose Run foliodata.mos and wait a few moments. The model compiles and runs, and a new file appears in the project tab, which now appears as:

The new file is result.dat, the output file written by the model, originally declared as a parameter in line 8. Note: Depending on the settings of your Xpress Workbench environment, some other files may also appear at this stage. For the purposes of this tutorial, they can safely be ignored.

7 Review the contents of result.dat. It contains:

Total return: 14.0667 treasury : 30.000% hardware : 0.000% theater : 20.000% telecom : 0.000% brewery : 6.667% highways : 30.000% cars : 0.000% bank : 0.000% software : 13.333% electronics : 0.000%

This reveals that the maximum achievable ROI is 14.0667, and that based on the model's constraints, the optimum division of investment capital among share types is 30% to treasury, 20% to theater, 6.667% to brewery, 30% to highways and 13.333% to software.

The model has been run in its native form as a Mosel model, albeit called and executed by Xpress Workbench.

Up and Running in Xpress Insight Before you can begin to add custom views to your Mosel model, some small but mandatory changes need to be made to the model code. These changes ensure that your model can be recognized by Xpress Insight itself, and that it can continue to be run independently via the Mosel command line. ■ The mminsight package must be loaded - it includes

the mminsight.dso Mosel module and implements the necessary interactions between Xpress Insight and the model.

■ To work with Xpress Insight, your model must implement

Page 25: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 25

the two required modes LOAD and RUN: - The model must implement the LOAD mode via code that

initializes all managed model entities. Execution of this loading code must be conditional on insightgetmode=INSIGHT_MODE_LOAD. Any calls to finalize must be included in the loading code.

- The model must implement the RUN mode - related code must be conditional on insightgetmode=INSIGHT_MODE_RUN and begin with a call to insightpopulate. Run mode code typically includes statements to construct the model from scenario data, optimize it and process the results.

■ Calls to maximize and minimize should be replaced with calls to insightmaximize and insightminimize.

■ Input or results data entities that you wish exposed to Xpress Insight should be declared with the public qualifier. Entities declared locally within procedures or functions are not visible to Xpress Insight, they need to be declared globally to be visible.

Making the Minimum, Mandatory Changes The code sample in this section shows the effect of applying the minimal set of changes to the example code. Within Xpress Workbench, change your foliodata.mos file so that it now appears as: 01: model "Portfolio optimization with LP" 02: 03: uses "mminsight" ! Mandatory for Xpress insight 04: uses "mmxprs" ! Use Xpress-Optimizer 05: 06: parameters 07: DATAFILE= "folio.dat" ! File with problem data 08: OUTFILE= "result.dat" ! Output file 09: MAXRISK = 1/3 ! Max. investment into high-risk values 10: MAXVAL = 0.3 ! Max. investment per share 11: MINAM = 0.5 ! Min. investment into N.-American values 12: end-parameters 13: 14: declarations 15: SHARES: set of string ! Set of shares 16: RISK: set of string ! Set of high-risk values among shares 17: NA: set of string ! Set of shares issued in N.-America 18: RET: array(SHARES) of real ! Estimated return in investment 19: end-declarations 20: 21: forward procedure datainput 22: 23: case insightgetmode of 24: INSIGHT_MODE_LOAD: do

Page 26: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

26 Fair Isaac Confidential and Proprietary

25: datainput 26: exit(0) 27: end-do 28: INSIGHT_MODE_RUN: 29: insightpopulate 30: else 31: datainput 32: end-case 33: 34: procedure datainput 35: initializations from DATAFILE 36: RISK RET NA 37: end-initializations 38: end-procedure 39: 40: declarations 41: frac: array(SHARES) of mpvar ! Fraction of capital used per share 42: end-declarations 43: 44: ! Objective: total return 45: Return:= sum(s in SHARES) RET(s)*frac(s) 46: 47: ! Limit the percentage of high-risk values 48: sum(s in RISK) frac(s) <= MAXRISK 49: 50: ! Minimum amount of North-American values 51: sum(s in NA) frac(s) >= MINAM 52: 53: ! Spend all the capital 54: sum(s in SHARES) frac(s) = 1 55: 56: ! Upper bounds on the investment per share 57: forall(s in SHARES) frac(s) <= MAXVAL 58: 59: ! Solve the problem 60: insightmaximize(Return) 61: 62: ! Solution printing to a file 63: fopen(OUTFILE, F_OUTPUT) 64: writeln("Total return: ", getobjval) 65: forall(s in SHARES) 66: writeln(strfmt(s,-12), ": \t", strfmt(getsol(frac(s))*100,5,2),"%") 67: fclose(F_OUTPUT) 68: 69: end-model

Commentary Line 3 includes the mminsight package.

Page 27: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 27

Line 21 contains a forward declaration of a procedure called datainput, which has been created so that it can be invoked from a later case statement, which takes one of three code paths depending on the value of insightgetmode. Lines 23-32 contain the LOAD mode code. If Xpress Insight is loading data, then datainput is called (line 25). If it is simply starting a run, then insightpopulate is called (line 29). If neither of these is true (i.e. the model is running in non-Xpress Insight mode) then datainput is called and execution continues with the next statements. Lines 34-38 wrap the original init ial izations block as the datainput procedure so it is only run if invoked explicit ly. Line 60 now contains a cal l to insightmaximize instead of maximize.

Publishing to Xpress Insight With the model converted, it's close to being able to run in Xpress Insight. Recall that earlier, when the initial Xpress Workbench project was created, we deleted the initial set of default resources. This was to prepare the way to run the model as a native Mosel model from Xpress Workbench. Now that the model is moving into Xpress Insight, it is time to acknowledge Xpress Insight's convention over configuration approach, and begin to develop its expected app directory structure. To publish the model as an Xpress Insight app and run it:

1 In the Xpress Workbench project tab, right-click on the Portfolio Optimization folder and select New Folder - name the new folder model_resources by overtyping New Folder.

2 Drag the folio.dat file from the root folder into the new model_resources folder. One way to provide input data files to Xpress Insight is to put them in a model_resources folder. Your project tab now looks like:

You may see some other files at the top level, such as foliodata.bim and foliodata.zip - they are the compiled version of foliodata.mos and an app archive respectively. More about this later, but for now, just ensure you have a model_resources folder containing folio.dat and a foliodata.mos one level above.

Page 28: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

28 Fair Isaac Confidential and Proprietary

3 Choose Run > Build from the main menu - wait a few moments and you will see a Process exited with code: 0 message in the Xpress Workbench console. If the console is not visible, press F6. If you see a different message, check that you have prepared the source and input files properly.

4 Click the Publish to Xpress Insight icon. If prompted, select Create a new app and click Publish, otherwise wait a few moments for your app to be sent to Xpress Insight.

Note: If the Publish to Xpress Insight icon - is not visible, click on the vertical tab on the right of the browser window labeled Xpress Insight - this expands the App panel. Your app is compiled and sent to an Xpress Insight instance - a message alert informs that the publishing event has occurred:

5 Click on the Open in Xpress Insight link in the message alert - you will be transferred to a running Xpress Insight instance.

6 Click on the grey shelf of the Xpress Insight user interface

and select your app's default scenario - it is called Scenario 1. A pill representing Scenario 1 appears on the grey shelf.

7 Click on the Scenario 1 pill and choose Load from the drop-down menu. The scenario's data loads.

8 Click on the Scenario 1 pill again and choose Run. The scenario executes.

Even without explicit user interface customizations, you can explore your model's entit ies via the Xpress Insight Entity Explorer.

In the original, pre-Xpress Insight model, the model's results were written to an output fi le - result.dat. Having moved the model into Xpress Insight, there is no need to remove the code responsible, as you may wish to run it again independently. However, Xpress Insight is aware of which entit ies are input entit ies and which are results entit ies and you can explore them together with other sal ient data items via the Entity Explorer.

Using the Entity Explorer Having made a minimal conversion of a Mosel model to an Xpress Insight app, there are no custom views, and no app-specific user

Page 29: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 29

interface. Instead, you can explore your model, its variables and entities via the Entity Explorer, which is accessible from the view navigator on the left of the App page.

Note To use the Entity Explorer, you need to have the DIRECT_DATA_VIEW system authority, which is automatically included in the Advanced User, Administrator and Developer authority groups. Contact your system administrator if the Entity Explorer is not accessible.

The figure shows the salient details of the Entity Explorer following an Xpress Insight run of the converted example app.

Clicking on an entity name causes a visual representation of the entity to be presented in the main browser panel. You can select to view only the input entities or only the results entities by making the relevant choice in the drop- down list. You can also choose to make hidden entities visible with the Show Hidden checkbox.

The following figure presents a composite image of the representations of all listed entities.

Page 30: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

30 Fair Isaac Confidential and Proprietary

Labeled items are: 1 The NA input array as initialized from the folio.dat file. 2 The SHARES input array as initialized from the folio.dat file. 3 The RET array, which has SHARES as an index set. Again,

this was initialized in the folio.dat file, and provides reference information about the ROI of each type of share.

4 The RISK array, which represents the riskier share types, as

Page 31: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 31

initialized in the folio.dat file. 5 The parameter values as established in the Mosel model. 6 The maximization objective result Return - a scalar. 7 The frac array, containing a representation of the optimal

proportions of share types to invest in. This is the same data as was written out to the result.dat file in the original, pre-Xpress Insight model.

Completing the Recommended Directory Structure When you deploy an Xpress Insight app, you will need to present an app archive file - a ZIP or GZIP file containing the app's resources arranged within a known directory structure. Following a convention over configuration approach, the expected structure for the example app is representative of the general pattern of files and folders expected by Xpress Insight for all apps:

■ foliodata.mos - an optional model source file, ultimately ignored by Xpress Insight. By convention, and when packaging apps manually, it is typically moved to the source folder.

■ foliodata.bim - the compiled model, located in the app root. Only one BIM file is allowed.

■ foliodata.xml - an optional companion file (also known as a cfile) which contains app configuration definitions.

■ client_resources - an optional folder containing user interface resource files - for example, files containing View Definition Language (VDL) code.

■ model_resources - an optional folder for model resource files. It currently contains the folio.dat file.

■ tableau - an optional folder for the Tableau workbooks and Tableau packaged workbook files.

Note The contents of a Tableau packaged workbook file are restricted to a Tableau workbook and images.

■ project_attachments - an optional folder containing files to attach to the app when it is created.

■ source - an optional folder that serves as a convenient means to bundle the Mosel model source with the app. All files in this folder are ignored by Xpress Insight. Model source files are also permitted in the root of the app archive, where they are also ignored.

Using Xpress Workbench, you don't have to generate the archive ZIP file manually - as soon as you publish the app to Xpress Insight, Xpress

Page 32: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

32 Fair Isaac Confidential and Proprietary

Workbench automatically generates it for you - if you have followed along as the example has progressed, there will be a foliodata.zip file underneath your project's root Portfolio Optimization folder.

Updating the Example App Folder Structure As things stand, the example app directory structure is fairly minimal, as few customizations have been applied up to this point.

To prepare the way for future VDL views and other user interface enhancements, create the following additional folders beneath your project's root:

■ client_resources ■ tableau

■ project_attachments

■ source

Recall that there is already a model_resources directory, containing the folio.dat input file. The organization of your project now looks like:

Working with Annotations Mosel annotations are a very powerful means by which you can configure the way in which entities interact with the Xpress Insight user interface.

Annotations are simply metadata expressed in the model source file that is retained in the resulting BIM file after compilation. A full annotation name is expressed as <category>.<name> where a category is a mechanism to group a set of annotations and other categories. Xpress Insight annotations belong to the insight category.

In the Mosel source file, annotations are included in special comments - a single line annotation is of the form:

Page 33: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 33

!@<category>.<name> <value>

Among other things, annotations give you the potential to define aliases for Mosel entities, so that they are presented in the user interface using their alias names, rather than their original model names. For example, placing the following annotation prior to the frac declaration in the example: [email protected] Outcomes frac: array(SHARES) of mpvar

sets an alias name that will be used in place of the entity name throughout the user interface. Annotations can also inform the system if an entity is an input or a result. Xpress Insight defaults to assuming that entities of primitive types are input entities and mpvar/linctr entities are result entities. However, there are often times, when, say, certain primitive entities are intended as results, in which case they should be annotated. The following snippet annotates the frac entity as a result (although in this case, as frac is an mpvar, it is not strictly necessary) using the insight.manage annotation: [email protected] result frac: array(SHARES) of mpvar

See the Xpress Insight Mosel Interface Reference Manual for further detailed information about the many available annotations.

Adding Some Initial Annotations Below, some initial annotations are added to the example model. Change the declarations sections of the example so that they now read: declarations [email protected] input [email protected] Set of all shares SHARES: set of string ! Set of share types [email protected] input [email protected] Set of high risk shares RISK: set of string ! Set of high-risk share types [email protected] input [email protected] Set of all North American shares NA: set of string ! Set of shares issued in N. America [email protected] input [email protected] ROI RET: array(SHARES) of real ! Estimated return on investment end-declarations

and

Page 34: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

34 Fair Isaac Confidential and Proprietary

declarations [email protected] result [email protected] Outcomes frac: array(SHARES) of mpvar ! Fraction of capital used per share end-declarations

All entities have had aliases applied, and all have also been identified as either input entities or result entities. It is good practice to use these and other comments and annotations when relevant as they make model code more readable - after all, they are comments - and help people who are unfamiliar with your app to quickly identify and categorize the key entities. If you rebuild and republish the app to Xpress Insight, the entity explorer reveals that the changes have been applied:

Checking and unchecking the Show Aliases checkbox toggles the entity names between their original model names and their aliases.

Introducing the Companion File Alongside the compiled Mosel file in the archive root directory, you can provide an additional file that contains metadata - the companion file (or cfile) - to customize your Xpress Insight app. Companion file metadata performs essential configuration activities that control the way the system behaves for apps and views. The companion file uses the XML format, has an XML file extension and is loaded into the system at the same time as the model itself. Unlike the model, you can update the companion file without deleting and recreating the app. While the companion file is technically optional, it is essential if you plan to add VDL or Tableau views to your app.

Page 35: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 35

A companion file has the same name as your model's MOS/BIM files, but has the XML file extension instead. For example, if your MOS file was called foliodata.mos, the correct name for the companion file would be foliodata.xml, and it should be placed alongside the foliodata.mos file, in the same directory. The full XSD schema of the companion file XML is documented in the <installdir>\docs\insight\XML_reference directory - examples of companion file markup are provided at many places in this guide.

Starting a Companion File In this section, a minimal companion file is added to the example project. Create a file called foliodata.xml at the same, root level as the foliodata.mos file (... and the foliodata.bim file if present), with the following contents: <?xml version="1.0" encoding="UTF-8"?>

<model-companion

xmlns=http://www.fico.com/xpress/optimization-modeler/model-companion version="3.0">

<client>

<view-group title="Portfolio Optimization"></view-group>

</client>

</model-companion>

A <model-companion> element is the root element for companion files - full XML documentation is available at <Xpress Installation Directory>/docs/insight/xml_reference/index.html. <client> elements are containers for client-side configuration. A <view-group> is a container for a group of views that will appear in the user interface. With a cfile as above, no actual views have been defined - if you republish the app to Xpress Insight, there is no discernable difference.

Adding a Custom User Interface You can create custom views using VDL, JavaScript and Tableau. This introductory chapter focuses on creating a custom user interface via simple VDL and Tableau views. For more information about creating views using the JavaScript API, see chapter 6. Before you can create and include a VDL view in your app, you need to declare it in your app's cfile using the <vdl-view> element.

Page 36: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

36 Fair Isaac Confidential and Proprietary

Adding a VDL View to the Example App Having declared a view in the cfile, you must create a related VDL file to contain the user interface elements - Xpress Insight expects this to be stored in the client_resources directory. Declare your first VDL view by changing the cfile (foliodata.xml) so that it now looks like: <?xml version="1.0" encoding="UTF-8"?> <model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0"> <client> <view-group title="Portfolio Optimization"> <vdl-view title="Portfolio" path="foliodata.vdl"></vdl-view> </view-group> </client> </model-companion>

Note how the <vdl-view> element is contained within the <view-group> element, that it has a tit le cal led Portfolio Optimization and a path attribute that points to foliodata.vdl, which by implication is found in the client_resources folder. Create a fi le cal led foliodata.vdl in the client_resources folder: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization"> </vdl-section> </vdl-page> </vdl>

VDL files all have a <vdl> element at their root. <vdl-page> elements are containers for view contents, and each view must contain one such element. <vdl-section> elements are used to organize page content. For smaller pages, you might only use one section, but for larger pages, it is a good idea to separate your page content into several sections to demarcate your app's boundaries. Here, the one <vdl-section> element used has a heading attribute Welcome to Portfolio Optimization. Republish your app in Xpress Insight and examine its user interface. If the Entity Explorer is still in view, select Advanced > Portfolio Optimization > Portfolio from the drop-down menu available in the top-left tab of the central browser pane.

Page 37: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 37

The Advanced view group - from which you could select the Entity Explorer option, has been joined by the Portfolio Optimization view group, as was configured in the cfile. The Portfolio tab arises because it is the title of the view specified in the <vdl-view> element in the cfile. The Welcome to Portfolio Optimization message was configured as the heading of the single <vdl-section> element in the foliodata.vdl file.It's a simple, initial static view that hasn't yet been linked to model data.

Binding the User Interface to Scenario Data VDL comes equipped with some very powerful core components that make it natural and simple to access bulk model data. Change your foliodata.vdl file so that it now reads as: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <vdl-section heading="Recommended share allocations" heading-level="3"> <vdl-table page-mode="paged" page-size="5" show-filter="true" column-filter="true"> <vdl-table-column entity="frac"></vdl-table-column> </vdl-table> </vdl-section> </vdl-section> </vdl-page> </vdl>

First, note that there are now two <vdl-section> elements - one nested inside another. This allows you to subdivide sections into small and related but distinct regions - the heading-level attribute is analogous to the HTML tags <h1>, <h2> etc. and determines the style of the fonts in which section headings are rendered.

Page 38: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

38 Fair Isaac Confidential and Proprietary

Next, is the first of two new elements - the <vdl-table> element. This is a wrapper for a table, and in the above example, its attributes have been set as:

■ page-mode="paged" - configures the table to be paginated ■ page-size="5" - sets the number of rows per page at 5 -

slightly contrived because the entity on which its child <vdl-table-column> element is based only has 10 records

■ show-filter="true" - adds an input field in which you can search the entire table for a specific or pattern-matched value

■ column-filter="true" - adds an input field to the top of each column, so you can restrict searches to specific columns

Finally, the second new element - the <vdl-table-column> element with its single attribute, entity="frac". This creates a column based on the values it discovers in the frac entity. Republish the app to Xpress Insight and ensure that you (re)load and rerun the scenario. It now appears:

The original section headed Welcome to Portfolio Optimization has been joined by a nested section with a heading Recommended share allocations - note how setting the heading-level to 3 has altered its font style. Configuring the table as page-mode="paged" was responsible for the appearance of the Show ... entries drop-down list and the pagination controls on the bottom right.

Page 39: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 39

The show-filter="true" attribute has provided a Search box at the top, while column-filter="true" has provided search boxes at the top of each column. The table itself has 5 rows as requested, and displays both the entries and the corresponding index entries for the frac entity. Column headings reflect the aliases assigned in foliodata.mos. Finally, the fields in the header row come automatically equipped with small widgets that enable column sorting. To summarize. In a few lines of markup most of which goes towards expressing declarative choices about desired features, the app has a production-ready table that is slaved to the underlying model data. As a user interface developer, you do not need to worry about lower level concerns like data marshaling and synchronization, styling, implementing search and pagination and so on.

Adding a New Column For other entities with the same index set, adding new columns to a <vdl- table> element is very simple. Locate the following line in foliodata.vdl: <vdl-table-column entity="frac"></vdl-table-column>

and add the following line beneath it: <vdl-table-column entity="RET"></vdl-table-column>

Republish the app in Xpress Insight:

Page 40: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

40 Fair Isaac Confidential and Proprietary

The new column references the RET entity, which is based on the same index set - SHARES - as frac. The column heading chooses its alias Estimated ROI per share as configured via annotation in foliodata.mos. The new column is fully-integrated with the table and its sort behavior synchronized with the other columns.

Using Expressions Expressions are statements that evaluate dynamic values for VDL attributes and often (but not always) lead to some visible change in the rendered user interface. This section introduces a new VDL feature and demonstrates how expressions are brought into play. An attribute called vdl-text can be used to insert child text into any VDL or HTML element that supports it. Below, vdl-text is used to set some static text within a <span> element:

<vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <vdl-section heading="Optimal result" heading-level="2"> <span vdl-text="Calculated optimal return: "></span> </vdl-section> <vdl-section heading="Recommended share allocations" heading-level="3"> <vdl-table page-mode="paged" page-size="5" show-filter="true" column-filter="true"> <vdl-table-column entity="frac"></vdl-table-column> <vdl-table-column entity="RET"></vdl-table-column> </vdl-table> </vdl-section> </vdl-section>

</vdl-page> </vdl>

which renders as:

Page 41: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 41

The text Calculated optimal return: renders into a new section with the heading Optimal result. The goal here is to access the model data, extract the calculated Return value, and add it to the existing static text with another <span> element. This is easily accomplished with a simple expression. Expressions are statements used as the targets of attribute assignments, and are used to allow the insertion of dynamic content or programmatically to control layout and data flow. An expression is denoted by an equal sign = as the first character of an attribute value. Everything after that is evaluated at runtime, and re- evaluated when any entities referenced within it change. The result of the evaluation is placed into the page at the appropriate point. Add a new <span> element beneath the existing one: <span vdl- text="Calculated optimal return: "></span>: <span vdl-text="=scenario.entities.Return.value"></span>

scenario.entities is a map containing all model entities. As a scalar, Return can be accessed by appending .value. The corresponding user interface looks like:

Page 42: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

42 Fair Isaac Confidential and Proprietary

Note how the value 14.066666666666588 is rendered in place. Of course it needs formatting - and Xpress Insight offers several approaches, one of which involves a timely introduction to the JavaScript API. The Xpress Insight JavaScript API enables you to invoke a wide range of library functions from within VDL. You can also create your own JavaScript functions within VDL via <script> blocks, but here, the Return scalar is formatted via a call to an existing function - insight.Formatter.formatNumber, which takes two arguments - the value to be formatted (here, this is the value of scenario.entities.Return.value), and a Java-style formatting string. Replace <span vdl-text="=scenario.entities.Return.value"></span>

with <span vdl-text="=insight.Formatter.formatNumber( scenario.entities.Return.value, '00.##')" > </span>

So that the entire foliodata.vdl file now looks like: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <vdl-section heading="Optimal result"

Page 43: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 43

heading-level="2"> <span vdl-text="Calculated optimal return: "></span> <span vdl-text="=insight.Formatter.formatNumber( scenario.entities.Return.value,'00.##')"> </span> </vdl-section> <vdl-section heading="Recommended share allocations" heading-level="3"> <vdl-table page-mode="paged" page-size="5" show-filter="true" column-filter="true"> <vdl-table-column entity="frac"></vdl-table-column> <vdl-table-column entity="RET"></vdl-table-column> </vdl-table> </vdl-section> </vdl-section> </vdl-page> </vdl>

Republish the app, and 14.066666666666588 now renders as 14.07. Note: Due to page-width limitations, it is not possible to present some of the longer VDL fragments on one line. Ensure that where possible, your own code reconstructs them in the correct form, or you may get errors during the build process. One such case above is the line beginning <span vdl-text="=insight.format.formatNumber ...">.

Adding Forms and Fields Two new tags - <vdl-form> and <vdl-field> - allow you to create VDL forms with editable fields. Using with a looping attribute - vdl-repeat - it is easy to generate form fields from elements in an array. Change foliodata.vdl so that it now reads: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <vdl-section heading="Return per share type" heading-level="2"> <vdl-form vdl-repeat="=s in scenario.entities.SHARES"> <vdl-field entity="RET" indices="=s.value" label="=s.label"> </vdl-field> </vdl-form> <vdl-execute-button caption="Run scenario"></vdl-execute-button> </vdl-section> <vdl-section heading="Optimal result" heading-level="2">

Page 44: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

44 Fair Isaac Confidential and Proprietary

<span vdl-text="Calculated optimal return: "></span> <span vdl-text="=insight.Formatter.formatNumber (scenario.entities.Return.value, '.##')"> </span> </vdl-section> <vdl-section heading="Recommended share allocations" heading-level="3"> <vdl-table page-mode="paged" page-size="5" show-filter="true" column-filter="true"> <vdl-table-column entity="frac"></vdl-table-column> <vdl-table-column entity="RET"></vdl-table-column> </vdl-table> </vdl-section> </vdl-section> </vdl-page> </vdl> These additions introduce some powerful new concepts. First, <vdl-form> is used to begin a form. Then, the vdl-repeat attribute is assigned to an expression =s in scenario.entities.SHARES which iterates over the SHARES entity. For each value s discovered in the collection, a <vdl-field> element is created, based on the RET entity and indexed by the value of the discovered share type. Finally, the field label has to be changed each time, and so it is set to be the same as the label from the share index. Also note the new <vdl-execute-button> element which can be placed anywhere in a view (not just within the confines of a form like an HTML submit button) to offer an effortless way to (re)run the scenario. After republishing, the end result looks like:

Page 45: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 45

By default, editing is enabled in VDL fields, and you can overtype the field values in the Return per share section, click Run Scenario to (re)run the scenario and review the new results.

Improving the User Interface While it is perfectly functional, the app is rather wasteful of screen real estate and it would be a better approach to let the user select a share type from a drop-down list before changing its estimated ROI. Doing this requires a slight change to the model, and this illustrates the iterative nature of Xpress Insight solution development. Start with a basic model, create an interface and iterate both as you seek to improve the user experience.

Page 46: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

46 Fair Isaac Confidential and Proprietary

The model needs a scalar entity in which to store the selected share name from the proposed drop-down list. Modify the declarations section of foliodata.mos by declaring the entity changeShare, adding it at the bottom: declarations ... RET: array(SHARES) of real [email protected] input changeShare: string end-declarations

For this example, a simple way to initialize it is by modifying the datainput procedure so that it now defines an initial value for the new scalar: ! Load input data procedure datainput initializations from DATAFILE RET RISK NA end-initializations changeShare:= "brewery" end-procedure

Replace the <vdl-form> containing the repeating fields, with a new form containing just two fields, so that the full foliodata.vdl file now reads: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <vdl-section heading="Return per share" heading-level="2"> <vdl-form> <vdl-field entity="changeShare" options-set="SHARES" label="Choose share type"></vdl-field> <vdl-field entity="RET" indices="=scenario.entities.changeShare.value" label="Estimated ROI"></vdl-field> </vdl-form> <vdl-execute-button caption="Run scenario"></vdl-execute-button> </vdl-section> <vdl-section heading="Optimal result" heading-level="2"> <span vdl-text="Calculated optimal return: "></span> <span vdl-text="=insight.Formatter.formatNumber( scenario.entities.Return.value, '.##')"> </span> </vdl-section> <vdl-section heading="Recommended share allocations" heading-level="3"> <vdl-table page-mode="paged" page-size="5" show-filter="true" column-filter="true"> <vdl-table-column entity="frac"></vdl-table-column> <vdl-table-column entity="RET"></vdl-table-column> </vdl-table>

Page 47: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 47

</vdl-section> </vdl-section> </vdl-page> </vdl>

The first new <vdl-field> element has its entity attribute set to changeShare - the new entity in the model. By using the options-set attribute, Xpress Insight is informed that the field should be a drop-down list, taking its set of options from the SHARES set. The field is completed with the assignment of a label. The second new <vdl-field> element references the RET array, with its indices attribute set to the value stored in the changeShare entity. Again, a suitable label is provided. Republish, reload and rerun the scenario:

The result is a much more compact user interface that conforms better to expectations. Should you need them, radio buttons and checkboxes are available as alternative VDL field types.

Validating User Input and Adding Tooltips The app is progressing, but there is currently no validation on the input field in the Return per share section.

Page 48: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

48 Fair Isaac Confidential and Proprietary

Even without any VDL modifications, as a user types into or selects a new value from a form field it is automatically validated. By default, type validation is applied according to the data type of the base entity. When a field becomes invalid, it is highlighted until it becomes valid again. You can use the <vdl-validate> element to apply extra validation to fields - you must provide it with a pass attribute that is either a function or a boolean expression which is evaluated every time a value is edited. For the example project, a boolean validator will ensure that the input field (i.e. the estimated ROI per share type expressed as a percentage) is greater than or equal to zero. Add a <vdl-validate> element within the input field, so that the relevant part of foliodata.vdl now looks like: <vdl version="4.0"> ... <vdl-form> <vdl-field entity="changeShare" options-set="SHARES" label="Choose share"></vdl-field> <vdl-field entity="RET" indices="=scenario.entities.changeShare.value" label="Estimated ROI"> <vdl-validate pass="=value >= 0">ROI must be zero or greater. </vdl-validate> </vdl-field> </vdl-form> ... </vdl>

The boolean expression =value >= 0 is evaluated on the field's validation events, and you can provide text content for the <vdl-validate> element that forms part of a pop-up error dialogue when an invalid value is entered. If you republish the app and enter an invalid value:

Figure 18: Validating User Input This is accompanied by a Validation Error dialog that contains the text provided as content for the <vdl-validate> element:

Page 49: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 49

There are several other validation options available, depending on your needs and their level of complexity. All are described in other places in this guide or the related API documentation.

Adding Tooltips It's easy to add informatory tooltips to elements in a VDL view. Place them inside elements and they are shown when a user hovers over that element. They can contain an optional title and body content, both of which can be static or dynamic expressions that resolve to text. You can add a tooltip to the input field of the example app by changing foliodata.vdl so that the relevant part now reads: <vdl version="4.0"> ... <vdl-form> <vdl-field entity="changeShare" options-set="SHAREs" label="Choose share"></vdl-field> <vdl-field entity="RET" indices="=scenario.entities.changeShare.value" label="Estimated ROI"> <vdl-tooltip title="Estimated ROI" content="Specify the expected percentage return on investment"> </vdl-tooltip> <vdl-validate pass="=value >= 0">ROI must be greater than zero. </vdl-validate> </vdl-field> </vdl-form> ... </vdl>

Here, the tooltip title has been set to Estimated ROI and its content to Specify the expected percentage return on investment. Republishing the app and hovering the cursor over the input field yields:

Page 50: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

50 Fair Isaac Confidential and Proprietary

Adding a Visualization Using Tableau for FICO You can incorporate Tableau visualizations in Xpress Insight apps as custom views that report on scenario data. Tableau visualizations obtain their data from a relational database. Xpress Insight holds scenario data in a compressed format for its own use, but mirrors it into a relational database - the mirror database - for Tableau. The schema and content of the mirror database is managed by Xpress Insight, via the companion file, which defines the mirror tables and specifies how they are populated.

Exposing Mirror Data to Tableau and Configuring a Data Source Change foliodata.xml so that it now reads: <?xml version="1.0" encoding="UTF-8"?> <model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/ model-companion" version="3.0"> <database-mirror table-prefix="shares_"> <mirror-tables> <mirror-table name="allocations"> <entity name="frac"></entity> </mirror-table> </mirror-tables> <data-sources> <data-source name="share_source"> <mirror-table-ref name="allocations"></mirror-table-ref> </data-source> </data-sources> </database-mirror> <client> <view-group title="Portfolio Optimization"> <vdl-view title="Portfolio" path="foliodata.vdl"></vdl-view> <tableau-workbook title="Optimal allocation" workbook="investments" managed="true"></tableau-workbook> </view-group>

Page 51: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 51

</client> </model-companion>

The <database-mirror> element marks the start of the mirror database configuration. It must be placed before the <client> element. The <mirror-tables> element is a container for potentially several <mirror- table> elements, in which the name attribute sets the table name. Within <mirror-table> elements, <entity> elements associate model entities with their mirror tables. Of course, a table name doesn't need to be the same as the entity on which it's based. The <data-sources> element begins the definition of (potentially several) data sources from which Tableau can access scenario data. Above, only one data source is defined - share_source - which contains a mirror table reference. Within the <view-group> element, there's a new <tableau-workbook> element that references the workbook investments, a title of Optimal allocation and sets its managed attribute to true. Workbooks thus marked are automatically published by Xpress Insight on loading an app if the workbook file can be located in the tableau folder of the app archive.

Creating a Simple Tableau View With the mirror tables and data source defined, the example project is ready for its first Tableau view. With the changes made to the foliodata.xml file as described:

1 Republish your app to Xpress Insight. There is no need to visit the Xpress Insight screen.

2 Click the Edit Tableau workbooks icon - . 3 When prompted with the message To continue, you must

select at least one scenario, click Scenario 1 in the scenario list (it will be the only item in the list) and then click Continue. In a few moments you are connected to the server-based version of Tableau in a new browser tab.

4 Choose Data sources in the main menu, and then click shares_share_source in the list of data sources list - this is the concatenation of the mirror table prefix and the data source name configured in the previous section.

5 Click New workbook in the main menu. 6 Click Sheet 1 > Rename sheet and give the sheet a

name - ROI. 7 Expand the shares_allocations entry in the Dimensions

panel on the left and drag the Set of all shares dimension

Page 52: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

52 Fair Isaac Confidential and Proprietary

into the Columns field of the main central pane. 8 Expand the shares_allocations entry in the Measures

panel on the left and drag the Outcomes measure into the Rows field of the main central pane. In a few moments, a bar chart showing the recommended allocation of share types appears.

9 Click Save as in the main menu, give the saved workbook

a name - investments - and click Save, leaving everything else at their default values.

10 Return to the Xpress Workbench tab and republish and visit the app, reloading and running the main scenario if necessary.

11 The app has a new tab called ROI - which displays the bar chart in its runtime mode. You can switch between the

Page 53: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 53

various tabs to modify the ROI per share type and review its effects on the visualization.

12 Note that the tableau folder of the app has been populated with a file called investments.twb - this is the Tableau workbook file, and needs to be present in the folder if you have marked the workbook as managed in the companion file.

This simple Tableau view illustrates one method of integrating Xpress Insight with Tableau, and barely scratches the surface of the many visualizations that Tableau makes possible. Refer to the official Tableau documentation for more detailed information about how to harness its full capabilities.

Using Attachments Attachments are files you can associate with an app or individual scenario. They can either be provided with the initial app archive in the project_attachments folder, or created and modified by interacting with Xpress Insight itself. Attachments can also be accessed using the standard data access functions of Mosel using the appropriate mminsight procedures, thus providing another way for a user to interact with the underlying model. One advantage of attachments over model resources (such as the folio.dat file configured in the example project) is that attachments can be updated by Xpress Insight, whereas model resources are not changeable once an app has been created. Other powerful use-cases for attachments (and, by implication, differences between attachments and model_resources files) include:

■ They can be written to at runtime and served dynamically via the JavaScript API.

■ Attachments can be easily switched or removed by users. ■ They are supported by a range of included editors. ■ Attachments can be associated with tags, allowing users to

control what data is processed without changing the underlying model.

In the following sections, an attachment is built-in to the app while developing it, and then it is changed at runtime in Xpress Insight, to demonstrate the two way interaction with the underlying model.

Adding an Attachment in Development Adding an attachment while developing an Xpress Insight app can be as simple as creating a file in the project_attachments directory.

Page 54: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

54 Fair Isaac Confidential and Proprietary

The example project is to be extended by loading some standard investment warning advice from a string stored in an app-level attachment. Initially, it will contain placeholder text, but later, it will be edited and updated from the app itself, demonstrating how the model interacts with attachments.

1 Create a file called caution.txt and save it in your app's project_attachments folder - its contents should be:

cautionText:"** Text to be replaced **"

The organization of your app now looks like:

2 Change the parameters section of foliodata.mos so that it

contains an entry for the name of the relevant attachment:

parameters ! Name of attachment to contain caution text CAUTIONTEXT = "caution.txt" ! File with problem data DATAFILE = "folio.dat" ! Output file OUTFILE = "result.dat" ... end-parameters

3 Change the first declarations section of foliodata.mos so that it contains a declaration for the string value to be ultimately read from caution.txt: declarations ... RET: array(SHARES) of real changeShare: string cautionText: string

Page 55: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 55

end-declarations

4 Change the datainput procedure in foliodata.mos so that it now reads:

! Load input data procedure datainput insightgetprojattach(CAUTIONTEXT) initializations from DATAFILE RET RISK NA end-initializations initializations from CAUTIONTEXT cautionText end-initializations changeShare:= "brewery" end-procedure

The call to insightgetprojattach causes Xpress Insight to locate the caution.txt file in project_attachments, and copy it into its working directory, whereupon it can be manipulated using Mosel's standard data manipulation functions. The second call to initializations initializes the cautionText value with that assigned in caution.txt - i.e. ** Text to be replaced **.

5 Change foliodata.vdl so that its first few lines now read: <vdl version="4.0"> <vdl-page> <vdl-section heading="Welcome to Portfolio Optimization" heading-level="1"> <span vdl-text="=scenario.entities.cautionText.value"></span> <vdl-section heading="Return per share" heading-level="2"> ...

The <span> element has a vdl-text attribute that uses an expression to evaluate and insert the runtime value of the cautionText entity.

Reviewing and Changing an Attachment at Runtime With an attachment built-in to the app archive, it is always accessible at runtime (subject to the appropriate permissions).

1 Republish your app, then reload and run Scenario 1. The value loaded into cautionText from the caution.txt attachment is displayed:

Page 56: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

56 Fair Isaac Confidential and Proprietary

This demonstrates that the text ** Text to be replaced ** comes from the model as was configured earlier.

2 Click the Actions icon in the top right of the browser, and select App Attachments from the drop-down menu.

The Attachments Dialog appears, in which a single attachment is listed - caution.txt. 3. Click the Edit with Text Editor icon and replace the existing

text with:

cautionText:"WARNING: Share prices can go down as well as up."

4. Click Save, Close and Close again. 5. Reload Scenario 1. 6. The caution text has been changed.

A runtime change to the attachment has made its way back into the model, where it was marshaled into the cautionText entity and displayed once again. Note, however, that this required a reload of the app data because the code which reads the attachment was added to the datainput procedure. More generally, attachments can be accessed from anywhere in your code and their accessibility is not dependent on reloading data.

Page 57: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 57

Understanding Execution Modes Every scenario execution initiated by Xpress Insight has an associated execution mode.

Execution modes are defined in models using Mosel annotations - when the model is run, it can test for the execution mode and make predicate-based decisions. Every app is assigned (and must implement behavior for) two standard execution modes - LOAD and RUN - they have constants associated with them in the model:

■ INSIGHT_MODE_LOAD ■ INSIGHT_MODE_RUN

These are used in a case statement in the example project to switch branching logic via the execution mode - in this case, to either load input data or populate Xpress Insight. A model can also define any number of additional custom execution modes - they can offer your app two additional forms of control:

■ Executing different model code paths based on the execution mode selected by a user.

■ Routing different kinds of Xpress Insight jobs to different worker resources configured on the server. For example, you could have a model that performs small, fast jobs as well as large, slow jobs. Using custom execution modes, you can route the two different kinds of jobs to the worker resources best equipped to serve them.

Adding a Custom Execution Mode In this section the example project is extended with the addition of a custom execution mode. The new execution mode is the same as INSIGHT_MODE_LOAD, except that it is invoked from a user interface button.

1 At the top of foliodata.mos, add a line so that it now reads:

model "Portfolio optimization with LP" ! Mandatory for Xpress Insight uses "mminsight" ! Use Xpress-Optimizer uses "mmxprs" [email protected] true ...

The new [email protected] true statement declares the new execution mode - RELOADBASEDATA - and assigns its clearinput attribute to be the boolean true, which states

Page 58: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

58 Fair Isaac Confidential and Proprietary

that data should be loaded directly from the underlying model, rather than the Xpress Insight server. 2 Change the case statement that drives the mode-specific logic

so that it now reads:

case insightgetmode of INSIGHT_MODE_LOAD: do datainput exit(0) end-do INSIGHT_MODE_RUN: insightpopulate "RELOADBASEDATA": do datainput exit(0) end-do else datainput end-case

Note the addition of a RELOADBASEDATA branch that behaves exactly like the LOAD branch. This new mode is invoked via the following user interface change which ties its use to a user interface button, rather than a drop-down menu on the shelf.

3 In foliodata.vdl, add two lines underneath <vdl-execute-button caption="Run scenario"></vdl-execute-button> so that it now reads: ...

<vdl-execute-button caption="Run scenario"></vdl-execute-button> <span> </span> <vdl-execute-button caption="RELOAD BASE DATA" mode="RELOADBASEDATA"></vdl-execute-button>

...

A <span> element adds some clearance between the original execute button captioned Run scenario, and a new execute button captioned Reload Base Data. Note how its mode attribute has been set to RELOADBASEDATA. When clicked, the RELOADBASEDATA branch in foliodata.mos is executed.

4 Republish your app to Xpress Insight, (re)load and run Scenario 1. Edit the ROI field for a number of share types using the drop-down box, and click Run Scenario. Depending on your choices, a new result appears.

5 Click the Reload Base Data button and click Load Data in the subsequent Loading Input Data dialog. The scenario loads data directly from the model, resetting all input data.

6 Click Run Scenario one last time.

Page 59: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 59

The scenario executes against the original data, producing the expected result of 14.07.

This short exercise has illustrated how to control model flow logic with a simple custom execution mode. Execution modes are capable of far more complex processing and by associating a custom execution mode with an existing execution service, you can also route Xpress Insight jobs to an appropriately provisioned server. These use cases are covered in more detail elsewhere in the documentation.

Moving to the Next Level This chapter has provided a brief introduction to a typical Xpress Insight workflow in which a Mosel model was transformed into a functional Xpress Insight solution. If you have completed and understood the progression of exercises, you are now in a position to consolidate your knowledge by exploring a similar journey with a modest Mosel model of your own. There is much more to Xpress Insight than has been possible to cover in this short introduction. The JavaScript API has barely been mentioned, and we have hardly skimmed the surface of what is possible with VDL. The rest of this guide and the related Xpress Insight documentation will take you deeper into the subject.

Page 60: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 60

CHAPTER 3 Developing an Application with Xpress Insight

How Xpress Insight Interacts with a Mosel Model Xpress Insight executes Mosel models by using the XPRD library to send the model using the Distributed Mosel mechanism to an xprmsrv instance. Every execution job sent from Xpress Insight has an execution mode associated with it. Execution modes are defined within each model using Mosel annotations. When a model is run it can test for the execution mode set and perform different actions based on that. The model can define any number of custom execution modes but each app is also assigned two standard execution modes. These standard execution modes are LOAD and RUN. The steps taken to execute a scenario are as follows: 1 A connection is made to an available xprmsrv service. 2 A new instance is created (the insight execution environment is applied). This

includes setting the requested execution mode. 3 Any model resources are copied to the working directory of the remote

instance. 4 The compiled model is sent to the instance and loaded. 5 The model is executed and it should call insightgetmode to get the execution

mode. 6 Parameters are passed to the model and are available from the beginning of

the model. 7 If the execution mode has clearinput set to true, for example LOAD mode:

a. As the model ends or exits, mminsight captures the data from any entity identified as a managed input.

8 If the execution mode has clearinput set to false, for example RUN mode: a. At insightpopulate, mminsight injects the input data into the model

entities marked as input by the schema. b. At insightminimize, mminsight disables constraints and add violation

variables as necessary, then calls minimize. When minimize completes, mminsight records the runtime metrics.

c. At end-model, mminsight captures the results entities and any input entities marked as to be updated on model end.

As a consequence of these execution sequences, managed input entities must be declared prior to calling insightpopulate. The standard execution modes that are automatically available in all apps have constants associated with them in the model:

Page 61: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 61

INSIGHT_MODE_LOAD INSIGHT_MODE_RUN These can be used in a switch statement, for example, to branch based on the execution mode. It is a requirement that a model implement behaviour for these standard execution modes, even if the model defines custom execution modes. It is always possible for users of Xpress Insight to submit jobs with these standard execution modes.

Xpress Insight Model Requirements The FICO Xpress-Mosel model developer must implement the following requirements in the model in order to use it in Xpress Insight: Include the mminsight package before any other packages. The mminsight

package includes the mminsight.dso Mosel module and implements the necessary interactions between Xpress Insight and the model.

The model must implement the Load mode by writing model code to initialize all managed model entities. The execution of this loading code must be conditional on insightgetmode = INSIGHT_MODE_LOAD. Any calls to finalize must be included in the loading code.

The model must implement the Run mode. The execution of this code must be conditional on insightgetmode = INSIGHT_MODE_RUN and begin with a call to insightpopulate. The Run mode code will typically include statements to construct the model from the scenario data, optimize it and process results.

Replace any call to minimize and maximize with insightminimize and insightmaximize.

Use the public qualifier to declare any input or results data entities if the “-s” (strip private symbols) compiler option is used. Entities declared locally within a procedure or functions are not visible to Xpress Insight, they need to be declared globally to be made visible.

Page 62: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

62 Fair Isaac Confidential and Proprietary

A typical model will have the following basic structure:

model mymodel uses "mminsight" uses "mmxprs" forward procedure datainput case insightgetmode of INSIGHT_MODE_LOAD: do datainput exit(0) ! Stop after data initialization end-do INSIGHT_MODE_RUN: insightpopulate ! Inject scenario data and continue else datainput ! Default (non-Xpress Insight): initialize data and continue end-case ! load input data procedure datainput

writeln("loading data") end-procedure ! create model constraints ! optimize ! post-process results end-model

The case statement (equivalent to if .. else if .. else) implements the flow control for each mode. The Run mode logic in the example above is implemented in the global scope of the model after the case statement. Larger models often encapsulate the Run mode logic in one or more procedures called from the case statement.

Supported Mosel Features, Types and Data Sources In general, so long as the requirements listed above are met by a model, Xpress Insight places no restrictions on the programmatic execution of the model. Statements, expressions, procedures, conditional logic, procedures, functions, packages and modules can be used as normal (see notes below). A model can solve several problems in series, or use mmjobs to solve sub-models.

Supported Mosel Types There are restrictions on what entity types can be persisted and manipulated. The following table describes these restrictions.

Page 63: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 63

Note Where a type is unsupported (such as nlctr), it can still be used in a model; unsupported types will be ignored by Xpress Insight and will not be captured as input or results data.

Table 1. Mosel Entity Type Supported Basic types (boolean, integer, real, string) Yes MP types (mpvar, linctr) Yes Sets Yes Lists No Arrays Yes Arrays Indexed by Real Numbers No Dynamic arrays Yes Records No Constants Yes User-defined types (including nested types) No Parameters Yes Types defined in modules No mpproblem type No Anonymous constraints No

Page 64: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

64 Fair Isaac Confidential and Proprietary

Notes

Entities declared locally within a procedure or function are not visible to Xpress Insight.

Custom DSO modules required by the model should be pre-installed into the MOSEL_DSO directory for each execution worker. By default, the MOSEL_DSO directory is <xpressdir>\dso. Custom types defined by a module are not currently supported by Xpress Insight. If custom types are used in the model, they will not be captured in the input or results data. This includes custom types from core modules including quadratic and non-linear variables and constraint types, text/date types and mmjob types. The Model type provided by mmjobs is not directly supported. See Modes using mmjobs for more details.

Difference between Treatment of Scalar and Parameter Types Scalar values, like all input data, are undefined at the start of the execution of a model. Scalar values are injected at insightpopulate for scenario executions. Parameters are passed to the model and are available to the model from the beginning of its execution. Parameters therefore provide a means of configuring how a scenario is loaded, such as determining which file or data connection to use.

Supported Data Sources Models can initialize the input data entities from any supported source, with the following caveats: The default security restrictions for xprmsrv are pre-configured to allow

Xpress Insight to connect to external databases but not to external files. Xpress Insight allows trusted file locations to be whitelisted as accessible

from the executing Mosel model. The whitelists for read, read-write and execute permissions can be edited in the execution worker configuration file (c:\xpressmp\bin\xprmsrv.cfg by default). The worker must be restarted for changes to take effect.

xprmsrv is started as a service so it may not be able to use the mmodbc.excel driver to access Microsoft Excel as a data source due to an issue with certain versions of Microsoft® Windows® (Vista, 7, 2008, 8 and 2012). The recommended solution is to use the new mmsheet.xslx driver.

Some ODBC drivers do not behave correctly with relative paths and so attempts to access model resource files that are locally referenced may fail. In this case, the “workdir” parameter can be used to get the absolute path to the current working directory. For example:

SQLconnect('DRIVER=Microsoft Excel Driver (*.xls);dbq=' + getparam("workdir")+"\\"+ExcelFile)

Page 65: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 65

Models using mmjobs A model managed by Xpress Insight can start additional sub-models using mmjobs if enough licenses are available for use. The existence and execution of these sub-models will be invisible to Xpress Insight. If a worker is licensed and configured, for, say, n jobs, but a job spawns sub-models that consume licenses, then Xpress Insight will be prevented from scheduling the full number of jobs.

The Xpress Insight Repository An app is the top-level node in the repository. It contains the following artifacts: A compiled model. A model companion file (optional).The model schema. Client resource files, which define the user interface of the app (optional). Model resource files, which are available to the Mosel model while it is

executing (optional). App attachments, which can be downloaded and modified via the Web

Client, and which are available to the Mosel model while it is executing (optional).

Note A model resource or app attachment can be a compiled model itself to allow, for example, the execution of sub-models by the master model.

An app can have zero or more folders and scenarios. A folder is a means of grouping scenarios and can contain zero or more scenarios and zero or more nested sub-folders.

The App A new app can be added to the system by providing separate files (.bim, .xml) or a .zip file containing all required files. To load a bim file, select File > New App and choose the appropriate bim file. If an XML file with the same filename and .xml extension is found in the same location, then the system will ask if the user wants to load this into the app as the companion file. App archives are also loaded by selecting File > New App. The structure of the app zip file is: mymodel.bim (error if more than one .bim file is located in the archive root) mymodel.xml (optional companion file) client_resources (optional folder for user interface resource files) model_resources (optional folder for model resource files)

Page 66: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

66 Fair Isaac Confidential and Proprietary

tableau (optional folder for the Tableau workbook and Tableau packaged workbook files)

project_attachments (optional folder containing files to attach to the app when it is created)

Note The contents of the Tableau packaged workbook file is restricted to a Tableau workbook and images.

The following figure shows the correct content structure:

A directory named “source” is allowed in the app zip file as a convenient means of bundling the Mosel model source with the app. All files in this directory are ignored by Xpress Insight. Model source files are also allowed in the root of the app archive and will also be ignored.

Page 67: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 67

Configuring the App The developer can provide an additional file, alongside the compiled model file, that contains metadata that customizes the behaviour of the Xpress Insight system. This file is XML-based and referred to as the companion file or c-file. The companion file is loaded into the system at the same time as the model and should have a .xml file extension. Unlike the model itself, the companion file can be updated by the developer without deleting and recreating the app. The full XSD schema of the companion file XML is documented in the <installdir>\docs\insight\XML_reference directory. Examples of companion file mark-up will be given where appropriate throughout this guide. The companion file meta-data can be used to perform a number of important configurations that control the way the system behaves for the app and views. In the version 2 specification of the companion file, Schema settings were specified by <entity> elements within the <schema> element and the enhancements were applied by the server interface when data was requested by a client. Version 3 of the companion file removes this section and delegates the configuration of the schema settings to the mosel model via the use of annotations. Web Client views have a corresponding element in the companion file within the <client> element. <model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0"> <client> <view-group title="Main"> <html-view title="Year Plan" default="true" path="yearplan.html"/> </view-group> </client> </model-companion>

App Name and Version On the Home page each app has a preset name and version. On importing an app the name is taken from the Mosel model name and the version is an optional setting in the Mosel file. For example model "units" version 1.0.0

Page 68: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

68 Fair Isaac Confidential and Proprietary

Custom Execution Modes Execution modes allow for two forms of control in your app: 1 Branching code in the model to perform different tasks based on the mode

selected by the end user. 2 Routing different types of job to different worker resources configured on the

Xpress Insight server. For example, you could have a model that performs small, quick jobs as well as large, slow jobs. If these two types of execution are designated custom execution modes then the model can detect the mode and branch accordingly. Also the systems administrator could configure the Xpress Insight server to run the small jobs on a cluster of execution workers and and large jobs on just a single, high-spec execution worker.

Defining Custom Execution Modes Custom execution modes are defined using annotations in the model. They should be declared after importing the mminsight package. When defining custom execution modes, or when modifying the characteristics of the standard execution modes, the following attributes are available: threads: (integer) The maximum number of threads that the model should

consume when running in this mode. Defaults to unlimited. preferredservice: (string) The execution service to try and map this

execution mode to when importing the app. If an execution service of this name does not exist on the server when importing the app then the app will still be imported but no mapping will automatically be made to an execution service. If not specified the execution mode will try to use the server’s default service unless later mapped.

clearinput: (boolean) Flags whether the scenario input data should be populated after model execution. Defaults to false.

descr: (string) A description of the execution mode to help a systems administrator determine the purpose or requirements of the execution mode. Defaults to empty description.

The built-in execution mode LOAD has the clearinput attribute set to true, while RUN as clearinput set to false.

Using Custom Execution Modes from the model In the model you can call insightgetmode to get the execution mode. You can use this in a switch statement to determine which branch of code to run. As a minimum you must check for the LOAD and RUN execution modes using the constants INSIGHT_MODE_LOAD and INSIGHT_MODE_RUN respectively.

Page 69: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 69

In the example below there are two custom execution modes:

model mymodel uses "mminsight" uses "mmxprs" [email protected]_ALL.preferredservice=BACKGROUND_SERVICE ([email protected]_ALL.descr=Long running background task to load complete data set from external datasource!) [email protected]_ALL.clearinput=true [email protected]_SEGMENTS.threads=1 [email protected]_SEGMENTS.preferredservice=FAST_SERVICE ([email protected]_SEGMENTS.descr=Quick job to evaluate segments. Does not perform any optimization!) [email protected] forward procedure datainput case insightgetmode of INSIGHT_MODE_LOAD: do datainput exit(0) end-do "LOAD_ALL": do writeln("load all data from external datasource") exit(0) end-do "EVALUATE_SEGMENTS": do writeln("evaluate segments") end-do INSIGHT_MODE_RUN: do insightpopulate end-do else datainput end-case ! load input data procedure datainput writeln("loading data") end-procedure ! create model constraints ! optimize ! post-process results end-model

Page 70: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

70 Fair Isaac Confidential and Proprietary

App Resources Files Three categories of resource files can be provided for the model: model resources, client resources and app attachments. Resources can be included in a new app by loading an app zip file instead of the .bim file alone. The resource files can be updated in place via the Actions menu in the Web Client and from within Xpress Workbench.

Model Resources Model resources are made accessible to the model during the execution of a scenario. These resources are copied to the working directory of the executing model and can be accessed by the standard data access functions of Mosel.

Note Non-default security settings for an execution worker may prevent model resources from being accessed by the model. Model resources can be flagged in the companion file as available only during the scenario load phase, which can then be used to avoid transferring large data files to the execution worker for subsequent runs.

User Interface Resources User interface resources, also known as client resources, define the user interface for the app. They are typically HTML/JavaScript or VDL source files used to view and interact with scenario data.

App Attachments App attachments are files which a user has associated with the app. They can be provided in the initial app zip file, and they can be created and modified via the Web Client and Xpress Workbench. mminsight provides procedures for retrieving app resources, copying them into the working directory of the executing model so that they can be accessed using the standard data access functions of Mosel.

Page 71: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 71

Data Management and Scalability

Note When considering scalability and performance, be sure to determine whether you need to capture the augmented data. For more information, see Implications For Data Management and Scalability.

When the first scenario of an app is loaded, the schema of the model is captured. The following rules are used to identify entities for input and results data.

Note Entities are included in the schema only if declared prior to the insightpopulate call:

Any entity of basic type is included in the schema as an input data entity. Any entity of MP type is identified in the schema as a results data entity.

These rules can be overridden by annotations in the mosel model. Entities can be explicitly identified as input, result, or ignore [email protected] input [email protected] state: string

In the example above, the state entity is identified as input data that should be updated at the end of the model. Normal behaviour is to ignore any modifications to the input data that the model itself makes during a scenario execution. However this can be overridden by using mosel annotations. Please see the Xpress Insight Mosel reference for details. Result data is always deleted when an index set is modified. This is to ensure that result arrays remain consistent after such a modification. If the input data is modified without the results data being deleted, then the results data will be flagged as “dirty” by the system until the scenario is executed again. This dirty status can be checked by the API. A custom view typically checks scenario.isResultsAvailable before deciding whether to do anything with the results data for that scenario. A custom view that is expected to cater to deferred results deletion may also want to check this in conjunction with the scenario.isDirty flag in order to decide whether to visualize the data (and if so, how to indicate that the results are out of date). Each loaded scenario holds an independent (compressed) copy of the input data, and each executed scenario holds an independent copy of the results. For very large models, performance can be improved by removing from the schema entities that do not strictly need to be persisted. These should be marked in the

Page 72: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

72 Fair Isaac Confidential and Proprietary

mosel annotations as [email protected] ignore for the corresponding entity element. For the input data, this would include input data that does not change from scenario to scenario. Such input data could be loaded from a model resource or a data source during the Run mode of model execution. The entities in this fixed data should be marked as ignored entities by the companion file.

Note Unmanaged (ignored) entities are not persisted or made available to a client through the server API. This drawback can be remedied by calculating in the model useful aggregated metrics from the fixed data and recording these in the results data.

Depending on the requirements of the application, it may be possible to improve the performance for handling large volumes of results data by persisting calculated metrics rather than the results data in its entirety. It is possible to engineer the model to make the selection between persisting metrics or the full results data based on a runtime parameter that could be set per scenario. The actual Mosel mpvar/linctr entities would be optionally excluded from the results and copied to an equivalent set of basic type entities that are included in the schema as results. If the copy step is skipped, then the empty entities will occupy negligible space for most scenarios.

Basic Presentation Customizations In the preceding section, the model was loaded into the Xpress Insight application with the minimal required changes. Once deployed, the named entities in the model are presented to the user unchanged, and anonymous entities in the model are not visible. The following options are customizable via the mosel annotations, to modify the way in which the model entities are presented. Each entity in the model can have the following options set using the annotations: insight.alias Sets an alias name that will be used in place of the entity

name throughout the user interface. insight.hidden true Marks the entity as hidden, and by default it will not be

listed anywhere in the user interface. Some views allow this state to be unset manually to make hidden entities locally visible.

insight.format $#,###.00 The format attribute controls how numeric values are displayed. If not present, numbers will be rendered in the manner of the current locale (e.g. the number 1234 would be rendered as “1,234” if your system uses US number formatting, or “1.234” if it uses French). The value of this attribute expresses, in a standard syntax, how the number is to be represented. This attribute can be used to control aspects such the

Page 73: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 73

currency symbol, the number of decimal places, and the presence and spacing of grouping separators. - The syntax of the format attribute value adopts the number formatting

conventions from Java (java.text.DecimalFormat).

- When editing or inserting a formatted value, the default formatting is used rather than the default formatting. The reason for this is so that numbers can be entered directly without having to conform to specific constraints (such as including a currency symbol or a set number of decimal places).

insight.transform.labels.entity Identifies an entity (B) to use for labels. Rather than display a data value from the original entity (A), the data value is used as the index for a lookup into the entity B. If the index exists in B, then the corresponding value from B is displayed rather than the original data value from A. The labels array B acts as a map from data values to labels for those data values and is commonly used to map integer data values to strings. The labels entity B is required to be an array with an index set that is the same type as the data type for A. The data type of entity B can be any primitive type.

insight.transform.labels.sortby values=value/label The sort-by annotation of the entity is used to determine how elements of this entity should be sorted. This can have value “label” (which is the default) to indicate that the labels themselves should be compared when sorting; or “value” to compare the underlying values. For example, an alert status code might be represented by an integer in range (1,2,3) with string labels (“RED”, “YELLOW”, GREEN”). An array of such status codes might have the sort-by attribute set to “value” so that in ascending order the RED alerts are listed first. (Contrast this with the ordering of the labels, which would be “GREEN”, “RED”, “YELLOW”.)

Debugging Aids Xpress Insight provides a fully-featured debugger which is seamlessly accessed from Xpress Workbench. Refer to chapter 5 of the Xpress Workbench User Guide for details. The mminsight module provides several further parameters to aid the process of developing and debugging a model for the Xpress Insight system. The insight_verbose parameter enables verbose output from the mminsight

module for diagnostic purposes and will cause additional information to be logged as mminsight interacts with the model at runtime.

Page 74: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

74 Fair Isaac Confidential and Proprietary

The insight_writeprob parameter instructs the system to export the optimization problem in mps format to a designated file path immediately prior to solving.

Additionally, the WildFly application server log file in <installdir>\insight\server\wildfly-9.0.1.Final\standalone\log\server.log may contain more information on any server-side errors that are encountered.

Adding an App Icon To customize the app icon displayed on the home page of the Web Client, create a 64x64 pixel PNG file named project-icon.png and place it in the app's client_resources folder.

Configuring App specific help You can configure the app’s companion file so that when the user clicks the Help link in the web client they are directed to help relating to the app rather than Xpress Insight. This only applies when the user is on the app page. To enable app specific help, you need to add a line to the app’s companion file: External URL example <?xml version="1.0"?> <model-companion xmlns=”http://www.fico.com/xpress/optimization-modeler/model-companion” version="3.0"> <help-url>https://my.external.help.url</help-url>

Relative URL example <?xml version="1.0"?> <model-companion xmlns=”http://www.fico.com/xpress/optimization-modeler/model-companion” version="3.0"> <help-url>path/relative/to/client_resources</help-url>

Page 75: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 75

Note A link is treated as absolute if it contains a scheme (eg https://). Otherwise it is treated as relative to client_resources.

Using Attachments The Web Client provides a way to attach files to an app and also to individual scenarios. These attachments can be accessed from Mosel, providing another way for the user to interact with the model.

Note Refer to the Web Client User Guide for more information about how to work with attachments.

App Attachments App attachments are read-only from the Mosel model. They can be used as an alternative to model resources to provide a source of input data. The advantage they have over model resources is that an app attachment can be updated via the Web Client, whereas model resources are final once the app has been created. Before the model can use an app attachment, it must download it from the Xpress Insight server: insightgetprojattach('input.dat')

After this call, a local copy of the file is available in Mosel's working directory where it can be read as you usually would in Mosel. For example: initializations from 'input.dat' MyData end-initializations

The model can also list all the available app attachments by calling insightlistprojattach, and can retrieve information about a particular attachment using insightgetprojattachinfo.

Scenario Attachments Scenario attachments can both be read and written by the model. There are two main uses: as an optional source of input data, and as a way of creating alternative result artifacts, such as a PDF or spreadsheet.

Page 76: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

76 Fair Isaac Confidential and Proprietary

When a scenario is created it has no attachments, so the model should check whether the attachment existed after trying to download it from the server. One option is to check for an app attachment of the same name if the scenario attachment does not exist: insightgetscenattach('input.dat') if insightattachstatus <> INSIGHT_ATTACH_OK then insightgetprojattach('input.dat') end-if

This allows an app to supply a default input data file as an app attachment, which can then be optionally overridden for each scenario by downloading it, modifying it, then uploading it as a scenario attachment. The model can also create scenario attachments as a result of its execution. The file to attach must exist must first be created in the Mosel working directory before being transferred to the server: ! E.g., use mmsheet to create a spreadsheet containing result data, then: insightputscenattach('results.xls')

Several other subroutines are available which affect scenario attachments: Calling insightsetscenattachdesc provides a description for an attachment, which will appear in the attachments dialog in the Web Client and can be retrieved using VDL and the JS API. Hide an attachment using insightsetscenattachhidden, so that it is not visible in the attachments dialog in the Web Client until the user chooses to show hidden attachments. Rename an attachment using insightrenamescenattach.

List all the available scenario attachments by calling insightlistscenattach, and retrieve information a particular attachment using insightgetscenattachinfo.

Note An app or scenario can have a maximum of 100 attachments, each of which has a maximum size of 60Mb. Scenario attachments are included when cloning and exporting the scenario.

Note While a scenario is queued or executing, the scenario attachments cannot be modified by another user. App attachments are not locked in this way, so care must be taken to ensure that changes to app attachments do not affect an executing model unexpectedly.

Page 77: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 77

Attachment Tags The app can define a number of attachment tags, which represent attachments which have a special function within the model. The model and custom views can then refer to these attachments by tag name, instead of by filename. The user can add and remove tags on an attachment using the attachments dialog in the Web Client, and in this way they can indicate that an attachment should be used by the model for a particular purpose. Without tags, the user could only achieve this by naming their file with a special filename known by the model. Users are not able to define custom attachment tags. Tags are defined in the companion file within the <attachment-config> element, which should be placed immediately before the <client> element. In addition to its name, a tag can have the following properties: description - A description of the tag's purpose, which will be displayed in

the attachments dialog in the Web Client. mandatory - If true, an attachment must exist with this tag before the

scenario can be executed. By default, it is false. usage - Can be single-file or multi-file. Determines whether only one

attachment per scenario can have this tag, or whether several attachments can have the tag at the same time. By default, a tag is multi-file.

Attachments provided in the app zip file in the project_attachments folder (see App Resources Files) can be automatically tagged when the app is created. This allows an app that depends on tagged attachments to be configured with default attachment data by the app developer, so that the user does not need to manually add tags to attachments before using it. This companion file fragment shows the syntax for defining attachment tags:

<attachment-config> <attachment-tags> <!-- A single-file, mandatory tag, which will initially be present on input.xlsx, provided in the app zip file. --> <attachment-tag name="input-sheet" usage="single-file" mandatory="true"> <description> A data source required by the Mosel model before it can execute (load or run). </description> <attachments> <attachment>input.xlsx</attachment> </attachments> </attachment-tag> <!-- A multi-file, non-mandatory tag, added by the model to any result files that it generates. --> <attachment-tag name="result-sheet">

Page 78: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

78 Fair Isaac Confidential and Proprietary

<description> An Excel file that is generated by the model containing the results. </description> </attachment-tag> </attachment-tags> </attachment-config>

The Mosel model can list of all the attachments with a given tag using insightlistscenattachbytag or insightlistprojattachbytag. It can then download them to Mosel's local working directory using insightgetscenattach or insightgetprojattach.

Alternatively the model can call insightgetattachbytag, which searches both the scenario and the app for an attachment or attachments with the given tag and then downloads them automatically. This makes it possible to provide a default attachment on the app, but allow the user to optionally override it on each scenario. There are two versions of this subroutine: one which retrieves a list of attachments (for multi-file tags), and one which retrieves just one attachment (for single-file tags). The Mosel model can also add tags to an attachment that it has generated, using insightsetscenattachtags, to mark that attachment for a particular purpose in the user interface. A custom view can then locate the attachment from VDL or the JS API using the tag name. See the Xpress Insight Mosel Interface Reference Manual for more information about these subroutines.

Page 79: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 79

CHAPTER 4 Authoring Custom Views

Options for Custom View Authoring The built in capabilities of FICO Xpress Insight can be augmented by the addition of custom views for rich, interactive interfaces specific to a particular application. There are three methods for adding custom views and each is covered extensively in a separate chapter. Each method and type of view has advantages and limitations that are discussed below.

The View Definition Language The View Definition Language (VDL) is a markup language designed to allow views to be authored using an XML notation. Markup tags are provided to define basic page structure and to incorporate and configure components such as tables and forms. The language has syntax for referencing scenario information, and for enumerating content over data sets from the scenario. VDL version 4.0 provides a set of functionality for defining basic interactive views through configuration only. VDL content can be augmented with customization (HTML markup, CSS styling and JavaScript code). However if extensive customization is required then the JavaScript API is likely to be a more suitable approach. VDL 4.0 views are supported for the following browsers: IE11, Chrome, Firefox.

The JavaScript API Xpress Insight provides an extensive JavaScript API for accessing and manipulating the state and data of the system. Methods are available to transform scenario data, execute scenarios and query results. The API includes a recommended set of CSS styling and a library of components designed to automate many typical operations of the view. JavaScript API 4.0 views are supported for the following browsers: IE11, Chrome, Firefox.

Tableau® for FICO Reporting Tableau for FICO is a powerful reporting tool that can create advanced tabular and charting dashboards. Tableau visualizations can be incorporated into Xpress Insight apps as custom views that report on the scenario data. Tableau visualizations are authored using the Tableau Desktop application and published to the Tableau Server integrated with Xpress Insight.

Page 80: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

80 Fair Isaac Confidential and Proprietary

Tableau visualizations are limited to read-only reports and cannot be used to modify the scenario data. Tableau views are supported for the following browsers: IE11, Chrome, Firefox.

Setting up your Development Environment

Custom View development with the JavaScript API involves editing JavaScript, HTML, and CSS source code. Although you can use a lightweight text editor to develop your view it is recommended that if you are working on any sizable app you should use Xpress Workbench. This provides code formatting, code analysis and code completion. This can lead to fewer mistakes and cleaner code. If you wish to use an alternative development environment, for example, WebStorm, you can setsup code completion on the Xpress Insight JavaScript API using the provided source code for the API in the following location: <installdir>\insight\lib\javascript

For example, you can setup your app in WebStorm to use this as a library as follows:

1. Go to the WebStorm application settings 2. Open Languages & Frameworks > JavaScript > Libraries 3. Click Add. 4. Name it XI JavaScript API and set Visibility to Global 5. Click Add to attach directories. 6. Select <installdir>\insight\lib\javascript\insight-4.0. 7. Click OK. 8. Make sure the new library added to the list is Enabled.

Manually updating an Xpress Insight App from the Web Client You can update the source files of an existing app via the Web Client. To do this you need a zip file containing the app source files that you wish to change. The zip file may be a complete app, or it may instead contain one or more of the following: An updated bim file An updated companion file New or modified model resources New or modified client resources New or modified managed Tableau workbooks New or modified app attachments

Page 81: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 81

Within the web client, click the Actions menu (the cog icon) and select Update App. Select your zip file when prompted, and then check the notification area at the bottom of the screen for errors or warning messages.

Note The updated bim file must have the same schema as the original bim file. Changes to the model may not be reflected in your scenarios until you reload them.

Note Model parameter values are captured when the scenario is first loaded. If an updated bim file contains different default values for existing parameters, these will be ignored.

Note New or modified Tableau workbooks will not be published unless the zip file also includes a companion file which configures the workbooks as managed=true.

Note Changes to Tableau workbooks will not take effect for other logged-in users until they log out and log back into Xpress Insight.

Automatic Code Refresh By default you are required to manually update your client resources through the each time you make a code change. However, you can specify a folder location on the computer hosting Xpress Insight Server as a place for a particular app to get its client resources from. This is an optional element that can be added to the companion file as follows. <client> <view-group title="Main"> <html-view title="Welcome" path="welcome.html"/> </view-group> <client-resources-local-path>C:\dev\example-app\client_resources</client-resources-local-path> </client>

To configure Xpress Insight server to use local paths to client resources, when specified, edit the following file:

<installdir>\insight\server\wildfly-9.0.1.Final\bin\standalone.conf.bat

Page 82: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

82 Fair Isaac Confidential and Proprietary

And add the following line anywhere in the file:

set INSIGHT_SERVER_MODE=development

You will need to restart the Xpress Insight server for this change to take effect. Once the server is restarted and the browser is showing a view in development then a query parameter needs to be added: ?debug=true

This needs to inserted into the browser URL after ‘insight/’ and before the string of characters that begins with the hash symbol ‘#’. For instance: http://localhost:8860/insight/?debug=true#...

This enables the developer to see local changes with only a browser refresh. If the Xpress Insight Server is not set to run in development mode, then the <client-resources-local-path/> element will be ignored and client resources will be served from the uploaded app bundle as normal. However, if you are running the Xpress Insight Server in development mode and the local path does not contain the requested client resource, you will get 404: page not found errors. When distributing a copy of your app, remove the <client-resources-local-path/> element from the companion file as it may cause unexpected behaviour in a demo or production environments.

Page 83: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 83

CHAPTER 5 Authoring a Custom View with the View Definition Language

The Xpress Insight View Definition Language (VDL) is a technology that enables rapid development of custom views. It allows you to associate UI components with model data to view and edit the data. VDL is a superset of HTML, meaning that a VDL view can contain any valid HTML markup as well as some additional elements that are provided by VDL. In addition, VDL is extensible so you can build on top of it to create reusable components.

Note Text.While reading through this development guide, please also refer to the VDL 4.0 Language app available in your install at:

<installdir>\examples\insight\vdl\vdl_language.zip

One of the main reasons VDL provides rapid development of views is that it has built-in knowledge of Xpress Insight scenarios and entities and gives you easy ways to bind on to your app's model data.

VDL Fundamentals To include a VDL view in you app you first need to define the view in your cfile: <client> <view-group title="Main"> <vdl-view title="Summary" path="summary.vdl"/> </view-group> </client>

Note The new entry is of type "vdl-view" and the file has the file extension ".vdl".

Create the ".vdl" file in your app's client_resources folder. Open the file in your text editor/IDE. You should be able to map the ".vdl" file extension to be treated as HTML files. A VDL view begins with the <vdl> tag which specifies the version number of the VDL syntax for the page. Within this you add a <vdl-page> which will contain your view contents. Here is an example of a small VDL page: <vdl version="4.0"> <vdl-page> <vdl-section heading="My Section"> <p vdl-text="=scenario.entities.Customers.value"></p> </vdl-section> </vdl-page> </vdl>

Page 84: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

84 Fair Isaac Confidential and Proprietary

Each VDL tag is prefixed with "vdl-". All VDL tags and standalone attributes are prefixed so they are easy to identify and so that they don't conflict with current or future HTML tags and attributes. VDL tags, such as <vdl-section>, have attributes to customise their behaviour. The attributes within VDL tags are not prefixed. VDL attributes that can be used on any tag (standalone attributes) are prefixed. You can refer to the VDL Reference for detailed information on all the available VDL tags and attributes. <xpressdir>\docs\insight\vdl_reference\index.html

VDL tags must have closing tags specified in your markup, for instance: <vdl-section></vdl-section>

VDL standalone attributes can be used on standard HTML elements but also on VDL tag. For example: <vdl-section heading="My Section" vdl-text="=scenario.entities.Customers.value"></vdl-section>

The "vdl-text" attribute contains a specially structured string, called an expression, that directs VDL to replace the contents of the element with the value of the referenced entity from the scenario data. Furthermore, VDL will keep the element value up to date if the entity changes locally or remotely. For more information on expression see the "Expressions" section.

Controlling page layout and styling VDL incorporates a default style sheet with a foundation of Bootstrap 3.x. This imposes rules on how built-in styling might be augmented for horizontal spacing and container sizes. There is a hierarchy of containers in which the other VDL components are placed. These correspond closely to the similarly-named container and layout classes in Bootstrap. Where there are vdl-section, vdl-row and vdl-column tags, they correspond to container, row and col-*-* classes in Bootstrap (3.x). For

Page 85: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 85

example:

Using the following VDL file:

<vdl version="4.0"> <vdl-page> <vdl-section heading="Section 1" width="500"> <vdl-row><p>Section content</p></vdl-row> </vdl-section> <vdl-section heading="Section 2" width="500"> <vdl-row><p>A VDL table.</p></vdl-row> <vdl-row> <vdl-table page-mode="paged" page-size="10"> <vdl-table-column entity="CustomerName" width="120"></vdl-table-column> <vdl-table-column entity="ConversionValue" width="120" editable="true"></vdl-table-column> </vdl-table> </vdl-row> </vdl-section> </vdl-page> </vdl>

Page 86: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

86 Fair Isaac Confidential and Proprietary

CSS styling can be applied in the application.css stylesheet as shown below:

/* The vdl-column tag with a class of ‘heading’ is generated by VDL in this example */ vdl-column.heading h2 { margin: 5px 0; } vdl-section vdl-row { margin-top: 5px; } vdl-section vdl-row vdl-column { outline: 1px solid #ccc; width: 100%; } vdl-section vdl-row vdl-column p, vdl-section vdl-row vdl-column .table-wrapper { margin-bottom: 0; padding: 5px; }

Note The following are CSS considerations:

Styles can be applied directly to VDL tags and classes that are attached to these. Do not tie CSS rules to the generated HTML.

Use outline rather than border to preserve the existing container layout because outline does not add to the size of the container.

While you can add spacing above and below vdl-sections, vdl-rows and vdl-columns, keep in mind that adding horizontal spacing will break the Bootstrap layout. While doing so may work in some situations where you only have one item per vdl-row horizontally, it should generally be avoided.

Autotable is wrapped with a container that has the class .table-wrapper. <p> paragraphs have a margin-bottom of 20px by default, which was

removed from the above example.

Compact layout A compact page style is available that reduces the vertical spacing between elements on the page (including row spacing in tables). To enable this add the "compact" class to the vdl-page. <vdl version="4.0"> <vdl-page class="compact"> ...</vdl-page> </vdl>

Page 87: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 87

Sections Page content can be organized into sections using the section tag. For smaller pages you might only use one section but for larger pages, separating your content into several sections will help you organize your layout. Sections can be nested and each one can have an optional heading. <vdl-section heading="First section"> This is the first section. <vdl-section heading="Section 1a" heading-level="4"> This subsection has a smaller heading.</vdl-section> </vdl-section> Heading levels follow the HTML convention, with level 1 being the largest. By default, sections have a fixed width (1140 pixels). If the browser window is too narrow to display the content, scrollbars will appear. The width can be customized by adding the width attribute to the section (widths are specified in pixels). <vdl-section width="1000">This section is 1000 pixels wide.</vdl-section> Alternatively a section can be defined as fluid. In this case, text and other content will reflow to fit the width of the browser window whenever it is resized. <vdl-section layout="fluid">

This text will wrap onto the next line if the window becomes too narrow. </vdl-section>

The width attribute is not permitted on a fluid section.

Column layouts Creating a multi-column layout is easily achieved using the column tag. Column sizes are given in 1/12ths of the page width. <vdl-section> <vdl-column size="3">The left-hand column occupies one quarter of the page.</vdl-column> <vdl-column size="6">The center column occupies the half of the page.</vdl-column> <vdl-column size="3">The right-hand column occupies one quarter of the page.</vdl-column> </vdl-section>

In a fluid section columns will resize as the browser window resizes, so that a column of size 3 always occupies one quarter of the browser window width. In a fixed section, the column widths remain the same when the browser window is resized.

Page 88: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

88 Fair Isaac Confidential and Proprietary

Note If the total width of all the columns adds up to more than 12, the surplus columns will wrap onto the next row. Columns that have wrapped onto the next row may not be displayed correctly.

If a column does not specify a size or width it will be given a size of 12 if the only column in a row, otherwise it will be made just big enough to hold the widest element contained in the column. This document refers to such columns as implicitly sized.

Grid layouts Grid layouts are created using the row tag within a section. Rows can contain columns, which function as cells in the grid. <vdl-section> <vdl-row> <vdl-column size="3">Top left</vdl-column> <vdl-column size="3">Top right</vdl-column> </vdl-row> <vdl-row> <vdl-column size="3">Bottom left</vdl-column> <vdl-column size="3">Bottom right</vdl-column> </vdl-row> </vdl-section>

Note All sections use a grid layout internally. Any content that is not within a vdl-column element is wrapped in a single implicitly sized vdl-column. Any vdl-columns that are not within a vdl-row are wrapped in a single vdl-row.

This example has content both within and outside of rows and columns. <vdl-section> Content within a section <vdl-row> Content within a row <vdl-column size="3">Content within a row and column</vdl-column> </vdl-row> <vdl-column size="2">Content within a column</vdl-column> More content within a section </vdl-section>

To conform to the grid layout, implicit vdl-rows and vdl-column elements will be added to the VDL, resulting in the following. <vdl-section> <vdl-row> <vdl-column size="12">Content within a section</vdl-column> </vdl-row> <vdl-row>

Page 89: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 89

<vdl-column>Content within a row</vdl-column> <vdl-column size="3">Content within a row and column</vdl-column> </vdl-row> <vdl-row> <vdl-column size="2">Content within a column</vdl-column> <vdl-column>More content within a section</vdl-column> </vdl-row> </vdl-section>

Calculating section widths In a fixed section, the column widths are fixed at 97.5 pixels per size unit. If the width of a fixed section is set different to the default then the column widths will adjust accordingly to always try and fit 12 columns in the section width. The same happens dynamically for fluid section widths. <vdl-section width="2000"> <vdl-column size="10">Left-hand column.</vdl-column> <vdl-column size="2">Right-hand column.</vdl-column> </vdl-section> You can embed vdl-row elements inside vdl-column elements, effectively subdividing a vdl-column into a further 12 units. <vdl-section> <vdl-column size="6"> <vdl-row> <vdl-column size="8">Left-hand column.</vdl-column> <vdl-column size="4">Middle column.</vdl-column> </vdl-row> </vdl-column> <vdl-column size="6">Right-hand column.</vdl-column> </vdl-section>

Expressions Expressions are statements that can be used as an alternative to static values for VDL attributes. They allow dynamic content to be inserted in the page or to be used to programmatically control layout and data flow. Here is an example of an expression: <span vdl-text="=scenario.entities.MyScalar.value"></span>

An expression is denoted by an equal sign "=" at the start of the attribute value. Everything after the equal sign is part of the expression that gets evaluated and reevaluated when any entities referenced within it change. The previous example references the value of MyScalar entity from the first scenario.

Syntax The basic syntax rules of the VDL expression languages are:

Page 90: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

90 Fair Isaac Confidential and Proprietary

Case sensitive Expressions are case sensitive. 'myentity' and 'MyEntity' refer to different objects.

Dot notation The 'dot' operator is used to access properties of objects. E.g. scenario.entities.MyScalar.value gives access to the entities property of the scenario object. This in turn is an object and then the second dot provides access to the MyScalar property of the entities object.

Array access Elements within an array are accessed using the square brackets. Inside the square brackets the index of the element required is specified e.g. scenarios[1] scenario.entities.MyArray(0).value Which refers to the second element (arrays count from zero)

Note It is unsafe to reference array elements directly without guarding the expression to check the element exists. Usually you will reference elements of an array within a loop over all the indices. To guard access to a specific element you can do the following: <span vdl-text="=scenario.entities.MyArray[0] ? scenario.entities.MyArray[0].value : ''"></span>

Function calls Functions may be written inline or in script blocks. Inline functions are written fully within the expression itself: <vdl-validate pass="=function(entity, value) { return value > 100; }"></vdl-validate> This is appropriate if the function is simple and doesn't need to be shared. Otherwise define the function in a script block like so: <script> Function MyFunc (entity, value) { return value < 10; } </script> <vdl-validate pass="=MyFunc"></vdl-validate>

This allows more space to write a function that is more complex and can be read easier but also allows it to be reused amongst several functions, if needed.

String demarcation

Page 91: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 91

Often strings will be needed within an expression. An expression is already contained within a pair of double quotes so it is essential to use single quotes for strings within expressions: <vdl-column vdl-text="='a' + 'bb' + 'ccc' "></vdl-column>

This would return the value as 'abbccc'.

Key value pairs Several vdl attributes take key value pairs as their input. For example: <div vdl-css="hilite: true, showing: false"></div>

The symbol before the colon (:) is called the 'key' anything after (up till the end of the attribute string or the next comma) is the 'value'. These are treated as evaluated expressions. If the key that is chosen contains anything other than alphanumeric character (a-z & 0-9) then the key must be placed inside quotes. To avoid clashing with the attribute quotes, use single quotes for this; where double quotes are used for attributes: <div vdl-css="'hilite-item': true, 'showing-item': false"></div>

Similarly, where the value is a string, then it should also be enclosed in single quotes.

Arithmetic and comparison (boolean) operators Standard arithmetic and boolean operators are available

+ add 2 + 2 = 5

- unary negative -10

- subtract 12 - 7 = 5

* multiply 8 * 7 = 56

/ divide 20 / 4 - 5

% remainder 20 % 7 = 6

< less than 3 < 6

<= less than or equal to 5 <= 10

> greater than 17 > 1

>= greater than or equal to 20 >= 20

== roughly equal to 3 == '3'

Page 92: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

92 Fair Isaac Confidential and Proprietary

!= roughly not equal 4 != '4'

=== strictly equal 6 === 6

!== strictly not equal 6 !== '6'

Note If in doubt, use the strictly comparisons.

For example with == then 3 == "3" is true but 3 === "3" is false. Use of the roughly equals operators (==, !=) can lead to unexpected matches. Better to use the strict equality for predictable results when comparing values. Logical operators

! not !false === true

&& logical and true && !true === false

|| logical false || true === true

Not all VDL attributes accept expressions. The VDL Reference lists all the available standalone attributes and attribute within each VDL tag. There is a flag "accepts expression" next to each attribute that accepts an expression. Expressions have a number of things implicitly available in scope. These are considered view globals and a list of them is as follows: • scenario - The first scenario on the shelf • scenario.entities - An object containing a map of all model entities, for

example: scenario.entities.MyScalar, scenario.entities.MyArray, scenario.entities.MySet

• scenario.parameters - A function to access model parameters, for example: scenario.parameters('MyParam')

• scenario.props - An object containing ScenarioProperties (see the JavaScript API documentation), for example: scenario.props.name, scenario.props.id

• scenarios - The array of [a][b][c]scenarios on the shelf, ordered as per the shelf ordering. Can be used to access entities from scenarios other than the first scenario. For example: scenarios[1].entities.MyArray, scenarios[1].props.name

• vars – A map of all the registered dynamic variables, see section Dynamic variables. For example: vars.MyVariable

• user – An object containing information about the currently logged in user. Contains the properties: firstName, lastName, userName, authorities.

Page 93: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 93

Entity values and labels When referencing any scalar entity or Set/Array element from the model an object will be returned with two properties:

• value: This is the raw value of the scalar or element. • label: If the model entity has an associated labels array this will be the

label corresponding with the current value of the scalar or element. If there is no label for the current value or if there is not a label array associated with the entity then the label with be a string representation of the current value. The label property will always be a string type.

A developer must reference either the value or label of an entity within expressions, otherwise any calculations may result in an error, or string concatenations might show the text [object Object]. If it is forgetten to specify the value or label, and in debug mode, then a log message will be shown in the web browser’s console. This message will state that the developer is trying to access an entity without specifying the value or label property. More information on VDL hints can be found in the section VDL Hints.

Accessing scalar entities Scalar entities have value and label properties and a reference. For example: <span vdl-text="=scenario.entities.MyScalar.value"></span> <span vdl-text="=scenarios[1].entities.MyScalar.label"></span>

You can also refer to scalars within a larger expression: <span vdl-text="='MyScalar is ' + scenario.entities.MyScalar.label"></span>

Accessing set entities A Set entity is treated as a one dimensional array, each element being an object with a value and a label property. Elements within a Set can be obtained using [] notation. In the example below the first element of the set is accessed: <span vdl-text="=scenario.entities.MySet[0].value"></span> <span vdl-text="=scenarios[1].entities.MySet[0].value"></span>

Set entities are simple arrays and so are easy to iterate over: <vdl-column vdl-repeat="=item in scenario.entities.MySet" size="1"> <p vdl-text="=item.value"><p> </vdl-column>

Note By default there is no guarantee about the order of a Set entity (within a script block a set sorter function can be assigned using the JavaScript API).

<script> function setSorter(originalSet) {

Page 94: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

94 Fair Isaac Confidential and Proprietary

// Sort the set, for example reverse the order of a set of integers return originalSet.sort(function(a,b) { return a < b; }; } insight.addSetSorter('MySet'); </script>

Accessing array entities Array entities can have multiple indices and so they cannot be represented as plain arrays i.e. array entities are not accessed with the [] notation. Instead the array entity name is called as a function, passing the indices as the arguments: <span vdl-text="=scenario.entities.MyArray(1, 'Medium').value"></span> <span vdl-text="=scenarios[1].entities.MyArray(1, 'Medium').label"></span>

Each array element is returned as an object with the value and label properties.

Accessing model parameters Parameters from the model are accessed as follows: <span vdl-text="=scenario.parameters('MyParam').value"></span> <span vdl-text="=scenarios[1].parameters('MyParam').label"></span>

The "scenario.parameters" global is used as an accessor function, passing in the name of the parameter to fetch. This will return an object with the value and label properties.

Accessing scenario properties Scenario Properties are used to access information about each scenario used within a view. This includes: id, name, notes, path, ownerId, shareStatus. For a full list of properties available see the JavaScript API documentation, ScenarioProperties class. The "scenario.props" global is an object that is pre-populated with the scenario properties. Scenario properties are accessed as follows: <span vdl-text="=scenario.props.name"></span> <span vdl-text="=scenarios[1].props.name"></span>

Accessing scenario attachments The scenarios used by the VDL view can have one or more file attachments associated with them. An app can define attachment tags which can then be assigned to individual attachments and used when querying the attachments from the VDL view.

Note Xpress Insight also supports app scoped attachments but these are

Page 95: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 95

not currently accessible via VDL expressions. However, they can be accessed via the JavaScript API.

The examples below describe the different ways in which scenario attachment data can be accessed. Loop over all scenario attachments: <ul> <li vdl-repeat="=attachment in scenario.attachments()"> <div vdl-text="=attachment.filename"></div> <div vdl-text="=attachment.description"></div> </li> </ul> Loop over scenario attachment tags: <ul> <li vdl-repeat="=tag in scenario.attachments.tags()"> <div vdl-text="=tag.name"></div> <div vdl-text="=tag.description"></div> </li> </ul> Loop over scenario attachment tag names: <ul> <li vdl-repeat="=tagName in scenario.attachments.tagNames()"> <div vdl-text="=tagName"></div> </li> </ul> Loop over scenarios that have a particular tag assigned to them: <ul> <li vdl-repeat="=attachment in

scenario.attachments.byTagName('input-sheet')"> <div vdl-text="=attachment.filename"></div> <div vdl-text="=attachment.description"></div> </li> </ul>

If no attachments match a tag name then an empty list will be returned. This could be used in a conditional expression: <div vdl-if="=scenario.attachments.byTagName('unknown-tag').length === 0"> No attachments found with the tag "unknown-tag". </div>

Note Conditionals are described in the section Conditionals.

Access an individual attachment by filename: <ul vdl-if="=scenario.attachments('input.xslx').id"> <li vdl-text="='filename: ' +

Page 96: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

96 Fair Isaac Confidential and Proprietary

scenario.attachments('input.xslx').filename"></li> <li vdl-text="='description: ' + scenario.attachments('input.xslx').description"></li> <li vdl-text="='size: ' + scenario.attachments('input.xslx').size"></li> </ul>

When no attachment matches the filename an empty object is returned, so in the above example the VDL conditional checks that a matching attachment exists by testing for the id property.

Dynamic variables When writing VDL expressions you may find that you are repeating some calculations or operations that would benefit from being defined once and referenced in multiple expressions. This is possible through the use of the <vdl-var> tag to define a variable and its value. Then you can reference that variable throughout the rest of your VDL view. Variable names should be unique. VDL variables can either be globally scoped or scenario scoped. Here is an example of creating and using a globally scoped variable: <vdl version="4.0"> <vdl-var name="title" value="My Page Title"></vdl-var> <vdl-var name="rows" value="=['one', 'two', 'three']"></vdl-var> <vdl-page> <vdl-section heading="=vars.title"> <vdl-column vdl-repeat="=row in vars.rows" heading="=row"> content here </vdl-column> </vdl-section> </vdl-page> </vdl>

Here is an example of creating and using a scenario scoped variable: <vdl version="4.0"> <vdl-page> <vdl-section> <vdl-column vdl-repeat="=s,i in scenarios"> <vdl-var name="title" value="='scenario: ' + s.props.name" scenario="=i"></vdl-var> <span vdl-text="=s.vars.title"></span> </vdl-column> </vdl-section> </vdl-page> </vdl>

Note With the scenario scoped variables the scenario attribute must be specified. This must be the scenario index, not id. In the example above the scenario index is being captured in the vdl-repeat as the loop variable

Page 97: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 97

"i". This is then used as the scenario index for the vdl-var.

Schema Access to schema information is available for any of the entities in the model. The information available can be found in the JavaScript API documentation. In addition to this it is easy to get the alias for an entity as follows: <p vdl-text="=schema.FactoryDemand.alias"></p>

Access to any of the other schema properties uses the getter methods listed in the JavaScript API documentation: <p vdl-text="=schema.FactoryDemand.getType()"></p> <p vdl-text="=schema.FactoryDemand.getIndexSets()"></p> <p vdl-text="=schema.FactoryDemand.isConstant()"></p>

User properties Information about the currently logged in user is available from within expressions. Reference the following properties from the user global:

• firstName • lastName • userName • authorities – returns an array of authority names as strings

A developer can also call the function, hasAuthority() passing an authority name as a string. For example, looping over the authorities: <vdl-column vdl-repeat="=auth in user.authorities" vdl-text="=auth"></vdl-column>

or checking for a particular authority: <span vdl-if="=user.hasAuthority('PROJECT_DELETE')"> Can delete app </span>

Advanced Expressions In addition to the above view globals it is also possible to make use of any standard JavaScript syntax and globals that are provided by the insight API, such as "insight", lodash "_" and jquery "$". It is common to define your a global function within script blocks or external script files and use them in the expression: <script> function add(a, b) { return a + b;

Page 98: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

98 Fair Isaac Confidential and Proprietary

} </script> <span vdl-text="=add(scenario.entities.MyInteger.value, scenario.entities.AnotherInteger.value)"></span>

The above example shows an inline script block that defines the "add(a, b)" global function. The expression calls this and passes in MyInteger and AnotherInteger from the model. The span text contents will be the result of the function call. For more complex functions it's best practice to place them in a separate file which can be imported as follows: <script src="math-functions.js"></script> <span vdl-text="=add(scenario.entities.MyInteger.value, scenario.entities.AnotherInteger.value)"></span>

Loops VDL provides a means of repeating a block of VDL content for each value in an array or set.

vdl-repeat attribute The vdl-repeat attribute is placed on a VDL or HTML element in order to repeat that same element by iterating over a collection. <h1 vdl-repeat="=s in scenarios"> This scenario is called <span vdl-text="=s.props.name"></span> </h1>

The format is '=<variable> in <collection>', where <variable> is a symbol of your choosing that can be referred to by further VDL expressions and <collection> is an array or other JavaScript collection as mentioned above.

Note This attribute repeats the element it is attached to and any child content of the element.

vdl-repeat-contents attribute This attribute works the same as vdl-repeat above. The only difference is that this extension only the repeats the child contents of the element it is attached to: <h1 vdl-repeat-contents="=num in [1,2,3]"><b vdl-text="=num"></b><h1>

which, in this case using a plain JavaScript array, would result in markup similar to: <h1><b>1</b><b>2</b><b>3</b></h1>

As you see, this has repeated the <b> tag and it's VDL generated content (using the vdl-text attribute extension) fed from iterating over the array using a local variable named num. This is useful in case where you might repeat several

Page 99: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 99

groups of elements without repeating the parent element, such as a pair of table cells for each iteration round the loop.

The loop index Both vdl-repeat and vdl-repeat-contents can use a second variable which is populated with the index position of the current iteration of the loop. <h2 vdl-repeat="num,idx in [10,20,30]">...</h2>

In this case num and idx would have the values 10,0 20,1 30,2 on each iteration. The index starts at zero for the first item.

HTML ids in loops Avoid using the HTML id attribute on any element within a loop. HTML ids should be unique within a page but of course adding them to elements within a loop will end up duplicating the id. Instead, try using an HTML class and in CSS selectors target elements of that class, even use an nth-child selector if necessary. The same advice goes for jQuery selectors if trying to locate elements within a loop.

Nested loops vdl-repeat and vdl-repeat-contents may be nested multiple times. Just take care to use unique variable names in the expression for both the current item from the collection and the index variable.

Conditionals Expressions can be combined with the VDL conditional attributes to implement conditional logic that can control whether content is included in the page, hidden and how it is styled etc. And valid VDL expression can be used so long as it evaluates to a value that can be interpreted as true/false.

'vdl-if' conditional This attribute determines whether the element and it's child elements are present in the view. <div vdl-if="=scenario.entities.BoolScalar.value"><h1>A Title</h1></div>

In this example, the div and h1 will only be shown when the value of the Mosel Scalar is true. <vdl-section vdl-if="=scenarios.length > 1">...</vdl-section>

This example illustrates that vdl-if can be used on a VDL tag and more complex expressions than simple booleans can be used. The vdl-if expression is evaluated once all page data had loaded and the conditional content is not included in the page until the evaluation. A side effect of this is that adding a vdl-if condition with a simple value of true will hide

Page 100: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

100 Fair Isaac Confidential and Proprietary

content until the view data is ready which can be useful in avoiding the partial rendering of the page. <div vdl-if="=true">I am visible when the data for this view is loaded</div>

'vdl-visible' conditional The vdl-visible attribute is similar to vdl-if except that the element it is placed upon, and it's children, are never removed from the view. When supplied with an expression which evaluates to false, vdl-visible will apply a style that causes the element to not be displayed. The difference with vdl-if is that the affected elements are still in the view DOM and can be manipulated even while they are not visible. This is important if there are sections of the view that need to be kept up to date even when they are not visible.

'vdl-css' conditional The vdl-css attribute extension is similar to vdl-if and vdl-visible. It adds CSS classes to the element on which the attribute is attached if the expression evaluates to truthy. The difference with the other two attributes is that this extension takes an object as a value: <div vdl-css="={danger: scenario.entities.BoolValue.value, error: scenarios.length === 0}">...</div>

This example shows usage of the vdl-css attribute to add a CSS class called danger if the scalar entity BoolValue is true in the first instance, and to add the error class when there are no scenarios selected on the web client shelf. In each case the key entry in the object is the name of the class to add and each value is an expression which evaluates to true or false.

VDL includes When an app written with VDL becomes quite large it is often the case that the same functionality is required on several independent views. There is also a case for creating custom extensions to handle a certain feature or layout across multiple views. These two use cases are satisfied with the <vdl-include> tag. <vdl-include> enables you to split out functionality into separate VDL files that can be included into multiple views. The basic usage for <vdl-include> is: <vdl-page> <vdl-include src="heading.vdl"></vdl-include> </vdl-page>

This would result in the contents of the VDL file replacing the <vdl-include> tag. For instance, if the file ‘heading.vdl’ contained the following: <vdl version="4.0">

Page 101: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 101

<h1>Included</h1> </vdl>

Then the result would be: <vdl-page> <h1>Included</h1> </vdl-page>

There are several points to note here: 1. The included file must be a valid VDL file with the version set to 4.0 2. The root <vdl> tag in the included file is stripped out. 3. There is no need to add a vdl-page tag in the included file because the

contents may be added at any place within the main view VDL code. 4. The initial vdl-include tag will be removed. 5. Included VDL files may not use the <vdl-include> tag. Nesting is not

supported. 6. An error will be thrown if the included file can not be found. 7. Files are included before all other processing of the VDL view. If a file is

included within a conditional section then the VDL source will get included whether the conditional is true or false.

8. The path for the included file is relative to the client_resources folder.

Core Components VDL offers a number of core components in the form of VDL tags and attributes. All core components are listed and documented in the VDL Reference. The next few sections discuss the features of the core components.

VDL tables (vdl-table) The vdl-table component is used to generate tables from a given list of array entities from one or more scenarios. A vdl-table will inspect the properties of each array entity and discover the index sets associated with them. It will only be able to generate a table if the index sets match for all array entities, although you have the ability to filter individual index sets per entity if you need to include arrays that contain additional indices. For the following example, assume that we have defined an array called ChannelCost in the Mosel model as follows: CHANNELS = 1..3 ChannelName : array(CHANNELS) of string ChannelCost : array(CHANNELS) of real ... ChannelName :: ["SMS", "Mail", "Phone"]

Page 102: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

102 Fair Isaac Confidential and Proprietary

ChannelCost :: [0.5, 1.2, 3.00]

And assume that the CHANNELS set is defined in the companion file to use the ChannelName entity for its labels: <entity name="CHANNELS"> <alias>Channel</alias> <transformation> <labels entity="ChannelName" /> </transformation> </entity>

The following VDL will show the ChannelCost array data in a table: <vdl-table> <vdl-table-column entity="ChannelCost"></vdl-table-column> </vdl-table>

The resulting table will look like this:

A row has been created for each element of the index set, CHANNELS. An extra column has automatically been inserted at the left showing the row labels, which are taken from the label entity for the index set, ChannelName. You can change the column titles by specifying a custom title as the text content of the vdl-table-column nodes. To customize any of the index columns, that are autogenerated, you can add in a vdl-table-column with the set attribute corresponding with the name of the index column to customize. The following example shows both the index column and the array column with custom titles. <vdl-table> <vdl-table-column set="CHANNELS">Channel name</vdl-table-column> <vdl-table-column entity="ChannelCost">Cost of channel ($)</vdl-table-column> </vdl-table>

Page 103: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 103

Table options VDL tables can be customized with various attributes that are documented in the VDL Reference. Pagination can be enabled by setting page-mode="paged". By default this will show 50 items per-page. You can change this by setting the page-size attribute. Table filters can be enabled by setting show-filter="true". This gives the end user an input at the top of the table to filter all cells by that value. You can also set column-filter="true" to add a filter input at the top of each column, allowing the end user to filter rows based upon matches in each column. The following example shows a simple table with pagination and filtering enabled: <vdl-table page-mode="paged" page-size="10" show-filter="true" column-filter="true" width="350"> <vdl-table-column entity="ChannelCost"></vdl-table-column> </vdl-table>

When adding the show-filter and column-filter attributes to a table you should bare in mind that by default cells are sorted and filtered by their underlying value rather than the displayed value. These differ if a set has a labels array associated with it or if a custom cell renderer has been applied to a column. You can change this behaviour by setting the following column options: <vdl-table-column set="CHANNELS" filter-by-formatted="true"> Channel name </vdl-table-column>

Page 104: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

104 Fair Isaac Confidential and Proprietary

Custom cell rendering You can control what is displayed in table cells by providing a render function per column. This render function takes in 3 arguments: • The cell value. • The cell render action: "filter", "display", "type", "sort" or “copy”. These

correspond to the actions DataTables performs when rendering cells. In most cases you can ignore this and return the same value for all render actions.

• The values from each cell in the corresponding row. You can provide the render function inline within the vdl-table-column render attribute or you can reference a function that has previously been defined in the VDL view, allowing render functions to be shared between multiple columns. In the following example a shared formatter is used to format currency values and an inline function is used to perform a simple transformation of the ChannelCapacity cells. <script> function formatCurrency(original) { return insight.Formatter.formatNumber(original, '$#,##0.#0'); } </script> <vdl-table> <vdl-table-column set="CHANNELS" width="70"></vdl-table-column> <vdl-table-column entity="ChannelCost" render="=formatCurrency"></vdl-table-column> <vdl-table-column entity="ChannelCapacity" render="=function(data, type, row) { return data + ' units'; }"></vdl-table-column> </vdl-table>

The next example includes taking an action dependent on the type argment passed to the italic function: function italic(data, type, row) { data = data ? data : ''; if (type === 'display') { return '<i>Italic text ' + _.escape(data) + '</i>'; } else if (type === 'copy') { return data + ' (in italics)'; } return data; }

Page 105: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 105

In this case, if the cell is rendered following a copy action, the contents of the cell are rendered in italics.

Number formatting When displaying integer and real entities to table columns it is common to want to format the values, for example displaying as currency. This can easily be achieved using the “format” attribute on <vdl-table-column>. The format attribute takes a string which represents the formatting to apply. Here is the syntax for the formatting string:

0 Digit

# Digit, zero shows as absent

. Decimal separator

- Negative sign

, Grouping Separator

% Percent (multiplies number by 100)

In addition to the symbols above a developer can add any arbitrary text, such as a currency symbol ($, £). Here is an example showing USD currency formatting: <vdl-table> <vdl-table-column entity="SupportCosts" format="$#,###.00"> </vdl-table-column> </vdl-table>

Editable tables Array data can be made editable within a VDL table. To do this simply add editable="true" to the column. By default the table will detect the data type of the array elements and show a suitable input control when the user clicks on a cell from an editable column. The edit behaviour can be customized using any of the editor-* attributes on the column, see the VDL Reference. The input control type can be changed by setting the editor-type attribute. You can display a list of select options by specifying either editor-options and giving an expression that provides the options or editor-options-set and specifying a set entity name to provide the options.

Validation Validation is applied to all editable cells in a table. There is standard, built-in validation which checks that the inputted value is of the same datatype as the

Page 106: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

106 Fair Isaac Confidential and Proprietary

underlying Mosel entity, but it is also possible to define custom validators for columns. Validation is applied as the user types or selects a value. When a value becomes invalid the cell will be highlighted with a red border. If the user tries to save the value that is invalid a message dialog will be shown containing the validation failure message. See the Validators section for more information.

Add/Remove row You can add controls to the table that allow the end user to add and remove rows, which updates the model data accordingly. To enable this feature set the add-remove-row attribute to "true". You will also need at least one editable column defined in the table. A dialog will pop-up when the add row button is pressed, containing a form that allows the end user to select indices based on existing values from the index sets. The add-remove-row attribute can also be set to "addrow-autoinc". In this mode, the add row button will immediately add a new row to the table. The index of the new row is automatically generated by incremented the maximum existing index value.

Note This feature can only be used with a table where the entities have a single, integer dimension.

At least one array column needs to be editable for the add/remove row controls to be shown. Rows can be selected for removal one at a time by clicking on one of the index cells:

Index filtering If you need to display arrays in the same table but one or more of the arrays have additional indices you need to filter the data by specifying fixed values for the additional indices . This can be done using one or more vdl-index-filter elements within a column. In the following example The CustomerName and CustomerPropensity arrays are being displayed in the same table. The CustomerName is index by (CUSTOMERS) and CustomerPropensity is index by (CUSTOMERS, CHANNELS). The CHANNELS set is fixed to "1" for the CustomerPropensity column.

Note The fixed value for the CHANNELS indices must be a value from the

Page 107: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 107

set rather than an associated label: <vdl-table page-mode="paged" page-size="10" width="400"> <vdl-table-column entity="CustomerName"></vdl-table-column> <vdl-table-column entity="CustomerPropensity" heading="Propensity (SMS)"> <vdl-index-filter set="CHANNELS" value="1"></vdl-index-filter> </vdl-table-column> </vdl-table>

Another use for index filtering is to pivot one of the indices of an array as columns in the table. You can achieve by repeating the column for each element in the set and using the index filter to fix the value for that indices. The following is an example of how this is done: <vdl-table page-mode="paged" page-size="10"> <vdl-table-column entity="CustomerName"></vdl-table-column> <vdl-table-column entity="CustomerPropensity" vdl-repeat="=c in scenario.entities.CHANNELS" heading="='Propensity (' + c.label + ')'"> <vdl-index-filter set="CHANNELS" value="=c.value"></vdl-index-filter> </vdl-table-column> </vdl-table>

Note In the heading for the generated columns the label for the channel is being used, whereas for the index filter the value is being used.

Multi-scenario By default vdl-table will display data from the first scenario on the shelf. This can be overridden for the table or for an individual table-column using the 'scenario' attribute. If the table references entities from multiple scenarios then data will be used from the corresponding index set(s) of all the scenarios. If those index sets also have associated label arrays then labels will be looked up across all the scenarios used in the table, in the same order as appears on the shelf. <vdl-table scenario="1"> <vdl-table-column entity="EntityOne"></vdl-table-column> <vdl-table-column entity="EntityTwo"></vdl-table-column> <vdl-table-column entity="EntityThree" scenario="2"></vdl-table-column> </vdl-table>

In this example data for EntityOne and EntityTwo will be fetched from the 2nd scenario on the shelf. Data for EntityThree will be fetched from the 3rd scenario on the shelf and the index columns will be a combination of the data from both

Page 108: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

108 Fair Isaac Confidential and Proprietary

the 2nd and 3rd scenarios on the shelf. The 'scenario' attribute on the vdl-table tag is referring to the second item in the zero indexed array of scenarios.

Modifying table configuration VDL tables are based on the DataTables open source app; see www.datatables.net. It is possible to add DataTables specific options to a table by using a VDL table modifier. Set the modifier attribute to be an expression that references a function. This function will be called before that table is drawn and before each update to the table. It will be passed a configuration object and should return a modified version of that object. The object contains a property named "overrides" that can be used to add any DataTables configuration options. In the following example a modifier is applied to a table that adds the DataTables scrollY option. This makes the table scrollable: <script> function scrollableTable(config) { config.overrides.scrollY = 200; return config; } </script> <vdl-table modifier="=scrollableTable" width="300"> <vdl-table-column entity="CustomerName"></vdl-table-column> </vdl-table>

Because the table modifiers are just functions that take in a table configuration object and return a new configuration object you can easily apply functional composition. The Lodash library that is provided with the JavaScript API can help when chaining multiple function calls:

Page 109: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 109

<script> function scrollableTable(config) { config.overrides.scrollY = 200; return config; } function makeEditable(config) { config.columnOptions.forEach(function (columnOptions) { if (columnOptions.title) { columnOptions.title = columnOptions.title + ' (editable)'; } columnOptions.editable = true; }); return config; } function logTableConfig(config) { console.log('vdl-table config (' + config.tableId + ')', config); return config; } </script> <vdl-table modifier="=function(config) { return _.flow(scrollableTable, makeEditable, logTableConfig)(config) }" width="300"> <vdl-table-column entity="CustomerName"></vdl-table-column> </vdl-table>

Row filtering Table rows can be filtered out based upon the result of an expression. When rows are filtered out they will be removed from the table dataset before the table is rendered, and so won't trigger any custom renderers and won't be included in any table or column level user filtering. To filter rows you can provide an expression to the row-filter attribute on a table. This can be a simple boolean expression and inline function or a function identifier. In all cases the following arguments are provided: • rowData: Data for all the row cells • indices: Data for the index columns of the row • position: Row position in the table • tableData: Data for all table rows and cells contained within When an inline function or a function identifier is specified they should return a boolean result, true signifying that a row should be kept. This function is called for each row in the table before it is rendered to the view. In the following example CustomerPropensity is being displayed for channels "1" (SMS) and "3" (Phone) where the propensity value is less than 0.07: <vdl-table row-filter="=(indices[1] === 1 || indices[1] === 3) &&

Page 110: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

110 Fair Isaac Confidential and Proprietary

rowData[1] < 0.07"> <vdl-table-column entity="CustomerPropensity"></vdl-table-column> </vdl-table>

Table layout When a table is in an unsized column its columns will stretch to fit their contents. When the total table width hits the section width it will wrap content in the columns. If it still exceeds the section width after applying word-wrap it will show a horizontal scrollbar within the vdl-section. To control the width of the table and the individual columns you can set the width attribute on them. This takes a number that is applied as the size in pixels. You can also control the width of a table by changing the size attribute of the vdl-section or vdl-column the table is contained within.

Table State Saving By default the display state of each table in a view is stored in the user’s browser session. If the table is redrawn or the user navigates back and forth between views or apps the tables will remain the same state, this includes:

• Global search value • Column search values • Column sorting • Pagination: page size, current page

If the user closes the browser window or if they log in as a different user within the same browser window then the state for all tables will be wiped. This is only considered temporary state that is kept whilst they are working within a given browser window and Xpress Insight session. During view development, if you are changing the configuration of tables, you may wish to display table state saving temporarily. You may also wish to disable it perminantly for particular tables in a view. To do this add the following attribute to the <vdl-table>: <vdl-table save-state="false">

Page 111: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 111

VDL forms (vdl-form and vdl-field) Use the vdl-form tag to create a form with editable fields. Add vdl-field tags for each entity or parameter you want the user to edit. The control type of the form input will be determined automatically based upon the data type of the entity. Boolean entities map to checkboxes, everything else maps to text fields by default. <vdl-form> <vdl-field parameter="NC"></vdl-field> <vdl-field entity="Budget"></vdl-field> <vdl-field entity="IncludeTax"></vdl-field> </vdl-form>

Labels are automatically generated for fields based on the entity alias (or the name, if there is no alias), and the fields are laid out in a form:

For array entities, you must also specify the indices for the array element that will be edited by the field. In this case, it can also be useful to override the label using the label attribute: <vdl-form> <vdl-field entity="CustomerPropensity" indices="1,2" label="Propensity (1, Mail)" label-size="4"></vdl-field> </vdl-form>

You can also generate form fields from elements in an array by looping over one or more of the index sets: <vdl-form vdl-repeat="=c in scenario.entities.CHANNELS"> <vdl-field entity="CustomerPropensity" indices="=[1,c.value]" label="='Propensity (1, ' + c.label + ')'" label-size="4"></vdl-field> </vdl-form>

Page 112: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

112 Fair Isaac Confidential and Proprietary

If the user can choose from a fixed set of values for an entity, you can create a drop-down select box by specifying a set entity to be used to generate the options: <vdl-field entity="Goal" options-set="Goals"></vdl-field>

You can also specify the options as a plain JavaScript array or object. These options could be generated by some function: <script> function generateGoalOptions() { return {1: 'Option 1', 2: 'Option 2'}; } </script> <vdl-form> <vdl-field entity="Goal" options="=generateGoalOptions()"></vdl-field> </vdl-form>

If the entity bound to a vdl-field is a string or an array you may want an empty option to be included to clear the string or remove the array element. To do this set the attribute options-include-empty="true". Instead of a select input, drop-down, you can show a radio group instead by setting type="radio" and including either the options-set or the options attribute:

Fields can be made read-only by toggling the enabled attribute. By default this is set to true, allowing user input. You can toggle the enabled state using an expression.

Page 113: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 113

In the following example the Goal field will be disabled if the IncludeTax entity is false: <vdl-form> <vdl-field entity="IncludeTax"></vdl-field> <vdl-field entity="Goal" enabled="=scenario.entities.IncludeTax.value" options-set="Goals"></vdl-field> </vdl-form>

Validation Validation is applied to all fields in a form. There is standard, built-in validation but it is also possible to define custom validators for fields. Validation is applied as the user types or selects a value. When a value becomes invalid the field will be highlighted with a red border. If the user tries to save the value that is invalid a message dialog will be shown containing the validation failure message. See the Validators section for more information.

Form layout The default layout for forms is horizontal. This means that each field will be on a separate line and will contain a label on the left and an input control on the right. By default the label and input will have a grid size of 2 if placed within an unsized vdl-column tag, such as: <vdl-column> <vdl-form layout="vertical"> <vdl-field entity="Budget"></vdl-field> <vdl-field entity="Goal" options-set="Goals"></vdl-field> </vdl-form> </vdl-column>

This follows the style of Forms as they were up to and including VDL 2.0. There is an alternative approach to controlling the width of a vdl-form and that is achieved by setting the size attribute to a gird value on the containing vdl-column. <vdl-column size=”6”> <vdl-form layout="vertical"> <vdl-field entity="Budget"></vdl-field> <vdl-field entity="Goal" options-set="Goals"></vdl-field> </vdl-form> </vdl-column>

Page 114: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

114 Fair Isaac Confidential and Proprietary

This tells the vdl-form to use this grid size for the form width. In this case with a column size of 6, the label and input fields would both have a grid size of 3 (half the column size). This sizing arrangement works all the way from a grid size of 12 down to 2. The layout mode can be changed to "vertical". In this mode each field will be on a separate line but the labels will appear above the associated input: <vdl-form layout="vertical"> <vdl-field entity="Budget"></vdl-field> <vdl-field entity="Goal" options-set="Goals"></vdl-field> </vdl-form>

It is also possible to have inline inputs. These will display the input control without a label. They will also float inline with text, etc: <vdl-form> This is the budget <vdl-field entity="Budget" inline="true"></vdl-field> and the goal is <vdl-field entity="Goal" inline="true" options-set="Goals"></vdl-field> </vdl-form>

Control grids As an example of a more complex form layout this is how you could create a grid of fields from one or more array entities: <style> vdl-page vdl-form .inline-form-input input { width: 100%; } .row-title { padding-top: 5px; } </style> <vdl-section> <vdl-row> <vdl-column size="1"></vdl-column> <vdl-column size="1">Cost $</vdl-column> <vdl-column size="1">Capacity %</vdl-column>

Page 115: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 115

</vdl-row> <vdl-row vdl-repeat="=channel in scenario.entities.CHANNELS"> <vdl-column size="1" style="text-align: right"> <div vdl-text="=channel.label" class="row-title"></div> </vdl-column> <vdl-column size="1"> <vdl-field entity="ChannelCost" indices="=channel.value" inline="true"></vdl-field> </vdl-column> <vdl-column size="1"> <vdl-field entity="ChannelCapacity" indices="=channel.value" inline="true"></vdl-field> </vdl-column> </vdl-row> </vdl-section>

The result looks like this:

VDL charts (vdl-chart) Offering a lightweight alternative to Tableau charts, VDL charts use the vdl-chart tag and enable you to embed charts within conventional VDL views. Chart data can originate as static, scripted data, or it can be retrieved from model entities. The range of supported chart types is:

• Bar • Stacked Bar • Line • Scatter • Pie

This section provides an overview of vdl-chart and its related markup – refer to the VDL 4.0 Reference for full details of all available tags and attributes.

Page 116: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

116 Fair Isaac Confidential and Proprietary

Creating simple and stacked bar charts using provided data It is straightforward to create a bar chart (the default chart type) using provided static data contained as the data attribute of vdl-chart-series elements: <vdl-chart id="test" title="The default chart type is a bar chart"> <vdl-chart-axis axis="x" title="Index"> </vdl-chart-axis> <vdl-chart-axis axis="y" title="Value" type="linear"> </vdl-chart-axis> <vdl-chart-series data="=[10,3,20]" labels="First"> </vdl-chart-series> <vdl-chart-series data="=[15,24,9]" labels="Second"> </vdl-chart-series> <vdl-chart-series data="=[25,14,4,18]" labels="Third"> </vdl-chart-series> </vdl-chart>

This renders as:

The significant tags are:

• vdl-chart: The container element for all charts. You can set a title for the chart with the title attribute.

• vdl-chart-axis: Allows you to define x and y axes for your chart via the axis attribute, to give your axes titles via the title attribute and to specify the axis type with the type attribute.

• vdl-chart-series: Use one of these elements for each independent set of data you wish plotted on a chart. In the above example, the data attribute is set to an expression that evaluates to a JavaScript array and the labels attribute designates the labels/legend for the series. The only

Page 117: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 117

exception to using multiple vdl-chart-series elements in a chart is with pie charts, where only one such element is permitted.

For stacked bar charts, include a bar-mode=”stack” attribute within the vdl-chart element: <vdl-chart bar-mode=”stack” title=”This is a stacked bar chart”> … </vdl-chart>

Creating line charts, scatter plots and pie charts using provided data All of the other chart types can be created from variations of the above examples, noting that the respective vdl-chart-series elements will need a type attribute in anything other than a default bar chart, and that only one vdl-chart-series element is permitted for pie charts. To create a line chart, use: <vdl-chart title=”This is a line chart”> <vdl-chart-axis axis="x" title="Index"></vdl-chart-axis> <vdl-chart-axis axis="y" title="Value" type="linear"> </vdl-chart-axis> <vdl-chart-series data="=[10,3,20]" type=”line” labels="First"> </vdl-chart-series> <vdl-chart-series data="=[15,24,9]" type="line" labels="Second"> </vdl-chart-series> <vdl-chart-series data="=[25,14,4,18]" type="line" labels="Third"> </vdl-chart-series> </vdl-chart>

Page 118: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

118 Fair Isaac Confidential and Proprietary

Note the type=”line” attribute on the vdl-chart-series elements. This renders as:

Use type=”scatter” and type=”pie” for scatter plots and pie charts respectively. Note that in addition to accepting just one series, pie charts can accept a data attribute containing an expression assigning keys and values, whereby the keys become the off-chart legends:

<vdl-chart title=”Pie Chart”> <vdl-chart-series data="={keys: ['good', 'better', 'best'], values: [19, 26, 55]}" type="pie" > </vdl-chart-series> </vdl-chart>

Which renders as:

Page 119: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 119

Using Entity Data in Charts To switch to using entity data in charts, just replace the data attribute of your vdl-chart-series element with a naming entity attribute: <vdl-chart> <vdl-chart-series type="bar" entity="ServiceLevelAgreements" > </vdl-chart-series> <vdl-chart-series type="bar" entity="SupportCosts" > </vdl-chart-series> </vdl-chart>

This produces:

Page 120: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

120 Fair Isaac Confidential and Proprietary

Configuring Chart Axes The vdl-chart-axis element has several possible attributes:

• axis: This string value can be set to x or y • min: The minimum bound for the axis – it must be specified if you are

using the max attribute • max: The maximum bound for the axis – it must be specified if you are

using the min attribute • step: The step increment for the axis • unit: The unit for the axis, e.g. cm • type: A string that can be set to linear, log, date or category (default

unless all series are of type scatter/line, when it defaults to linear) • title: A string used as a title for an axis, which can be a dynamic

expression • show-grid: A boolean, defaulting to true, which controls whether or not a

background grid is rendered – this can also be the result of a dynamic expression

The above attributes can give rise to VDL charts defined, for example, as:

Page 121: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 121

<vdl-chart> <vdl-chart-axis axis=”x” min=”0” max=”100” step=”20” units=”cm” type=”category”/> <vdl-chart-axis axis=”y” min=”0” max=”100” step=”20” units=”cm” type=”category”/> </vdl-chart>

Index Filters You may wish to chart entities that have too many dimensions to render in a 2D chart. In this case, you can use an index filter to reduce the dimensionality of the index set for your entity, so that the remaining elements can be included in charts. Use the vdl-index-filter element as a child of vdl-chart-series. Its set attribute takes the name of the index set you wish to use, and its value attribute the name of the dimension. <vdl-chart> <vdl-chart-series type="bar" entity="FactorySupply" > <vdl-index-filter set="Factories" value="New York"> </vdl-index-filter> </vdl-chart-series> <vdl-chart-series type="bar" entity="FactoryDemand" > <vdl-index-filter set="Factories" value="Paris"> </vdl-index-filter> </vdl-chart-series> </vdl-chart>

Charting with Multiple Scenarios To create a chart that displays data from more than one scenario, just use a scenario attribute on a vdl-chart-series element. Set its value to the index of the scenario you wish to use as the source of the data. <vdl-chart> <vdl-chart-series type="bar" entity="FactorySupply" scenario="0"> <vdl-index-filter set="Factories" value="New York"> </vdl-index-filter> </vdl-chart-series> <vdl-chart-series type="bar" entity="FactoryDemand" scenario="1"> <vdl-index-filter set="Factories" value="Paris"> </vdl-index-filter> </vdl-chart-series> <vdl-chart>

Pie charts are an exception to this principle, as multiple pie charts cannot be overlaid. In this case, you can draw multiple pie charts separately using the vdl-repeat attribute of vdl-chart, indexing through the scenarios as required.

Page 122: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

122 Fair Isaac Confidential and Proprietary

<vdl-chart vdl-repeat="=s,i in scenarios" title="Multi-scenario, Multi-entity"> <vdl-chart-series type="pie" entity="ServiceLevelAgreements" scenario="=i"> </vdl-chart-series> </vdl-chart>

Validators As the user types into or selects a new value from a form field or editable cell it will automatically be validated. By default fields and cells will have type validation applied to them corresponding to the data type of the entity or, in the case of an array, its elements. They will also automatically apply any entity validators that have been registered, see the JavaScript API documentation. When a field or cell becomes invalid it will be outlined in red as the user types. This red outline will be removed when the value becomes valid again. If the user tries to save an invalid value a dialog will be shown containing a validation error message explaining what is wrong and the value will be reverted. As well as the default validation you can also supply one or more validators per form field or table column. A vdl-validate tag must have a pass attribute that is either a function or a boolean expression called whenever a value is edited. It should also have text content that will be used as the error message if the validation fails. If text content is not supplied to a vdl-validate element and the validation fails it will revert the value without showing the user a message.[h] Below are examples of providing a boolean expression and a function as the pass attribute. Whichever type is provided they both get passed the same information: • entityName: The name of the entity being edited. • value: The cell value. • key: The indices of the element being edited, if it is from an array. In the following example a simple boolean expression is given as the pass attribute: vdl-field: <vdl-field entity="ChannelCost" indices="1" label="Cost (SMS)"> <vdl-validate pass="=value > 1">Cost must be greater than 1</vdl-validate> </vdl-field>

vdl-table: <vdl-table> <vdl-table-column set="CHANNELS" width="70"></vdl-table-column> <vdl-table-column entity="ChannelCost" editable="true"

Page 123: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 123

heading="Channel Cost"> <vdl-validate pass="=value > 1">Cost must be greater than 1</vdl-validate> </vdl-table-column> </vdl-table>

The same validation can be given as a reusable function: <script> function greaterThan1(entityName, value, key) { return value > 1; } </script>

vdl-field: <vdl-field entity="ChannelCost" indices="1" label="Cost (SMS)"> <vdl-validate pass="=greaterThan1">Cost must be greater than 1</vdl-validate> </vdl-field>

vdl-table: <vdl-table> <vdl-table-column set="CHANNELS" width="70"></vdl-table-column> <vdl-table-column entity="ChannelCost" editable="true" heading="Channel Cost"> <vdl-validate pass="=greaterThan1">Cost must be greater than 1</vdl-validate> </vdl-table-column> </vdl-table>

In both cases the result is a boolean value. The expression should resolve to a boolean and the function returns a boolean. You could use the entityName argument to create validation functions that work across multiple entities and behave differently in each case. Also, the key

Page 124: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

124 Fair Isaac Confidential and Proprietary

argument becomes useful if you want to validate depending upon the position in an array. So far all validation has prevented the new value from being saved, and the cell value will be reverted. However, you may sometimes need to apply "soft" validation which will mark fields or cells as invalid but still allow the values to be saved. This is useful if you need to validate a group of values in a table but allow the user to save invalidate states as they fix-up each cell in the group. Just set allow-save="true" on the vdl-validate element to enable this behaviour per validator. Because validators are applied to columns as child elements to vdl-field or vdl-table-column this allows multiple validators to be defined. It also allows you to generate validators within a loop over a set or JavaScript array and to conditionally apply validators. In the following example there are two validators for the ChannelCost field and column but one is conditionally applied: vdl-field: <vdl-field entity="ChannelCost" indices="1" heading="Cost (SMS)"> <vdl-validate pass="=value > 1">Cost must be greater than 1</vdl-validate> <vdl-validate vdl-if="=scenario.entities.LIMIT_COST.value" pass="=value <= 10"> Cost limits in force. Cost must not be greater than 10 </vdl-validate> </vdl-field>

vdl-table: <vdl-table> <vdl-table-column set="CHANNELS" width="70"></vdl-table-column> <vdl-table-column entity="ChannelCost" editable="true" heading="Channel Cost"> <vdl-validate pass="=value > 1">Cost must be greater than 1</vdl-validate> <vdl-validate vdl-if="=scenario.entities.LIMIT_COST.value" pass="=value <= 10"> Cost limits in force. Cost must not be greater than 10 </vdl-validate> </vdl-table-column> </vdl-table>

Page 125: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 125

Row information available to cell validation The <vdl-validate> tag 'pass' attribute provides access to the current row data when used with a <vdl-table>. When a validation callback is supplied to the 'pass' attribute it is called for each row with four parameters: entityName, value, indices and rowData. 'rowData' contains an array of the indices and all cell values that exist in the adjacent cells of the row in which this cell is being validated. This enables the developer to validate a cell value based on one or more values from adjacent cells in a table row. <vdl-table-column set="A">Index A</vdl-table--column>

<vdl-table-column entity="B">Entity B</vdl-table--column> <vdl-table-column entity="C"> <vdl-validate pass="=function(entityName, value, indices, rowData) {return value < rowData[1]}"><vdl-validate>

</vdl-table--column>

In this example the validator causes an error if the value in column C is greater than or equal to the value in Column B.

Execute buttons A button can be added to your view that allows the user to submit a scenario for execution with a given execution mode, and optionally setting a scalar entity first. An execute button doesn't need to be within a form, you can place it anywhere on the page. By default an execute button will use the first scenario and will set the execution mode to RUN. It will also have the caption "Run Mode", for example: <vdl-execute-button></vdl-execute-button>

You can set the button execution mode, scenario and caption as follows: <vdl-execute-button mode="load" caption="Load the second scenario" scenario="1"></vdl-execute-button>

It is possible to set the mode to be any custom execution mode defined in the model or one of the standard modes (LOAD and RUN), for example: <vdl-execute-button mode="EVALUATE_SEGMENTS" caption="Evaluate Segments"></vdl-execute-button>

Page 126: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

126 Fair Isaac Confidential and Proprietary

It can also be useful to set a scalar value before execution. The value attribute accepts an expression so you can also calculate the value based upon the current values of other entities in the model, for example: <vdl-execute-button entity="LIMIT" value=”=getLimit()” caption="Evaluate limited dataset"></vdl-execute-button>

Attachment buttons The vdl-attachment-button component provides management, upload and download, creation and editing actions for scenario and app attachments.

Note Attachments are only supported within the Web Client.

When adding an attachment button to the page an action must be specified. The available actions are: • upload-scenario-attachment- opens an upload scenario attachment dialog • upload-project-attachment - opens an upload app attachment dialog • download-scenario-attachment - downloads a scenario attachment • download-project-attachment - downloads an app attachment • manage-scenario-attachments - opens a manage scenario attachment dialog • manage-project-attachments - opens a manage app attachment dialog • edit-scenario-attachment-properties - opens edit scenario attachment dialog • edit-project-attachment-properties - opens edit app attachment dialog Also, a filename or tag must be specified. A message can also be specified, which will be displayed to the user when the dialog options. In the following example the Edit button will open the attachment edit dialog for a scenario attachment. It finds the attachment by tag name, "result-sheet": <vdl-attachment-button scenario="=s.id" action="edit-scenario-attachment-properties" tag="result-sheet" field="description">Edit</vdl-attachment-button>

Page 127: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 127

The following is an example of an attachment button that downloads an attachment: <vdl-attachment-button action="download-scenario-attachment" tag="result-sheet">Download</vdl-attachment-button>

New attachment from custom code The <vdl-attachment-button> tag can be used to create new file attachments. Two actions: 'create-project-attachment' and 'create-scenario-attachment' are for creating App and Scenario attachments respectively.. In addition there are three optional attributes that affect the behaviour when creating the attachments: editor Allows the developer to specify an attachment editor and hence define what type of file attachment to create. filename Allows the developer to specify a filename. As this attribute supplies the filename the attachment is created when the user clicks the button and they are then taken directly into the relevant editor. tag A single tag can be applied to the file attachment using this attribute.

VDL button/JS API to launch editor You can open an existing file attachment with <vdl-attachment-button action="edit-scenario-attachment" editor="EDITOR_NAME"

filename="README.txt"> where 'editor' can be one of "CTAttachmentEditor",

Page 128: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

128 Fair Isaac Confidential and Proprietary

"TextAttachmentEditor", "DMNAttachmentEditor" or "DecisionTableAttachmentEditor".

Callback on editor close The 'on-close' attribute for the <vdl-attachment-button> allows the developer to provide a callback and is called when the user closes the attachment editor after the attachment is created or edited. The callback has one parameter 'result' which has properties representing the attachment and a status field. The 'status' property will be the string "saved" or "unmodified" to reflect what happened to the attachment in the editor. If the callback is defined inline then it has direct access to the 'result' variable: <vdl-attachment-button action="edit-scenario-attachment" filename="bacon.csv" editor="TextAttachmentEditor" on-close="=alert('saved:' + result.status + '. Last modified date: ' + result.attachment.lastModifiedDate)">Edit attachment</vdl-attachment-button>

VDL text The vdl-text attribute extension is used to display values that may change at any time. This could be Mosel entity values, view globals or the result of script calculations and any combination of these as is necessary to show the correct results to the end user. For instance to display the number of scenarios on the shelf: Number of scenarios is <span vdl-text="=scenarios.length"></span> The vdl-text attribute accepts any valid VDL 4.0 expression and will always try to display a sensible text representation of the expression's returned value. It can be assigned to any VDL or HTML tag that allows child text. A simple fixed calculation: <h1 vdl-text="= 99 * 88 + 77"></h1>

The value of a scalar entity: <div vdl-text="=scenario.entities.StringScalar.value"></div>

A combination of strings, a scalar value and a single element of an array entity: <p vdl-text="= 'This value: ' + scenario.entities.ThisValue.value + ' and that: ' + (scenario.entities.StringArray(2) ? scenario.entities.StringArray(2).value : '')"></p>

Tooltips Informative tooltips can be added to a VDL view. Ad them inside other elements and they are shown when a user hovers over that element. They can contain an

Page 129: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 129

optional title and body content, both of which can be static text or dynamic expressions that resolve to text. The text for the title and content will be HTML escaped before being displayed. Tooltips can also be placed on either side or at the top or bottom of the surrounding element using the “placement” attribute. By default it will be displayed on the right side of the element. Here is an example of a tooltip applied to a form field: <vdl-field entity="demand"> <vdl-tooltip title="Energy Demand" content="Set the energy demand for this scenario"></vdl-tooltip> </vdl-field>

Advanced VDL

Dynamic attributes Dynamic attributes enable the VDL view developer to set VDL and HTML attributes on tags using the result of VDL expressions.

Expression value The most common use case is inside a vdl-repeat or vdl-repeat-contents where the value or index of the loop iteration is needed to populate an attribute in a VDL or HTML element.

<div vdl-repeat="=s,i in scenarios" vdl-attr="={id: 'scenarioId'+s.id}"></div>

Which would result in each div in the repeat loop gaining an id attribute based on combining the string 'scenarioId' with the id of each scenario referenced in the loop (i.e. all scenarios on the shelf)

String value There is a slightly simpler syntax for specifying the value of vdl-attr which is supplied as a string: <vdl-row vdl-repeat-contents="=num, idx in ['a', 'b', 'c']"> <vdl-column vdl-attr="size: idx+1">...</vdl-column> </vdl-row>

Page 130: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

130 Fair Isaac Confidential and Proprietary

This works the same but dispenses with a few extra characters and some developers may find this way easier to read.

Image attachments It's possible to use scenario attachments as images in theview. Use the vdl-attr component on an <img> element and write an expression to find the appropriate attachment and get the dataUrl property from it. For example: <img vdl-attr="={src: scenario.attachments('logo.png').dataUrl}" width="200" height="100" />

It's best practice to set a fixed width and height (if known) so that the page doesn't jump when the images appears.

No-Results overlays You can hide the content in portions of your view when a specific scenario or all scenarios have no result data. This is useful for multi-scenario views where you are showing the results and comparing them. The View Configuration section discusses more about customizing the No-Results overlay. To mark a section in the view as dependent on result data add the "if-results-available" class to the element: <vdl-row class="if-results-available">

To prevent the section from being displayed until the view knows whether the scenario has results or not add "display: none" as an inline style. This prevents a flash of unstyled content: <vdl-row class="if-results-available" style="display: none"></vdl-row>

This will overlay the element with a "no results" message if any of the scenarios in the view have no results. When looping over the available scenarios and creating each section you also need to add the data-scenario="0" attribute where the value is the index of the scenario. This will only overlay the section when the specified scenario has no results. You can add this as a dynamic attribute based on the loop variable. The following example loops over all scenarios in the view and creates a section for each. Within each section is a table bound to that scenario and showing a result entity. The row within each scenario section has the "if-results-available" class and the "display: none" inline style. It also sets data-scenario dynamically, based on the scenario index in the loop: <vdl-section vdl-repeat="=s, scenarioIndex in scenarios" heading="=s.props.name"> <vdl-row vdl-attr="={'data-scenario': scenarioIndex}" class="if-results-available" style="display: none"> <vdl-column> <vdl-table scenario="=scenarioIndex"> <vdl-table-column entity="metriccontactperchannel"></vdl-

Page 131: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 131

table-column> </vdl-table> </vdl-column> </vdl-row> </vdl-section>

The results look like this if scenario 1 has no results:

View links Adding a link on the page to another view would make use of code similar to the following: <a vdl-event="click: function() { insight.openView('Welcome') }">go to Welcome</a>

Here the vdl-event attribute extension is being used as a click handler to insight.openView()

Custom Extensions One of the core concepts in the development of VDL 4.0 was the idea that the VDL language should be extendable and adding to the language should be as natural as creating VDL views. The transition from VDL 2 to VDL has entailed a full rewrite of the underlying platform and all the language elements detailed in this development guide and in the VDL 4.0 reference document have been created using this concept of custom extensions. Furthermore, custom extensions can be defined directly in VDL views allowing the developer to mould the language to more closely model their problem domain.

Page 132: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

132 Fair Isaac Confidential and Proprietary

VDL custom extensions At the simplest level a custom extension can be defined as assigning a new tag-name to a collection of existing VDL and HTML tags. <vdl-extension name="my-banner"> <vdl-template><div class="banner"> <h1><vdl-contents></vdl-contents></h1> </div></vdl-template> </vdl-extension>

Which could now be used like so: <my-banner>Welcome</my-banner>

Resulting in VDL markup similar to: <div class="banner"> <h1>Welcome</h1> </div>

The vdl-extension tag takes one attribute 'name' which defines the tag to be used.

Note All VDL tags are now required to be namespaced and this takes the form of two words separated by the hyphen character. It is an error to attempt to define a custom extension without the namespace. The purpose of the namespace is to minimise collisions between set of tags and you encouraged to define your own prefix for grouping and identification purposes.

Within the vdl-extension tag you will see a range of markup but two tags in particular are important at this stage.

vdl-template This tag tells the vdl-extension what markup to augment your extension with when it used later in the view. In our example we used a div and a h1 tag and you will see that they get placed into the view when we use our tag (custom extension)

vdl-contents Within the vdl-template definition we use the vdl-contents tag to say to VDL that any contents of the later usage of our custom extension should be inserted at run time at this point. So where we used the word 'Welcome' this then replaced the vdl-contents tag for the generated markup. The contents can be any combination of text and VDL and HTML tags. Although this takes some setting up, you should notice that the my-banner tag is now part of the VDL language, for your current view, and can be used exactly the same way as any other VDL or HTML tag.

Page 133: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 133

Adding scripts Custom extensions are already useful for reuse of snippets of VDL and HTML markup but come into their own when scripting is introduced. This allows much greater functionality and interactivity and is how most of the core VDL extensions were developed. Scripting is added using standard JavaScript. It is assigned to a custom extension using a call to global VDL function that is available anywhere in your view. The function takes two arguments, the tag name and a JavaScript Object for any configuration needed: <script> VDL('extension-name', {}); </script>

This is the simplest call you can make to the VDL function. The only purpose it has is to define (or enhance) a custom extension, in this case called 'extension-name'. This extension could be used immediately: <extension-name></extension-name>

Only it would have little to no effect because no options have been supplied to the second argument. At this stage, where we are adding the scripting to a VDL custom extension definition, we would place the script block within the vdl-extension tag, like so: <vdl-extension name="my-extension"> <vdl-template>...<vdl-contents></vdl-template>...</vdl-contents> <script> VDL('my-extension', {}); </script> </vdl-extension>

Note The string supplied to the VDL function must be identical to the name attribute of the vdl-extension tag in order to assign the script and VDL template to the same custom extension.

So this is the template for a new VDL custom extension. Next we will describe the options a view developer should consider passing to the VDL function.

VDL function options The current options available to the VDL function include: • tag • attributes • modifiesDescendants

Page 134: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

134 Fair Isaac Confidential and Proprietary

• requiredParent • transform • template • errorTargetSelector • createViewModel These are documented as the VdlExtension class in the JavaScript API documentation but the following are most useful in defining custom extensions:

tag If creating a custom tag extension define the tag text that will be used by supplying a string here. Alternatively if your extension is an attribute extension then omit this property and define an attribute instead.

attributes It is possible to tell your custom extension about any attributes that are required, or are optional, whether they accept a dynamic expression and various other properties that will prove useful to your extension.

transform The transform option is used to supply a JavaScript callback function to your custom extension. This callback allows the extension developer to manipulate the final markup and to extract the necessary attributes from the usage of their tag. There is also an extension API object available to provide common operations. // within a vdl-extension script block VDL('my-extension', { transform: function (element, attributes, api) { // Your custom JS code in here }});

As you can see the transform function you create is called by the VDL system with three optional arguments: * element - the tag and all its contents * attributes - a JavaScript object containing all the attributes used with the extension * api - the extensions API which provides many helper functions Enhancing VDL only extensions with scripting makes use of the transform function when a straightforward replacement of the tag with the contents of the template is not enough. Within the transform function you might rearrange the child tags of your tag, you might also generate content based on the attributes that have been set and you will also likely call on the extensions API to enable better interaction with the view as a whole. <script>

Page 135: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 135

VDL('my-tag', { transform: function(element, attributes, api) { $(element).addClass('my-class'); // jQuery is globally available } }); </script>

createViewModel Where the transform callback enables the extension developer to modify the construction of the view markup when the view is starting up, this callback enables you them to supply a custom view model to modify and enhance runtime behaviour. In particular the values of dynamic expressions are only available at runtime so createViewModel allows the extension developer to interact with and consume these values once they have been calculated by the VDL runtime. <script> VDL('my-tag', { createViewModel: function(params) { return { // uses a VDL helper method // to create an observable value value: VDL.createVariable(56) }; } }); </script>

This example creates a variable which can be observed within an expression e.g. vdl-text="=value"

Third party libraries Custom extensions allow usage of third party library code that can also be integrated as part of the native VDL 4.0 language. A simple script tag with a src attribute can be used as in HTML to bring in the library and then code to use the library is added to the transform and createViewModel callbacks depending on whether the code needs to transform the dom or make updates at runtime.

DOM Events The vdl-event attribute extension attaches HTML event handlers to VDL and HTML tags. This comes in useful when the user interface needs to react to other events than the core components provide. There are lots of events that elements within a view can raise and respond to. This page on the Mozilla documentation website lists the main ones and their application: https://developer.mozilla.org/en-US/docs/Web/Events

Page 136: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

136 Fair Isaac Confidential and Proprietary

<script> function txtChange(event) { console.log('keyUp fired'); } </script> <input id="txtbox" type="text" vdl-event="keyup:txtChange">

The attribute takes any 1 or more key value pairs, each pair separated by a colon, where the key is the event name and the value is a function reference. In this example the keyup handler is assigned to the txtChange function.

Multiple events In cases where several handlers need to be assigned to the same element then each key value pair would be separated by a comma, as so: <vdl-field entity="MyScalar" vdl-event="click: fieldClick, blur: fieldBlur"></vdl-field>

Where the click handler is assigned to a function fieldClick and blur to the function fieldBlur.

Event handler callback signature The event handler, when assigned this way, is called with the following arguments: function eventHandler( element, event ) { … }

Where element is the Element object from the DOM that the handler was placed upon and event is a jQuery Event object.

VDL Hints When developing VDL views there are some mistakes or sub-optimal cases that are flagged up to the VDL developer so that they can be fixed. For example:

• Forgetting to specify value/label on an entity – This would be a mistake at development time and can easily be rectified by adding either .value or .label to the end of the entity reference.

• Accessing an entity for which data has not automatically been batch fetched – This hints that the VDL engine could not determine the usage of the given scenario/entity combination and you should consider providing more information in the VDL file to improve performance.

The hints are only shown when you are in debug mode; see section Debugging Custom Views in the Web Client. You can find them in the web browser’s console window. All hint messages will be prefixed with [VDL HINT] so you can easily search for them from within the console.

Page 137: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 137

Entity Preloading When a VDL view is loaded it will be initially scanned for scenario/entity references. These references will be collated and nework requests for the data will be batched together in a preload step. Also the view will be hidden behind a loading spinner until this data is available. This results in more optimal data fetching and less UI flicker. It is not always possible for the VDL engine to determine all scenario/entity usage until the preload step has completed and the UI is partially rendered. The view will still function correctly as the data will be requested on demand, however it is not optimal. If entity data is fetched on demand, after the preload step, a VDL hint will be logged in the console, see the section VDL Hints. This hint will tell you the scenario/entity that is being requested and will also give you a generated VDL tag that can be added to your VDL code to include this in the preload. You can manually specify entities, parameters or attachments be preloaded for one or more scenario using the <vdl-preload> tag. The following example will preload the entities MyBool and IntArray for the second scenario: <vdl-preload entities="MyBool,IntArray" scenarios="1"></vdl-preload>

The following will preload the entity IntArray from all scenarios: <vdl-preload entities="IntArray" scenarios="all"></vdl-preload>

The following will preload all parameters for all scenarios: <vdl-preload load-parameters="true" scenarios="all"></vdl-preload>

The following will preload all attachment metadata for the second scenario: <vdl-preload load-attachments="true" scenarios="1"></vdl-preload>

Page 138: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

138 Fair Isaac Confidential and Proprietary

Page 139: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 139

CHAPTER 6 Authoring a Custom View with the JavaScript API

The JavaScript API offers a powerful way to create custom views for a FICO® Xpress Insight application. With this API you can access the underlying data model, modify scenario data, and control the execution of scenarios. The API makes sure that the same data is not fetched multiple times per view, even if your code contains multiple requests to use the same entity. All communications with the server are asynchronous and batched where possible. This helps to keep your custom application responsive. The JavaScript API documentation can be found in the following location: <installdir>\docs\insight\javascript_api\index.html

Loading the API Every HTML view starts with a definition in the companion file that points to the associated HTML file, for example: <html-view title="Input View" path="input.html"/>

The path is relative to the client_resources folder within your app bundle/zip file. You should take the Quick Start app as a starting point and use one of the HTML files within there as a template. For Example, if you take the input.html file from this app it already has the latest JavaScript API loaded in with the following lines: <link type="text/css" rel="stylesheet" href="$distrib/insight-4.0.css"/> <script src="$distrib/insight-4.0.js"></script>

The JavaScript API is bundled into a single JavaScript file, $distrib/insight-4.0.js, and a single CSS file, $distrib/insight-4.0.css. Once the JavaScript API is loaded into you view you need to wait until the API is ready before you can start using it. The reason for this is that some information about the current app, the view selection and model schema have to be loaded in before data can be accessed. Your custom code needs to be wrapped in a callback function that will be invoked when the API is ready. This is done as follows: insight.ready(function() { // Your code here });

The JavaScript API exposes a global variable called insight. This is the starting point for all API calls. There are also a few third-party libraries that are loaded in along with the JavaScript API and these are exposed as global variables too. See Appendix B for more details on what is exposed.

Page 140: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

140 Fair Isaac Confidential and Proprietary

Concepts There are a few high-level concepts from Xpress Insight that the JavaScript API uses. VIEW Represents a single instance of the custom view, the context

information passed to the view by the client framework when the view was opened, and the current state of the view.

PROJECT Represents the app parent of the scenarios and other objects being visualized by the view.

SCENARIO Represents a single scenario in the app; each scenario has its own copies of the model entities and properties such as: name, id, notes, ownership and sharing information.

SCENARIO SUMMARY DATA Information about the completed solution for a scenario. This includes: execution time, the objective, number of solutions and the model status.

MODEL SCHEMA Represents the schema of the scenario data for this app; the list of data entities including name and data type information.

MODEL ENTITIES The individual variables within the model. They can be input, result or parameter entities.

The Selection Any view opened by the user has a selection of one or more scenarios associated with it, either explicitly (such as right-clicking on one or more selected nodes in the repository panes and choosing the view menu option) or implicitly (such as double-clicking on a node in the repository pane that opens the default view registered for that object type).

Page 141: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 141

The JavaScript API currently supports selections containing one or more scenario objects. The scenario items in a selection are what you specify when you are using the View#withScenarios method, where the values passed in are the selection indices starting from 0. You can also query the number of scenarios selected using View#getScenarioCount.

Example: Hello, World! This section shows a very simple JavaScript application that you should be able to run within minutes. First, get a copy of the Quick Start example provided in the Xpress Insight installation located in the following location: <installdir>\examples\insight\quick_start.zip Create the files “hello-world.html” and “js/hello-world.js”. You will also need a compiled Mosel model to drop into the app. You can copy the .bim file from the hello-world-example example app as shown here: <installdir>\examples\insight\developer_guide\chapter5\hello-world-example\application.bim

You should now have the following app structure:

Custom JavaScript views need to be registered in the app’s application.xml file, known as the companion file. Add the following interface to the <view-group> section of the companion file: <html-view title="Hello World Example" default="true" path="hello-world.html"/>

Page 142: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

142 Fair Isaac Confidential and Proprietary

The “Hello World Example” view is specified as the default view when one or more scenarios are selected. The view will be available in the Xpress Insight Web Client as a tab when the app is selected. Enter the following code into your JavaScript file hello-world.js and save it: insight.ready(function () { var view = insight.getView(); view.withFirstScenario() .bindAutoText('#hellomessage'); view.start(); });

This first example demonstrates a starting point for your first application using JavaScript 4.0 API.

Note The JavaScript API is an HTML file and a JavaScript file.

Notice that the JavaScript code is wrapped up in a call to insight.ready. This ensures that your code will not be executed until the Xpress Insight API is fully initialized. The following code should be copied into your hello-world.html file and saved: <!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link type="text/css" rel="stylesheet" href="$distrib/insight-4.0.css"/> <script src="$distrib/insight-4.0.js"></script> <script src="js/hello-world.js"></script> </head> <body> <p class="view-initializing">Initializing...</p> <div class="view-initialized" style="display: none"> <h1>Hello, world! AutoText Example</h1> <!-- start custom content --> <h1 id="hellomessage" data-entity="MyScalar"></h1> <!-- end custom content --> </div> </body> </html>

Page 143: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 143

The preceding code shows all of the HTML code required to include and initialize JavaScript API 4.0; it provides all the data, state, and view management needed to develop Xpress Insight applications. The following sections describe these codes examples in more detail.

The View The first interesting line of code in the JavaScript file hello-world.js fetches a reference to the current view: var view = insight.getView();

This object is a representation of a single view in the client (specifically, the tab that you clicked on in the Web Client. For the remainder of this chapter, all interactions are demonstrated using the Web client. Each view has its own HTML file and typically an accompanying JavaScript file as well. Each view also has a reference in the companion file, and together these elements make up the view that is displayed when you click on the corresponding tab in the Web Client. This View instance that is returned from the 'getView()' function call has a number of methods and properties that you can call to interact with the View; however, the focus here will be on 'withFirstScenario'.

Note The JavaScript reference for the View class lists the other methods and options available.

view.withFirstScenario()

This code specifies that we are only interested in the first scenario that has been selected by the user; the function responds by returning a ScenarioObserver object that will handle all our interactions with the view. There are two other similar functions we can call, specifically 'withScenarios' and 'withAllScenarios', but for now the focus will be on the first scenario. You will learn how and when to use the other function calls with multi-scenario views later in this chapter.

Observers Now we have our ScenarioObserver “observer” object, we need to bind our AutoText component to the HTML node in the markup so that the value of the “HelloMessage” scalar will be automatically fetched from the server and displayed within our page. The next line of code achieves this: .bindAutoText('#hello-message');

This single line of code tells the observer to bind a new AutoText component to the HTML node with the “hello-message” ID, which registers your element to

Page 144: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

144 Fair Isaac Confidential and Proprietary

listen for updates to the “HelloMessage” scalar by other users, the executing scenario, or other components in the same view. Finally, the 'start' method on the view is called: view.start();

The preceding line is very important: it tells the view to begin fetching data from the server and to start all the observers that react to changes in data and state to which your application will respond.

Note If you do not see data appearing in your application views, then check that your code calls view.start(). Without this code, nothing will happen.

AutoText To provide a bit more detail on what is happening in the example, look more closely at the AutoText component. There are two code snippets specified in the creation of the AutoText component: HTML <h1 id="hello-message" data-entity="HelloMessage"></h1>

JavaScript observer.bindAutoText('#hello-message');

The HTML declaration can be any type of HTML that allows the display of text in the page. Two attributes: 'id' and 'data-entity' have been added. The 'id' ensures that the 'bindAutoText' call can locate where in the DOM (HTML Document Object Model, which is the structure of the web page as described by the HTML markup) is to attach the necessary code that displays the value of the scalar. Each 'id' used in the HTML markup must be unique to this view; that is, you must not have another HTML element with the same id. The 'data-entity' attribute tells the AutoText component which Entity in the Mosel model we want to observe. Be sure to use the Entity name and not its alias. The call to 'bindAutoText' on the ScenarioObserver then sets up the association with the specified ID so that it is ready for the view.start() call to start the process of pulling data into the component. These two lines of JavaScript code and HTML hook into the system that takes care of the details that are important for the proper running of your application. This includes reacting to changes in the state of the Mosel model and propagating the changes made by one user to all other users of the application.

Page 145: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 145

CSS Styling The JavaScript API and components make use of a framework called Bootstrap 3 to provide styled UI elements. For more information on Bootstrap 3 see http://getbootstrap.com. On top of the standard Bootstrap framework Xpress Insight applies some custom styling and additional CSS rules. However, you can follow the Bootstrap documentation to layout your view. Bootstrap 3 usually offers responsive layout capabilities; this is where the width of elements will change at certain browser widths. However, we have disabled this functionality as generally has little benefit for custom views but can cause additional development overhead. The JavaScript API and VDL views use a fixed width of 1170px. This is derived from the Bootstrap 3 medium devices profile. If you reduce the width of your browser below this a horizontal scrollbar will appear unless your view is using “fluid” layout. If you have existing view written against a JavaScript API 1.4 or earlier see the section Migrating to Bootstrap 3.

Common Issues Below are common issues that may be encountered. You can use this as a checklist when you are new to the AutoText component. The IDs do not match in the HTML and the JavaScript or either code item

has not been written. The user has either specified the name of the entity incorrectly or has

mistakenly used the alias. The entity is not a single value, i.e., not a scalar or parameter data type. The call to view.start() was never made. Earlier errors in the JavaScript cause the code not to run. The entity is a result value and there are no results present in the scenario. The AutoText component is working but the entity value is empty or a non-

displaying character such as an empty string.

The ScenarioObserver If you want to work with data from scenarios you need to create a scenario observer, which we will hereby refer to as an 'observer'. You create a new observer by configuring it to watch one or more scenarios and entities. You always need to declare the scenarios to watch but you can either specify a list of entities from those scenarios or that you just want to scenario state information itself.

Page 146: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

146 Fair Isaac Confidential and Proprietary

Once registered and started an observer will fetch the data immediately and callback on a specified function. You can either configure it to just load the data as a one-off or, as is more common, you can configure it to call the specified function every time the data changes. var view = insight.getView(); view.withFirstScenario() .withEntities('SCALAR1', 'ARRAY1', 'PARAMETER1', 'SET1') .notify(function(scenario) { console.log(scenario); }) .start();

Once an observer is declared you can either start that observer immediately (as above) or you can setup one or more observers and start them in one go when the view is start, for example:

// Create a few observers but don't call .start() on them // This will start any observers that have not yet been started view.start();

If you have created an observer with ScenarioObserver#notify then you can stop that observer at any time by calling ScenarioObserver#dispose: var observer = view.withFirstScenario() .withEntities('SCALAR1', 'ARRAY1', 'PARAMETER1', 'SET1') .notify(function(scenario) { console.log(scenario); }) .start(); // A some other point in your code observer.dispose();

You can listen to multiple scenarios with view.withAllScenarios() or view.withScenarios(0,1). If you want to fetch data once and dispose the observer immediately after then you can use: view.withFirstScenario() .withEntities('ARRAY1') .once(function(scenario) { scenario.getArray('ARRAY1'); }) .start();

Page 147: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 147

When the observer notify/once callback is invoked it is passed either a single scenario (when ScenarioObserver#withFirstScenario is used) or an array of scenarios (when ScenarioObserver#withScenarios or ScenarioObserver#withAllScenarios are used). These scenario objects are pre-loaded with the scenario properties, scenario summary data and all the entity data that has been requested. All the data is immutable, that is it will not change while the callback function is running: fresh objects will passed in on a future callback. Also, the scenario object will only allow you to access entities that were declared in the observer configuration.

Page 148: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

148 Fair Isaac Confidential and Proprietary

// Single scenario view.withFirstScenario() .withEntities('ARRAY1', 'SET1') .notify(function(scenario) { var array1 = scenario.getArray('ARRAY1'); var set1 = scenario.getSet('SET1'); // This would throw an error as ARRAY2 has // not been requested var array2 = scenario.getArray('ARRAY2'); }) .start(); // Multi scenario view.withAllScenarios() .withEntities('ARRAY1') .notify(function(scenarios) { scenarios.forEach(function(scenario) { scenario.getArray('ARRAY1'); }); }) .start();

An observer can subscribe to entity data, scenario summary data or both. Scenario summary data is information about the current (if currently executing) or last solution (if completed, even in error). If you subscribe to just summary data then the notify callback will be called when any existing solution is deleted (a job has been queued) and when a new solution is available (a job has completed). It will not be called for any of the intermediate stages. // With scenario summary data only view.withFirstScenario() .withSummaryData() .notify(function(scenario) { // You cannot access any entity data here as // no entities have been subscribed to var hasResultData = scenario.getSummaryData().hasResultData(); var objective = scenario.getSummaryData().getObjective(); }) .start();

When you subscribe to entities and scenario summary data then the notify callback will be called whenever the solution changes (as mentioned above) or when any of the entities change. // With entity data and scenario summary data view.withFirstScenario() .withSummaryData() .withEntities('ARRAY1') .notify(function(scenario) {

Page 149: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 149

var array1 = scenario.getArray('ARRAY1'); var hasResultData = scenario.getSummaryData().hasResultData(); var objective = scenario.getSummaryData().getObjective(); }) .start();

It is best to split your view up with multiple scenario observers. Each one should be kept as small as possible, listening to the least number of entities possible, and keeping the responsibility of the notify callback to a minimum. The benefits of this are that you code is more maintainable, easier to separate into modules, and it minimizes the number of UI updates for any given entity change.

Array Filters Sometimes you only need a slice of the data from particular arrays. The keys from the array that should be included needs to be generated, this will usually be calculated from some user input or iteration over a related set. You can add an array filter for any of the array entities that a scenario observer is listening to. The array filter is a function that should return a map of the keys (set name or indices ordinal) from the array to be fetched. // Array filters view.withFirstScenario() .withEntities('ARRAY1', 'ARRAY2') .filter('ARRAY1', function() { // Return a map of the set name to values that // should be included. Only specify the indices // you want to filter down return { 'SET1': [1,2,3], 'SET2': [false] }; }) .filter('ARRAY2', function() { // You can also refer to the indices by ordinal // rather than set name return {0: ['A', 'B']}; }) .notify(function(scenario) { var array1 = scenario.getArray('ARRAY1'); // Can only access the keys from the array that // have been included in the filter var value = array1.getValue([1, false, 'test']); }) .start();

Page 150: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

150 Fair Isaac Confidential and Proprietary

The scenario observers will call the filter functions each time they need to fetch data for those arrays. Evaluating before each fetch allows the filter values to be dynamic. If multiple observers use the same array from the same scenario and filtered by the same values then the data will only be downloaded once, maintaining efficiency for the view.

Note Any changes to an array entity will cause a scenario observer to update. It does not take array filters into account.

Accessing Data When a scenario observer notify callback is invoked the scenario objects passed in are preloaded with the latest data for the observed entities. You can access the data for these entities as follows: // Accessing entity data view.withFirstScenario() .withEntities('SCALAR1', 'PARAMETER1', 'SET1') .notify(function(scenario) { var scalar1 = scenario.getScalar('SCALAR1'); var parameter1 = scenario.getParameter('PARAMETER1'); // set1 is a JavaScript array var set1 = scenario.getSet('SET1'); }) .start();

Sets are returned as JavaScript arrays with the values in the array corresponding to the set elements. By default the server will order set values alphanumerically. scenario.getSet('myset').forEach(function(v) { console.log(v); });

Array values are accessed by specifying the array entity name and one or more tuples of index values. // Accessing array entity data view.withFirstScenario() .withEntities('Population', 'Countries') .notify(function(scenario) { var countries = scenario.getSet('Countries'); var population = scenario.getArray('Population'); countries.forEach(function(country) { var country = population.getValue([country]); console.log(country); }); }) .start();

Page 151: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 151

Accessing Array Data There are several ways to access the data from an InsightArray object. If you have access to the associated sets you can build up the possible keys for the array using these and iterate over each, calling InsightArray#getValue on each. However, this is very inefficient in most cases as the set data needs to be downloaded separately. The key information is already available in the InsightArray object and you can use one of the follow methods instead. You can get an iterator for the array and loop through that:

// Using an array iterator view.withFirstScenario() .withEntities('Population') .notify(function(scenario) { var population = scenario.getArray('Population'); var iterator = population.getIterator(); var item; while(item = iterator.next()) { // item will contain {key: ['UK'], value: 64000000} } }) .start();

It is also possible to get a list of all the populated keys for an InsightArray:

var population = scenario.getArray('Population'); var keys = population.getKeys(); // keys will contain an array of composite keys

Finally, it is possible to get a JavaScript array listing all entries of the InsightArray, both keys and values:

var population = scenario.getArray('Population'); var keyValues = population.toObjectArray(); // keyValues will contain be an array of key-value objects keyValues.forEach(function(entry) { // entry.key will be ['UK'] // entry.value will be 64000000 });

View Properties It is often necessary to track some state or user input specifically for the view. This will not be represented in the model and only exists for the lifetime of the view. For example, you may need to track the value from a form input so that you can respond to changes or you may have a number of tabs within the view and you need to track the current tab selected.

Page 152: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

152 Fair Isaac Confidential and Proprietary

At a basic level you would use jQuery to listen for changes and to capture the current value: HTML <select id="country"> <option value="uk">United Kingdom</option> <option value="fr">France</option> </select>

JavaScript $('#country').on('change', function(event) { var selectedCountry = $(event.target).val(); });

If you want other parts of your view to respond to changes to the selected country you can create a view property. View properties are simply key-value pairs that are stored against the view object. $('#country').on('change', function(event) { view.setViewProperty('selectedCountry', $(event.target).val()); });

You can create or update them at any time while the view is running. You can get the current value for a view property from your code, however the really useful thing about them is that they work with scenario observers. You can configure scenario observers to subscribe to view properties and they will update whenever the specified view properties change. // Subscribe to view properties view.withFirstScenario() .withViewProperties('selectedCountry') .withEntities('Population') .notify(function(scenario, viewProperties) { var populations = scenario.getArray('Population'); var country = viewProperties.get('selectedCountry'); // This will get the population value for the // selected country var population = populations.getValue([country]); }) .start();

The notify callback will be passed a second argument which is an accessor object for the observed view properties, known as the MaskedViewProperties. This will throw an error if you try to access any view properties not previously declared for that scenario observer.

Page 153: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 153

View Properties and Array Filters Another very useful feature of view properties is that you can use them within array filter callbacks for your scenario observers. So you can prevent the browser from having to download unnecessary elements of your arrays. To expand on the previous example; instead of fetching the entire array you could instead instruct the scenario observer to filter the array by the selected value. // Array filter using a view property view.withFirstScenario() .withViewProperties('selectedCountry') .withEntities('Population') .filter('Population', function(viewProperties) { var country = viewProperties.get('selectedCountry'); return {'Country': [country]}; }) .notify(function(scenario, viewProperties) { var populations = scenario.getArray('Population'); var country = viewProperties.get('selectedCountry'); // This will get the population for the selected country var population = populations.getValue([country]); }) .start();

You can see from the above example that a view properties accessor is passed into the filter callback as the first argument. This is again an instance of MaskedViewProperties and only allows access to view properties that are being observed by the scenario observer.

Promise API Some methods in the JavaScript API return an instance of the Promise object. This is a global object exposed within the browser. Some browsers do not currently support it as its part of the next version of JavaScript, known as ECMAScript 6. For those browsers we include a library which emulates the Promise object very closely so there should be no difference. This is listed in Appendix B. Promises are returned from JavaScript API methods that involve some asynchronous process, such as fetching or sending data over the network. The JavaScript API documentation shows which calls return promises and what each promise resolves to. This is in the following format: Promise.<User>

This example shows that User is the type of object that the promise resolves to.

Page 154: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

154 Fair Isaac Confidential and Proprietary

A promise is returned when the return value of a method is not immediately available. It allows your code and the browser to continue with other tasks until that value is available. Given a promise object you can attach functions to be called when it resolves or if it fails. You can also collect a number of promises and chain them or call a function once they have all resolved or if one fails. The methods available on a promise are: promise.then(function(value) { // This function is invoked when the promise has // 'resolved' and the first argument passed in will // be the return value from the call made, if there is one. }).catch(function(error) { // You can chain the "then" and "catch" calls on a promise // The first argument passed into catch will be an Error // object explaining the error that occurred });

As you can see there are only two methods on a promise object, "then" and "catch". They can be chained and you can also return a new value from a then or catch function that will be wrapped in a promise and sent on to the next in the chain. Once a promise is resolved or rejected it will never change, it will only be settled once. There are some static methods available on the Promise object. One particularly useful one is Promise.all(). This takes an array of promises that you have captured and will return a new promise that settles when all the promises resolve or if one of them is rejected. For example: var tasks = [ view.getUser(), view.getScenarioProperties(0), view.start() ]; Promise.all(tasks).then(function(values) { // The resolved values are available in an array passed as the // first argument, in the same order as that defined // in the "tasks" array. var user = values[0]; var scenarioProperties = values[1]; }).catch(function(error) { console.error('could not start view. Reason: ' + error.message); });

Page 155: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 155

Modifying Scenario Data The JavaScript API provides a way of requesting a set of changes to scenario input data and applying those changes on the server. The changes are expressed as a list of changes to be applied in the specified order then they are committed to the server for processing. If any of these changes fail to be applied they will all be rolled back and nothing will be modified. Upon completion the server will either respond as successful or if a failure occurs it will provide an error message and status code.

Note Changes to scenario data are not applied to the scenario object within a particular invocation of a scenario observer. When a scenario observer is called it is passed immutable scenario data.

The key features of scenario data modification are: Batched: Changes are created as a batch request and committed to the

server as one request. Atomic: All changes are applied as an atomic operation on the server. Transactional: If an error is encountered while applying the changes

everything will be rolled back. Asynchronous: When changes are sent to the server a Promise is returned

which either will be resolved or rejected based on the server response. Ordered: The order in which you specify the changes is the order in which

they are applied on the server. Scenario-oriented: Each batch request is applied to a specific scenario. Applied server-side: Changes are not applied to any existing scenario objects

in your view. The changes will not be available until scenario observers update themselves.

To request changes to scenario data, you first need to create a ScenarioDataChange object for a specific scenario. This can be created in two ways: From a scenario observer view.withFirstScenario() .withEntities('SCALAR1', 'ARRAY1') .notify(function(scenario) { // Create a ScenarioDataChange object for // the first scenario var changes = scenario.modify(); }) .start();

Page 156: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

156 Fair Isaac Confidential and Proprietary

Outside a scenario observer // Create a new ScenarioDataChange object for the first scenario. // The number argument is the selection index of the scenario var changes = view.modifyScenario(0);

The first approach is more convenient if you are already using a scenario observer. Also there is a subtle difference in the way change events are propagated around your view with these two approaches. See Local data changes for more details. The ScenarioDataChange object offers a chainable API (each call returns the ScenarioDataChange instance) to express your changes and then commit them. When the changes are committed a Promise is returned so you can detect and respond to success or failure. scenario.modify() .setScalar('SCALAR1', 55) .addToSet('SET1', [15, 16, 17]) .setArrayElement('ARRAY1', {key: [15], value: 'fifteen'}) .removeFromSet('SET1', [16, 17]) .commit() .then(function() { // Applied successfully }) .catch(function(error) { // Error applying changes // Server rolled back any partial changes console.log('Could not apply changes, reason: ' + error.message +', status code: ' + error.status); });

The JavaScript API documentation lists all the available methods on ScenarioDataChange. Because the changes are applied in order you can add elements to a set and then reference those keys in arrays index by that set. If you add array elements and then remove the set elements corresponding to the keys the array element will end up never existing in the scenario data.

Local Data Changes When a scenario modification is completed successfully the server does not issue a data change event to the client that submitted the change. However, the JavaScript API creates local data change events within your view so that the scenario observers are triggered to update. The way this works changes slightly depending upon which method you use to create the ScenarioDataChange object:

Page 157: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 157

Scenario#modify: When completed successfully a change event will trigger other scenario observers listening to any modified entities to fetch the latest data from the server and be called with that data. The observer from which the scenario object originates will NOT be notified of any changes related to this request. It will be your responsibility to make sure the changes are not only committed to the server but also applied to any UI elements managed by this observer.

View#modifyScenario: When completed successfully a change event will trigger all scenario observers listening to any modified entities to fetch the latest data from the server and be called with that data. You need to be careful not to use this within an observer which you don't want to refresh after the change, use the other method instead. It would cause forms or editable tables to redraw and so possibly lose the user's position or focus.

Executing a scenario You can execute individual scenarios using the JS API. There are two ways to do this: from a scenario object you have loaded via a ScenarioObserver or from the View object, passing in a scenario id. In both cases you can specify the execution mode to submit the job with, this defaults to RUN. Both methods submit the execution job asynchronously and return a Promise object which resolves when the job has been successfully submitted or gets rejected if the job could not be queued. The following is an example of executing a scenario directly from the scenario object. It uses a custom execution mode named “FAST_MODE”: insight.getView().withFirstScenario()

.withSummaryData() .notify(function (scenario) { scenario.execute('FAST_MODE') .then(function () { console.log('scenario successfully queued'); }) .catch(function () { console.error('scenario failed to queue') }) })

.start();

The next example executes a scenario from outside of a ScenarioObserver. First it looks up the id of the first scenario in the selection. Then it uses that together with the custom execution mode name, “FAST_MODE”: var view = insight.getView(); view.getScenarioProperties(0)

.then(function (props) { return props.getId(); }) .then(function (scenarioId) {

Page 158: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

158 Fair Isaac Confidential and Proprietary

return view.executeScenario(scenarioId, 'FAST_MODE'); }) .then(function () { console.log('scenario successfully queued'); }) .catch(function (error) { console.error('scenario failed to queue'); });

The AutoComponents The AutoText component that we used in the “Hello World” example is one of the AutoComponents supplied with the JavaScript API for Xpress Insight. These components take much of the laborious preparation work out of setting up the most commonly used data-driven web components. They provide a great deal of functionality that can be configured with only a small amount of easily understood code.

AutoText AutoText enables HTML elements to be populated automatically with the values from scalar, parameter, or array entities through the addition of extra attributes to the HTML elements. The earlier example showed AutoText being supplied its data from a scalar entity. You can also specify a parameter such as the following: <span id="parameterText" data-parameter="ParameterOne"></span>

This will bring in the data from a parameter called 'ParameterOne'. Because AutoText only displays single values, arrays and sets are not allowed in their entirety. However, with the “data-indices” attribute we can pick a single element from an array or set: <span id="arrayItemText" data-entity="AnArray" data-indices="1" />

Page 159: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 159

Note This example has two data-* attributes, one, “data-entity”, to specify the Entity by name and the other, “data-indices”, to tell AutoText which element in the Array Entity we want displayed. The attribute is called “data-indices” in plural form because an array may have more than one index, in which case you could, for example, write:

<span id="arrayItemText" data-entity="AnArray" data-indices="3,10" />

The indices are separated by commas. If you specify an index that does not have an item in that array or set, then the HTML node will be empty. Check the web developer console in your browser for any errors. The remaining feature of the AutoText component is formatting. This is specified on the individual Entity and is covered in the section Entity Formatting.

AutoForm AutoForm associates form input elements with scalar, parameter, or array entity elements. It can also be used to bind form buttons to the following Scenario actions: load, run and save. Below are the behaviors of the AutoForm component: 1 Input elements are automatically populated on page load. 2 All requests for data are collected and fired off as one request when

view.start() is called. This makes for more efficient data-loading and less network traffic and delays due to latency.

3 Each input field is saved when switching between fields or pressing the Enter key.

4 The user can back out of an edit by pressing the ‘Escape’ key on their keyboard.

5 Simple validation based on the entity type, e.g., an integer entity will highlight with an error border if you attempt to input invalid characters.

6 Any custom entity validation will also be tested against when a user edits a field.

Page 160: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

160 Fair Isaac Confidential and Proprietary

AutoForm Input Types The type of each form element that you use will correspond to the entity type to which the element will be bound. For ARRAY entities, it is the data type of the array elements that should be considered. STRING, INTEGER, REAL and PARAMETER data types will need to be text inputs whereas BOOLEAN types will be checkboxes. Sometimes your model will store Boolean values in a STRING or INTEGER. These can be represented by checkboxes in the form and AutoForm will use the values 0 and 1 for INTEGERS and “0” and “1” for STRINGS.

AutoForm Example Now we will run through a basic example for the AutoForm component. In many respects AutoForm could be regarded as an expansion upon the AutoText component, binding entities from the scenario data model to editable form elements. AutoForm works with HTML Forms and Form input elements. Unlike traditional web forms, AutoForm takes advantage of AJAX when updating information back to the server and never involves a traditional HTML Form submission with the corresponding server refresh. For our example we will again use the 'Quick Start' app as a base. The app code structure will be the same with only the file names differing.

Note The client_resources folder is a fixed name required by Xpress Insight so that it can find your view files when loading the app. Also, remember that the name of the main view file “input-form.html” needs to be registered in the companion file for it to be available as a view.

Page 161: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 161

From now on we will only specify the HTML snippet that you need to add to the base HTML file from the 'Quick Start' app rather than the whole HTML file, since much of the base file will be the same for every example. input-form.html file <!-- input-form.html --> <form id="input-form-example"> <input name="SupportLevel" data-entity="SupportLevel" type="text"> <input name="SupportCosts" data-entity=" SupportCosts " data-indices="1" type="text"> <input type="radio" name="goal" value="1" data-entity="Goal"/> Maximize Value <input type="radio" name="goal" value="2" data-entity="Goal"/> Minimize Cost <input type="radio" name="goal" value="3" data-entity="Goal"/> Maximize Efficiency <select id="my-integer" data-entity="MyInteger" data-options-set="Jobs"> <option value="">-- None selected --</option> </select> <input id="runbutton" type="button" name="run" value="Optimize"/> </form>

This example shows the HTML markup for constructing the AutoForm. As you will see this is created using basic HTML, much the same as you would use if you were creating an input form for a typical web page. The difference is in the extra data attributes that tell the JavaScript API how to bind to the underlying Mosel model, and those entities we want to expose for the purpose of editing. The first input field “SupportLevel” uses the data-entity attribute to specify the Entity that AutoForm should bind with this input. This means that it will be populated with the data from the “SupportLevel” Entity and any changes made by the user will be persisted back to the Entity in the model. The second input field “SupportCosts” demonstrates the same type of construct only this time SupportCosts would be an array declaration in the Mosel model and the data-indices attribute is used to specify which item by index we wish to edit. In some cases where the array is known to be small, we could have one of these input tags for each index. Where there are a large number of items in the array we would usually recommend an editable AutoTable component, which is explained in a later section. The next three input fields make up what we refer to as a “radio button group” that consists of small round buttons, with labels, which can only have one button selected, or none at start if no value is in the target Entity. Any of the values (1,2,3) can be selected by the end user and this will then be saved in the “Goal” entity. The shared ‘name’ attribute is important in tying the behavior of these three radio buttons together.

Page 162: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

162 Fair Isaac Confidential and Proprietary

After the radio button group, we have a “select” input field. This usually displays as a button that triggers a drop-down menu when clicked from which the end user can select a value to populate the Entity. As usual, data-entity specifies the name of the Entity we want to display and edit but the ”data-options-set” attributes names the Entity that holds a set used to populate the list of items in the drop-down menu. We have also specified a single child “option” tag. This is standard HTML and specifies the message to show if the “MyInteger” entity is empty. Finally, we have an input type of button, which does not submit the form as in traditional HTML input forms but is available for us to attach functionality as detailed in the next section. input-form.js file var view = insight.getView(); var observer = view.withFirstScenario(); observer .bindAutoForm({ formId: 'input-form-example', runButton: 'runbutton' }); view.start();

The JavaScript code to bind the HTML as an AutoForm is very succinct, much like AutoText, except with a few differences. The code snippet starts the same by fetching the current view and creating an observer, ScenarioObserver, and then making the call to “bindAutoForm”. Up to this point the code is nearly identical, but you will notice that, where we passed in a string to “bindAutoText”, we are now passing a JavaScript object with a couple of key/value pairs as options for the AutoForm component: formId: a required property. A String corresponding to the idea of the form

we created in the HTML markup. runButton: an optional property. A String specifying the id of a HTML button

that is wired up by AutoForm for the purpose of providing an in-view control to execute the current Scenario. 'runButton' is optional because the user can always use the respective client to execute scenarios, however, it can provide a more obvious and attractive means for the user to interact with your application. There are a number of other options that can be set in the bindAutoForm options object parameter. Please see the JavaScript reference under Insight.components.AutoForm for more details.

Page 163: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 163

AutoTable The AutoTable component is used to generate HTML tables from a given list of array entities. An AutoTable will inspect the properties of each array entity and discover the index sets associated with them. It will only be able to generate a table if the index sets match for all array entities, although you have the ability to filter individual index sets per entity if you need to include arrays that contain additional indices. AutoTable has the following presentation features: Sorting Filtering Pagination Custom cell rendering Data editing and validation

This section provides examples demonstrating pertinent AutoTable features. The examples will correspond to source code found in the Component Examples library from the following location: <installdir>/examples/insight/javascript/component_library.zip

AutoTable is based on the DataTables open source app; see www.datatables.net. If the functionality provided by AutoTable is not sufficient, then the underlying DataTables component can be configured directly.

Creating a Basic AutoTable The markup for a basic Autotable is a standard HTML table tag with an id identifier: <table id="example1"></table>

Page 164: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

164 Fair Isaac Confidential and Proprietary

The table tag is transformed into an AutoTable using the following view code: var view = insight.getView(); var observer = view.withFirstScenario(); observer .bindAutoTable({ tableId: 'example1', columnOptions: [ {name: 'Array1'} ] }); view.start();

The data for the AutoTable is fetched from the Mosel array named Array1. The following shows the resulting AutoTable:

Note The index set Rows for Array1 has been included in the resulting table.

By default AutoTable will show all data to the user. This will not be practical for larger data sets. AutoTable can be configured to paginate through a large data set. To paginate the AutoTable, an overrides key should be added to the configuration that takes a nested child JavaScript Object as its value. This object allows us to pass in many of the DataTables options, as shown in the following example: overrides: { bPaginate: true, iDisplayLength: 10 }

bPaginate and iDisplayLength are both options that get passed in to the DataTables code. See the http://datatables.net website for details on all the options that are available.

Note Only arrays with unique index sets can be displayed in an autotable. If an array uses the same index set more than once, an error will be logged and the table will not be drawn.

Page 165: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 165

Filtering AutoTable can be configured to present a filter to the user. This allows the user to narrow the table to show relevant data. A filter can be added using the following configuration: overrides: { bFilter: true } By default, filtering is based on the underlying data. However filtering can be configured on displayed values (such as displaying the value 1000

as 1,000) using the columnOptions tag: columnOptions: [ { name: 'Array1', filterByFormatted: true } ]

In some circumstances, this can make it easier for the user to search for data in the table.

Layout By default, an AutoTable will occupy all space available in the parent container. To constrain the width of the AutoTable, first set the default width that should apply to all columns using the overrides tag, and then explicitly specify the width of specific column using the columnOptions tag: overrides: { bAutoWidth: false, aoColumns: [ { sWidth: '20px' } ] }, columnOptions: [ { name: 'Array1', width: '40px' } ]

Page 166: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

166 Fair Isaac Confidential and Proprietary

The preceding code fragment will style the index set column to be 20px wide and the Array1 column as 40px width. To enforce this spacing, a parent container should be created that is 40px width as follows: <div style="width: 40px"> <table id="example1"></table> </div>

Sorting Data AutoTable sorts on the first column at startup. Custom sorting can be specified by passing extra configuration to the underlying DataTable. For example to sort on the second column, use the following configuration: overrides: { aaSorting: [ [1, 'desc'] ] }

Note By default, the sorting will occur on the underlying data values. To sort using formatted values, specify sortByFormatted on the columnOptions tag.

Data Editing AutoTable can be configured to allow edits to the backing Mosel array. For example to make Array1 editable, specify editable in the columnOptions.

Note A number of options can be used in conjunction with editable. For example, if dealing with a Boolean type value, an editorType option can be specified. Then a value can be specified for the checked/unchecked options as shown in the following code fragment: columnOptions: [ { name: 'Array1', editable: true, editorType: insight.components.Table.EditorType.CHECKBOX, uncheckedValue: 'on', checkedValue: 'off' } ]

Page 167: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 167

Row Addition and Deletion Where edits are permitted, it is also possible to allow the addition and removal of rows in the table (and therefore the addition and deletion of elements in the underlying arrays). To enable row addition and deletion within an AutoTable specify addRemoveRow: true in the options to create the table. You will also need at least one editable column defined in the columnOptions. This will cause add and delete row buttons to be displayed. Clicking on an index value in a row will select the row and activate the delete button. A subsequent click on the Delete button will remove the row from the Mosel Array. Clicking the Add button will display a form allowing selection of a set of index values for the new row in the array. You can also specify add row behavior that will auto increment a single, integer index set. To do this specify addRemoveRow: ‘addrow-autoinc’, for example: insight.getView() .withFirstScenario() .bindAutoTable({ tableId: 'table-1', columnOptions: [ {name: 'ArrayEntity', editable: true}, {name: 'AnotherArray', editable: true} ], addRemoveRow: 'addrow-autoinc' }) .start();

If the array entities ArrayEntity and AnotherArray are both indexed by a single, integer set then the add row button in the table will create a new set value which will by the current maximum value + 1.

Note The scenario data is not updated until at least one non-index value is populated for the new row.

The row addition and deletion behavior can be customized, and in addition event notification of adding and removing rows is also available. Refer to the JavaScript API reference for more information.

Multi-scenario By default AutoTable data for columns and indices will be loaded from the first scenario on the shelf. You can override this table-wide and per array column. If you use arrays from more than one scenario the indices will be loaded and combined from each of the scenarios referenced. If there are any associated label arrays for the index sets then they will be resolved from each scenario used in the table, in the order they appear on the shelf. Here is an example of a multi-scenario table:

Page 168: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

168 Fair Isaac Confidential and Proprietary

insight.getView() .withScenarios(1, 2) .bindAutoTable({ tableId: 'multi-scenario-table', scenario: 1 // Default scenario for the table columnOptions: [ {name: 'ArrayEntity’}, // Uses the default table scenario {name: 'ArrayEntity', scenario: 2}, {name: 'AnotherArray', scenario: 2} ] }) .start();

The index columns that are generated will contain the corresponding index set values from the 2nd and 3rd scenarios on the shelf.

Table State Saving By default the display state of each table in a view is stored in the user’s browser session. If the table is redrawn or the user navigates back and forth between views or apps the tables will remain the same state, this includes:

• Global search value • Column search values • Column sorting • Pagination: page size, current page

If the user closes the browser window or if they log in as a different user within the same browser window then the state for all tables will be wiped. This is only considered temporary state that is kept whilst they are working within a given browser window and Xpress Insight session. During view development, if you are changing the configuration of tables, you may wish to display table state saving temporarily. You may also wish to disable it perminantly for particular tables in a view. To do this add the following property to your AutoTable configuration: { tableId: 'table-no-state-saving', columnOptions: [ ... ], saveState: false }

Entity Validation The AutoForm and AutoTable components have built-in validation. They take account of the data type from the underlying Entity to give you the simplest level

Page 169: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 169

of client-side validation. This is not a security feature but assistance to the user when entering data, to notify them if they have entered either the wrong type of data or have left the input field empty. As your application develops, you will almost certainly need additional input validation depending on your applications requirements. For example, you might want to validate a string field to be a valid credit card. This is achieved with custom formatters specified at the Entity level and is described in a later section. The built-in validation covers you for simple cases.

input-form Example It is worth taking some time to explore the features of your new AutoForm by doing the following: See what happens when you input data with each type of input field. Notice that the data changes when you move focus from an input field. Try entering different or no values and seeing when the validations notify you of invalid input. Notice that you can back out of an edit with the Escape key on your keyboard. Taking some time to familiarize yourself with the workings of the AutoForm now will lead to fewer surprises when you develop more complex input forms and will help you field questions from the end users of your application.

Creating a Custom Table The Table component is a wrapper around the third-party library, DataTables. See http://www.datatables.net for more information. The generated table will have some standard styling and options applied. The data for Table needs to be supplied as an array of arrays, where each inner array represents a row: // Table data. 2 rows, 5 columns var tableData = [ [1, 16, 2, 24, 64], [2, 17, 5, 96, 22] ];

You need to create a <table> element in your HTML with an id to which you can refer: <table id="actions-table"></table>

You need to create a new insight.components.Table object and pass in a reference to the container id in the markup, the column configuration, the data,

Page 170: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

170 Fair Isaac Confidential and Proprietary

and optionally extra DataTables settings to pass through for additional customizations: var table1 = new insight.components.Table( 'actions-table', [ {name: 'Index', width: '40px'}, {name: 'Column 1', width: '60px'}, {name: 'Column 2', width: '60px'}, {name: 'Column 3', width: '60px'}, {name: 'Column 4', width: '60px'} ], tableData );

The second argument is an array of column configuration objects. Each configuration object needs to contain all the required properties and can contain any of the optional properties. For a full list of required and optional properties, see the JavaScript API reference for insight.components.Table. By default no data formatting will be applied to columns. However if you specify the “type” property in the column configuration with which you instantiate the Table component, then you can benefit from any global formatting rules that apply. There are system default number formats that can be modified globally and will be applied to INTEGERS and REALS. You can also fallback to using the DataTable mRender configuration property for custom rendering and formatting of cells. The Table component can be made editable per column. When configuring editable columns, you will need to provide a callback function that will be invoked on each edit finishing. This callback will be passed the new value of the cell, an array of row data, and the actual cell object. Within the callback, you can perform validation of the new value (or use the editorValidate configuration property as described in the javascript documentation) and take any action needed upon success. When validation fails or if there is a problem processing the value, you should throw an Error with a meaningful message for the end user. The following is an example of an editable table being initialized: var table = new insight.components.Table( 'data-table', [ { name: 'Boolean', type: insight.enums.DataType.INTEGER, editable: true, editorType: 'checkbox', uncheckedValue: 0, checkedValue: 1 }, {

Page 171: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 171

name: 'Integer (1-10000)', type: insight.enums.DataType.INTEGER, editable: true, editorSave: function (newValue, rowData, cellElement) { // Should only accept integers between 1-10000 if (!isNaN(newValue) && (newValue % 1 === 0) && newValue >= 1 && newValue <= 10000) { alert('Perform some action on new value: ' + newValue); return; } // Throw Errors if anything goes wrong throw new Error('New value is invalid, will not save: ' + newValue); } } ], data );

Entity Formatting The Xpress Insight API provides a display formatter that can make formatting consistent for numeric and other data. The insight.Formatter object holds the default formats for different numeric data types (integer and real) and provides a formatting method insight.Formatter.formatNumber() that can be applied to any data within your view code. Model entities can be formatted according to their data type (or element data type, in the case of arrays) by using the insight.Formatter.formatEntityValue() method. If the entity is a set and has an associated labels entity, you can get the formatted label value using the insight.Formatter.getFormattedLabel() method. You can also supply a custom formatter on a per-entity basis. To do this, use the insight.Formatter.setEntityFormatter() method. Any occurrence of this entity will then be formatted using your custom formatting function.

Important In setting a custom formatter for an entity, it will override any standard formatting.

After an entity formatter has been set, the Xpress Insight components automatically apply formatting on the specified entities when they are displayed in an AutoTable or AutoText component. // Arrays and sets only; in this case 'Array1' is an array. insight.Formatter.setEntityFormatter('Array1', function(original) {

Page 172: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

172 Fair Isaac Confidential and Proprietary

return insight.Formatter.formatNumber(original, '$#,##0.0#', null); });

Note See insight.Formatter in the JavaScript API documentation for function signatures and other details.

Entity Validation The Xpress Insight API provides an entity validator, insight.validation.EntityValidator. You can pass in a value with an entity to test against to the insight.validation.EntityValidator.checkValue() method. This will do the following tasks as required: If the data dimension is NORMAL_DATA then base (primitive) type checking

is performed. If a custom validator is specified for the entity in the given dimension, it is

performed after the base type checking. You can supply a custom validator for an entity in a given dimension by using the insight.validation.EntityValidator.setValidator() method. The EntityValidator and any callback functions supplied to the setValidator() method should all return an insight.validation.Result instance. This return object is used to store the Boolean result of a validation process as well as an optional error message (if an error occurred).

Custom Set Sorting You can supply custom set sorting functions per set in a given dimension. The insight.addSetSorter(), insight.removeSetSorter() and insight.getSetSorter() methods can be used to manage the custom set sorting functions. When you call insight.Scenario.getSet(), it will pass the set(s) through any matching set sorters that have been added.

View Configuration

Overlays The best-practice behavior for a view is to indicate when a scenario is executing, or when results are not available to be displayed. The API provides built in overlay functionality for these two cases. The Execution Overlay will hide the entire view’s contents and instead show a spinner and a message. This will happen whenever one or more scenarios that are in use by the view are in some execution state (queued, paused, executing, and so forth).

Page 173: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 173

A view considers a scenario to be in use if there is a ScenarioObserver registered against it. So the following example considers scenarios 0 and 1 as in use and will show the execution overlay if either of them are being executed: var view = insight.getView(); view.withScenarios(0,1);

You can customize the look of the execution overlay using the CSS rule “.execution-overlay”. You can also make use of the following class that is added to the body when the overlay is activated, “scenario-executing”. The No-Results Overlay is used mark areas of a view are dependent on result data. If the results are not available for a marked up area, then the area will be hidden and in its place will be an overlay saying “no results available”. The view will watch the state of each scenario and manage the visibility of the overlays but it is up to you to mark up areas of the page to show they are interested in result data and optionally specify which scenarios to watch. To mark an area as dependent on results do the following: <div class="if-results-available" style="display: none;"> <!-- content --> </div>This will hide the content of the div whenever any scenario in the selection is executing. If you need to limit the scenarios that are watched for a particular area on the page, you can add the following optional attribute: <div class="if-results-available" data-scenario="0" style="display: none;">

This will only hide the contents of the area if the first scenario in the selection is executing. You can specify multiple, comma-separated, scenarios in the data-scenario attribute: <div class="if-results-available" data-scenario="0,1,3" style="display: none;">

In a similar way, you can configure an overlay to be shown whenever a scenario has no input data: <div class="if-scenario-loaded" data-scenario="0" style="display: none;">

You can customize the style of the overlays using the CSS rules .no-results-overlay and .scenario-not-loaded-overlay. The overlays are enabled by default but will only start taking effect when you have started the view:

Page 174: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

174 Fair Isaac Confidential and Proprietary

var view = insight.getView(); view.start();

There are some basic configuration parameters available for the overlays. They allow you to enable/disable the overlays and change the messages presented to the end-user. Pass the options in to the View.configure() method, for example here are the defaults: var view = insight.getView(); view.configure({ noResultsOverlay: true, noResultsMessage: 'no results available', notLoadedOverlay: true, notLoadedMessage: 'scenario not loaded', executionOverlay: true, executionOverlayMessage: 'Please wait...' });

Exception Handling The JavaScript API will output various levels of logging and you can see these logs by opening your browser’s web developer tools. Warnings and Errors are always output to the console but when an unrecoverable error has occurred a JavaScript error will be thrown. These errors bubble up to the top layer of the JavaScript API and are output as console error messages along with a stacktrace, if available. When you are developing a view, you should test it and run with the developer tools open so that you can spot any console errors as early as possible. In some cases an error may only occur when certain data values are present. In these situations you may need to add in some data checking before processing. Developer tools in most web browsers allow you to pause execution of JavaScript when an unhandled exception occurs. This is useful as you can then step through the code and also see what calls led up to the exception. As multiple browsers are supported in the Web Client, you need to test your custom views across the different browsers.

Working with Unloaded Scenarios When a scenario is first created, it will have no input data nor any result data. The input data will be populated only after the scenario has been loaded. Most custom views are designed to display and edit input or result data, so opening a custom view against an unloaded scenario is disabled by default. However, there are some cases where you do want a custom view to be enabled for an unloaded scenario: if the custom view provides a way to edit model parameters, such as an AutoForm, and if these parameters will affect how the

Page 175: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 175

input data is loaded, it makes sense for the custom view to be used to initialize these parameters before loading the scenario. In this situation, you can mark the view in the companion file as not requiring a loaded scenario, by setting the requires-scenario-loaded attribute to false:

Page 176: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

176 Fair Isaac Confidential and Proprietary

<view-group title="Main"> <vdl-view title="Parameters" path="params.vdl" requires-scenario-loaded="false"/> ... </view-group>

This setting only affects HTML and VDL views. Tableau views always require a loaded scenario.

Using Modal Dialog Boxes You should avoid using browser native alert boxes, using the JavaScript alert() or confirm() function calls. These block JavaScript from executing until the dialog is closed. You can use the provided third-party library called Bootbox. This creates a HTML-based alert or confirmation popup. You can also overwrite the browser default alert() function with the Bootbox.alert() method to automatically benefit from it. An example of how to use the Bootbox alert and confirmation pop-ups can be seen in the hello-world-example, “Modal Dialog Example” view: <installdir>\examples\insight\developer_guide\chapter5\hello-world-example

Including Additional JavaScript Libraries Third-party libraries should normally be imported after insight-4.0.js. This particularly applies to jQuery plugins, because insight-4.0.js includes a version of jQuery. For example, if we have a jQuery library called “jquery.TableCSVExport.js” in a subfolder “js/lib”, then we would load it in as follows: <script src="$distrib/insight-4.0.js"></script> <script src="js/lib/jquery.TableCSVExport.js"><script>

Working with Attachments The JavaScript API provides access to all of the attachments on the scenario and the app. The attachments can be listed, downloaded, and information about them can be retrieved. Custom views can be notified whenever the attachments on the app or scenario change, so that parts of the view can be redrawn accordingly.

Page 177: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 177

Attachments cannot be edited directly using the JavaScript API, but the API provides several methods which open the regular attachments dialog, allowing the intended action to be completed using the familiar Web Client user interface. For general information about attachments and attachment tags, see Using Attachments in this document, and the Xpress Insight Web Client User Guide. For a complete description of the attachments API, see the JavaScript API documentation in <installdir>\docs\insight\javascript_api.

The Attachments API The attachments on an app or scenario can only be accessed from within a scenario observer (see The ScenarioObserver). To observe attachments, call the withAttachments method when constructing the observer. Optionally, a list of filenames or tags to observe can be provided, in which case, the callback will only be called when attachments that match the given filenames or tags are modified:

var view = insight.getView(); view.withFirstScenario() .withAttachments() .notify(function (scenario) { var attachments = scenario.getScenarioAttachments(); console.log('The scenario has ' + attachments.length + ' attachments'); }) .start();

view.withFirstScenario() .withAttachments({ tags: ['input-sheet'] }) .notify(function (scenario) { var attachments = scenario.getTaggedScenarioAttachments('input-sheet'); if (attachments.length) { var filename = attachments[0].getFilename(); console.log('The input sheet was replaced with ' + filename); } else { console.log('The input sheet has been removed'); } }) .start();

Page 178: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

178 Fair Isaac Confidential and Proprietary

Downloading an attachment Most of the attachment methods on Scenario return an Attachment or list of Attachments. Along with methods to get the filename, description and other attachment properties, this object has a download() method, which when called downloads the attachment using the web browser's normal download dialog. This can be used to implement a simple download button:

...

.notify(function (scenario) { var readme = scenario.getProjectAttachment('readme.txt'); if (readme) { $('button#download-readme').off('click') .prop('disabled', false); $('button#download-readme').click(function () { readme.download(); }); } else { // No readme file available. $('button#download-readme').prop('disabled', true); } }) ...

Note The click handler needs to be installed within the notify callback in order to access the attachment, and because this callback is invoked whenever the attachments change, the previous click handler should be removed before installing a new one.

Editing attachment properties The Attachment.openProperties() method opens the attachments dialog and automatically navigates to the given attachment so that it can be reviewed or edited. If the name of an attachment field is passed in as an argument to this method, the dialog will start out in edit mode on that field. The following attachment fields are supported in edit mode: filename – Edit the filename of the attachment. description – Edit the description of the attachment. Tags – Edit the tags of the attachment.

Page 179: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 179

For example, the following code sets up a button which when clicked allows the user to edit the description of a particular attachment:

...

.notify(function (scenario) { var inputSheet = scenario.getTaggedScenarioAttachments('input-sheet'); if (inputSheet.length) { $('button#download-readme').off('click') .prop('disabled', false); $('button#download-readme').click(function () { inputSheet[0].openProperties('description'); }); } else { // No input sheet available. $('button#download-readme').prop('disabled', true); } }) ...

Opening the attachments dialog The attachments dialog can also be opened in its usual form, allowing the user to upload, download, edit and delete attachments using the familiar Web Client user interface. To open the attachments dialog, call View.openScenarioAttachmentsDialog() or View.openProjectAttachmentsDialog(). An optional message can be provided as the first argument, which will be displayed at the bottom of the attachments dialog. This message can be used to prompt or instruct the user about what they are expected to achieve using the dialog. With openScenarioAttachmentsDialog, you can also specify the scenario whose attachments should be displayed by passing the scenario's id or index (within the current selection) as an optional second argument.

var view = insight.getView(); view.openScenarioAttachmentsDialog('Delete any input files which are no longer needed');

Uploading an attachment The attachments dialog can also be opened in a special mode which allows a user to upload a file and then have that file automatically tagged with a given attachment tag:

Page 180: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

180 Fair Isaac Confidential and Proprietary

Once the user has uploaded a file, the dialog will resume its normal appearance. To open the dialog in this mode, call View.uploadScenarioAttachment(tagName) or View.uploadProjectAttachment(tagName). The tag to apply to the new attachment must be passed as the first argument. An optional message can be provided in the second argument, which can be used to give the user more detailed instructions.

var view = insight.getView(); view.uploadScenarioAttachment('input-sheet', 'Choose a spreadsheet from which to load the account data');

The Attachment Tags API The JavaScript API provides methods to retrieve information about the attachment tags defined by the app. This enables a view developer to access information from the companion file (for example, the description of an attachment tag), rather than having to duplicate that information within the custom view.

Page 181: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 181

The Project.getAttachmentTags() method returns a promise (see Promise API), which resolves to an array of AttachmentTag objects. These objects have methods to get the name, description, and other details of an attachment tag.

var project = insight.getView().getProject(); project.getAttachmentTags().then(function (tags) { console.log('The app defines the following tags:'); for (var i = 0; i < tags.length; i++) { console.log(tags[i].getName()); } });

Displaying Attachment Data with AutoText Information about attachments present on the app or scenario can be displayed in a custom view by using the AutoText component (see AutoText). This is achieved by adding the data-text attribute to an HTML element. The tag name of the attachment must be specified, along with the name of the field that you wish to display: filename - The filename of the attachment. description - The description of the attachment. tags - A comma-separated list of all tags present on the attachment. lastModifiedDate - The date when the attachment file contents were last

modified. lastModifiedUser - The name of the user who last modified the

attachment file contents. hidden - Whether or not the attachment is hidden in the UI (either "True"

or "False").

The examples below demonstrate how to use the data-text attribute:

The filename of the app attachment tagged with input-sheet is: <span data-text="attachment:project/input-sheet/filename"></span> The description of the scenario attachment tagged with result-chart is: <span data-text="attachment:scenario/result-chart/description"></span> <!-- For scenario attachments, the "scenario/" prefix is optional: --> The scenario attachment tagged with input-sheet was last modified by: <span data-text="attachment:input-sheet/lastModifiedBy"></span>

Page 182: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

182 Fair Isaac Confidential and Proprietary

A ScenarioObserver must then be created, and bindAutoText called, passing a CSS selector which matches the HTML elements to be populated:

var view = insight.getView(); view.withFirstScenario() .bindAutoText('span[data-text]') .start();

If no attachment exists with the specified tag, the HTML element will be populated with a fallback message, "The attachment is not currently available". An alternative message can be specified using the data-fallback attribute. For example:

The filename of the app attachment tagged with input-sheet is: <span data-text="attachment:project/input-sheet/filename" data-fallback="No input sheet has been uploaded"></span>

Displaying Attachment Tag Data with AutoText The data-text attribute can also be used to display information about an attachment tag itself, by using the tag: prefix in place of the attachment: prefix used above. This is useful to avoid duplication of information such as the tag description in both the companion file and the custom view source file. The following tag fields can be displayed, all of which are defined in the companion file: name - The name of the tag. description - The description of the tag. mandatory - Whether the tag must be present on an attachment before

the scenario can be executed ("True" or "False"). usage - Whether only one attachment per scenario can have this tag, or

whether several attachments can have the tag at the same time ("Single-file" or "Multi-file").

The example below demonstrates how to use the data-text attribute to display information about an attachment tag:

<h3>Help with uploading an input spreadsheet</h3> <p data-text="tag:input-sheet/description"></p>

As before, a ScenarioObserver must also be configured. In this example, all HTML elements with the data-text attribute are populated with a single observer:

var view = insight.getView(); view.withFirstScenario() .bindAutoText('[data-text]') .start();

Page 183: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 183

Image attachments The ScenarioObserver.bindImageAttachments() method allows image files attached to the scenario or app to be displayed in a custom view. Define an HTML img tag in the view, and specify the filename of the attachment using the data-attachment-filename attribute (specifying the attachment by tag name is not supported). If no attachment exists with the specified filename, the image will be replaced with a fallback message, "The attachment is not currently available". An alternative message can be specified using the data-fallback attribute. For example:

<h3>Results chart</h3> <img id="results-chart" data-attachment-filename="chart.png" data-fallback="The chart is not available">

Finally, create a scenario observer to populate the img tags in the view

var view = insight.getView(); view.withFirstScenario() .bindImageAttachments('#results-chart') .start();

The normal width and height attributes can optionally be used to specify the size of the image.

Advanced Subjects

Configuring the Web Client Welcome Page The Xpress Insight Web Client can display a designated view when no scenario is selected. This can be useful for displaying an introductory view. The code below designates that the “welcome.html” file be used for this purpose: <html-view title="Welcome page" empty-selection-default="true" path="welcome.html"/>

Reflection and the Model Schema The data schema for every scenario in the app is represented by the Model Schema and Model Entity objects.

Page 184: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

184 Fair Isaac Confidential and Proprietary

var view = insight.getView(); var project = view.getProject(); var schema = project.getModelSchema(); var myarray = schema.getEntity(‘myarray’);

There are three entity types supported by Xpress Insight. These are: Scalar: A single data item. Sets: A single dimension collection of unordered data items. Arrays: A single or multi-dimensional associative array of data items where

the possible index values for a given dimension of the array are represented by a set entity.

Each scalar, set, and array entity has a further type for the data value or values residing in the entity. The main value types are BOOLEAN, INTEGER, REAL, STRING, DECISION_VARIABLE and CONSTRAINT. Xpress Insight adds several more value types (VARIABLE_TYPE, CONSTRAINT_TYPE, MODEL, and PROBLEM_STATUS) to represent the augmented data collected by Xpress Insight. Parameters are represented as an array(string) of strings. The union of entity and data types is enumerated by the insight.enums.DataType namespace. The type of an entity is returned by getType. For scalar entities, this returns a value type. For set entities, this returns SET. For array entities this returns ARRAY. In both cases, the value type of the entity can be queried with getElementType.

Web Client Performance Specifics The Web Client saves all changes as they happen and the API call to save a view's state has no effect. The Web Client itself will not hold any locks on selected scenarios and it cannot detect if a scenario is locked. HTML elements that are bound using JavaScript API auto components will automatically be disabled when a view is in read-only mode.

Data Dimensions Xpress Insight captures extra information alongside the basic contents of the entities it is managing. This data is made available as extra dimensions to the original data. The JavaScript functions for getting and setting the data values accept a dimension parameter to indicate that the action should be performed on an extra dimension of the data.

Page 185: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 185

Normal Dimension The dimension parameter defaults to 0, which indicates the normal data dimension. The following table shows what data is captured as the normal dimension for each type of data managed by Xpress Insight.

Entity Type Normal Data model Objective value primitive type Primitive value mpvar Solution value linctr Constraint activity

Extra Dimensions for Model Entity Dimension Value Extra Data 101 Run time 102 Gap 103 Number of solutions 104 Problem status

Extra Dimensions for Constraint (linctr) Entities Dimension Value Extra Data 1 Disable (is constraint disabled) 2 Relax (was constraint relaxed) 52 Violation 54 RHS 55 Type 56 Dual value

Extra Dimensions for Decision Variable (mpvar) Entities Dimension Value Extra Data 81 Reduced cost 82 Type

Debugging Custom Views in the Web Client To debug custom views, both VDL and JS API, you need to add the parameter debug=true to the URL. For example, if you are running Xpress Insight on your local machine you can request the following URL: http://localhost:8860/insight/?debug=true

Doing so will trigger debug logs to show up in the browser’s console.

Page 186: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

186 Fair Isaac Confidential and Proprietary

Common Issues Data-entity attributes and Entity names do not match. The same applies to

all the other data-* attributes. view.start() was not called. When you call the function observer.bindAutoForm(...) you must pass in an

object with the correct keys. The formId key has a capital 'I' for Id. (This is easily missed.) The formId value is the id of the HTML form in your markup. It should not

include the pound (or hash) symbol and cannot be any other kind of CSS selector (such as a classname). This is slightly different behavior from the AutoText component that accepts a CSS selector because it can work on multiple items with one call. The bindAutoForm function only works with one form.

Always check the developer tools console of your browser in case any errors were introduced into the code.

If the view is locked in another client view then any attempts to edit an input value will fail with an error message.

Page 187: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 187

CHAPTER 7 Authoring a Custom View with Tableau for FICO

Tableau for FICO is a powerful Business Intelligence application that allows you to analyze many different types of structured data using a greatly expanded range of chart and graph formats to create your views. Tableau visualizations can be incorporated into FICO® Xpress Insight apps as custom views that report on the scenario data. This chapter describes the tasks that a developer needs to execute in order to incorporate Tableau visualizations as views in an Xpress Insight app. These developer tasks are as follows: Configure Xpress Insight to expose data to Tableau Create a Tableau workbook Incorporate the workbook in the Xpress Insight app

The steps involved in performing these tasks will be described in the context of adding a Tableau view to the Facility Location example that can be found in <installdir>\examples\insight\javascript\facility_location. If you want to follow the steps, we suggest you take a copy of the example app zip file and apply the changes to this.

Configuring the Mirror to Expose Data to Tableau Tableau visualizations source their data from a relational database. Because Xpress Insight holds scenario data in a compressed format, it has to be mirrored into a relational database for Tableau. This database is referred to as the Mirror. The schema and content of the mirror database is managed by Xpress Insight. Apps define their mirror tables and how they are populated. The following companion file fragment defines the table, facility_clients, populated with three arrays:

<database-mirror table-prefix="facility_"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> </mirror-table> </mirror-tables> </database-mirror>

A database table is created for each mirror table definition. Database columns are created for each array and their associated index sets. All arrays in a mirror

Page 188: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

188 Fair Isaac Confidential and Proprietary

table must therefore have the same dimensions, that is, they share the same index sets. Column names default to the entity’s name, that is, the name of the set or array. The mirror-table element offers additional attributes to fine tune the content of the table such as overriding the default column names or applying aliases and labels. For more information, see the XML Reference Guide.

Note The combination of the table-prefix and table-name must not exceed 64 characters.

Note The column name must not exceed 64 characters.

Note The table prefix, table name, column name must be a character in the Unicode range U+0001 to U+FFFF, excluding the back quote (`).

Note Entities of Boolean data type will be mirrored as integers with a value of 1 indicating true and a value of 0 indicating false.

Note The column name, mirror_row_id, is a reserved column name by Xpress Insight.

The following steps configure the mirror database for the Facility Location example. 1 Open and edit the app companion file FacilityLocation.xml file. <?xml version="1.0" encoding="UTF-8"?> <model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0"> <client> <view-group title="Main"> <custom-view view-class-id=".customFacilityLocation" default="true"/> </view-group> </client> </model-companion>

2 Configure the mirror database by adding the following section to the companion file below the schema element. <database-mirror table-prefix="facility_"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> </mirror-table> </mirror-tables> </database-mirror>

Page 189: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 189

All three arrays are indexed by the Clients set. The resultant mirror database will therefore contain a table named facility_clients with columns CLIENTS, CLIENT_LATITUDE, CLIENT_LONGITUDE and DEM. Five further database tables are automatically populated in the mirror database: The insight_projects table contains the list of apps that has had one or more

scenarios mirrored. The table contains the app id, app name, and the table prefix that is used for the mirrored data.

The insight_scenarios table contains the list of scenarios in the app that have been mirrored. The table contains the scenario id, app id, scenario name and scenario path.

The insight_security table contains a mapping of users to the scenarios they have access to. The username provided in this table is the user’s Tableau username. See Securing Tableau Workbooks for more information.

The insight_authority_groups table contains a mapping between Tableau user name and authority group names of all the authority groups that the user is assigned in the system.

The insight_authorities table contains mappings of users to custom authorities, so none of the system defined authorities will be present in this table. These authorities are selected from the authority groups the user is a member of.

The mirror database also includes tables prefixed with __internal. These tables are internal to Xpress Insight, should not be used by Tableau views and may change in future releases.

Creating a Workbook The following instructions describe how to create a new workbook in Tableau desktop, connect to the database, and specify the table or view to be used by Xpress Insight.

Note It is also possible to author a workbook on Tableau 9.3 using Xpress Workbench. See the Xpress Workbench User Guide or the simple example in Chapter 2 of this guide (which presents an equivalent task using Tableau Server) for more information.

1 Open Tableau and create a workbook. 2 Click File > New to display the following screen:

Page 190: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

190 Fair Isaac Confidential and Proprietary

3 Click Connect to Data (as shown in the previous example). To generate a

datasource for this workbook, click PostgreSQL, which is the database type used by Xpress Insight.

Select the PostgreSQL database type

Page 191: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 191

Note You can instead use a data source configured in the companion file which is already already published to Xpress Insight. See Configuring a data source in Xpress Insight to expose data to Tableau for more details on how to create a data source. To use a published data source, click Tableau Server (rather than PostgreSQL) and select the datasource from the list. Skip to step 11.

4 From the PostgreSQL Connection form, enter the name of the server where the Xpress Insight server is installed (the default is localhost) and database (insightmirror), and the username and password. The publisher user account should be used in this circumstance. Be sure to check with your Administrator if you do not have this information.

5 Click Connect. 6 Change the connection name to Facility Data Source.

Page 192: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

192 Fair Isaac Confidential and Proprietary

7 Drag the facility_clients table into the query designer.

8 Drag insight_scenarios into the query designer and select Scenario Id as the

Data Source join and Id as the insight_scenarios join.

Page 193: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 193

9 To secure the workbook drag the insight_security table into the query designer.

The join is automatically established.

10 Ensure the Live Connection option is selected and verify the data source by

clicking the Update Now button

Page 194: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

194 Fair Isaac Confidential and Proprietary

Important: Be sure to always choose the Live connection option to ensure that the Tableau view always shows live data from the mirror and not cached data.

Note The scenario_id and insight_security table filters must be added to Tableau views to ensure correct behavior when used within Xpress Insight. The scenario_id filter restricts the workbook to show only the scenarios selected by the user. The security filters ensure the workbook only contains data that the user is authorized to view.

11 After you have selected how you want to connect to your data, click Go to Worksheet and the Tableau workbook displays as shown in the following example. Rename the Sheet 1 tab to Clients Table by double-clicking on the Sheet 1 tab.

12 Apply the user security filter onto the data source. First sign into Tableau

server by selecting the menu option Server – Sign in.

Double-click to rename sheet to Client Table

Page 195: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 195

13 And enter the name of the Tableau server and credentials that have publish

rights to Tableau server.

Note This step is optional but is recommended as it gives Tableau a user context and allows the user to see the data as seen by this user. This is useful when testing the data source.

Note The user account should be one that is currently associated to an Xpress Insight user. The Xpress Insight user should have: Access to the app the Tableau data source is defined for. Run one or more of the scenarios for the app.

14 Select the menu option Data > Facility Data Source > Edit Data Source

Filters.

Page 196: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

196 Fair Isaac Confidential and Proprietary

15 Click Add.

16 Select username and then click OK.

Page 197: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 197

17 Click on the radio button located next to the By formula label and then enter

the following formula into the field. [username] = USERNAME()

Page 198: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

198 Fair Isaac Confidential and Proprietary

18 Click OK.

Page 199: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 199

Creating a Simple View The basis of any Tableau view is the data source. Now that a data source has been created the following steps outline how to author a simple view. 1 Add a title to the blank view by right clicking on view area. A context menu

appears.

2 Select Title from the context menu.

Page 200: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

200 Fair Isaac Confidential and Proprietary

3 Populate the rows of the table by dragging the Clients entry from the

Dimensions pane, located on the far left hand side of the window, to the Rows area.

Page 201: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 201

4 Populate the columns area of the table by dragging the Client.Demand entry from the Measures pane, located on the far left hand side of the window, to the text icon located in the Marks pane.

5 Apply the scenario security filter onto the view. This is done by dragging the

Scenario Id from the Insight Security table in the Dimensions pane into the Filter pane. The following dialog will be shown.

Page 202: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

202 Fair Isaac Confidential and Proprietary

6 Click OK. The data table will disappear. This is because the filter has been

applied to the data and no scenarios have been selected. When a view is shown, the id(s) of the selected scenario(s) are added automatically to the call to show the view within the client.

Page 203: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 203

7 Click Save. The Tableau view is now available to be published to the Tableau server.

Adding Tableau Workbooks to an Xpress Insight App

There are two actions required to include a workbook in an Xpress Insight app. Register the workbook as required by the app Publish the workbook to the Tableau Server

Workbook dependencies for an app are registered in the companion file. A Tableau workbook can be added to a view group.

Note Individual Tableau visualizations are not registered directly, the visualizations contained in the workbook are determined automatically.

Tableau workbooks can be registered in the companion file as either managed or unmanaged workbooks.

Page 204: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

204 Fair Isaac Confidential and Proprietary

Managed Workbooks Workbooks marked as managed in the companion file will be automatically published by Xpress Insight on loading the new app if the workbook file can be located in the tableau folder of the app archive.

Managed workbooks can also be uploaded via the Publish Workbook feature within the Web Client. Managed workbooks will also be downloaded and included in an app export and will be deleted from the Tableau server when the app is deleted. During the upload process the workbook connection(s) are transformed to reference the mirror database of the system being uploaded to.

Unmanaged Workbooks Workbooks in the companion file that do not have the managed attribute or have this set to false are seen as unmanaged. These workbooks have to be published to Tableau server using either Tableau Desktop or via Tableau server tabcmd command line utility.

Adding a Tableau Workbook as a Managed Workbook To add a Tableau workbook as a managed workbook: 1 Add the workbook in the app companion file.

<client> <view-group title="Main"> <html-view title="A html view" path="index.html"/> <tableau-workbook title="facility" workbook="Facility" managed="true"/> </view-group> </client>

Page 205: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 205

Note The name provided in the workbook attribute must match the name of the Tableau workbook. The file extension of the workbook should not be included.

2 Add the workbook to the app zip into the tableau folder of the app archive.

Adding a Tableau Workbook as an Unmanaged Workbook To add a Tableau workbook as a managed workbook: 1 Add the workbook in the app companion file.

<client> <view-group title="Main"> <html-view title="A html view" path="index.html"/> <tableau-workbook title="facility" workbook="Facility"/> </view-group> </client>

Note The name provided in the workbook attribute must match the name of the Tableau workbook. The file extension of the workbook should not be included.

2 Publish the workbook via Tableau Desktop or via the Tableau server tabcmd command line utility.

Note When publishing the workbook the name defined in publish dialog should match the workbook attribute in the app companion file.

Page 206: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

206 Fair Isaac Confidential and Proprietary

Publishing Workbooks Manually via the Web Client The Xpress Insight Web Client provides the ability to publish workbooks to Tableau Server. This option is particularly useful during app development where a workbook can be updated in place without reloading the whole Xpress Insight app. During the upload process the workbook connection(s) are transformed to reference the mirror database of the system being uploaded to. Before you use the instructions in this section, review the following information Tableau must be enabled for Xpress Insight. Tableau must be enabled for the user performing this operation. The possible workbooks that can be uploaded correspond to the ‘managed’

workbooks registered in the companion file. If there is only one ‘managed’ workbook defined for a given app companion file then this workbook will automatically display; otherwise you can select from the multiple workbooks that show in the drop-down list.

You must have WORKBOOK_PUBLISH authority to perform this task.

Page 207: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 207

Be sure that you are on a specific app page from the Web Client interface. Tableau workbook (TWB) and Tableau packaged workbook (TWBX) files can

be published via this mechanism.

Note The contents of the Tableau packaged workbook file is restricted to a Tableau workbook and images.

On successful publishing of a workbook, any changes will be available immediately in your web client session.

Note These changes will only appear for other users after they log out and log back in.

This feature should only be used with workbooks with data source that connect to the Xpress Insight mirror database.

Any workbooks that contain one or more data sources that do not connect to the Xpress Insight mirror database will be rejected and an error message will display.

The following steps outline the process of publishing a workbook via the Web Client. 1 From the Xpress Insight Web Client interface, select the app (that already has

workbooks associated with it). For this example, select the FlowShop app and use the pull-down menu to select Publish Workbook.

The following dialog will display. For this example, we will select the FlowShop workbook and publish it as FlowShop.

Page 208: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

208 Fair Isaac Confidential and Proprietary

2 Click Publish.

The dialog will close and an overlay will be shown indicating that the app is being updated. Once that has completed a success or failure message will be shown at the bottom of the page indicating whether publish was successful or not.

Page 209: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 209

Publishing Workbooks Manually via Tableau Desktop

Tableau Desktop can be used to publish unmanaged Tableau workbooks to the Tableau Server. 1 From Tableau, click Server > Publish Workbook. Enter the server

credentials. For more information about the Tableau username and password, see the Xpress Insight Installation Guide.

2 Click Sign In to display the Publish Workbook to Tableau Server dialog.

Page 210: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

210 Fair Isaac Confidential and Proprietary

3 Click Authentication and change the database password storage from

Prompt to Embedded. 4 Click Publish.

Note The name entered in the dialog should match the workbook attribute defined in the app companion file for Tableau workbook.

A preview of the published view displays as shown. Do not worry if the view is empty. This is due to the security filters that have been added to the view.

5 Close the preview window and exit Tableau Desktop.

Configuring a data source in Xpress Insight to expose data to Tableau

Xpress Insight provides two mechanisms by which a Tableau view developer can obtain data. One is directly from the Xpress Insight mirror tables, by configuring a database connection within the Tableau workbook and choosing the tables and their joins using the Tableau UI. An alternative approach is to define a data source within Xpress Insight and to then pull that into the Tableau workbook. Each companion file data source

Page 211: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 211

definition contains one or more mirror table references, each of which refers to one of the configured mirror tables in the companion file. The following companion file fragment shows an extension of the previous mirror table example with three data sources defined:

<database-mirror table-prefix="facility_"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> </mirror-table> <mirror-table name="depots"> <entity name="DEPOT_LONGITUDE"/> <entity name="DEPOT_LONGITUDE"/> <entity name="CAP"/> </mirror-table> <mirror-table name="driving"> <entity name="DRIVING_DISTANCE"> <entity name="DRIVING_TIME"> </mirror-table> </mirror-tables> <data-sources> <data-source name="clients_datasource"> <mirror-table-ref name="clients"/> </data-source> <data-source name="depots_datasource"> <mirror-table-ref name="depots"/> </data-source> <data-source name="driving_datasource"> <mirror-table-ref name="clients "/> <mirror-table-ref name="depots"/> <mirror-table-ref name="driving "/> </data-source> </data-sources> </database-mirror>

Xpress Insight uses the datasource definition to generate and publish a Tableau data source. Joins are generated between the specified tables and also with the insight_scenarios, insight_projects and insight_security tables. The generated data source also includes a filter to ensure users only have access to data in scenarios for which they are authorized.

Note When a workbook is subsequently created in Tableau, it can be configured to refer to a datasource from the companion file. The data source will be named using the defined name prefixed with the table-prefix. Eg. For the example above, “facility_clients_datasource”.

Page 212: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

212 Fair Isaac Confidential and Proprietary

Note If a workbook contains its own embedded data source then it will be used in preference to any data source defined in the companion file.

Note Data source definitions are only supported in companion file version 3.0 or later and for use with Tableau 9.3.

When creating a Tableau datasource using a companion file data source definition, Xpress Insight joins the mirror tables using the following rules:

1. A mirror table containing one or more scalars is joined to other mirror tables using the scenario_id column.

2. A mirror table containing a set can only be joined to a mirror table containing one or more scalars by the scenario_id column. A mirror table containing a set cannot be joined to other mirror tables which contain a set or arrays.

3. A mirror table containing one or more arrays can be joined to a mirror table containing one or more scalars by scenario id. It can also be joined to mirror tables containing arrays if they have one or more index sets in common. In this case the tables will be joined by the largest common subset of their index sets.

4. In all cases the mirror tables will be joined to insight_scenarios, insight_projects and insight_security via their scenario_id column.

Note Data source definitions are processed when an app is imported or updated in Xpress Insight. If any of the data source definitions are invalid then an error will be displayed and the operation will be aborted.

Securing Tableau Workbooks Xpress Insight is a secure system and only fully authenticated users will be able to view Tableau workbooks with the Xpress Insight interface. However, Xpress Insight also provides an access control model where a scenario can be read-only or shared with other users. This access control is honored through obfuscation (one user would need to guess the scenario id of another users’ private scenario to view) in the standard workbook configuration, which is typically adequate for single-tenant environments where the access model is governing workflow and organization of scenarios between trusted team members rather than security. However for shared systems and systems exposed to the internet in a hosted deployment, an additional level of access control is available. The details in the next section cover how to explicitly enforce the access control model, should a stricter policy be desired

Restricting the Data Source to Authorized Users The following steps define the additional development action required to implement a workbook that strictly enforces the user access model.

Page 213: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 213

1 Sign into Tableau server by selection the menu option Server – Sign in.

2 Enter the name of the Tableau server and credentials that have publish rights

to Tableau server.

Note This step is optional but is recommended as it gives Tableau a user context and allows the user to see the data as seen by this user. This is useful when testing the data source.

Note The user account should be one that is currently associated to an Xpress Insight user. The Xpress Insight user should have: Access to the app the Tableau data source is defined for. Run one or more of the scenarios for the app.

3 Select the menu option Data – Facility Data Source – Edit Data Source Filters.

Page 214: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

214 Fair Isaac Confidential and Proprietary

4 Click Add.

5 Select username and then click OK.

Page 215: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 215

6 Click on the radio button located next to the By Formula label and then enter

the following formula into the field. [username] = USERNAME()

Page 216: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

216 Fair Isaac Confidential and Proprietary

7 Click OK.

Page 217: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 217

Restricting the View to Only the Selected Scenarios in the Client A view must have a filter on Scenario Id to enable Xpress Insight to dictate on which scenario data to report. If this filter is not available in the view, the view will show an aggregation of data across all scenarios (or for a secure workbook, no data at all). For the purposes of designing a view, it is helpful to set the filter manually to the ID of one or more of the scenarios in the mirror so that Tableau for FICO renders the view with representative data. When published, Xpress Insight will reset the filter to whatever scenario or scenarios are being reported at the time the view is invoked. 1 From the Dimensions pane in Tableau, click Scenario Id and drag it to the

Filters pane to display in the Filter (Scenario Id) dialog box as shown in the following example.

Page 218: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

218 Fair Isaac Confidential and Proprietary

2 From the Filter dialog, click OK.

Restricting the Data Source to Authorities and Authority Groups By using the insight_authorities and insight_authoriy_groups tables provided in the mirror, it is possible to control the data displayed in the view based on security set against the user in the system. For instance, a user could be given an authority that corresponds to a certain region. The workbook author could then restrict the data being displayed in the view to only select data for a certain region matching the specific authority and therefore limit what each user can see.

Note Care should be taken when joining in user authorities against data sources, as a user could conceivably have multiple authorities represented in the data, potentially causing the data to be counted multiple times.

Tableau Global Filters Tableau Global Filters is a feature provided by the Xpress Insight integration with Tableau. It allows a developer to define within the Xpress Insight companion file Tableau filters and parameters whose scope is across multiple views that reside within the same or other workbooks.

Page 219: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 219

Note This feature is only available in the Web Client.

Note Tableau Global Filters are only applied when a view is opened. Changes to a filter in one view will not automatically update in another view.

Defining Tableau Global Filters Tableau Global Filters are defined in the Xpress Insight companion file. These should be located under the tableau element located within the client element must be located after the definition of any view-group elements.

A Tableau Global Filter is defined using a global-filter tag and has a mandatory name attribute. The contents of the attribute should match exactly the filter or parameter name as defined within the Tableau view. These can be obtained from the Filters and Parameters sections of the view when shown within Tableau Desktop. A Tableau Global Filter can have zero or more include or exclude elements. By default it will apply to all views unless one or more exclude elements are defined. When an include element is added the Tableau Global Filter immediately changes so that all views are excluded except for those specifically included. The exclude/include elements have a mandatory workbook attribute and an optional view attribute. These should match exactly with the names of the workbook and view.

Note When a combination of exclude/include elements are defined for a Tableau Global Filter, the include elements are processed before the exclude elements irrespective of the order in which they were defined.

The following shows several examples of the definition of Tableau Global Filters within a companion file.

<client> <view-group title=”Tableau views”> <tableau-workbook title="workbook1" workbook="Workbook1" managed="true"/> <tableau-workbook title="workbook2" workbook="Workbook2" managed="true"/> </view-group> <tableau> <!-- Applied to all views in all workbooks -->

Page 220: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

220 Fair Isaac Confidential and Proprietary

<global-filter name=”MyEx1”/> <!-- Applied to all views except the views in Workbook2 --> <global-filter name=”MyEx2”> <exclude workbook=”Workbook2”/> </global-filter> <!-- Applied to all views except for the MyW2View view --> <global-filter name=”MyEx3”> <exclude workbook=”Workbook2” view=”MyW2View”/> </global-filter> <!-- Applied only to views in Workbook1 --> <global-filter name=”MyEx4”> <include workbook=”Workbook1”/> </global-filter> <!-- Applied only to the MyW1View view in Workbook1 --> <global-filter name=”MyEx5”> <include workbook=”Workbook1” view=”MyW1View”/> </global-filter> <!-- Applied only to the MyW1View and MyW2View views in Workbook1 and Workbook2 --> <global-filter name=”MyEx6”> <include workbook=”Workbook1” view=”MyW1View”/> <include workbook=”Workbook2” view=”MyW2View”/> </global-filter> </tableau> </client>

When defining Filters and Parameters in Tableau that will be used as Tableau Global Filters Several considerations should be taken into account when defining a filter or parameter if it is to be used as Tableau Global Filter. Only String, Boolean and Numeric data types are supported. Tableau Global

Filters using an unsupported data type will be ignored. Only for categorical filters are supported. i.e. filters that are applied by

selecting one or more values via a dropdown, radio button, check boxes or wildcard.

A Tableau Global Filter will be applied to a view even if it does not appear in the list of filters or parameters for the view but does appear in the definition of the data source(s) used by the view.

Page 221: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 221

When defining a Tableau Global Filter ensure that the selection criteria (single, multiple or wildcard) for the any displayed Tableau Quick Filter is the same for all views within the scope of the Tableau Global Filter. The Tableau Global Filter values are applied irrespective to the selection criteria of the Quick Filter as it is not possible for Xpress Insight to discover this from the view. For example on ViewA a Tableau Quick Filter is shown where a user can select multiple values. On ViewB the same Tableau Quick Filter is shown but the user can only select one value. If on ViewA the user changes the filtered values and selects multiple items and then moves to ViewB, the Tableau Quick Filter will only show one item selected in the Tableau Quick Filter but will filter based on the multiple items selected in ViewA.

When defining a Tableau Global Filter ensure that any Tableau Quick Filters relating to a Tableau Global Filter shows all filter values and not just the filter values that relate to the data shown on the view. This is controlled via the Tableau 'Show More/Fewer' feature against a Quick Filter. As the Tableau Global Filter may act across several views it may cause confusion if a user cannot see exactly which filter values have been applied to the view.

Tableau Global Filters in the Web Client When a user opens a Tableau view within the Xpress Insight Web Client any stored values of applicable Tableau Global Filter(s) will automatically be applied. Tableau Global Filter values are stored by the Web Client when the user modifies the filter or parameter within the Tableau view via a Quick Filter or a Parameter selection control. These are stored for a maximum of 12 weeks from the last time they were modified and will persist between and across sessions.

Note The persistence of the Tableau Global Filters values are done client side only. These will be persistence mechanism will attempt to store them in one of the following depending on the browser being used and its configuration: local storage, session storage, global storage, user data or in memory.

Note Tableau Global Filter values that contain commas are not supported and will be ignored.

Note Filtering applied via Keep Only or Exclude options on a mark card is not supported.

Page 222: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

222 Fair Isaac Confidential and Proprietary

Reverting existing Tableau Global Filters To revert any stored Tableau Global Filters click on the Actions icon (cog icon) and click on the Revert Filters link.

This will remove any stored Tableau Global Filters stored for the app and will reload the Tableau view restoring it back to showing the default values as defined in the workbook.

Developing Workbooks for the FICO Analytic Cloud When developing a workbook that will be deployed into the FICO Analytic Cloud the view developer must be aware that the mirror database on the cloud is a MySQL database and not a PostgreSQL database, as supplied in the on premise version of Xpress Insight. When the workbook is published to the Tableau server through Xpress Insight, the Xpress Insight server will perform some simple transformations on the workbook data sources. Due to feature differences between PostgreSQL and MySQL and also differences in the definition of Tableau data sources between Tableau versions, workbooks will be rejected by Xpress Insight if one or more of the following conditions occur: The Tableau workbook was created using Tableau 8.1.x or earlier. One or more of the data sources in the workbook contains a FULL OUTER

join. Warnings will also be displayed if one or more of the following conditions occur: One or more of the data sources in the workbook uses custom SQL. Xpress

Insight cannot guarantee that this SQL will run correctly against a MySQL database.

The workbook uses RAWSQL_ or RAWSQLAGG_ Tableau functions. These can contain SQL. Xpress Insight cannot guarantee that the SQL contained in these will run correctly against a MySQL database.

Page 223: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 223

It is advised that custom SQL data sources, RAWSQL_ and RAWSQLAGG_ Tableau functions are not used in workbooks that are to be published to the cloud.

Tableau Packaged Workbooks (TWBX) Xpress Insight supports the deployment of both Tableau workbooks (TWB) and Tableau packaged workbooks (TWBX). With Tableau packaged workbooks, Xpress Insight imposes that the packaged workbook can only contain the following file types: Tableau workbook and any image files. To create a Tableau packaged workbook click File – Save as within Tableau Desktop and save the workbook as a file type of Tableau packaged workbook.

Note When saving a Tableau workbook as a Tableau packaged workbook you may be asked whether you wish to export the data into an external data source. Please do not accept this.

Note When saving a Tableau workbook as a Tableau packaged workbook a warning message may appear indicating that the workbook may be not usable with Tableau reader. Please accept and ignore this message.

Advanced Mirror Configuration When a user opens a Tableau view, Xpress Insight first ensures the data in the mirror is up to date. Updating the mirror typically takes a few seconds depending on the size of the tables. Xpress Insight can populate the mirror at two stages: post-execution and on-demand when a view is opened. The default behavior offers a balanced approach to mirror population that should be suitable for most apps. Small mirror tables (that is, <50k rows) are automatically populated post-execution. The remaining tables will be populated on-demand. The following describes how this can be controlled at a finer level.

Controlling On-demand Mirror Table Population When a Tableau view is opened Xpress Insight ensures the mirror tables are up to date. Managed workbooks created by Tableau 8.2 or later benefit from faster mirror times; Xpress Insight detects which tables are required by the Tableau view and populates just those tables. This default behavior should be suitable for most apps and is unlikely to need further configuration. However, for unmanaged or pre-Tableau 8.2 workbooks all mirror tables are populated. The mapping between Tableau views and mirror tables can instead be configured. First set the mirror detection to manual for the affected workbook. Then augment the mirror table definition with a sync-for-tableau-views element to control precisely which views cause its population.

Page 224: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

224 Fair Isaac Confidential and Proprietary

The example below configures the facility_clients table to only be populated for all views in the Analysis workbook and the Summary view in the Forecast workbook. If the user opens another view in the Forecast workbook then this table would not be populated, thereby improving the responsiveness of that Tableau view. A mirror table can also be excluded from population for workbooks or views. The example below configures the interval table not to be populated for the Comparison view in the Analysis workbook.

<database-mirror table-prefix="facility_" sync-after-execution="false"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> <sync-for-tableau-view> <include workbook="Analysis"/> <include workbook="Forecast" view="Summary"/> </sync-for-tableau-view> </mirror-table> <mirror-table name="interval"> <entity name="INTERVAL_START"/> <entity name="INTERVAL_DURATION"/> <sync-for-tableau-view> <exclude workbook="Analysis" view="Comparison"/> </sync-for-tableau-view> </mirror-table> </mirror-tables> </database-mirror> … <tableau-workbook title="analysis" workbook="Analysis" mirror-table-detection="manual"/> <tableau-workbook title="forecast" workbook="Forecast" mirror-table-detection="manual"/> …

The include and exclude elements require the workbook attribute, but the view attribute is optional. These should exactly match the names of the workbook and view. include elements are evaluated before exclude elements, regardless of order in the configuration.

Page 225: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 225

Controlling Post-execution Mirror Table Population Mirror population can also be performed when a scenario is executed. Populating the mirror at this stage can improve responsiveness when opening a Tableau view – the table will already be populated. The drawback is increasing execution time and populating the mirror with data that may never be used. By default Xpress Insight automatically populates mirror tables post-execution when they contain up to 50k rows. Larger tables are left to be populated on-demand. This approach balances Tableau view responsiveness, database volumes, and execution time and should be suitable for most apps. This default behavior can be overridden to configure which tables are populated post-execution; whether all, some, or none. Typically, large tables should be mirrored on-demand. Usage patterns within an app may benefit from ensuring a specific large table is always populated post-execution. The data would be mirrored ahead of time, hence opening the Tableau view is more responsive. The following example forces the interval table to always be populated post-execution, regardless of size.

<database-mirror table-prefix="facility_"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> </mirror-table> <mirror-table name="interval" sync-after-execution="true"> <entity name="INTERVAL_START"/> <entity name="INTERVAL_DURATION"/> </mirror-table> </mirror-tables> </database-mirror>

The sync-after-execution attribute on database-mirror determines the default behavior of each mirror table. The following example configures the default post-execution behavior always to populate and the interval table never to populate post-execution.

Page 226: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

226 Fair Isaac Confidential and Proprietary

<database-mirror table-prefix="facility_" sync-after-execution="true"> <mirror-tables> <mirror-table name="clients"> <entity name="CLIENT_LATITUDE"/> <entity name="CLIENT_LONGITUDE"/> <entity name="DEM"/> </mirror-table> <mirror-table name="interval" sync-after-execution="false"> <entity name="INTERVAL_START"/> <entity name="INTERVAL_DURATION"/> </mirror-table> </mirror-tables> </database-mirror>

Page 227: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 227

Page 228: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 228

CHAPTER 8 Accessing the Xpress Insight Server Using the REST API

The Xpress Insight REST API provides a web services interface to the Xpress Insight server. Xpress Insight supports a Representation State Transfer (REST) API to access and interact with the Xpress Insight resources using a fixed set of operations. The Xpress Insight REST API exposes concepts with which end users are familiar; specifically, apps, scenarios and their data, as well as the schema of the model and the execution queue.

Note Detailed documentation on the Xpress Insight REST API can be found in

<installdir>\docs\insight\rest_api\index.html

This documentation covers details regarding available resources, operations and the data model.

Some of these concepts are described in the following sections.

Authentication The supported authentication method is Token-based authentication. Posting a valid username and password to the AuthenticationResource’s login operation will return an authorization token. Subsequent requests should include this token in the Authorization HTTP header to link the request to the Xpress Insight session. For example: Authorization: Token d09ebcd1-e29f-4acf-8c50-959360deeeb1

Each login with token-based authentication results in a separate Xpress Insight session; hence the same user can have multiple concurrent Xpress Insight sessions.

Logout It is recommended that you use the AuthenticationResource’s logout operation to log out of an Xpress Insight session. Sessions will timeout after 30 minutes of inactivity; however an explicit logout will free up server resources immediately.

Page 229: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 229

Mime Types The REST API accepts and produces JSON content using the mime type application/json. For example, the list of apps is retrieved by a GET request to: http://servername:8860/insightservices/rest/v1/data/project

that returns a response similar to: { "start": 0, "maxResults": 50, "count": 3, "items": [ { "id": "c3302770-8bae-451e-8a5f-d5610b1436a1", "displayName": "Chess 2 HTML View", "objectType": "PROJECT" }, { "id": "a0049c9e-3315-4ee7-b54f-5f0196f0b757", "displayName": "Component Examples", "objectType": "PROJECT" }, { "id": "f90267d3-4243-4e39-bb88-8049935336ae", "displayName": "Chess 2 with Insight.Components", "objectType": "PROJECT" } ] }

Identifiers All REST resources are identified by a Globally Unique Identifier (GUID) of the form d09ebcd1-e29f-4acf-8c50-959360deeeb1.

Locking All REST operations are atomic. Relevant locks are automatically acquired at the start of the operation, the changes are then made, and the locks release. No further interaction is required to make changes persistent or to acquire or release locks.

Page 230: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

230 Fair Isaac Confidential and Proprietary

Pagination All operations that return lists of results are paginated to ensure the scalability and performance of the REST API. Requests to a list optionally specify the start position and the maximum number of results to return in the list. To retrieve a large list in its entirety, a request must be made for each page of the list with a suitable start position. The ordering of the list is stated in the REST API documentation referenced earlier in this chapter.

Page 231: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 231

Page 232: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 232

CHAPTER 9 Advanced Topics

Understanding Inter-Scenario Data Access Inter-Scenario data access is a feature that allows an Xpress Insight scenario to use data from another Xpress Insight scenario anywhere else in the repository. Inter-scenario data access can be used to do, for example, the following tasks: Using the results of one scenario in the construction of another Accessing scenarios that contain some common, user-specified data

Using Inter-Scenario Data Access Data from external scenarios can be accessed using the mminsight.scenariodata I/O driver with a standard Mosel initializations-from block. Example (in Mosel model): declarations CITIES: set of string DRIVING_DISTANCES: array(CITIES,CITIES) of real end-declarations initializations from “mminsight.scenariodata:/DrivingDistancesModel/USDrivingDistances” DRIVING_DISTANCES as “CityDrivingDistances” end-initializations

This populates the array DRIVING_DISTANCES with the content of the array CityDrivingDistances from the scenario USDrivingDistances in the model DrivingDistancesModel. The basic format for the initializations from block is as follows: initializations from “mminsight.scenariodata:<repository path>” LOCAL ENTITY_NAME_1 as “ENTITY_NAME_1_IN_EXTERNAL_SCENARIO” LOCAL ENTITY_NAME_2 as “ENTITY_NAME_2_IN_EXTERNAL_SCENARIO” LOCAL ENTITY_NAME_3 as “ENTITY_NAME_3_IN_EXTERNAL_SCENARIO” end-initializations

There is no limitation the number of external entities you can specify. To access more than one scenario, use multiple initialization from blocks.

Page 233: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 233

Repository Paths Scenarios are identified by a ‘repository path’. As with a regular file-system path, this path allows a scenario to be specified by its position in the ‘repository tree’. Each element of a repository path is separated by /. The repository path always starts with /, followed by the name of the model, the name of any folders, all of which are separated by /), and ending with the scenario name, as shown in the following examples: Examples: /MyModelName/MyScenarioName /MyModelName/MyFolderName/MySubFolderName/MyScenarioName

Note You could also specify a scenario’s unique identifier (returned by calling XPRIScenario.getScenarioIdentifier().toString() from the view or client API) instead of using a repository path.

Supported Types The local variables you specify in the initializations-from block must have the same types as the entities in the external scenario. These variables can be any of the types normally supported by Xpress Insight, such as: scalar boolean, integer, string or real set of boolean, integer or string array of boolean, integer, string or real

Additionally, solution values (mpvar or linctr) can be read into local variables of type real. (Similarly, values from an array of mpvar or linctr can be read into an array of real.)

Limitations Access to external scenarios is covered by the standard Xpress Insight access and authorizations system. (For example, a scenario SCEN1 will only be able to read from an external scenario EXT if the user who selected Run for SCEN1 has permission to see scenario EXT.)

Page 234: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

234 Fair Isaac Confidential and Proprietary

Controlling Access to VDL, JavaScript, and Tableau Views

An interface can optionally specify a list of authorities that the user must possess in order for the view interface to be accessible. This is particularly useful to control access to custom or Tableau views.

Note You control access to all views in a Tableau workbook (not individual views). Examples of custom or Tableau View configurations for access control are shown below.

Multiple authorities can be specified, separated by whitespace. The authorities required can be taken from the standard authorities (such as SCENARIO_EDIT), or any custom authorities.

Note The user will need to have all the authorities listed (though not necessarily in the same authority group) in order to access the view.

There is no restriction on what can be specified here. In particular, it is not enforced that the authorities listed in the companion file have to exist on the system. Custom JavaScript View Example <client> <view-group title="Main"> <html-view title="Strategy Dashboard" authorities="PAYGRADE_CEO" path="index.html"/> </view-group> </client>

Custom Tableau View Example <client> <view-group title="Main"> <tableau-workbook authorities="SYS_USER DEVELOPER" workbook="TableauTest"/> </view-group> </client>

Page 235: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 235

An app can specify the custom authorities it depends on in the companion file. These authorities will be created when the companion file is loaded with the app or via the developer update option, if they do not already exist, as shown below: <model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0"> <custom-authorities> <custom-authority>PAYGRADE_CEO</custom-authority> <custom-authority>PAYGRADE_MANAGER</custom-authority> <custom-authority>PAYGRADE_ENGINEER</custom-authority> </custom-authorities> </model-companion>

Multiple Users and Authorization Xpress Insight implements a user authentication and authorization security system. Any client must successfully log in to the Xpress Insight Server with an authenticated set of user credentials before the program can make any requests of the Server. Once a user is authenticated, the authorization system returns a set of authorities for the logged in user. Certain authorities are required to invoke actions by the Xpress Insight Server. The Xpress Xpress Insight Administrators Guide contains a full list of the built-in authorities and the actions they authorize. A user account is associated with one or more authority groups.. Each app has a list of users that are members of that app. A user must be a member of the app to access any of the content of that app. The creator of an app is granted membership automatically. Xpress Insight Administration Interface can be used to assign membership to other users (see chapter 2 of the Xpress Insight Administrators Guide for more details). Each folder and scenario has an owner and a share status. By default the owner is the user who created the object although ownership can be changed for existing objects. There are 3 levels of share status: private, read-only and full. When an object is created it inherits the share status of its parent folder (in the case of objects created in the app root, the share status will be private). The share status and ownership attributes of an object dictate which users have access to the object, and what actions are allowed on that object. In general only the owner of a private object can view and edit that object (the exception to this is a user who has the SCENARIO_ALL privilege that grants access to any object). All members of the app can view (but not edit) read-only shared objects owned by other users. All members of an app can view and potentially (if possessing the required authority to edit the object) edit an object shared fully. Share status and ownership can be set by any user who can edit the object in question.

Page 236: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

236 Fair Isaac Confidential and Proprietary

Building Apps that use the Decision Tree Editor If the app you are building generates or imports FSML decision trees, you can make it possible for your users to be able to edit the trees as attachments. To integrate this functionality, three attachments are required:

• The FSML decision tree itself, tagged as decision-tree. PMML decision trees are not currently supported by Xpress Insight.

• An input data file in CSV or ZIP format tagged as decision-tree-data. Note that Xpress Insight has an upper size limit of 150MB for all attachments.

• A JSON configuration file that is either tagged as decision-tree-cfg or has the same name as the decision tree itself (preferred). This file provides important metadata to the decision tree editor. An example: { "decisionKeys": [ { "name":"DK1", "displayName":"Decision Key 1", "type": "real" }, { "name":"DK2", "displayName":"Decision Key 2", "type": "string", "constraints": ["category1", "category2"] } ], "treatments": [ { "actionId": "1234", "name":"T1", "displayName":"Treatment 1", "type": "string" } ], "profileVariables": [ { "name":"PV1", "displayName": "Profile Variable 1", "type":"counts" }, { "name":"PV2", "displayName": "Profile Variable 2", "profileType":"categorical", "categories": ["category1", "category2"]

Page 237: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 237

} ], "sampleWeight": "mySampleWeightVar" }

The file identifies: • Decision keys • Treatments • Profile variables • Sample weight – the name of a column to be interpreted as a sample

weight for each row See the Xpress Insight Web Client Users Guide for a detailed overview of the facilities provided for end-user decision tree editing.

Page 238: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

238 Fair Isaac Confidential and Proprietary

APPENDIX A Upgrade Guide

Migrating from Companion File 2.0 to 3.0 and using Mosel Annotations

Mosel annotations are now used to configure the model and entities, as opposed to the previous way of using both the mosel file and the companion file. Global annotations are those that apply to the whole model, and they are placed before any of the entity declarations but after any import statements. Where the companion file previously had <resultsdata delete="on-execute"/>, this option is now a global mosel annotation, insight.resultdata.delete. This can be set to any of the values on-change/on-queue/on-execute. A new addition to the configuration options are execution modes. The namespaced annotations insight.execmodes.[execmodeName] allow the developer to add descriptions and other options, which are fully shown in the Xpress Insight Mosel Reference. There are several entity specific annotations that allow for customization of entities within the model. These replace the <entity> tag in the companion file including its attributes and child tags. These are placed in the mosel file, right above the entity declaration, or a declarations block. Examples of how these are used as annotations within the mosel are as follows: [email protected] Days [email protected] true [email protected] true

There are various other annotations that can be applied to an entity, such as for sorting, formatting and transformations. For a full list of these options and the syntax, please refer to the Xpress Insight Mosel Reference.

Note You must use a version 4.0 companion file for Xpress Insight to recognize insight annotations within your model.

Note Existing applications which use version 2.0 of the companion file are unaffected by this change and will continue to work as before.

Page 239: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 239

Migrating VDL 2.0 apps to VDL 4.0 There are several steps to take when converting a VDL 2.0 app to VDL 4.0 1. Change the VDL version of your .vdl file 2. Namespacing tags and attributes 3. AutoText changes 4. Convert custom runner code to script blocks 5. Table modifiers 6. Remove custom runner references from c-file 7. Remove handlebars reference, replace with VDL 4.0 equivalents

Change the version of your VDL file The root tag needs to be: <vdl version="4.0">

Namespacing tags and attributes In VDL 3 the decision was made to namespace all non HTML5 tags. Also vdl extension attributes, where they are used on HTML tags should be namespaced as well. The format for namespacing is two words separated by a hyphen, as in:

<vdl-page>

The vdl namespace (the first word) is used for core extensions both for tags and attributes. The VDL Reference is your guide for renaming VDL 2.0 tags to the namespaced VDL 4.0 versions. In many cases it is the same tags with 'vdl-' prepended. The obvious exceptions are the tags that were referenced as autotable , autoform etc.. These are now:

<vdl-table> <vdl-table-column> <vdl-form>

In addition the autotext tag has been removed and VDL 4.0 now has the vdl-text attribute extension as mentioned below.

Page 240: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

240 Fair Isaac Confidential and Proprietary

For your own custom extensions you should choose a namespace relevant to your organisation, or your application or the function of the extensions. E.g.

<ibm-panel> <office-text> <d3-piechart>

Would all be acceptable namespaces.

AutoText changes Where VDL 2.0 had the autotext and text tags, VDL 4.0 has the single attribute 'vdl-text'. This attribute enables the developer to expose the values of Mosel entities from the model, scenario properties and numerous other values which are available at run time.

<p vdl-text="=scenario.entities.MyScalar"></p>

This would then add the value of the MyScalar entity as child text to the paragraph(p) tag. Most VDL and HTML tags can accept the vdl-text attribute as long as they are capable of displaying text. This extends the abilities of autotext by allowing the value of any dynamic expression to be displayed.

Convert custom runner code to script blocks In VDL 2.0 the custom runner file allowed the view developer to layer on extra scripted functionality. This generally took the form of:

insight .getView().applyVDL('#main', function () { // custom code here });

Which was placed in a script block in carefully constructed html that made up the custom runner which was referenced from the runner attribute in the companion file. This is no longer needed. VDL 4.0 now allows script blocks to be placed within the view, or in linked JavaScript libraries, and this removed the need for a separate custom runner file.

Table modifiers One of the main uses for a custom runner was to add functionality to AutoTables. The vdl-table tag, which is the VDL 4.0 version of the VDL 2.0 autotable-tag, has a modifier attribute which accepts a single function reference as an expression.

<script>

Page 241: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 241

function modifierFunc(config) { // do something with config object as needed return config; } </script> <vdl-table modifier="=modifierFunc"></vdl-table>

The modifier function is called with the existing AutoTable config and it is required to alter this config and return it for further customization of the AutoTable.

Remove custom runner references from c-file Remove any references to custom runners in the Companion File. This is the 'runner' attribute on vdl-view tags.

Remove Handlebars references In VDL 2.0 dynamic access to some entities, scenario properties and loop variables was achieved with the so-called 'Handlebars syntax'. This has been replaced in VDL 4.0 with the much more powerful dynamic expressions feature. Following are some examples of how you would convert from one to the other:

Example 1 Scenario {{scenario.name}} was created on {{scenario.creationDate}}. Scenario <span vdl-text="=scenario.props.name"></span> was created on <span vdl-text="=scenario.props.creationDate"></span>.

Example 2 There are {{scenario.CHANNELS.length}} channels. The first channel is named {{scenario.CHANNELS.0.label}} and it has a value of {{scenario.CHANNELS.0.value}}. The second channel is named {{scenario.CHANNELS.1.label}} and it has a value of {{scenario.CHANNELS.1.value}}. <p>There are <span vdl-text="=scenario.entities.Factories.length"></span> factories.</p> <p>The first factory is named <span vdl-text="=scenario.entities.Factories[0]"></span>.</p> <p>The second factory is named <span vdl-text="=scenario.entities.Factories[1]"></span>.</p>

Page 242: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

242 Fair Isaac Confidential and Proprietary

Example 3 <section repeat="s in scenarios"> Scenario results for {{s.name}}: ... </section> <vdl-row vdl-repeat="=sc in scenarios"> Scenario results for <span vdl-text="=sc.props.name"></span> … </vdl-row>

Upgrading to Xpress Insight 4.2

Changes to mminsight All of the functions and procedures in mminsight have been renamed or replaced with an alternative API. All of the old functions and procedures are deprecated. The old names are still available as aliases, but you are advised to update your model to use the new names. The deprecated functions and procedures are as follows: Table 2.

Original function/procedure Replaced with

insight_use_original_data insightgetmode

insight_end_initializations insightpopulate

insight_results_available insightresultsready

insight_prepare_constraints insightpreparectrs

insight_minimize insightminimize

insight_maximize insightmaximise

insight_update insightupdate

insight_update_progress insightupdateprogress

insight_reset_progress insightresetprogress

See Chapter 2, section How Xpress Insight Interacts with a Mosel Model, for best practice usage of the new functions.

Page 243: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 243

The mminsight reference documentation is now located at <installdir>\docs\insight\mminsight\.

Upgrading from Xpress Insight 4.0 or earlier Mosel models compiled with Xpress Insight 2 (Xpress 7.7) or earlier will not work correctly after upgrading to Xpress Insight 4.1. If you have Mosel models that have not been recently compiled, rebuild them against the latest installation of Xpress/Xpress Insight to resolve any issues. The mminsight package must now be used at the top of the model, before using any other packages. If this is not the case, you may see an error message when creating the project referring to incomplete entity definitions. Compiling your model with the “-s” (strip private symbols) option may result in some entities not being available in Xpress Insight. If this occurs, ensure that the relevant entities are declared within a public declarations block.

VDL 2.0 For pure VDL views, i.e. not using a custom runner, the only change that should be necessary is to change the VDL version number in each page.

<vdl version="2.0">

Version 2.0 includes a major rework of page styling so things will look different. But any purely VDL structures and components should remain working. If you have used any of the previous Bootstrap CSS or element structures then you will need to migrate these to Bootstrap 3. For any views where you are using a custom runner you need to make sure you upgrade the version number in your VDL source file, as mentioned above. But you also need to upgrade the JavaScript API version number to 4.0 in the HTML file. Take a look at the default VDL runner for version 2.0 to see what needs changing: <installdir>\insight\lib\javascript\default-vdl-runner-2.0.html

Page 244: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

244 Fair Isaac Confidential and Proprietary

JavaScript API 2.X When upgrading a custom VDL runner or a JavaScript API view from version 1.4 or earlier to version 2.0 or later you need to take the following into account:

Various API calls have been made asynchronous, returning promise objects. You can no longer get a reference to a scenario synchronously, using the old

View#getSelection and View#getFirstScenario methods. You will need to wrap your code in scenario observers.

The only way to access scenario data is through scenario observers. To modify scenario data you need to first get a ScenarioDataChange object

for that scenario. You also need to call ScenarioDataChange#commit before the data is saved.

Most of the calls on ScenarioDataChange to update entities are named the same and accept the same arguments as the previous versions of the API.

If you have any calls to ScenarioObserver#notifyLocalChange you should remove them. Local change events are now automatically generated after changes have been applied successfully on the server.

Because a lot of the JavaScript API has become asynchronous this will have the knock-on effect of making your view code asynchronous. Some parts of your code will have to be split into callbacks that can be invoked when these promises resolve. In some cases you can chain the promise objects returned by the API, using the Promise.all() static method for example. JavaScript API 2.X removes the events for scenario job execution from the ScenarioObserver. This was problematic in the past and could lead to design issues in the view. The ScenarioObserver#onStateChange method has been replaced with ScenarioObserver#withSummaryData and the main difference is that now it will not issue updates to your scenario observer during execution. To refactor your views so that they do not need to monitor scenario job execution you may need to augment the Mosel model with some state entities that both the view and the model can update. This way you can detect when a view transitions to the next state after the model has been run. Your view state will then be driven by entity data rather than a sequence of user actions and scenario job execution. Information about the model solution has been moved from the Scenario object onto the ScenarioSummaryData object. It is easy to get the summary data.

var summary = scenario.getSummaryData(); summary.getObjective(); summary.getModelStatus(); summary.hasResultData();

Page 245: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 245

If you do need to get the current execution status this is now an asynchronous call and will return a promise:

scenario.getCurrentExecutionStatus().then(function(status) { status.getNumberOfSolutions(); status.getStatus(); });

The current execution status is passed into the resolve callback of the promise and you can use that object as you did in previous JavaScript API versions. If you need to monitor the execution status then you will need to call this on a regular interval to get the current status.

Migrating to Bootstrap 3 JavaScript API 2.0 and later introduce Bootstrap 3 as the framework for HTML layout and styling. Some work will be required to migrate existing views to JavaScript API 2.X because of this. Bootstrap 3 changes a lot of the expected HTML structures and CSS class names as well as adding new components and removing some old ones. The Bootstrap documentation website goes into detail about what has changed and how to use Bootstrap 3, see http://getbootstrap.com/getting-started. The core concept of Bootstrap has not changed. There is still a 12 column grid system and a choice between fixed and fluid layouts. When following the Bootstrap documentation please be aware that we have themed Bootstrap to follow the Xpress Insight style. This is mainly changes to the fonts, colors, padding and margin. We have also disabled responsive layout so the different column size classes will all have the same behaviour, e.g: col-xs-3 == col-md-3 == col-lg-3. This means that your view will not change to stack columns when it becomes very narrow. Also, views will default to a fixed width of 1170px.

Loading the JavaScript API Custom HTML views developed against JavaScript API 1.2 or earlier used the RequireJS module system to import the JavaScript API into each view. Since Xpress Insight 3.2 the API that no longer uses RequireJS. Include the JavaScript API directly:

<script src="$distrib/insight-4.0.js"></script>

This import defines a global variable, insight, which is the top-level namespace object for the API.

Page 246: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

246 Fair Isaac Confidential and Proprietary

Your JavaScript code still needs to be wrapped in a function that will be executed when the API is ready, but instead of using the require function, call insight.ready:

insight.ready(function () { // Your view code here });

Note In earlier versions, the insight API object was made available to you via an argument that you defined in your callback function, like this:

require('insight-api-1.2', function(insight) { // The API used to be available via local variable insight });

This is no longer the case, and you should remove all arguments to any callback function that is passed to insight.ready function, to avoid the global insight variable being shadowed by a local argument variable with the same name. You may find that the old argument had a different name, such as Insight, in which case, any references to it will need to be renamed. As in previous releases, the latest JavaScript API ships with several third-party libraries, including jQuery. Once you have imported insight-4.0.js, these libraries are available for use in your custom view without having to explicitly include them. Any other libraries that you need in addition to these should be included after insight-4.0.js. In previous releases, you may have used RequireJS to do this, but with the 2.X API you include them using a simple <script src="..."> tag. See Third Party Libraries Bundled with Xpress Insight Javascript API for a full list. Here is a complete example of how to import the API, also demonstrating that jQuery is available without being explicitly imported.

Page 247: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 247

Note The path to the Xpress Insight stylesheet has changed slightly too:

<html> <head> <link type="text/css" rel="stylesheet" href="$distrib/insight-4.0.css"/> <script src="$distrib/insight-4.0.js"></script> <script> insight.ready(function () { var view = insight.getView(); // etc... }); </script> </head> <body> etc... </body> </html>

New Companion File Format The format of the companion file has changed since release 3.1 of Xpress Insight. The most significant change is a simpler and more intuitive way to define custom views for the app. Here is a simple companion file in the new format that illustrates how to define several custom views:

<model-companion xmlns="http://www.fico.com/xpress/optimization-modeler/model-companion" version="3.0"> <client> <view-group title="Main"> <html-view title="Welcome" path="welcome.html" empty-selection-default="true"/> <vdl-view title="Inputs" path="input.vdl" default="true"/> <tableau-workbook workbook="ExampleWorkbook"/> </view-group> <client-resources-local-path>C:\example_app\client_resources </client-resources-local-path> </client> </model-companion>

Page 248: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

248 Fair Isaac Confidential and Proprietary

The two new attributes at the document root, xmlns and version, indicate that this is a version 2 companion file. The <client> tag contains one or more view groups, in which the custom views are defined. Apps containing old-style companion files can still be imported - the companion file will be automatically upgraded and the new version will be printed to the Client Log window. It is recommended that you replace your old companion file with the upgraded version.

Summary of Companion File Changes There is a new mandatory attribute, version, on the <model-companion>

tag, which must have a value of "2.0". The XML namespace attribute (xmlns) is mandatory on the <model-

companion> tag. The <client> tag no longer has an id attribute. The <interfaces> and <interface> tags have been removed. Views are

now defined within one or more <view-group> tags, which contain <*-view> tags specific to the view type.

Custom views must be explicitly declared using the <custom-view> tag, or they will not be visible in the UI.

All interface attributes now appear on the <*-view> tag, including: - title (was text) - id - authorities - default

New requires-scenarios-loaded attribute on view tags, which can be set to false to make a view available when the current scenario has not been loaded. This is useful when creating a custom view for editing model parameters before loading a scenario.

The <version> tag has been renamed to <project-version>. The authority names listed in the authorities attribute for a view must be

space-separated (previously, they could be comma-separated). The <client-resources-local-path> tag is valid only within the

<client> tag. The <object-type-defaults> tag is obsolete; the default action when

double-clicking a scenario is to open the default custom view. The baseline-only attribute on model resources has been renamed to

load-only.

Page 249: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 249

The other sections of the companion file remain largely unchanged from release 3.0: Schema Model resources Database mirrors Custom authorities

Page 250: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

250 Fair Isaac Confidential and Proprietary

Page 251: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

Fair Isaac Confidential and Proprietary 251

APPENDIX B Third-party Libraries Bundled with Xpress Insight JavaScript API

The following libraries are bundled with the Xpress Insight JavaScript API 4.0 and are available to custom view developers automatically. Using a different version of any of these libraries within a custom view is not recommended. Table 3. Libraries bundled with Xpress Insight JavaScript API

Library Version Description Global variable

es6-promise 3.0.2 A polyfill library for the JavaScript Promise object.

Promise

jQuery 2.2.3 General-purpose library. $

jquery-numberformatter 1.2.3 Number formatting and parsing. n/a

jquery.debugPath 1.0.0 Debug logging of DOM element locations.

n/a

DataTables 1.10.7 Displays data in tables. $ - a jQuery plugin

Bootstrap 3.3.2 Responsive HTML layouts. $ - a jQuery plugin

DataTables/Scroller 1.2.1 DataTables plugin for scroll-style paging.

n/a

Lodash 3.10.1 Functional programming library. _

Bootbox.js 4.4.0 Modal dialogs. bootbox

jshashtable 2.1 HashTable collection library, required by jquery-numberformatter.

Hashtable

plotly.js 1.26.1 Client-side charting for the web. Plotly

Moment.js 2.10.3 Time and date formatting. moment

postal.js 0.12.3 Publish/subscribe library. postal

KnockoutJS 3.4.0 MVVM framework ko

Page 252: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

252 Fair Isaac Confidential and Proprietary

Page 253: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

Fair Isaac Confidential and Proprietary 253

APPENDIX C Contacting FICO

FICO provides clients with support and services for all our products. Refer to the following sections for more information.

Product Support FICO offers technical support and services ranging from self-help tools to direct assistance with a FICO technical support engineer. Support is available to all clients who have purchased a FICO product and have an active support or maintenance contract. You can find support contact information on the Product Support home page (www.fico.com/support). On the Product Support home page, you can also register for credentials to log on to FICO Online Support, our web-based support tool to access Product Support 24x7 from anywhere in the world. Using FICO Online Support, you can enter cases online, track them through resolution, find articles in the FICO Knowledge Base, and query known issues.

Product Education FICO Product Education is the principal provider of product training for our clients and partners. Product Education offers instructor-led classroom courses, web-based training, seminars, and training tools for both new user enablement and ongoing performance support. For additional information, visit us at www.fico.com/education or email [email protected].

Product Documentation FICO continually looks for new ways to improve and enhance the value of the products and services we provide. If you have comments or suggestions regarding how we can improve this documentation, let us know by sending your suggestions to [email protected].

Page 254: Developer Guide - examples.xpress.fico.com · Features of Xpress Workbench – a modern development environment for Xpress Insight apps - are documented in the Xpress Workbench User

FICO Xpress Insight Developer Guide

254 Fair Isaac Confidential and Proprietary

Sales and Maintenance USA, Canada, and all Americas:

- Email: [email protected] Worldwide:

- Email: [email protected] - Tel: +44 207 940 8718

Fax: +44 870 420 3601 Xpress Team FICO House International Square Starley Way Birmingham B377GN UK

Related Services Strategy Consulting: Included in your contract with FICO may be a specified amount of consulting time to assist you in using FICO Xpress Insight to meet your business needs. Additional consulting time can be arranged by contract. Conferences and Seminars: FICO offers conferences and seminars on our products and services. For announcements concerning these events, go to www.fico.com or contact your FICO account representative.

About FICO FICO (NYSE:FICO) delivers superior predictive analytics solutions that drive smarter decisions. The company’s groundbreaking use of mathematics to predict consumer behavior has transformed entire industries and revolutionized the way risk is managed and products are marketed. FICO’s innovative solutions include the FICO® Score—the standard measure of consumer credit risk in the United States—along with industry-leading solutions for managing credit accounts, identifying and minimizing the impact of fraud, and customizing consumer offers with pinpoint accuracy. Most of the world’s top banks, as well as leading insurers, retailers, pharmaceutical companies, and government agencies, rely on FICO solutions to accelerate growth, control risk, boost profits, and meet regulatory and competitive demands. FICO also helps millions of individuals manage their personal credit health through www.myfico.com. Learn more at www.fico.com. FICO: Make every decision count™.