Hey everybody!

This blog assumes you have some experience creating applications with SAP BusinessObjects Design Studio with CSS and scripting.

Last time out in Extending Design Studio with an HTML extension and HTML bars I showed you how to use HTML (and avoid script injection) to create a comparison bar for SAP BusinessObjects Design Studio, so you could make something that looks a bit like this:

HTML_layout_and_bars.png

Now, I will show you how to use that HTML within Design Studio including how to update it at runtime with real data.

Pre-requisites

You can find links to these in the resources section below…

For this you will either need an understanding of HTML and scripting in Design Studio as well as:

  1. The HTML extension and the Design Studio SDK sample KPI Tile extension installed.
  2. OR the HTML extension and use out of the box Design Studio controls for the rest of the tile…
  3. OR if you could try the Rapid Prototyping HTML extension but you then need to watch out for script injection on your own.

The choice is yours… Although I’d recommend option 1 for following along with this blog 😉


Steps

These steps are for SAP BusinessObjects Design Studio 1.6 to create a fiori-like Headcount tile:

Comparison+Tile+screenshot.png


Create the overall tile in your Design Studio application


  1. Add a Panel component to the canvas and use these settings:
    1. Width: 184
    2. Height: 176
  2. Add a KPI Tile component into your panel and use these settings:
    1. Top Margin: 0
    2. Left Margin: 0
    3. Width: 184
    4. Height: 176
    5. Header: Headcount
    6. Title:
    7. Footer:
    8. Value:
    9. Value Suffix:
  3. Add a HTML component into your panel and use these settings:
    1. Top Margin: 40
    2. Left Margin: 10
    3. Width: 164
    4. Height: 100

The tile should look something like this:
KPI_tile_blank.png

Create the Design Studio script to set the HTML bars at runtime

Here is the HTML for the hard coded bars from the last blog:


<table width="100%" style="bottom: 14px; border-collapse: collapse; position: absolute; line-height: normal; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: normal;" border="0">
    <tbody>
        <tr style="border-top-color: transparent; border-top-style: solid;">
            <td style="color: rgb(51, 51, 51);">Male</td>
            <td align="right" style="color: rgb(51, 51, 51);">5,845</td>
        </tr>
        <tr>
            <td height="12" style="background: linear-gradient(to right, rgb(88, 181, 230) 0%, rgb(88, 181, 230) 100%, rgb(211, 217, 221) 100%, rgb(211, 217, 221) 100%, rgb(211, 217, 221) 100%);" colspan="2" /> </tr>
        <tr style="border-top-color: transparent; border-top-style: solid;">
            <td style="color: rgb(51, 51, 51);">Female</td>
            <td align="right" style="color: rgb(51, 51, 51);">4,957</td>
        </tr>
        <tr>
            <td height="12" style="background: linear-gradient(to right, rgb(88, 181, 230) 0%, rgb(88, 181, 230) 84.81%, rgb(211, 217, 221) 84.81%, rgb(211, 217, 221) 84.81%, rgb(211, 217, 221) 100%);" colspan="2" /> </tr>
    </tbody>
</table>







