Skip to Content
Technical Articles
Author's profile photo Arijit Das

D3 Force Bubble Custom Widget for SAP Analytics Cloud

Hello everyone!! This is my first blog on SAC Custom widgets. Here let me share the custom Force Bubble widget for SAC that I’ve created using D3.js.

In this widget, each data point is represented by a bubble which are plotted on x-axis with help of D3 – Force Layout.

Short Demo:

Features:

Builder panel:

Following configuration options are given in the Builder panel:

1. Data:

Hard-coded data can be fed to the chart with this option. Data to be entered in following format:

[
  {"name":"Label 1","size":850.84, "color":50.7, "xvalue":100},
  {"name":"Label 2","size":3308.76, "color":10, "xvalue":20.5}
]
  • name: The label of the bubble.
  • size: The value which is represented by the size of the bubble.
  • color: The value which is represented by the color of the bubble.
  • xvalue: The value based on which the bubbles are plotted on x-axis.

After the data is keyed in, Set Data button to be clicked to feed the data into the chart.

It is also possible to set the data by script. This is described in the Scripting section.

2. X-Axis label: The label to be used for the measure plotted on x-axis of the chart.

3. Size-Axis label: The label to be used for the measure represented by size of the bubble.

4. Color-Axis label: The label to be used for the measure represented by color of the bubble.

5. Decimal place of value on x-axis: Decimal places to display for the measure plotted on x-axis of the chart.

6. Decimal place of value on size-axis: Decimal places to display for the measure represented by size of the bubble.

7. Decimal place of value on color-axis: Decimal places to display for the measure represented by color of the bubble.

 

Styling panel:

Following configuration options are given in the Styling panel:

1. Title: The title of the chart.

2. Show Title: Show or hide the title of the chart.

3. Show Average Line: Show or hide the average line in the chart.

4. Define Color Scale: Define the start and end color of the color scale. The lowest value will be represented by start color and the highest value will be represented by the end color.

 

Event:

onSelect(): void

Called when a bubble is clicked. The widget only supports single selection. The selected bubble to be clicked again to de-select.

 

Scripting:

In addition to the standard methods inherited from Widget, following methods are available for the component to be used in scripting:

setTitle(textstring)void Set title of the chart.
setTitleVisible(flag: boolean): void Show / hide the title of the chart.
setAvgVisible(flag: boolean): void Show / hide the average line in the chart.
setStartColor(color: string): void Set the start color of the color scale.

Example: 
FBUBBLE_1.setStartColor("#f00");
setEndColor(color: string): void Set the end color of the color scale.

Example: 
FBUBBLE_1.setEndColor("green");
setXAxisLabel(textstring)void Set the name to be used for the measure plotted on x-axis of the chart.
setSizeAxisLabel(textstring)void Set the name to be used for the measure represented by size of the bubble.
setColorAxisLabel(textstring)void Set the name to be used for the measure represented by color of the bubble.
setValueDecimal(value: integer): void Set the decimal places to display for the measure plotted on x-axis of the chart.
setSizeValueDecimal(value: integer): void Set the decimal places to display for the measure represented by size of the bubble.
setColorValueDecimal(value: integer): void Set the decimal places to display for the measure represented by color of the bubble.
setData(jsonData: string): void

Set the data to be plotted in the chart. The data to be passed as a string in following JSON format:

[

  {“name”:“Label 1”, “size”:850.84, “color”:50.7, “xvalue”:100},

  {“name”:“Label 2”, “size”:3308.76, “color”:10, “xvalue”:20.5}

]

Example:
FBUBBLE_1.setData('[{"name":"Label 1","size":850.84, "color":50.7, "xvalue":100},{"name":"Label 2","size":3308.76, "color":10, "xvalue":20.5}]');
getSelectedLabel(): string

Returns the label of the selected bubble when a bubble is clicked.

When de-selected, this method returns undefined.

getSelectedXValue(): number

Returns the x-axis value of the selected bubble when a bubble is clicked.

When de-selected, this method returns undefined.

getSelectedSizeValue(): number

Returns the size-axis value of the selected bubble when a bubble is clicked.

When de-selected, this method returns undefined.

getSelectedColorValue(): number

Returns the color-axis value of the selected bubble when a bubble is clicked.

When de-selected, this method returns undefined.

 

How to prepare data for the chart:

