Reader small image

You're reading from  Learning Pentaho CTools

Product typeBook
Published inMay 2016
Reading LevelIntermediate
PublisherPackt
ISBN-139781785283420
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Miguel Gaspar
Miguel Gaspar
author image
Miguel Gaspar

Miguel Gaspar started working at Webdetails about 3 years ago, some time before the acquisition of Webdetails by Pentaho. He was a consultant in the Implementation team and his work involved developing dashboard solutions as part of services. He is now acting as the technical owner of some of the Implementations projects as part of the Webdetails team in Pentaho. He likes to be as professional as possible, but in an informal way. One of his favorite hobbies is learning and his particular areas of interest are: business analytics, predictive analysis and big data, augmented reality, and cloud computing. He likes to play and is a huge martial arts fan and also one of the worst soccer players ever. He is married and a parent of two young and lovely daughters, who would like to spend more time playing like crazies with him. He also likes to spend time with friends or just having a drink and a good talk with someone else, if possible with his family at his side. He really hates liars.
Read more about Miguel Gaspar

Right arrow

Chapter 3. Building the Dashboard Using CDF

There are two ways to build the community dashboards: using the Community Dashboards Framework (CDF) or the Community Dashboard Editor (CDE). You could leverage some of the work and do it faster when you are using the second option, but behind it, we will still be using CDF. You could choose not to read this chapter, but to have proper knowledge of how the CDE works, and to achieve better results, you should be able to understand the concepts behind the CDF API. In this chapter, you will get the chance to see the lifecycle of the dashboard and its components. Pentaho uses the CDF framework on the platform, so acquiring knowledge about how to use CDF can be an advantage when using other tools than CDE.

While covering CDF, we will present to you some of the most important and commonly used methods/functions available for this tool. Of course, we need to start covering the components and get them working. Sending parameters to the queries is an important...

Understanding the basics of a CDF dashboard


We have already mentioned that CDF will work on the browser as a HTML page that will make use of the JavaScript and CSS languages, frameworks, and libraries.

But how does CDF really work? When we are making a request to the Pentaho platform to get a dashboard, we make a request to a Pentaho plugin. That request is done through the Web API that the plugin is providing on the server side. This server-side code is written in Java, and by reading the dashboard's files, will send the HTML and JavaScript code to the browser for the execution of the dashboard on the client side (the browser). This code will include some scripts that are mandatory so that the plugins can execute themselves in the browser. The number of libraries may vary depending on the components included. The following image is a really simple diagram that should give you a clear understanding of how the requests to get the dashboards are handled:

Lifecycle of dashboards and components...

Using components inside the dashboards


We have not really covered the concept of a dashboard if we do not show any Key Performance Indicators (KPIs), charts, tables, and so on. CDF provides many components we can use to create the dashboard. To use them, we just need to extend the code we used previously. You saw that we need to include the modules we will need. Each component is a module that has its own dependencies that will be loaded automatically when we include the component.

The previous example shows the code that should be placed inside the XCDF file. This code creates a dashboard with a simple text component that returns a simple Hello World! message.

If you look at the code, you will find that we are including the dashboard module and also the component module. You will see that we are already using the Bootstrap framework. For this case, we are also including cdf/components/TextComponent, the module that makes it possible to use a text component, one of the simplest components...

Defining data sources for components


We don't want static dashboards, we want to query data to be shown in them. There are two ways to set queries in components. The data sources can be of one of two types, CDA and non-CDA:

  • Going the CDA way, you need to define it using the query it's defining, inside the component, an object such as queryDefinition or chartDefiniton depending on the component, with a set of properties:

    • path: This is the path that points to a CDA file. You can make use of the CDA files created as explained in the chapter dedicated to CDA.

    • dataAccessId: This should set the ID of an available data source, also covered in the CDA chapter, that is set in the file we are pointing at.

  • Going the non-CDA way, by just using a simple SQL or MDX query, we can define, inside the component, an object queryDefinition or chartDefiniton, depending on the component, with a set of properties:

    • queryType: This is the type of the query selecting one of the two values available, mdx or sql.

    • jndi...

Creating and using parameters in data sources


You can see a parameter as a variable which is storing some value. In the last example, we created a parameter, and now we want to make use of it so we can send it to the query and have queries that can give back different results, depending on the input. To achieve this, we need to have a parameter inside the query in a way that we can later pass some value through the parameter. You already saw how to create parameters in the queries and how to set default values. Now we want to send a value to the query that can change depending on the user interaction, so the user can get the intended results, and have a proper visualization with the correct information in it:

