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
Advisor
Advisor

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

In our last installment, we too our first baby steps with D3; drawing a colored arc with defined inner and outer radii. We did this in raw html and the next step here will be to bring this into Design Studio.  To do this, we’ll need to do two things:

  1. We’ll need to ensure that D3 is available to Design Studio’s component.
  2. We'll need to copy our javascript from the html file to the component's component.js file and adapt it for life within a component.

Starting with your component project open in Eclipse:

Step 2b.1 -

Our first challenge is with adding includes in Design Studio components.  We actually did this for our component.js file in Step 1.10f, when we set up our component.  The <jsInclude> element lets you define any Javascript file that is going to be imported and can be an internet URL, or a local filepath.  Now we could import D3 this way and grab it from the location that we used in the <script> element of our HTML file.  It won't work, however.  The problem is that D3 - as it currently stands - does not play nice with Include.js; which Design Studio's SDK uses to manage diverse javascript packages.  Therefore, Design Studio's SDK includes a patched D3.  Libraries that ship with Design Studio's SDK can be accessed via another tag; <stdInclude>, with the attribute indicating the kind of standard include.   So, just above your jsInclude  for the component.js file, add the following line:


<stdInclude kind="d3"/>







Note.  In our original component setup, we'd already accidentally included it in the provided component.xml, even though it was not mentioned.  So if you simply copied it from there, then it is already in.

Step 2b.2 -

Recall from Step 1.9 of the project setup instalment, that our component.js fille currently looks like this:


sap.designstudio.sdk.Component.subclass("com.sap.sample.scngauge.SCNGauge", function() {



     var that = this;



});







Inside of this subclass, we are going to override the init() function of the parent class.  You can leave the contents of the function blank for the moment:


sap.designstudio.sdk.Component.subclass("com.sap.sample.scngauge.SCNGauge", function() {



     var that = this;



     this.init = function() {



     };


});







Step 2b.3 -

Let's start by copying and pasting the PI declaration from step 2a.2 of the last instalment, so that we don't forget it.  While we're at it, let's declare it alongside the that = this declaration, so that it is accessible outside of the init() function.  Our component.js should not look like this:


sap.designstudio.sdk.Component.subclass("com.sap.sample.scngauge.SCNGauge", function() {



     var that = this;


     var pi = Math.PI;



     this.init = function() {



     };


});







Step 2b.4 -

As you may recall from step Step 2a.3  of the last instalment, we attached an svg container element to the div that we'd set aside for holding our visualization.  We were looking for a div with the tag "#content" and attaching our svg there.  For review, that line of code looked like this:


var vis = d3.select("#content")


                    .append("svg:svg")


                    .attr("width", "100%")


                    .attr("height", "100%");







We'll be doing something conceptually similar inside of our init() function; attaching an svg element to a div and then working with it.  The key difference is that previously, we were working directly with the html document DOM and in Design Studio components, this is a discouraged practice.  You should stay within your component handler, for the sake of security and stability.  (in fact, SAP won't certify a partner component that goes outside of its handler)  The syntax is slightly different.

We'll still be using D3's select method to get our div, but we won't be passing a tag to it.  We'll first ask the component handler to giv us the div and we'll then pass the div itself as the parameter:


var myDiv = this.$()[0];







Let's break this down.  this is the handler instance.  The $() is a Jquery method for getting the root div within the handler instance. $ is shorthand for Jquery and you'll often see it in JavaScript code that uses Jquery.  If there is an id parameter, tag parameter, or a css class parameter, we'd take that, but if the S() call has an empty, it will select the root div.  Since this returns a list, we'll take the first element.   As you may recall from Step 1.9 of the initial project creation instalment, we can't *always* be certain that this is in fact the component handler and that the scope might have changed on us.  That's what we declare a variable named that and set it to this,  We'll use that here, instead of this.

So now we can actually add the line to init():

var myDiv = that.$()[0];

Now that we have the div, we can select it and attach the svg element:


var vis = d3.select(myDiv)


                    .append("svg:svg")


                    .attr("width", "100%")


                    .attr("height", "100%");







Step 2b.5 -

Copy and paste the rest of the Javascript code from last time; specifcially the parts from steps 2a.4 and 2a.5.  Your component.js should now look like the following:


sap.designstudio.sdk.Component.subclass("com.sap.sample.scngauge.SCNGauge", function() {



     var that = this;


     var pi = Math.PI;



     this.init = function() {


          var myDiv = that.$()[0];


          var vis = d3.select(myDiv).append("svg:svg").attr("width", "100%").attr("height", "100%");



          var arc = d3.svg.arc()


                         .innerRadius(0)


                         .outerRadius(70)


                         .startAngle(45 * (pi/180)) //converting from degs to radians


                         .endAngle(3) //just radians



          vis.attr("width", "400").attr("height", "400") // Added height and width so arc is visible


               .append("path")


               .attr("d", arc)


               .attr("fill", "red")


               .attr("transform", "translate(200,200)");


     };



});







Step 2b.6 -

Start Design Studio in debug mode, with the component project open.  Add the gauge component to the canvas of an otherwise blank DS app.

Note that even though the component is supposedly a 100pc x 100px component, the arc is actually entered on a position offset 200x200 from the origin.  That's because we've hardcoded our gauge's size and offset and ignore what's in the properties pane.  In a later instalment, we'll fix this.

As always, the completed extension (as of part 2) is available as a Github repository.

Next Instalment: Part 3a - Making the Arc Configurable

6 Comments