As of now, there is no option to bind a custom widget with a data source. Hence, we have to feed data to the widget dynamically using the setData method. Here is an example on how to prepare the data in desired format before feeding to this custom widget:

Step #1:

Insert a table in the canvas with one or more dimensions and minimum three measures. In this example, I have taken Product as dimension and Units_Sold, Sales_Value and Discount as measures.

Step #2:

Create a Script Function createJSONData(): string as below:

var DS_1 = Table_1.getDataSource();
var dimList = DS_1.getMembers("Product",100);
var json = "";
for(var i = 0; i < dimList.length; i++){
	var label = '"name":"'+dimList[i].id+'"';
	var value = DS_1.getData({
		"@MeasureDimension":"[Account].[parentId].&[Sales_Value]", 
		"Product":dimList[i].id
	});
	var svalue = DS_1.getData({
		"@MeasureDimension":"[Account].[parentId].&[Units_Sold]", 
		"Product":dimList[i].id
	});
	var cvalue = DS_1.getData({
		"@MeasureDimension":"[Account].[parentId].&[Discount]", 
		"Product":dimList[i].id
	});		
	var val='';
	var sval='';
	var cval='';
	if(value === undefined || svalue === undefined || cvalue === undefined){
		// Do nothing
	}else{
		val = value.rawValue;
		sval = svalue.rawValue;
		cval = cvalue.rawValue;
		json = json + "{" + label + "," + '"xvalue":' + val + ","+'"size":' + sval +',"color":'+cval+"},";
	}	
}
json = "[" + json.substring(0,json.length-1) + "]";
return json;

Step #3:

Call following script in Application – onInitialization (and if required, in Table_1 – onResultChanged) to feed the data into the custom widget:

FBUBBLE_1.setData(ScriptObject_1.createJSONData());

If the table is not to be displayed, we can hide the table with:

Table_1.setVisible(false);

 

Code:

The code is available here if you are interested to have a look:

 

Assigned Tags

      9 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Ramu Moraboyina
      Ramu Moraboyina

      Hi Arjit,

      Thanks for the informative blog.

      Is there any information on how to connect Custom widget to a model?

       

      Regards

      Ramu

      Author's profile photo Arijit Das
      Arijit Das
      Blog Post Author

      Hi Ramu,

      Unfortunately, binding a custom widget directly to a model is not possible as of now. This is a limitation of SAC at present. That's why in this example we have used script to feed the data to the widget.

       

      Regards,

      Arijit

      Author's profile photo Shimon Chhabra
      Shimon Chhabra

      Hi Arijit,

      Thanks for the wonderful blog.

      I am new to this world and would like to know how can I utilize the existing chart libraries for eg. D3, AMcharts etc. As the third party libraries are available in the combination of HTML+JS+CSS, but the code you have provided here in the form of web component.

      Regards,

      Shimon

      Author's profile photo Arijit Das
      Arijit Das
      Blog Post Author

      The extension for SAC Analytic Designer is created as web component. You can easily use D3, AMCharts etc to create the main component. In this example, I have used D3 and lodash third party libraries.

      Author's profile photo Shimon Chhabra
      Shimon Chhabra

      Hello Arijit,

      Thanks for the reply. Are their any tutorials available to create the main component for D3 or AMcharts. Could you please share some links.

       

      Thanks and regards,

      Shimon

      Author's profile photo Arijit Das
      Arijit Das
      Blog Post Author

      The only tutorial that I found was the official product documentation from SAP (https://help.sap.com/viewer/0ac8c6754ff84605a4372468d002f2bf/release/en-US).

      You can also follow the blogs from Ferry Djaja.

       

      Regards,

      Arijit

      Author's profile photo Barry Corcoran
      Barry Corcoran

      Hi Arijit,

      This is a great tutorial, is there any update or functionality now to support connecting a custom widget to a dataset or model within SAC?

      Regards,

      Barry

      Author's profile photo Arijit Das
      Arijit Das
      Blog Post Author

      Thanks Barry.

      Unfortunately binding a custom widget directly with a data source is still not possible. I am unable to find anything regarding this in the roadmap as well.

      Regards,

      Arijit

      Author's profile photo Barry Corcoran
      Barry Corcoran

      That's very unfortunate. Do you know of any charting libraries that facilitate connecting a custom widget to a dataset or model?

      Regards,

      Barry