We are now going to turn that script into global scripts within Design Studio:

  1. In Design Studio, under Technical Components, create a Global Scripts Object
  2. We will split the script into three parts:
    1. The header – the top of the HTML table
    2. A bar – we will call this for the Male and the Female entries
    3. The footer – the bottom of the HTML table
  3. Create the table header HTML global script function:
    1. On GLOBAL_SCRIPTS_1 create a script function:
      1. Name: createMiniChartHeader
      2. Input Parameters:
        1. None
      3. Return Type:
        1. String
      4. Code:
        
        return "<table width='100%' style='bottom: 14px; " +
         "border-collapse: collapse; " +
         "position: absolute; line-height: normal; " +
         "font-family: Arial, Helvetica, sans-serif; " +
         "font-size: 14px; font-weight: normal;' border='0'>" +
         "<tbody>";
        
  4. Create the bar HTML global script function:
    1. On GLOBAL_SCRIPTS_1 create a script function:
      1. Name: createMiniChartBar
      2. Input Parameters:
        1. title of type String
        2. valueText of type String
        3. valuePercent of type float
        4. color of type String
        5. noFillColor of type String
      3. Return Type:
        1. String
      4. Code:
        
        // Max bar is 100%.
        valuePercent = Math.min(100.0, valuePercent);
        // Return the title, value and linear gradient bar html for the value percentage.
        
  5. Create the table footer HTML global script function:
    1. On GLOBAL_SCRIPTS_1 create a script function:
      1. Name: createMiniChartFooter
      2. Input Parameters:
        1. None
      3. Return Type:
        1. String
      4. Code:
        
        return "</tbody></table>";
        
  6. The data behind this app is simple:
    Title Value
    Male 5845
    Female 4957
  7. The data source DS_1 looks like this in Edit Initial View:
    KPI_tile_EditInitialView.png
  8. And finally for the scripting, create the script that uses the three mini chart scripts to create the bars at runtime:
    1. We are going to create the application startup script that:
      1. Reads the titles and values from from DS_1
      2. Keeps track of the total value and maximum value (used to calculate the value percentages later on)
      3. Creates the mini chart header HTML
      4. For each title from DS_1 it adds a mini chart bar HTML based on the value percentage (so in this case one for Male and one for Female)
      5. Creates the mini chart footer
      6. Shows the mini chart in HTML_1
      7. Shows the total value in the KPI_TILE_1 footer
    2. On the application add the following to your On Startup event script:
    3. 
      // Calculate max value.
      var title = "";
      var value = 0.0;
      var maxValue = 0.0;
      var totalValue = 0.0;
      var memberValues = DS_1.getMembers("Title", 2);
      memberValues.forEach(function(element, index) {
        // Get the value title and value.
        title = element.internalKey;
        value = DS_1.getData("Value", {
          "Title": title
        }).value;
        // Keep track of the total and maximum value.
        totalValue = totalValue + value;
        maxValue = Math.max(value, maxValue);
      });
      // Create the mini chart HTML header.
      var miniChart = GLOBAL_SCRIPTS_1.createMiniChartHeader();
      // Create the mini chart HTML bars.
      var valuePercent = 0.0;
      var valueText = "";
      var numFormat = "#,##0";
      var color = "rgb(88, 181, 230)";  // Blue.
      var noFillColor = " rgb(211, 217, 221)";  // Light gray.
      memberValues.forEach(function(element, index) {
        // Get the value title and value.
        title = element.internalKey;
        value = DS_1.getData("Value", {
          "Title": title
        }).value;
        // Convert the value into a formatted string.
        valueText = Convert.floatToString(value, numFormat);
        // Calculate the value percentage.
        valuePercent = 0;
        if (maxValue > 0) {
          valuePercent = value / maxValue * 100.0;
        }
        // Add the bar HTML.
        miniChart = miniChart +
              GLOBAL_SCRIPTS_1.createMiniChartBar(title,
                  valueText, valuePercent, color, noFillColor);
      });
      // Create the mini chart HTML footer.
      miniChart = miniChart + GLOBAL_SCRIPTS_1.createMiniChartFooter();
      // Set the HTML bar.
      HTML_1.setHtml(miniChart);
      // Set the KPI Tile footer - the total value.
      KPITILE_1.setFooterText("Total: " +
          Convert.floatToString(totalValue, numFormat));
      
  9. Test your app in a browser and it should look something like this:
    KPI_tile_before_CSS.png

Thats getting very close, finally we can add some CSS to the tile title and total.

Add CSS for styling the tile and bars

  1. Go to the Custom CSS setting for your application and if you don’t have one assigned, click the blank field and then the Pencil button to create an empty CSS file. Then click the button to browse for your file.
  2. Add the following CSS to your Custom CSS file:
  3. 
    .borderBox {
    box-sizing: border-box !important; /* do not include the margins in the overall size, so we match the width and height set in Design Studio */
    }
    .kpiTile {
    background-color: #FFFFFF;
    border: 1px solid #797979;
    border-radius: 4px;
    box-sizing: border-box !important; /* do not include the margins in the overall size, so we match the width and height set in Design Studio */
    }
    .kpiTileHeader {
    font-family: arial,sans-serif;
    font-size: 16px;
    font-weight: normal;
    color: #333333 !important;
    box-sizing: border-box !important; /* do not include the margins in the overall size, so we match the width and height set in Design Studio */
    }
    .kpiTileFooter {
    font-family: arial,sans-serif;
    font-size: 14px;
    font-weight: normal;
    color: #666666;
    box-sizing: border-box !important; /* do not include the margins in the overall size, so we match the width and height set in Design Studio */
    }
  4. Now we can assign these CSS classes to your components:
    1. Change your panel component settings:
      1. CSS Class: borderBox
    2. Change the KPI Tile settings:
      1. CSS Class: kpiTile
      2. Header CSS Class: kpiTileHeader
      3. Footer CSS Class: kpiTileFooter
      4. Footer Horizontal Alignment: right
  5. And thats it!

