SAP Analytics Cloud comes with a wide range of charts right out of the cloud. Should you have charting requirements that go beyond the standard functionality, power users can add new chart types for their business users through R scripting. These new charts can be static or interactive.
In this blog I explain how to add an interactive Sankey chart to SAP Analytics Cloud. This new chart type will come with mouse-overs and even drag and drop functionality. Since R already has a chart that does all this, the chart does not have to be created from scratch. We just need to embed that chart into SAP Analytics Cloud.
The steps in this blog are meant to be implemented by a power user, who is familiar with R. A business users can then easily work with that chart without having to know how the chart was created.
The R code in this blog was prepared for a customer who found it useful. The usual small print applies though. Please note that this sample is not part of the official product, it is not supported, and please do your own tests to ensure that it is working as expected.
I am assuming you are already familiar with SAP Analytics Cloud and how to add new R Visualizations. This
blog by Yannick Schaper for instance gives a very detailed overview and Marc Daniau published an extensive
blog series on adding charts to SAP Analytics Cloud.
Being familiar with the typical steps of adding such a chart to SAP Analytics Cloud will hopefully help you adjust the Sankey chart, if needed. Maybe you will even want to add additional chart types to SAP Analytics Cloud. Hence I am sharing the code in the different stages of development. If you are just interested in the final outcome, you can skip right to the end of this blog (step 3).
Step 1: Create a basic version of the chart
Firstly, you want to be sure that the charting library you are working with will be able to deliver the graphic you are looking for. Hence, begin by creating a simple chart based on some sample data.
Paste the following code into a new R Visualization and hit 'Execute'.
# Plot
library('plotly')
plot_ly(
type = 'sankey',
orientation = 'h',
textfont = list(size=15),
node = list(
label = c("Americas", "Europe", "USA", "Finland", "Canada", "Germany", "Switzerland", "Austria"),
color = c(rep("ed7c31", 2), rep("5b9bd5", 6)),
pad = 10,
thickness = 30,
line = list(
color = "black",
width = 1
)
),
link = list(
source = c(0, 1, 0, 1, 1, 1),
target = c(2, 3, 4, 5, 6, 7),
value = c(9, 20, 90, 4, 4, 😎
)
)
The chart shows up! The "Environment" section is still empty, as no data is yet dynamically passed from SAP Analytics Cloud into the chart.
You see in the above code that all values that are to be displayed and all additional parameters are hardcoded directly in the charting function. To better understand this plot_ly() function from the plotly package, which produces the chart, see this
introduction.
When creating your own charts it is important to use only
R packages that are installed in SAP Analytics Cloud. Should you require additional R packages, you must provide your
own R server.
Step 2: Re-design the code to deal with different datasets
In the previous step we hardcoded many settings to quickly produce and test a chart, which is absolutely fine at this stage. To deploy the chart into production, it has to be able to deal with different datasets though, ie with datasets that have more or fewer rows of data. In this step the code is adjusted to add this dynamic element.
In the following code the data for the chart is stored in a data frame and the plotting function dynamically retrieves all necessary information from that data frame. Replace the existing R syntax in SAP Analytics Cloud with the following code and hit 'Execute'.
# input data
left <- c("Americas", "Europe", "Americas", "Europe", "Europe", "Europe")
right <- c("USA", "Finland", "Canada", "Germany", "Switzerland", "Austria")
measure <- c(9, 20, 90, 4, 4, 😎
# data prep for charting
df_raw <- data.frame(left, right, measure, stringsAsFactors=FALSE)
df_sorted <- df_raw[order(df_raw$left, df_raw$right), ]
# Plot
library('plotly')
plot_ly(
type = 'sankey',
orientation = "h",
textfont = list(size=15),
node = list(
label = c(unique(df_sorted[order(df_sorted$left, df_sorted$right), ]$left), (df_sorted[order(df_sorted$left, df_sorted$right), ]$right)),
color = c(rep("ed7c31", length(unique(df_sorted$left))), rep("5b9bd5", length(unique(df_sorted$right)))),
pad = 10,
thickness = 30,
line = list(
color = "black",
width = 1
)
),
link = list(
source = as.integer(factor(df_sorted[order(df_sorted$left, df_sorted$right), ]$left)) -1,
target = c(length(unique(df_sorted$left)) : (length(unique(df_sorted$left)) + length(unique(df_sorted$right)) - 1)),
value = df_sorted[order(df_sorted$left, df_sorted$right), ]$measure
)
)
The chart should look just like before. But the code is now generic and dynamically derives all details from a given dataset. This means the chart is ready for the final step.
Step 3: Connect to SAP Analytics Cloud data
Now that the code can deal with different datasets, you can dynamically pass data from SAP Analytic Cloud into the chart.
Load this
dataset into SAP Analytics cloud. Assign it as Input Data for the R Visualization and select the Country and Region as dimensions for the chart.
Then replace the existing script with the following code, which dynamically passes the three columns Region, Country and Registrations from the Input Data into the chart.
# input data
left <- as.character(VehicleRegistrations2018ByRegion.csv$Region)
right <- as.character(VehicleRegistrations2018ByRegion.csv$Country)
measure <- VehicleRegistrations2018ByRegion.csv$Registrations
# data prep for charting
df_raw <- data.frame(left, right, measure, stringsAsFactors=FALSE)
df_sorted <- df_raw[order(df_raw$left, df_raw$right), ]
# Plot
library('plotly')
plot_ly(
type = 'sankey',
orientation = "h",
textfont = list(size=15),
node = list(
label = c(unique(df_sorted[order(df_sorted$left, df_sorted$right), ]$left), (df_sorted[order(df_sorted$left, df_sorted$right), ]$right)),
color = c(rep("ed7c31", length(unique(df_sorted$left))), rep("5b9bd5", length(unique(df_sorted$right)))),
pad = 10,
thickness = 30,
line = list(
color = "black",
width = 1
)
),
link = list(
source = as.integer(factor(df_sorted[order(df_sorted$left, df_sorted$right), ]$left)) -1,
target = c(length(unique(df_sorted$left)) : (length(unique(df_sorted$left)) + length(unique(df_sorted$right)) - 1)),
value = df_sorted[order(df_sorted$left, df_sorted$right), ]$measure
)
)
Executing the code should show this chart.
Hit "Apply" and your end users can easily work with the Sankey chart. Try filtering your story and the chart should get updated. Mouse-overs show the relevant measures and you can move the data segments around!
In case any special characters do not show up correctly on the chart, you may need to set the appropriate
locale. Adding this line on top for instance, makes "Österreich" (German for Austria) appear correctly.
Sys.setlocale("LC_ALL", "de_DE.UTF-8")
Happy charting