Skip to Content
Technical Articles

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:

 

2 Comments
You must be Logged on to comment or reply to a post.
    • 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