Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
david_stocker
Contributor
0 Kudos

This is part of a tutorial series on creating extension components for Design Studio.

Last time, we examined the new Array and Object property types, introduced in Design Studio 1.6.  Now we'll put that to use to add some conditional formatting.

Cleaning up the Extension and App

Before we go any further, let's remove the example array and object from last time.  They are dead ends, have no future in our gauge component and only serve to clutter up the properties pane, component.js and contribution.ztl.

  1. Clear out any values from the Array and Object from last time.
  2. Remove me._arrayExample from component.js
  3. Remove the me.getArrayExample function in component.js
  4. Remove ist functions from contribution.ztl

Our strategy for conditional formatting will be as follows:

  • We'll add a new group for managing color, simply to clean of organization in the properties pane.
  • We'll have a default color for the graph.
  • We'll maintain a list of threshold measure value (aka threshold) /color pairs.
  • Whenever we redraw, we need to double check the color.  We do this be running through the list of threshold /color pairs.  If the measure value is greater than the threshold value, then that color becomes the color of the gauge.
  • If none of the threshold values are met, the default color is kept.

We'll now take these each in turn and implement our conditional formatting.

We'll add a new group for managing color, simply to clean of organization in the properties pane.

To implement the new group, we'll add it to the contribution.xml file


  <group


  id="SCNGaugeColorSettings"


  title="Color"


  tooltip="Gauge Color and Conditional Formatting Settings"/>





We'll have a default color for the graph

The colorCode property will remain mostly unchanged.  We'll simply change its display text to "Default Color" and move it to the new Color group.


<property


  id="colorCode"


  title="Default Color"


  type="Color"


  bindable="true"


  group="SCNGaugeColorSettings"/>





We'll maintain a list of threshold  /color pairs.

For each threshold  /color pair, we'll use an Object, with threshold and color as properties.  Threshold will be an integer and color will be of type color; allowing us to use the color picker.  Since we'll have 0..n threshold  /color pairs, we'll wrap that Object into an Array.


<property id="colorArray" type="Array" title="Conditional Formatting" group="SCNGaugeColorSettings">


  <property id="conditionalFormat" type="Object" title="Conditional Format">


    <property id="threshold" type="int" title="Measure Threshold" />


  <property id="colorID" type="Color" title="Color Code" />


  </property>


</property>





We've got the basics of the properties covered.  We should now have a Color group, with a default color and an Array of Conditional Formatting objects.

Whenever we redraw, we need to double check the color...

To do this, we'll introduce a new, component.js only property; called me._displayedColor.  The redraw() function should use this property to color the gauge, rather than color.  Our colorArray also needs a getter/setter function.


//Part 7 conditional formatting


me._colorCode = 'blue';


me._displayedColor = 'blue'


me._colorArray = 1;  //abusing JS duck typing here.  😉





me.colorArray = function(value) {


  if (value === undefined) {


  return me._colorArray;


  } else {


  me._colorArray = value;


  me.redraw();


  return this;


  }


};





var guageArc = vis.append("path")


    .style("fill", me._displayedColor)


    .attr("width", me.$().width()).attr("height", me.$().height()) // Added height and width so arc is visible


    .attr("transform", "translate(" + me._offsetLeft + "," + me._offsetDown + ")")


    .attr("d", arcDef);




Now, before we do anything else in redraw(), we'll go ahead and determine the color of the gauge.  We'll call this new function me.recolor().

  1. Start with colorCode as the candidate color.
  2. Run down the formatting objects in the array.  If the measure value is greater than the threshold value, then the corresponding color code becomes the new candidate color.
  3. The candidate color is applied to me._displayedColor


//Recolors the gauge, using the bottommost valid conditional formatting rule


//   and defaulting to me._colorCode if no conditions are met.


me.recolor = function() {




  // Always default to the color defined in the Color property of the properties pane


  //   If no conditional formatting rules are met, then this will be the color that we use.


  var formattingColor = me._colorCode;



  if (me._colorArray != undefined){


  var index;


  for (index = 0; index < me._colorArray.length; index++){


  var conditionalFormattingRule = me._colorArray[index];


  if (conditionalFormattingRule.threshold <= me._measureVal){


  formattingColor = conditionalFormattingRule.colorID;


  }


  }



  //Only update me._displayedColor (and trigger a redraw) if the color is actually


  if (formattingColor != me._displayedColor){


  me._displayedColor = formattingColor;


  me.redraw();


  }


  }


  return this;


}




Calling it from me.redraw() only takes a single line of code, at the beginning:


//What color should we use?


me.recolor();




Now we can test our gauge.  We'll use the following in the test:

  • Default Color is Red
  • Conditional Formatting Rule 1: Threshold = 1000000, Color = Yellow
  • Conditional Formatting Rule 1: Threshold = 2000000, Color = Green

When the gauge Measure Value property is less than one million, the Gauge is Red:

When the gauge Measure Value property is greater than one million and less than two million, the Gauge is Yellow:

When the gauge Measure Value property is greater than two million, the Gauge is Green:

As usual, the current state of the project is in Github.