require(['cdf/Dashboard.Bootstrap', 'cdf/components/TableComponent'], 
   function(Dashboard, TableComponent) {
      dashboard = new Dashboard();
      dashboard.addParameter('marketDashParam','[Markets].[All Markets]');
      var path = dashboard.context.path;
      var dashPath =...

The importance of listeners inside the components


We do not want our users to be executing code and making the changes. What we want is to have a way to let the components know that they need to update themselves when a change happens in the dashboard. That's the purpose of the listeners. You could say that a component should be listening for the changes in the parameter(s) that exist in the dashboard. Components have a property called listeners, which you should define as an array. When creating a dashboard, what do you think provides the user with the ability to interact with the dashboard during runtime? The answer is, mostly the listeners.

In the console of your browser, run the following lines:

dashboard.setParameter('marketDashParam', '[Markets].[EMEA]');
var component = dashboard.getComponentByName('top50Customers');
component.update();

The first line of the code is used to change the value of the dashboard parameter, the second is to get the component instance, and the last one is to...

Interaction between components


However, this is not enough—you need something more, because we still need to execute a line of code to make changes happen. If you make a filter available to the user, a dropdown for instance, which makes them able to apply changes to the table, they will not hesitate to use it. I am pretty sure you will want to do this, if not with a dropdown, then with a date selector, a button, a radio button, a checkbox, a simple text box, or whatever you can think of where the user can make a change or selection.

The first step is to add some kind of component that can provide interaction with the user. For our purposes, let's use a simple dropdown. The following code is an example of how to create a new instance of a select component:

new SelectComponent({
       name: "marketFilter",
       type: "selectComponent",
       parameter: "marketDashParam",
       valueAsId: false,
       queryDefinition: {
         path: dashPath+"/customers.cda",
          dataAccessId: ...

Using preExecution and postExecution


The preExecution and postExecution functions are very similar concerning their usage, but different in their purposes.

The first one, preExecution, you can see as preparing the execution of the component. One really good example is to point to another data source, or even to a different CDA file. Let's suppose you have multiple queries that are used in multiple dashboards, and you want to have a simple file where all the common queries are placed. This is possible to change with just a couple of lines of code in the PreExecution function.

Another good example is when you want to have cascading parameters. Let's suppose you want to have a selector where you can choose between the market level (country or city), and the second filter will show you countries or cities depending on what you have selected for the first one. The first will drive the query for your second filter, and so the values to select will vary between country or city. The following code...

Understanding how to work with postFetch


In the Steel Wheels sample data, which we have been using in our examples and is available with the standard installation of Pentaho, we have one territory showing in the selector as having a #null value. This description is not friendly to the end user, so we may make a change, thereby manipulating the result set that we get from the execution of the query. With this, we can change the description of #null to something like NA.

The following code is for the territory selector component, where we just added a function to define the code to be executed on the postFetch function:

dashboard.addComponent(new SelectComponent({
                name: "territoryFilter",
                type: "selectComponent",
                parameter: "territoryDashParam",
                valueAsId: false,
                queryDefinition: {
                path: dashPath+"/customers.cda",
                dataAccessId: "territories"
              },
                htmlObject...

Using preChange and postChange


Now it's time to cover preChange and postChange. These two functions will only be available in components whose main purpose is to be used as filters. Examples of this are select, input, date range, radio button, button, multi button, and so on.

Every component where we can set a parameter to store the selections and the lifecycle of the component will trigger fireChange to that parameter. We have the option to specify the function that will be executed both before this happens and after applying the changes to the parameter, preChange and postChange. Take a look at following image:

As you can figure out, that the first function, the preChange function, can be used to execute the code that can validate the options and take some actions before changing the parameter value. Can be used to prepare something before other components starts to execute because they are listening to that same parameter. The other postExecution function, can be used to perform operations...

Priority of component execution


The order of the execution of the components will depend on another property for each component. The priority property should be set using integer values. Lower values as higher priorities. The default value of the property is 5. The components with the same priority are executed at almost the same time and they are executed in an arbitrary order, but during the same routine. If a different and higher priority is set for a component, it will only be executed after the ones with a lower priority are executed. Each similar priority will correspond to a cycle, where it will start with the execution of the components, and will end after the last component that has the same priority finishes.

Inside a dashboard, to change the order of execution of the components, you just need to change the priority property and set another value.

Let's look at the following example where we have five components:

  • Components 1 and 2: priority 5

  • Components 3: priority 10

  • Components 4...

Available components and properties


When defining new components, you need to define a set of properties that define the object and/or the behavior. The generic and mandatory properties of all/almost all the components are:

  • type: This property assumes a variety of values such as tableComponent, buttonComponent, selectComponent, and so on, depending on the component that is used.

  • name: This is the unique identifier of the component inside the dashboard.

  • listeners: Will accept an array of a strings with the name of the parameters. If a value on each one of those parameters changes, the component will be updated. This array is crucial to create interaction among components.

  • parameters: This accepts an array of arrays, where each array will have the name of the parameters of the query and the parameters of the dashboard with the value to be used.

  • parameter: For components where user input is required, this is where the input is stored to be used later.

  • htmlObject: This is the ID of the HTML...

Adding resources – JavaScript and CSS


You already saw how to create a new dashboard, and add components, but you haven't yet seen how to include JavaScript and CSS code, which is available in CDF. I always like to add my JavaScript files with the code for the project/dashboard. Regardless of whether we are creating a dashboard or multiple dashboards in a project, we should always develop it while bearing in mind that we may need to have multiple dashboards, and some of the code and style could be reused for these multiple dashboards.

If you are building dashboards that are similar to each other, you should rethink the way you are creating or designing your dashboards. A dashboard can be flexible in a way that will let you change the behavior and the data to be displayed in an easy way, without too many components and or too much logic.

Let's suppose we are creating four dashboards and all the dashboards will share the style, but also will have different components. Some of the components will...

Dashboards utilities


There was once a time when we needed to add libraries as external resources to leverage the process of formatting dates and numbers. Nowadays, it is possible to do the formatting without the need to include external files. We can do the formatting just by including the cfd/dashboard/Utils module. This will make require load all the dependencies without any more effort.

Formatting numbers

Numbers can be formatted to look like currency, percentages with decimal places, thousands, and abbreviations. To format numbers, you should use the function numberFormat, available in the dashboard object. In our examples, you could do this by calling Utils.numberFormat(value[, format[, langCode]]). The function accepts the arguments; the first one is the value to format, the second one is the format mask, and the last is the language and locale to use when formatting the number.

The mask or format argument is a string made up of symbols that shows how to format the number. The most commonly...

Dashboard storage


It's now possible to maintain parameter states between different sessions. Instead of using simple parameters, objects inside the special namespace storage can be saved and restored.

Dashboards can store values as per the user preferences. Let's suppose you have a dashboard where you want to persist the status next time you get on the dashboard. It's possible to do this with the storage functionality of CDF. Each time that the function dashboard.saveStorage() is called, CDF will store the content of the dashboard.storage object. When the dashboard is loaded for that user, the dashboard will have access to the object dashboard.storage where all the collections (objects and arrays) or functions are defined.

Tip

Don't forget to save the storage:

Storage will only be saved on the server side after running the dashboard.saveStorage()function; otherwise if you refresh the dashboard before saving it, you will notice that you have lost the last changes before the last save.

You can...

Dashboard context


When the dashboard loads, there is also an object that will be available to get some information about the context where the dashboard is running. This object can be accessed using the variable that is instantiating the dashboard. Let's check the content of the object:

  • user: This is the ID of the user that is logged in

  • roles: This is an array of strings that contains the roles associated with the user

  • serverLocalDate: This is the timestamp of the server

  • serverUTCDate: This is the UTC timestamp on the server

  • sessionTimeout: This is the time timeout interval for the session

  • path: This is the dashboard path in the Pentaho repository

  • locale: This is the language and locale that is set on the Pentaho server for the logged in user

Sometimes there is the need to add some more information when generating the dashboard, so CDF gives you the capability to add that information, and you are able to do this in two ways: using values from session variables directly in Pentaho, or using...

Useful functions of the CDF API


CDF provides a list of methods/functions that you can and should use when building the dashboards. Next, you will find some of the most used functions.

Functions from the dashboards module:

  • init(components): This function is used to start the execution of the dashboard. You have seen this function in our examples. It receives an argument and an array of the components to execute. This function can be called without any argument, but in this context we need to add the components to the dashboard using the addComponents function.

  • addComponents(components): This function accepts an array with the components to add to the dashboard.

  • addComponent(component): This is the same as the previous function, but will just add one component.

  • removeComponent(component): This will remove a component from the list of the components of the dashboard.

  • getComponentByName(component): This returns the component with the name specified as an argument.

  • update(component): This will...

Summary


CDF is the API to create dashboards and reports. By this point, you should understand the concepts behind the lifecycle of the dashboard and components. You should also know how to create a dashboard using the CDF API, and know the most part of the available methods, which are very important when creating advanced dashboards. We also covered a very important topic related to the use of parameters and listeners to create interaction among components.

Of course, you have a lot more to learn, and there are some more advanced concepts that we will cover in the following chapters.

In the next chapter, we will start covering CDE, and how to build a dashboard in an easier and faster way than by just using CDF.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learning Pentaho CTools
Published in: May 2016Publisher: PacktISBN-13: 9781785283420
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Miguel Gaspar

Miguel Gaspar started working at Webdetails about 3 years ago, some time before the acquisition of Webdetails by Pentaho. He was a consultant in the Implementation team and his work involved developing dashboard solutions as part of services. He is now acting as the technical owner of some of the Implementations projects as part of the Webdetails team in Pentaho. He likes to be as professional as possible, but in an informal way. One of his favorite hobbies is learning and his particular areas of interest are: business analytics, predictive analysis and big data, augmented reality, and cloud computing. He likes to play and is a huge martial arts fan and also one of the worst soccer players ever. He is married and a parent of two young and lovely daughters, who would like to spend more time playing like crazies with him. He also likes to spend time with friends or just having a drink and a good talk with someone else, if possible with his family at his side. He really hates liars.
Read more about Miguel Gaspar