Here is the finished tile running in a web browser

KPI_tile_finished.png

And as a bonus exercise you can tidy up the Design Studio script by moving the header and bar styles into your CSS file.

Thanks for tuning in, Happy Holidays, see you again in 2016!


Resources


To report this post you need to login first.

5 Comments

You must be Logged on to comment or reply to a post.

    1. Matt Lloyd Post author

      Hi Cristina,

      I’ll update this post once it is out, but it is not out as yet…

      If you have the SCN components already I mentioned in the post that you can try the Rapid Prototyping as that is similar but be careful of script injection.

      Regards

      Matt

      (0) 
  1. Ruben Valdez

    Hi Matt,

    I used Rapid Prototyping, but i have a problem with script:

    Script validation error. Contact the application designer to resolve the issue. Details logged using

    the only difference is that I am using Events

    OnBackground Processing

    var titled = “”; 

    var value = 0.0; 

    var maxValue = 0.0; 

    var totalValue = 0.0; 

    var memberValues = DS_1.getMembers(“YYYY”, 100); 

    memberValues.forEach(function(element, index) { 

      // Get the value title and value. 

      titled = element.internalKey; 

      value = DS_1.getData(“XXXX”, { 

        “YYYY”: titled 

      }).value; 

      // Keep track of the total and maximum value. 

      totalValue = totalValue + value; 

      maxValue = Math.max(value, maxValue); 

    }); 

    // Create the mini chart HTML header. 

    var miniChart = GLOBAL_SCRIPTS_1.createMiniChartHeader(“”);

    // Create the mini chart HTML bars. 

    var valuePercent = 0.0; 

    var valueText = “”; 

    var numFormat = “#,##0”; 

    var color = “rgb(88, 181, 230)”;  // Blue. 

    var noFillColor = ” rgb(211, 217, 221)”;  // Light gray. 

    memberValues.forEach(function(element, index) { 

      // Get the value title and value. 

      titled = element.internalKey; 

      value = DS_1.getData(“XXX”, { 

        “YYYY”: titled 

      }).value; 

      // Convert the value into a formatted string. 

      valueText = Convert.floatToString(value, numFormat); 

      // Calculate the value percentage. 

      valuePercent = 0; 

      if (maxValue > 0) { 

        valuePercent = value / maxValue * 100.0; 

      } 

      // Add the bar HTML. 

      miniChart = miniChart + 

            GLOBAL_SCRIPTS_1.createMiniChartBar(titled, 

                valueText, valuePercent, color, noFillColor); 

    }); 

    // Create the mini chart HTML footer. 

    miniChart = miniChart + GLOBAL_SCRIPTS_1.createMiniChartFooter(); 

    // Set the HTML bar. 

    RAPIDPROTOTYPE_1.setHTML(miniChart); 



    (0) 
  2. Ruben Valdez

    Hi Matt,

    Bootstrap would also like to include this component libraries using impressive source icons or sapui , I recommend that you give more presentation of this KPI.

    regards

    (0) 
  3. Maddy Pena

    Hi Matt!

    I’m trying to do this with RapidPrototyping, but I’m having trouble generating the graph… the header and footer are fine (with the correct value at the footer), the bars are the ones I’m having trouble with.

    I must be missing something, but with the step 4, createMiniChartBar, the result I’m obtaining is this:

    Capture.PNG

    I change the code to: return “valuePercent = Math.min(100.0, valuePercent);”;

    otherwise it wouldn’t work…

    Am I missing anything? I unsderstand that Math.min is a function of desing studio scripting and not from HTML, but I can’t find my error…Do I need to somewhat adapt the previous html code from your last post?

    Thanks a lot for your time!

    Edit:

    Nevermind, I got it!

    Here’s the code if anyone needs it:

    return  “<tr style=’border-top-color: transparent;’border-top-style: solid;’>” +

    “<td style=’color: rgb(51, 51, 51);’>” + title + “</td>” + 

    “<td align=’right’ style=’color: rgb(51, 51, 51);’>” + valueText + “</td></tr>” +

    “<tr>” +

    “<td height=’12’ style=’background: linear-gradient(to right, ” + color + ” ” + valuePercent + “%,” + color + ” ” + valuePercent + “%,” + noFillColor + ” ” + valuePercent + “%,” + noFillColor + ” ” + valuePercent + “%,” + noFillColor + ” ” + valuePercent + “%);’ colspan=’2′> </td> </tr>”;

    (0) 

Leave a Reply